@babylonjs/loaders 5.17.0 → 5.19.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 {};
|