@babylonjs/loaders 5.17.1 → 5.20.0
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/glTF/2.0/Extensions/KHR_animation_pointer.d.ts +76 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.js +281 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.map.d.ts +15 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.map.js +484 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.map.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.d.ts +1 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.js +1 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.js.map +1 -1
- package/glTF/2.0/Extensions/index.d.ts +1 -0
- package/glTF/2.0/Extensions/index.js +1 -0
- package/glTF/2.0/Extensions/index.js.map +1 -1
- package/glTF/2.0/glTFLoader.d.ts +3 -14
- package/glTF/2.0/glTFLoader.js +27 -207
- package/glTF/2.0/glTFLoader.js.map +1 -1
- package/glTF/2.0/glTFLoaderInterfaces.d.ts +11 -0
- package/glTF/2.0/glTFLoaderInterfaces.js.map +1 -1
- package/glTF/2.0/glTFUtilities.d.ts +7 -0
- package/glTF/2.0/glTFUtilities.js +23 -0
- package/glTF/2.0/glTFUtilities.js.map +1 -0
- package/package.json +3 -3
@@ -0,0 +1,76 @@
|
|
1
|
+
import type { IGLTFLoaderExtension } from "../glTFLoaderExtension";
|
2
|
+
import { GLTFLoader } from "../glTFLoader";
|
3
|
+
import type { Nullable } from "@babylonjs/core/types.js";
|
4
|
+
import { AnimationGroup } from "@babylonjs/core/Animations/animationGroup.js";
|
5
|
+
import type { IAnimatable } from "@babylonjs/core/Animations/animatable.interface.js";
|
6
|
+
import type { IAnimation, IAnimationChannel } from "../glTFLoaderInterfaces";
|
7
|
+
/**
|
8
|
+
* [Specification PR](https://github.com/KhronosGroup/glTF/pull/2147)
|
9
|
+
*/
|
10
|
+
export declare class KHR_animation_pointer implements IGLTFLoaderExtension {
|
11
|
+
/**
|
12
|
+
* used to gently ignore invalid pointer. If false, invalid pointer will throw exception.
|
13
|
+
*/
|
14
|
+
ignoreInvalidPointer: boolean;
|
15
|
+
/**
|
16
|
+
* The name of this extension.
|
17
|
+
*/
|
18
|
+
readonly name = "KHR_animation_pointer";
|
19
|
+
private _loader;
|
20
|
+
/**
|
21
|
+
* @param loader
|
22
|
+
* @hidden
|
23
|
+
*/
|
24
|
+
constructor(loader: GLTFLoader);
|
25
|
+
/**
|
26
|
+
* Defines whether this extension is enabled.
|
27
|
+
*/
|
28
|
+
get enabled(): boolean;
|
29
|
+
/** @hidden */
|
30
|
+
dispose(): void;
|
31
|
+
/**
|
32
|
+
* according to specification,
|
33
|
+
* It is not allowed to animate a glTFid property, as it does change the structure of the glTF in general
|
34
|
+
* It is not allowed to animate a name property in general.
|
35
|
+
* @param property
|
36
|
+
* @hidden
|
37
|
+
*/
|
38
|
+
accept(property: string): boolean;
|
39
|
+
loadAnimationAsync(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
|
40
|
+
/**
|
41
|
+
* @hidden Loads a glTF animation channel.
|
42
|
+
* @param context The context when loading the asset
|
43
|
+
* @param animationContext The context of the animation when loading the asset
|
44
|
+
* @param animation The glTF animation property
|
45
|
+
* @param channel The glTF animation channel property
|
46
|
+
* @param animationTargetOverride The babylon animation channel target override property. My be null.
|
47
|
+
* @returns A void promise when the channel load is complete
|
48
|
+
*/
|
49
|
+
_loadAnimationChannelAsync(context: string, animationContext: string, animation: IAnimation, channel: IAnimationChannel, animationTargetOverride?: Nullable<IAnimatable>): Promise<void>;
|
50
|
+
private _loadAnimationSamplerAsync;
|
51
|
+
/**
|
52
|
+
* parsing animation pointer is the core of animation channel.
|
53
|
+
* Animation pointer is a Json pointer, which mean it locate an item into the json hierarchy.
|
54
|
+
* Consequentely the pointer has the following BNF
|
55
|
+
|
56
|
+
* <animationPointer> := <sep><assetContainer><sep><assetIndex><sep><propertyPath>
|
57
|
+
* <assetContainer> := "nodes" | "materials" | "meshes" | "cameras" | "extensions"
|
58
|
+
* <assetIndex> := <digit> | <name>
|
59
|
+
* <propertyPath> := <extensionPath> | <standardPath>
|
60
|
+
* <extensionPath> := "extensions"<sep><name><sep><standardPath>
|
61
|
+
* <standardPath> := <name> | <name><sep><standardPath>
|
62
|
+
* <sep>:= "/"
|
63
|
+
* <name> := W+
|
64
|
+
* <digit> := D+
|
65
|
+
*
|
66
|
+
* examples of pointer are
|
67
|
+
* - "/nodes/0/rotation"
|
68
|
+
* - "/materials/2/emissiveFactor"
|
69
|
+
* - "/materials/2/pbrMetallicRoughness/baseColorFactor"
|
70
|
+
* - "/materials/2/extensions/KHR_materials_emissive_strength/emissiveStrength"
|
71
|
+
* @param context
|
72
|
+
* @param pointer
|
73
|
+
* @return
|
74
|
+
*/
|
75
|
+
private _parseAnimationPointer;
|
76
|
+
}
|
@@ -0,0 +1,281 @@
|
|
1
|
+
import { ArrayItem, GLTFLoader } from "../glTFLoader.js";
|
2
|
+
import { AnimationGroup } from "@babylonjs/core/Animations/animationGroup.js";
|
3
|
+
import { AnimationKeyInterpolation } from "@babylonjs/core/Animations/animationKey.js";
|
4
|
+
import { CoreAnimationPointerMap } from "./KHR_animation_pointer.map.js";
|
5
|
+
import { getDataAccessorElementCount } from "../glTFUtilities.js";
|
6
|
+
var NAME = GLTFLoader._KHRAnimationPointerName;
|
7
|
+
/**
|
8
|
+
* [Specification PR](https://github.com/KhronosGroup/glTF/pull/2147)
|
9
|
+
*/
|
10
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
11
|
+
var KHR_animation_pointer = /** @class */ (function () {
|
12
|
+
/**
|
13
|
+
* @param loader
|
14
|
+
* @hidden
|
15
|
+
*/
|
16
|
+
function KHR_animation_pointer(loader) {
|
17
|
+
/**
|
18
|
+
* used to gently ignore invalid pointer. If false, invalid pointer will throw exception.
|
19
|
+
*/
|
20
|
+
this.ignoreInvalidPointer = true;
|
21
|
+
/**
|
22
|
+
* The name of this extension.
|
23
|
+
*/
|
24
|
+
this.name = NAME;
|
25
|
+
this._loader = loader;
|
26
|
+
}
|
27
|
+
Object.defineProperty(KHR_animation_pointer.prototype, "enabled", {
|
28
|
+
/**
|
29
|
+
* Defines whether this extension is enabled.
|
30
|
+
*/
|
31
|
+
get: function () {
|
32
|
+
return this._loader.isExtensionUsed(NAME);
|
33
|
+
},
|
34
|
+
enumerable: false,
|
35
|
+
configurable: true
|
36
|
+
});
|
37
|
+
/** @hidden */
|
38
|
+
KHR_animation_pointer.prototype.dispose = function () {
|
39
|
+
this._loader = null;
|
40
|
+
};
|
41
|
+
/**
|
42
|
+
* according to specification,
|
43
|
+
* It is not allowed to animate a glTFid property, as it does change the structure of the glTF in general
|
44
|
+
* It is not allowed to animate a name property in general.
|
45
|
+
* @param property
|
46
|
+
* @hidden
|
47
|
+
*/
|
48
|
+
KHR_animation_pointer.prototype.accept = function (property) {
|
49
|
+
return property != "name";
|
50
|
+
};
|
51
|
+
KHR_animation_pointer.prototype.loadAnimationAsync = function (context, animation) {
|
52
|
+
// ensure an animation group is present.
|
53
|
+
if (!animation._babylonAnimationGroup) {
|
54
|
+
this._loader.babylonScene._blockEntityCollection = !!this._loader._assetContainer;
|
55
|
+
var group = new AnimationGroup(animation.name || "animation".concat(animation.index), this._loader.babylonScene);
|
56
|
+
group._parentContainer = this._loader._assetContainer;
|
57
|
+
this._loader.babylonScene._blockEntityCollection = false;
|
58
|
+
animation._babylonAnimationGroup = group;
|
59
|
+
}
|
60
|
+
var babylonAnimationGroup = animation._babylonAnimationGroup;
|
61
|
+
var promises = new Array();
|
62
|
+
ArrayItem.Assign(animation.channels);
|
63
|
+
ArrayItem.Assign(animation.samplers);
|
64
|
+
for (var _i = 0, _a = animation.channels; _i < _a.length; _i++) {
|
65
|
+
var channel = _a[_i];
|
66
|
+
promises.push(this._loadAnimationChannelAsync("".concat(context, "/channels/").concat(channel.index), context, animation, channel));
|
67
|
+
}
|
68
|
+
return Promise.all(promises).then(function () {
|
69
|
+
babylonAnimationGroup.normalize(0);
|
70
|
+
return babylonAnimationGroup;
|
71
|
+
});
|
72
|
+
};
|
73
|
+
/**
|
74
|
+
* @hidden Loads a glTF animation channel.
|
75
|
+
* @param context The context when loading the asset
|
76
|
+
* @param animationContext The context of the animation when loading the asset
|
77
|
+
* @param animation The glTF animation property
|
78
|
+
* @param channel The glTF animation channel property
|
79
|
+
* @param animationTargetOverride The babylon animation channel target override property. My be null.
|
80
|
+
* @returns A void promise when the channel load is complete
|
81
|
+
*/
|
82
|
+
KHR_animation_pointer.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, animationTargetOverride) {
|
83
|
+
var _this = this;
|
84
|
+
var _a, _b;
|
85
|
+
if (animationTargetOverride === void 0) { animationTargetOverride = null; }
|
86
|
+
if (channel.target.path != "pointer" /* POINTER */) {
|
87
|
+
throw new Error("".concat(context, "/target/path: Invalid value (").concat(channel.target.path, ")"));
|
88
|
+
}
|
89
|
+
if (channel.target.node != undefined) {
|
90
|
+
// According to KHR_animation_pointer specification
|
91
|
+
// If this extension is used, the animation.channel.target.node must not be set.
|
92
|
+
// Because the node is defined, the channel is ignored and not animated due to the specification.
|
93
|
+
return Promise.resolve();
|
94
|
+
}
|
95
|
+
var pointer = (_b = (_a = channel.target.extensions) === null || _a === void 0 ? void 0 : _a.KHR_animation_pointer) === null || _b === void 0 ? void 0 : _b.pointer;
|
96
|
+
if (!pointer) {
|
97
|
+
throw new Error("".concat(context, "/target/extensions/").concat(this.name, ": Pointer is missing"));
|
98
|
+
}
|
99
|
+
var sampler = ArrayItem.Get("".concat(context, "/sampler"), animation.samplers, channel.sampler);
|
100
|
+
return this._loadAnimationSamplerAsync("".concat(context, "/samplers/").concat(channel.sampler), sampler).then(function (data) {
|
101
|
+
var _a;
|
102
|
+
// this is where we process the pointer.
|
103
|
+
var animationTarget = _this._parseAnimationPointer("".concat(context, "/extensions/").concat(_this.name, "/pointer"), pointer);
|
104
|
+
if (!animationTarget) {
|
105
|
+
return;
|
106
|
+
}
|
107
|
+
// build the keys
|
108
|
+
// build the animations into the group
|
109
|
+
var babylonAnimationGroup = animation._babylonAnimationGroup;
|
110
|
+
if (!babylonAnimationGroup) {
|
111
|
+
return;
|
112
|
+
}
|
113
|
+
var outputAccessor = ArrayItem.Get("".concat(context, "/output"), _this._loader.gltf.accessors, sampler.output);
|
114
|
+
// stride is the size of each element stored into the output buffer.
|
115
|
+
var stride = (_a = animationTarget.stride) !== null && _a !== void 0 ? _a : getDataAccessorElementCount(outputAccessor.type);
|
116
|
+
var fps = _this._loader.parent.targetFps;
|
117
|
+
// we extract the corresponding values from the read value.
|
118
|
+
// the reason for that is one GLTF value may be dispatched to several Babylon properties
|
119
|
+
// one of example is baseColorFactor which is a Color4 under GLTF and dispatched to
|
120
|
+
// - albedoColor as Color3(Color4.r,Color4.g,Color4.b)
|
121
|
+
// - alpha as Color4.a
|
122
|
+
for (var _i = 0, _b = animationTarget.properties; _i < _b.length; _i++) {
|
123
|
+
var propertyInfo = _b[_i];
|
124
|
+
// Ignore animations that have no animation valid targets.
|
125
|
+
if (!propertyInfo.isValid(animationTarget.target)) {
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
// build the keys.
|
129
|
+
var keys = new Array(data.input.length);
|
130
|
+
var outputOffset = 0;
|
131
|
+
switch (data.interpolation) {
|
132
|
+
case "STEP" /* STEP */: {
|
133
|
+
for (var frameIndex = 0; frameIndex < data.input.length; frameIndex++) {
|
134
|
+
keys[frameIndex] = {
|
135
|
+
frame: data.input[frameIndex] * fps,
|
136
|
+
value: propertyInfo.get(animationTarget.target, data.output, outputOffset),
|
137
|
+
interpolation: AnimationKeyInterpolation.STEP,
|
138
|
+
};
|
139
|
+
outputOffset += stride;
|
140
|
+
}
|
141
|
+
break;
|
142
|
+
}
|
143
|
+
case "CUBICSPLINE" /* CUBICSPLINE */: {
|
144
|
+
var invfps = 1 / fps;
|
145
|
+
for (var frameIndex = 0; frameIndex < data.input.length; frameIndex++) {
|
146
|
+
var k = {
|
147
|
+
frame: data.input[frameIndex] * fps,
|
148
|
+
};
|
149
|
+
(k.inTangent = propertyInfo.get(animationTarget.target, data.output, outputOffset, invfps)), (outputOffset += stride);
|
150
|
+
(k.value = propertyInfo.get(animationTarget.target, data.output, outputOffset)), (outputOffset += stride);
|
151
|
+
(k.outTangent = propertyInfo.get(animationTarget.target, data.output, outputOffset, invfps)), (outputOffset += stride);
|
152
|
+
keys[frameIndex] = k;
|
153
|
+
}
|
154
|
+
break;
|
155
|
+
}
|
156
|
+
case "LINEAR" /* LINEAR */:
|
157
|
+
default: {
|
158
|
+
for (var frameIndex = 0; frameIndex < data.input.length; frameIndex++) {
|
159
|
+
keys[frameIndex] = {
|
160
|
+
frame: data.input[frameIndex] * fps,
|
161
|
+
value: propertyInfo.get(animationTarget.target, data.output, outputOffset),
|
162
|
+
};
|
163
|
+
outputOffset += stride;
|
164
|
+
}
|
165
|
+
break;
|
166
|
+
}
|
167
|
+
}
|
168
|
+
// each properties has its own build animation process.
|
169
|
+
// these logics are located into KHR_animation_pointer.map.ts
|
170
|
+
propertyInfo.buildAnimations(animationTarget.target, fps, keys, babylonAnimationGroup, animationTargetOverride, animationTarget.params);
|
171
|
+
}
|
172
|
+
});
|
173
|
+
};
|
174
|
+
KHR_animation_pointer.prototype._loadAnimationSamplerAsync = function (context, sampler) {
|
175
|
+
if (sampler._data) {
|
176
|
+
return sampler._data;
|
177
|
+
}
|
178
|
+
var interpolation = sampler.interpolation || "LINEAR" /* LINEAR */;
|
179
|
+
switch (interpolation) {
|
180
|
+
case "STEP" /* STEP */:
|
181
|
+
case "LINEAR" /* LINEAR */:
|
182
|
+
case "CUBICSPLINE" /* CUBICSPLINE */: {
|
183
|
+
break;
|
184
|
+
}
|
185
|
+
default: {
|
186
|
+
throw new Error("".concat(context, "/interpolation: Invalid value (").concat(sampler.interpolation, ")"));
|
187
|
+
}
|
188
|
+
}
|
189
|
+
var inputAccessor = ArrayItem.Get("".concat(context, "/input"), this._loader.gltf.accessors, sampler.input);
|
190
|
+
var outputAccessor = ArrayItem.Get("".concat(context, "/output"), this._loader.gltf.accessors, sampler.output);
|
191
|
+
sampler._data = Promise.all([
|
192
|
+
this._loader._loadFloatAccessorAsync("/accessors/".concat(inputAccessor.index), inputAccessor),
|
193
|
+
this._loader._loadFloatAccessorAsync("/accessors/".concat(outputAccessor.index), outputAccessor),
|
194
|
+
]).then(function (_a) {
|
195
|
+
var inputData = _a[0], outputData = _a[1];
|
196
|
+
return {
|
197
|
+
input: inputData,
|
198
|
+
interpolation: interpolation,
|
199
|
+
output: outputData,
|
200
|
+
};
|
201
|
+
});
|
202
|
+
return sampler._data;
|
203
|
+
};
|
204
|
+
/**
|
205
|
+
* parsing animation pointer is the core of animation channel.
|
206
|
+
* Animation pointer is a Json pointer, which mean it locate an item into the json hierarchy.
|
207
|
+
* Consequentely the pointer has the following BNF
|
208
|
+
|
209
|
+
* <animationPointer> := <sep><assetContainer><sep><assetIndex><sep><propertyPath>
|
210
|
+
* <assetContainer> := "nodes" | "materials" | "meshes" | "cameras" | "extensions"
|
211
|
+
* <assetIndex> := <digit> | <name>
|
212
|
+
* <propertyPath> := <extensionPath> | <standardPath>
|
213
|
+
* <extensionPath> := "extensions"<sep><name><sep><standardPath>
|
214
|
+
* <standardPath> := <name> | <name><sep><standardPath>
|
215
|
+
* <sep>:= "/"
|
216
|
+
* <name> := W+
|
217
|
+
* <digit> := D+
|
218
|
+
*
|
219
|
+
* examples of pointer are
|
220
|
+
* - "/nodes/0/rotation"
|
221
|
+
* - "/materials/2/emissiveFactor"
|
222
|
+
* - "/materials/2/pbrMetallicRoughness/baseColorFactor"
|
223
|
+
* - "/materials/2/extensions/KHR_materials_emissive_strength/emissiveStrength"
|
224
|
+
* @param context
|
225
|
+
* @param pointer
|
226
|
+
* @return
|
227
|
+
*/
|
228
|
+
KHR_animation_pointer.prototype._parseAnimationPointer = function (context, pointer) {
|
229
|
+
var sep = "/";
|
230
|
+
if (pointer.charAt(0) == sep) {
|
231
|
+
pointer = pointer.substring(1);
|
232
|
+
}
|
233
|
+
var parts = pointer.split(sep);
|
234
|
+
// we have a least 3 part
|
235
|
+
if (parts.length >= 3) {
|
236
|
+
var node = CoreAnimationPointerMap; // the map of possible path
|
237
|
+
var indices = [];
|
238
|
+
var getTarget = null;
|
239
|
+
for (var i = 0; i < parts.length; i++) {
|
240
|
+
var part = parts[i];
|
241
|
+
node = node[part];
|
242
|
+
if (!node) {
|
243
|
+
// nothing to do so far
|
244
|
+
break;
|
245
|
+
}
|
246
|
+
if (node.getTarget) {
|
247
|
+
getTarget = node.getTarget;
|
248
|
+
}
|
249
|
+
if (node.hasIndex) {
|
250
|
+
indices.push(parts[++i]);
|
251
|
+
// move to the next part
|
252
|
+
continue;
|
253
|
+
}
|
254
|
+
if (node.isIndex) {
|
255
|
+
indices.push(part);
|
256
|
+
// move to the next part
|
257
|
+
continue;
|
258
|
+
}
|
259
|
+
if (node.properties && getTarget) {
|
260
|
+
var t = getTarget(this._loader.gltf, indices[0]);
|
261
|
+
if (t != null) {
|
262
|
+
return {
|
263
|
+
target: t,
|
264
|
+
stride: node.getStride ? node.getStride(t) : undefined,
|
265
|
+
properties: node.properties,
|
266
|
+
params: indices,
|
267
|
+
};
|
268
|
+
}
|
269
|
+
}
|
270
|
+
}
|
271
|
+
}
|
272
|
+
if (this.ignoreInvalidPointer) {
|
273
|
+
return null;
|
274
|
+
}
|
275
|
+
throw new Error("".concat(context, " invalid pointer. ").concat(pointer));
|
276
|
+
};
|
277
|
+
return KHR_animation_pointer;
|
278
|
+
}());
|
279
|
+
export { KHR_animation_pointer };
|
280
|
+
GLTFLoader.RegisterExtension(NAME, function (loader) { return new KHR_animation_pointer(loader); });
|
281
|
+
//# sourceMappingURL=KHR_animation_pointer.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"KHR_animation_pointer.js","sourceRoot":"","sources":["../../../../../../../lts/loaders/generated/glTF/2.0/Extensions/KHR_animation_pointer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IGLTFLoaderExtension } from \"../glTFLoaderExtension\";\r\nimport { ArrayItem, GLTFLoader } from \"../glTFLoader\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { AnimationGroup } from \"core/Animations/animationGroup\";\r\nimport type { IAnimatable } from \"core/Animations/animatable.interface\";\r\nimport type { IAnimation, IAnimationChannel, _IAnimationSamplerData, IAnimationSampler } from \"../glTFLoaderInterfaces\";\r\n\r\nimport { AnimationChannelTargetPath, AnimationSamplerInterpolation } from \"babylonjs-gltf2interface\";\r\nimport { AnimationKeyInterpolation } from \"core/Animations/animationKey\";\r\nimport { CoreAnimationPointerMap } from \"./KHR_animation_pointer.map\";\r\nimport type { GetGltfNodeTargetFn, IAnimationPointerPropertyInfos } from \"./KHR_animation_pointer.map\";\r\nimport { getDataAccessorElementCount } from \"../glTFUtilities\";\r\n\r\nconst NAME = GLTFLoader._KHRAnimationPointerName;\r\n\r\ninterface IAnimationChannelTarget {\r\n stride?: number;\r\n target: any;\r\n properties: Array<IAnimationPointerPropertyInfos>;\r\n params: any;\r\n}\r\n\r\n/**\r\n * [Specification PR](https://github.com/KhronosGroup/glTF/pull/2147)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_animation_pointer implements IGLTFLoaderExtension {\r\n /**\r\n * used to gently ignore invalid pointer. If false, invalid pointer will throw exception.\r\n */\r\n public ignoreInvalidPointer: boolean = true;\r\n\r\n /**\r\n * The name of this extension.\r\n */\r\n public readonly name = NAME;\r\n\r\n private _loader: GLTFLoader;\r\n\r\n /**\r\n * @param loader\r\n * @hidden\r\n */\r\n constructor(loader: GLTFLoader) {\r\n this._loader = loader;\r\n }\r\n\r\n /**\r\n * Defines whether this extension is enabled.\r\n */\r\n public get enabled(): boolean {\r\n return this._loader.isExtensionUsed(NAME);\r\n }\r\n\r\n /** @hidden */\r\n public dispose() {\r\n (this._loader as any) = null;\r\n }\r\n\r\n /**\r\n * according to specification,\r\n * It is not allowed to animate a glTFid property, as it does change the structure of the glTF in general\r\n * It is not allowed to animate a name property in general.\r\n * @param property\r\n * @hidden\r\n */\r\n public accept(property: string): boolean {\r\n return property != \"name\";\r\n }\r\n\r\n public loadAnimationAsync(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>> {\r\n // ensure an animation group is present.\r\n if (!animation._babylonAnimationGroup) {\r\n this._loader.babylonScene._blockEntityCollection = !!this._loader._assetContainer;\r\n const group = new AnimationGroup(animation.name || `animation${animation.index}`, this._loader.babylonScene);\r\n group._parentContainer = this._loader._assetContainer;\r\n this._loader.babylonScene._blockEntityCollection = false;\r\n animation._babylonAnimationGroup = group;\r\n }\r\n const babylonAnimationGroup = animation._babylonAnimationGroup;\r\n\r\n const promises = new Array<Promise<any>>();\r\n ArrayItem.Assign(animation.channels);\r\n ArrayItem.Assign(animation.samplers);\r\n\r\n for (const channel of animation.channels) {\r\n promises.push(this._loadAnimationChannelAsync(`${context}/channels/${channel.index}`, context, animation, channel));\r\n }\r\n\r\n return Promise.all(promises).then(() => {\r\n babylonAnimationGroup.normalize(0);\r\n return babylonAnimationGroup;\r\n });\r\n }\r\n\r\n /**\r\n * @hidden Loads a glTF animation channel.\r\n * @param context The context when loading the asset\r\n * @param animationContext The context of the animation when loading the asset\r\n * @param animation The glTF animation property\r\n * @param channel The glTF animation channel property\r\n * @param animationTargetOverride The babylon animation channel target override property. My be null.\r\n * @returns A void promise when the channel load is complete\r\n */\r\n public _loadAnimationChannelAsync(\r\n context: string,\r\n animationContext: string,\r\n animation: IAnimation,\r\n channel: IAnimationChannel,\r\n animationTargetOverride: Nullable<IAnimatable> = null\r\n ): Promise<void> {\r\n if (channel.target.path != AnimationChannelTargetPath.POINTER) {\r\n throw new Error(`${context}/target/path: Invalid value (${channel.target.path})`);\r\n }\r\n\r\n if (channel.target.node != undefined) {\r\n // According to KHR_animation_pointer specification\r\n // If this extension is used, the animation.channel.target.node must not be set.\r\n // Because the node is defined, the channel is ignored and not animated due to the specification.\r\n return Promise.resolve();\r\n }\r\n\r\n const pointer = channel.target.extensions?.KHR_animation_pointer?.pointer;\r\n if (!pointer) {\r\n throw new Error(`${context}/target/extensions/${this.name}: Pointer is missing`);\r\n }\r\n\r\n const sampler = ArrayItem.Get(`${context}/sampler`, animation.samplers, channel.sampler);\r\n\r\n return this._loadAnimationSamplerAsync(`${context}/samplers/${channel.sampler}`, sampler).then((data) => {\r\n // this is where we process the pointer.\r\n const animationTarget = this._parseAnimationPointer(`${context}/extensions/${this.name}/pointer`, pointer);\r\n\r\n if (!animationTarget) {\r\n return;\r\n }\r\n // build the keys\r\n // build the animations into the group\r\n const babylonAnimationGroup = animation._babylonAnimationGroup;\r\n if (!babylonAnimationGroup) {\r\n return;\r\n }\r\n\r\n const outputAccessor = ArrayItem.Get(`${context}/output`, this._loader.gltf.accessors, sampler.output);\r\n // stride is the size of each element stored into the output buffer.\r\n const stride = animationTarget.stride ?? getDataAccessorElementCount(outputAccessor.type);\r\n const fps = this._loader.parent.targetFps;\r\n\r\n // we extract the corresponding values from the read value.\r\n // the reason for that is one GLTF value may be dispatched to several Babylon properties\r\n // one of example is baseColorFactor which is a Color4 under GLTF and dispatched to\r\n // - albedoColor as Color3(Color4.r,Color4.g,Color4.b)\r\n // - alpha as Color4.a\r\n for (const propertyInfo of animationTarget.properties) {\r\n // Ignore animations that have no animation valid targets.\r\n if (!propertyInfo.isValid(animationTarget.target)) {\r\n return;\r\n }\r\n\r\n // build the keys.\r\n const keys = new Array(data.input.length);\r\n let outputOffset = 0;\r\n\r\n switch (data.interpolation) {\r\n case AnimationSamplerInterpolation.STEP: {\r\n for (let frameIndex = 0; frameIndex < data.input.length; frameIndex++) {\r\n keys[frameIndex] = {\r\n frame: data.input[frameIndex] * fps,\r\n value: propertyInfo.get(animationTarget.target, data.output, outputOffset),\r\n interpolation: AnimationKeyInterpolation.STEP,\r\n };\r\n outputOffset += stride;\r\n }\r\n break;\r\n }\r\n case AnimationSamplerInterpolation.CUBICSPLINE: {\r\n const invfps = 1 / fps;\r\n for (let frameIndex = 0; frameIndex < data.input.length; frameIndex++) {\r\n const k: any = {\r\n frame: data.input[frameIndex] * fps,\r\n };\r\n\r\n (k.inTangent = propertyInfo.get(animationTarget.target, data.output, outputOffset, invfps)), (outputOffset += stride);\r\n (k.value = propertyInfo.get(animationTarget.target, data.output, outputOffset)), (outputOffset += stride);\r\n (k.outTangent = propertyInfo.get(animationTarget.target, data.output, outputOffset, invfps)), (outputOffset += stride);\r\n\r\n keys[frameIndex] = k;\r\n }\r\n break;\r\n }\r\n case AnimationSamplerInterpolation.LINEAR:\r\n default: {\r\n for (let frameIndex = 0; frameIndex < data.input.length; frameIndex++) {\r\n keys[frameIndex] = {\r\n frame: data.input[frameIndex] * fps,\r\n value: propertyInfo.get(animationTarget.target, data.output, outputOffset),\r\n };\r\n outputOffset += stride;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n // each properties has its own build animation process.\r\n // these logics are located into KHR_animation_pointer.map.ts\r\n propertyInfo.buildAnimations(animationTarget.target, fps, keys, babylonAnimationGroup, animationTargetOverride, animationTarget.params);\r\n }\r\n });\r\n }\r\n\r\n private _loadAnimationSamplerAsync(context: string, sampler: IAnimationSampler): Promise<_IAnimationSamplerData> {\r\n if (sampler._data) {\r\n return sampler._data;\r\n }\r\n\r\n const interpolation = sampler.interpolation || AnimationSamplerInterpolation.LINEAR;\r\n switch (interpolation) {\r\n case AnimationSamplerInterpolation.STEP:\r\n case AnimationSamplerInterpolation.LINEAR:\r\n case AnimationSamplerInterpolation.CUBICSPLINE: {\r\n break;\r\n }\r\n default: {\r\n throw new Error(`${context}/interpolation: Invalid value (${sampler.interpolation})`);\r\n }\r\n }\r\n\r\n const inputAccessor = ArrayItem.Get(`${context}/input`, this._loader.gltf.accessors, sampler.input);\r\n const outputAccessor = ArrayItem.Get(`${context}/output`, this._loader.gltf.accessors, sampler.output);\r\n sampler._data = Promise.all([\r\n this._loader._loadFloatAccessorAsync(`/accessors/${inputAccessor.index}`, inputAccessor),\r\n this._loader._loadFloatAccessorAsync(`/accessors/${outputAccessor.index}`, outputAccessor),\r\n ]).then(([inputData, outputData]) => {\r\n return {\r\n input: inputData,\r\n interpolation: interpolation,\r\n output: outputData,\r\n };\r\n });\r\n\r\n return sampler._data;\r\n }\r\n\r\n /**\r\n * parsing animation pointer is the core of animation channel.\r\n * Animation pointer is a Json pointer, which mean it locate an item into the json hierarchy.\r\n * Consequentely the pointer has the following BNF\r\n \r\n * <animationPointer> := <sep><assetContainer><sep><assetIndex><sep><propertyPath>\r\n * <assetContainer> := \"nodes\" | \"materials\" | \"meshes\" | \"cameras\" | \"extensions\" \r\n * <assetIndex> := <digit> | <name>\r\n * <propertyPath> := <extensionPath> | <standardPath>\r\n * <extensionPath> := \"extensions\"<sep><name><sep><standardPath>\r\n * <standardPath> := <name> | <name><sep><standardPath> \r\n * <sep>:= \"/\"\r\n * <name> := W+\r\n * <digit> := D+\r\n * \r\n * examples of pointer are\r\n * - \"/nodes/0/rotation\"\r\n * - \"/materials/2/emissiveFactor\"\r\n * - \"/materials/2/pbrMetallicRoughness/baseColorFactor\"\r\n * - \"/materials/2/extensions/KHR_materials_emissive_strength/emissiveStrength\"\r\n * @param context \r\n * @param pointer \r\n * @return \r\n */\r\n private _parseAnimationPointer(context: string, pointer: string): Nullable<IAnimationChannelTarget> {\r\n const sep = \"/\";\r\n if (pointer.charAt(0) == sep) {\r\n pointer = pointer.substring(1);\r\n }\r\n const parts = pointer.split(sep);\r\n // we have a least 3 part\r\n if (parts.length >= 3) {\r\n let node = CoreAnimationPointerMap; // the map of possible path\r\n const indices = [];\r\n let getTarget: Nullable<GetGltfNodeTargetFn> = null;\r\n for (let i = 0; i < parts.length; i++) {\r\n const part = parts[i];\r\n node = node[part];\r\n\r\n if (!node) {\r\n // nothing to do so far\r\n break;\r\n }\r\n\r\n if (node.getTarget) {\r\n getTarget = node.getTarget;\r\n }\r\n\r\n if (node.hasIndex) {\r\n indices.push(parts[++i]);\r\n // move to the next part\r\n continue;\r\n }\r\n\r\n if (node.isIndex) {\r\n indices.push(part);\r\n // move to the next part\r\n continue;\r\n }\r\n\r\n if (node.properties && getTarget) {\r\n const t = getTarget(this._loader.gltf, indices[0]);\r\n if (t != null) {\r\n return {\r\n target: t,\r\n stride: node.getStride ? node.getStride(t) : undefined,\r\n properties: node.properties,\r\n params: indices,\r\n };\r\n }\r\n }\r\n }\r\n }\r\n if (this.ignoreInvalidPointer) {\r\n return null;\r\n }\r\n throw new Error(`${context} invalid pointer. ${pointer}`);\r\n }\r\n}\r\n\r\nGLTFLoader.RegisterExtension(NAME, (loader) => new KHR_animation_pointer(loader));\r\n"]}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import type { AnimationGroup } from "@babylonjs/core/Animations/animationGroup.js";
|
2
|
+
import type { IGLTF } from "../glTFLoaderInterfaces";
|
3
|
+
import type { IAnimatable } from "@babylonjs/core/Animations/animatable.interface.js";
|
4
|
+
import type { Nullable } from "@babylonjs/core/types.js";
|
5
|
+
export declare type GetGltfNodeTargetFn = (source: IGLTF, indices: string) => any;
|
6
|
+
declare type GetValueFn = (target: any, source: Float32Array, offset: number, scale?: number) => any;
|
7
|
+
export interface IAnimationPointerPropertyInfos {
|
8
|
+
type: number;
|
9
|
+
name: string;
|
10
|
+
get: GetValueFn;
|
11
|
+
isValid(target: any): boolean;
|
12
|
+
buildAnimations(target: any, fps: number, keys: any[], group: AnimationGroup, animationTargetOverride: Nullable<IAnimatable>, params?: any): void;
|
13
|
+
}
|
14
|
+
export declare const CoreAnimationPointerMap: any;
|
15
|
+
export {};
|