@needle-tools/three-animation-pointer 1.0.0 → 1.0.1-next.1a466a6
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/CHANGELOG.md +1 -1
- package/README.md +37 -2
- package/dist/three-animation-pointer.js +343 -0
- package/package.json +14 -5
package/CHANGELOG.md
CHANGED
|
@@ -4,5 +4,5 @@ All notable changes to this package will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
-
## [1.0.
|
|
7
|
+
## [1.0.1] - 2025-08-27
|
|
8
8
|
- Initial release
|
package/README.md
CHANGED
|
@@ -2,7 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
This package adds a [three.js](https://github.com/mrdoob/three.js) GLTFLoader plugin for [KHR_animation_pointer](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_animation_pointer) support.
|
|
4
4
|
|
|
5
|
-
###
|
|
5
|
+
### Animate anything
|
|
6
|
+
- all material properties 💎 (including texture transforms)
|
|
7
|
+
- cameras 🎥
|
|
8
|
+
- lights 💡
|
|
9
|
+
- custom code/scripts 📄
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Three.js Example
|
|
13
|
+
<a href="https://threejs.org/examples/?q=gltf#webgl_loader_gltf_animation_pointer" target="_blank">
|
|
14
|
+
<img width="1240" height="696" alt="image" src="https://github.com/user-attachments/assets/baa109d8-974b-4c97-9ae9-31a4391e651b" />
|
|
15
|
+
</a>
|
|
16
|
+
|
|
17
|
+
https://github.com/user-attachments/assets/13fe4102-00ee-430f-9a17-9611fa543f77
|
|
18
|
+
|
|
19
|
+
[three.js Example](https://threejs.org/examples/?q=gltf#webgl_loader_gltf_animation_pointer)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### How to use
|
|
6
24
|
|
|
7
25
|
Install the package:
|
|
8
26
|
`npm i @needle-tools/three-animation-pointer`
|
|
@@ -16,9 +34,26 @@ import { GLTFAnimationPointerExtension } from "@needle-tools/three-animation-poi
|
|
|
16
34
|
const loader = new GLTFLoader();
|
|
17
35
|
loader.register(p => {
|
|
18
36
|
return new GLTFAnimationPointerExtension(p);
|
|
19
|
-
}
|
|
37
|
+
});
|
|
20
38
|
```
|
|
21
39
|
|
|
40
|
+
### How to create glTF files using KHR_animation_pointer
|
|
41
|
+
|
|
42
|
+
You can use one of the listed tools below to export glTF animations in the right format
|
|
43
|
+
|
|
44
|
+
- [Blender 4.3](https://www.blender.org/) and newer - *experimental KHR_animation_pointer support, currently only in 'scene animation' mode ([#2285](https://github.com/KhronosGroup/glTF-Blender-IO/issues/2285))*
|
|
45
|
+
- [Needle Engine for Unity](https://engine.needle.tools/docs/unity/) - defaults to KHR_animation_pointer and battle tested since 2022
|
|
46
|
+
- [UnityGLTF](https://github.com/KhronosGroup/UnityGLTF)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
**Mini Unity Tutorial**
|
|
50
|
+
|
|
51
|
+
https://github.com/user-attachments/assets/e118a33d-9725-4313-b1d4-b4dbfc7a5a48
|
|
52
|
+
|
|
53
|
+
*Note: If you use UnityGLTF for exporting the glTF file make sure to enable the `KHR_animation_pointer` option in the UnityGLTF export settings.*
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
22
57
|
## Links
|
|
23
58
|
|
|
24
59
|
- [Khronos KHR_animation_pointer spec](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_animation_pointer)
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { SkinnedMesh as S, InterpolateDiscrete as M, InterpolateLinear as F, AnimationClip as W, PropertyBinding as C, QuaternionKeyframeTrack as w, ColorKeyframeTrack as D, VectorKeyframeTrack as E, NumberKeyframeTrack as O } from "three";
|
|
2
|
+
const f = {
|
|
3
|
+
node: "node",
|
|
4
|
+
material: "material",
|
|
5
|
+
camera: "camera",
|
|
6
|
+
light: "light"
|
|
7
|
+
}, R = "KHR_animation_pointer", U = {
|
|
8
|
+
// We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each
|
|
9
|
+
// keyframe track will be initialized with a default interpolation type, then modified.
|
|
10
|
+
CUBICSPLINE: void 0,
|
|
11
|
+
LINEAR: F,
|
|
12
|
+
STEP: M
|
|
13
|
+
};
|
|
14
|
+
class j {
|
|
15
|
+
/** @type {import("three/examples/jsm/loaders/GLTFLoader").GLTFParser} */
|
|
16
|
+
constructor(r) {
|
|
17
|
+
this.name = R, this.parser = r, this.animationPointerResolver = null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @param {import("..").AnimationPointerResolver | null} animationPointerResolver
|
|
21
|
+
*/
|
|
22
|
+
setAnimationPointerResolver(r) {
|
|
23
|
+
return this.animationPointerResolver = r, this;
|
|
24
|
+
}
|
|
25
|
+
/* DUPLICATE of functionality in GLTFLoader */
|
|
26
|
+
loadAnimationTargetFromChannel(r) {
|
|
27
|
+
const s = r.target, a = s.node !== void 0 ? s.node : s.id;
|
|
28
|
+
return this.parser.getDependency("node", a);
|
|
29
|
+
}
|
|
30
|
+
loadAnimationTargetFromChannelWithAnimationPointer(r) {
|
|
31
|
+
var c;
|
|
32
|
+
B();
|
|
33
|
+
const s = r.target, a = s.extensions && s.extensions[R] && s.path && s.path === "pointer";
|
|
34
|
+
if (!a) return null;
|
|
35
|
+
let e, t = f.node, n;
|
|
36
|
+
if (a) {
|
|
37
|
+
const m = s.extensions[R];
|
|
38
|
+
let o = m.pointer;
|
|
39
|
+
if (!o) {
|
|
40
|
+
console.warn("Invalid path", m, s);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (o.startsWith("/materials/") ? t = f.material : o.startsWith("/extensions/KHR_lights_punctual/lights/") ? t = f.light : o.startsWith("/cameras/") && (t = f.camera), n = this._tryResolveTargetId(o, t), n === null || isNaN(n)) {
|
|
44
|
+
console.warn("Failed resolving animation node id: " + n, o);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
switch (t) {
|
|
48
|
+
case f.material:
|
|
49
|
+
const x = ("/materials/" + n.toString() + "/").length, h = o.substring(0, x);
|
|
50
|
+
switch (e = o.substring(x), e) {
|
|
51
|
+
case "pbrMetallicRoughness/baseColorFactor":
|
|
52
|
+
e = "color";
|
|
53
|
+
break;
|
|
54
|
+
case "pbrMetallicRoughness/roughnessFactor":
|
|
55
|
+
e = "roughness";
|
|
56
|
+
break;
|
|
57
|
+
case "pbrMetallicRoughness/metallicFactor":
|
|
58
|
+
e = "metalness";
|
|
59
|
+
break;
|
|
60
|
+
case "emissiveFactor":
|
|
61
|
+
e = "emissive";
|
|
62
|
+
break;
|
|
63
|
+
case "alphaCutoff":
|
|
64
|
+
e = "alphaTest";
|
|
65
|
+
break;
|
|
66
|
+
case "occlusionTexture/strength":
|
|
67
|
+
e = "aoMapIntensity";
|
|
68
|
+
break;
|
|
69
|
+
case "normalTexture/scale":
|
|
70
|
+
e = "normalScale";
|
|
71
|
+
break;
|
|
72
|
+
case "pbrMetallicRoughness/baseColorTexture/extensions/KHR_texture_transform/scale":
|
|
73
|
+
e = "map/repeat";
|
|
74
|
+
break;
|
|
75
|
+
case "pbrMetallicRoughness/baseColorTexture/extensions/KHR_texture_transform/offset":
|
|
76
|
+
e = "map/offset";
|
|
77
|
+
break;
|
|
78
|
+
case "emissiveTexture/extensions/KHR_texture_transform/scale":
|
|
79
|
+
e = "emissiveMap/repeat";
|
|
80
|
+
break;
|
|
81
|
+
case "emissiveTexture/extensions/KHR_texture_transform/offset":
|
|
82
|
+
e = "emissiveMap/offset";
|
|
83
|
+
break;
|
|
84
|
+
case "extensions/KHR_materials_emissive_strength/emissiveStrength":
|
|
85
|
+
e = "emissiveIntensity";
|
|
86
|
+
break;
|
|
87
|
+
case "extensions/KHR_materials_transmission/transmissionFactor":
|
|
88
|
+
e = "transmission";
|
|
89
|
+
break;
|
|
90
|
+
case "extensions/KHR_materials_ior/ior":
|
|
91
|
+
e = "ior";
|
|
92
|
+
break;
|
|
93
|
+
case "extensions/KHR_materials_volume/thicknessFactor":
|
|
94
|
+
e = "thickness";
|
|
95
|
+
break;
|
|
96
|
+
case "extensions/KHR_materials_volume/attenuationColor":
|
|
97
|
+
e = "attenuationColor";
|
|
98
|
+
break;
|
|
99
|
+
case "extensions/KHR_materials_volume/attenuationDistance":
|
|
100
|
+
e = "attenuationDistance";
|
|
101
|
+
break;
|
|
102
|
+
case "extensions/KHR_materials_iridescence/iridescenceFactor":
|
|
103
|
+
e = "iridescence";
|
|
104
|
+
break;
|
|
105
|
+
case "extensions/KHR_materials_iridescence/iridescenceIor":
|
|
106
|
+
e = "iridescenceIOR";
|
|
107
|
+
break;
|
|
108
|
+
case "extensions/KHR_materials_iridescence/iridescenceThicknessMinimum":
|
|
109
|
+
e = "iridescenceThicknessRange[0]";
|
|
110
|
+
break;
|
|
111
|
+
case "extensions/KHR_materials_iridescence/iridescenceThicknessMaximum":
|
|
112
|
+
e = "iridescenceThicknessRange[1]";
|
|
113
|
+
break;
|
|
114
|
+
case "extensions/KHR_materials_clearcoat/clearcoatFactor":
|
|
115
|
+
e = "clearcoat";
|
|
116
|
+
break;
|
|
117
|
+
case "extensions/KHR_materials_clearcoat/clearcoatRoughnessFactor":
|
|
118
|
+
e = "clearcoatRoughness";
|
|
119
|
+
break;
|
|
120
|
+
case "extensions/KHR_materials_sheen/sheenColorFactor":
|
|
121
|
+
e = "sheenColor";
|
|
122
|
+
break;
|
|
123
|
+
case "extensions/KHR_materials_sheen/sheenRoughnessFactor":
|
|
124
|
+
e = "sheenRoughness";
|
|
125
|
+
break;
|
|
126
|
+
case "extensions/KHR_materials_specular/specularFactor":
|
|
127
|
+
e = "specularIntensity";
|
|
128
|
+
break;
|
|
129
|
+
case "extensions/KHR_materials_specular/specularColorFactor":
|
|
130
|
+
e = "specularColor";
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
o = h + e;
|
|
134
|
+
break;
|
|
135
|
+
case f.node:
|
|
136
|
+
const u = ("/nodes/" + n.toString() + "/").length, l = o.substring(0, u);
|
|
137
|
+
switch (e = o.substring(u), e) {
|
|
138
|
+
case "translation":
|
|
139
|
+
e = "position";
|
|
140
|
+
break;
|
|
141
|
+
case "rotation":
|
|
142
|
+
e = "quaternion";
|
|
143
|
+
break;
|
|
144
|
+
case "scale":
|
|
145
|
+
e = "scale";
|
|
146
|
+
break;
|
|
147
|
+
case "weights":
|
|
148
|
+
e = "morphTargetInfluences";
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
o = l + e;
|
|
152
|
+
break;
|
|
153
|
+
case f.light:
|
|
154
|
+
const p = ("/extensions/KHR_lights_punctual/lights/" + n.toString() + "/").length;
|
|
155
|
+
switch (e = o.substring(p), e) {
|
|
156
|
+
case "color":
|
|
157
|
+
break;
|
|
158
|
+
case "intensity":
|
|
159
|
+
break;
|
|
160
|
+
case "spot/innerConeAngle":
|
|
161
|
+
e = "penumbra";
|
|
162
|
+
break;
|
|
163
|
+
case "spot/outerConeAngle":
|
|
164
|
+
e = "angle";
|
|
165
|
+
break;
|
|
166
|
+
case "range":
|
|
167
|
+
e = "distance";
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
o = "/lights/" + n.toString() + "/" + e;
|
|
171
|
+
break;
|
|
172
|
+
case f.camera:
|
|
173
|
+
const g = ("/cameras/" + n.toString() + "/").length, b = o.substring(0, g);
|
|
174
|
+
switch (e = o.substring(g), e) {
|
|
175
|
+
case "perspective/yfov":
|
|
176
|
+
e = "fov";
|
|
177
|
+
break;
|
|
178
|
+
case "perspective/znear":
|
|
179
|
+
case "orthographic/znear":
|
|
180
|
+
e = "near";
|
|
181
|
+
break;
|
|
182
|
+
case "perspective/zfar":
|
|
183
|
+
case "orthographic/zfar":
|
|
184
|
+
e = "far";
|
|
185
|
+
break;
|
|
186
|
+
case "perspective/aspect":
|
|
187
|
+
e = "aspect";
|
|
188
|
+
break;
|
|
189
|
+
case "orthographic/xmag":
|
|
190
|
+
e = "zoom";
|
|
191
|
+
break;
|
|
192
|
+
case "orthographic/ymag":
|
|
193
|
+
e = "zoom";
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
o = b + e;
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
(c = this.animationPointerResolver) != null && c.resolvePath && (o = this.animationPointerResolver.resolvePath(o)), s.extensions[R].pointer = o;
|
|
200
|
+
}
|
|
201
|
+
if (n == null || isNaN(n)) {
|
|
202
|
+
console.warn("Failed resolving animation node id: " + n, s);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
let i;
|
|
206
|
+
return t === f.node ? i = this.parser.getDependency("node", n) : t === f.material ? i = this.parser.getDependency("material", n) : t === f.light ? i = this.parser.getDependency("light", n) : t === f.camera ? i = this.parser.getDependency("camera", n) : console.error("Unhandled type", t), i;
|
|
207
|
+
}
|
|
208
|
+
createAnimationTracksWithAnimationPointer(r, s, a, e, t) {
|
|
209
|
+
if (!(t.extensions && t.extensions[R] && t.path && t.path === "pointer")) return null;
|
|
210
|
+
let i = t.extensions[R].pointer;
|
|
211
|
+
if (!i) return null;
|
|
212
|
+
const c = [];
|
|
213
|
+
i = i.replaceAll("/", ".");
|
|
214
|
+
const m = i.split(".");
|
|
215
|
+
var x = r.name !== void 0 && r.name !== null ? r.name : r.uuid;
|
|
216
|
+
if (m[2] = x, m[3] === "morphTargetInfluences" && r.type === "Group") {
|
|
217
|
+
for (const u of r.children)
|
|
218
|
+
u instanceof S && u.morphTargetInfluences && (m[3] = u.name, m[4] = "morphTargetInfluences", h(this.parser));
|
|
219
|
+
return c;
|
|
220
|
+
}
|
|
221
|
+
h(this.parser);
|
|
222
|
+
function h(u) {
|
|
223
|
+
i = m.join(".");
|
|
224
|
+
let l;
|
|
225
|
+
switch (a.itemSize) {
|
|
226
|
+
case 1:
|
|
227
|
+
l = O;
|
|
228
|
+
break;
|
|
229
|
+
case 2:
|
|
230
|
+
case 3:
|
|
231
|
+
l = E;
|
|
232
|
+
break;
|
|
233
|
+
case 4:
|
|
234
|
+
i.endsWith(".quaternion") ? l = w : l = D;
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
if (!l) {
|
|
238
|
+
console.warn("Unsupported output accessor format", a);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const p = e.interpolation !== void 0 ? U[e.interpolation] : F;
|
|
242
|
+
let g = u._getArrayFromAccessor(a);
|
|
243
|
+
i.endsWith(".fov") && (g = g.map((k) => k / Math.PI * 180));
|
|
244
|
+
const b = new l(
|
|
245
|
+
i,
|
|
246
|
+
s.array,
|
|
247
|
+
g,
|
|
248
|
+
p
|
|
249
|
+
);
|
|
250
|
+
if (p === "CUBICSPLINE" && u._createCubicSplineTrackInterpolant(b), c.push(b), i && a.itemSize === 4 && i.startsWith(".materials.") && i.endsWith(".color")) {
|
|
251
|
+
const k = new Float32Array(g.length / 4);
|
|
252
|
+
for (let T = 0, _ = g.length / 4; T < _; T += 1)
|
|
253
|
+
k[T] = g[T * 4 + 3];
|
|
254
|
+
const d = new l(
|
|
255
|
+
i.replace(".color", ".opacity"),
|
|
256
|
+
s.array,
|
|
257
|
+
k,
|
|
258
|
+
p
|
|
259
|
+
);
|
|
260
|
+
p === "CUBICSPLINE" && u._createCubicSplineTrackInterpolant(b), c.push(d);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return c;
|
|
264
|
+
}
|
|
265
|
+
_tryResolveTargetId(r, s) {
|
|
266
|
+
let a = "";
|
|
267
|
+
return s === "node" ? a = r.substring(7) : s === "material" ? a = r.substring(11) : s === "light" ? a = r.substring(39) : s === "camera" && (a = r.substring(9)), a = a.substring(0, a.indexOf("/")), Number.parseInt(a);
|
|
268
|
+
}
|
|
269
|
+
/* MOSTLY DUPLICATE of GLTFLoader.loadAnimation, but also tries to resolve KHR_animation_pointer. */
|
|
270
|
+
/**
|
|
271
|
+
* Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations
|
|
272
|
+
* @param {number} animationIndex
|
|
273
|
+
* @return {Promise<AnimationClip>}
|
|
274
|
+
*/
|
|
275
|
+
loadAnimation(r) {
|
|
276
|
+
const s = this, a = this.parser.json, e = this.parser, t = a.animations[r], n = t.name ? t.name : "animation_" + r, i = [], c = [], m = [], o = [], x = [];
|
|
277
|
+
for (let h = 0, u = t.channels.length; h < u; h++) {
|
|
278
|
+
const l = t.channels[h], p = t.samplers[l.sampler], g = l.target, b = t.parameters !== void 0 ? t.parameters[p.input] : p.input, k = t.parameters !== void 0 ? t.parameters[p.output] : p.output;
|
|
279
|
+
let d = s.loadAnimationTargetFromChannelWithAnimationPointer(l);
|
|
280
|
+
d || (d = s.loadAnimationTargetFromChannel(l)), i.push(d), c.push(e.getDependency("accessor", b)), m.push(e.getDependency("accessor", k)), o.push(p), x.push(g);
|
|
281
|
+
}
|
|
282
|
+
return Promise.all([
|
|
283
|
+
Promise.all(i),
|
|
284
|
+
Promise.all(c),
|
|
285
|
+
Promise.all(m),
|
|
286
|
+
Promise.all(o),
|
|
287
|
+
Promise.all(x)
|
|
288
|
+
]).then(function(h) {
|
|
289
|
+
const u = h[0], l = h[1], p = h[2], g = h[3], b = h[4], k = [];
|
|
290
|
+
for (let d = 0, T = u.length; d < T; d++) {
|
|
291
|
+
const _ = u[d], v = l[d], A = p[d], N = g[d], K = b[d];
|
|
292
|
+
if (_ === void 0) continue;
|
|
293
|
+
_.updateMatrix && (_.updateMatrix(), _.matrixAutoUpdate = !0);
|
|
294
|
+
let y = s.createAnimationTracksWithAnimationPointer(_, v, A, N, K);
|
|
295
|
+
if (y || (y = e._createAnimationTracks(_, v, A, N, K)), y)
|
|
296
|
+
for (let P = 0; P < y.length; P++)
|
|
297
|
+
k.push(y[P]);
|
|
298
|
+
}
|
|
299
|
+
return new W(n, void 0, k);
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
let H = !1, z = null;
|
|
304
|
+
function B() {
|
|
305
|
+
if (H) return;
|
|
306
|
+
H = !0;
|
|
307
|
+
const I = z || (z = C.findNode);
|
|
308
|
+
C.findNode = function(r, s) {
|
|
309
|
+
if (s.startsWith(".materials.")) {
|
|
310
|
+
const a = s.substring(11).substring(s.indexOf(".")), e = a.indexOf("."), t = e < 0 ? a : a.substring(0, e);
|
|
311
|
+
let n = null;
|
|
312
|
+
return r.traverse((i) => {
|
|
313
|
+
n !== null || i.type !== "Mesh" && i.type !== "SkinnedMesh" || i.material && (i.material.uuid === t || i.material.name === t) && (n = i.material, n !== null && (a.endsWith(".map") ? n = n.map : a.endsWith(".emissiveMap") && (n = n.emissiveMap)));
|
|
314
|
+
}), n;
|
|
315
|
+
} else if (s.startsWith(".nodes.") || s.startsWith(".lights.") || s.startsWith(".cameras.")) {
|
|
316
|
+
const a = s.split(".");
|
|
317
|
+
let e;
|
|
318
|
+
for (let t = 1; t < a.length; t++) {
|
|
319
|
+
const n = a[t];
|
|
320
|
+
if (n.length == 36)
|
|
321
|
+
e = r.getObjectByProperty("uuid", n);
|
|
322
|
+
else if (e && e[n]) {
|
|
323
|
+
const c = Number.parseInt(n);
|
|
324
|
+
let m = n;
|
|
325
|
+
c >= 0 && (m = c), e = e[m];
|
|
326
|
+
} else {
|
|
327
|
+
const c = r.getObjectByName(n);
|
|
328
|
+
c && (e = c);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (!e) {
|
|
332
|
+
const t = I(r, a[2]);
|
|
333
|
+
return t || console.warn(R + ": Property binding not found", s, r, r.name, a), t;
|
|
334
|
+
}
|
|
335
|
+
return e;
|
|
336
|
+
}
|
|
337
|
+
return I(r, s);
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
export {
|
|
341
|
+
j as GLTFAnimationPointerExtension,
|
|
342
|
+
j as default
|
|
343
|
+
};
|
package/package.json
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/three-animation-pointer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1-next.1a466a6",
|
|
4
4
|
"description": "KHR_animation_pointer support for three.js",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "
|
|
6
|
+
"main": "dist/three-animation-pointer.js",
|
|
7
|
+
"module": "dist/three-animation-pointer.js",
|
|
7
8
|
"types": "types/index.d.ts",
|
|
8
9
|
"exports": {
|
|
9
10
|
".": {
|
|
10
|
-
"
|
|
11
|
+
"types": "./types/index.d.ts",
|
|
12
|
+
"import": "./src/index.js",
|
|
13
|
+
"require": "./src/index.js"
|
|
11
14
|
}
|
|
12
15
|
},
|
|
13
16
|
"files": [
|
|
14
17
|
"src",
|
|
18
|
+
"dist",
|
|
15
19
|
"types",
|
|
16
20
|
"package.json",
|
|
17
21
|
"README.md",
|
|
@@ -27,8 +31,13 @@
|
|
|
27
31
|
"url": "https://github.com/needle-tools/three-animation-pointer"
|
|
28
32
|
},
|
|
29
33
|
"license": "MIT",
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "vite build",
|
|
36
|
+
"prepublishOnly": "npm run build"
|
|
37
|
+
},
|
|
30
38
|
"devDependencies": {
|
|
31
|
-
"three": ">=0.179.1"
|
|
39
|
+
"three": ">=0.179.1",
|
|
40
|
+
"vite": "^5.0.0"
|
|
32
41
|
},
|
|
33
42
|
"peerDependencies": {
|
|
34
43
|
"three": ">=0.165.0"
|
|
@@ -37,4 +46,4 @@
|
|
|
37
46
|
"registry": "https://registry.npmjs.org/",
|
|
38
47
|
"access": "public"
|
|
39
48
|
}
|
|
40
|
-
}
|
|
49
|
+
}
|