redhotmagma-visualization 1.41.0 → 1.42.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/AlignTargetProvider.js +50 -79
- package/CommonUtils/Deferred.js +11 -38
- package/CommonUtils/Observable.js +29 -48
- package/CommonUtils/PropertyObserver.js +10 -17
- package/CommonUtils/SyncCurrentFunction.js +33 -42
- package/CommonUtils/SyncObservableEvent.js +2 -6
- package/CommonUtils/pointerEvent.js +50 -98
- package/Constants.js +6 -6
- package/DevApp.js +187 -309
- package/ExposedModules.js +2 -9
- package/FallbackVisualization.js +4 -10
- package/PrintingEffects/ColorEmbossingEffect.js +15 -26
- package/PrintingEffects/DomingEffect.js +29 -52
- package/PrintingEffects/EmbossingEffect.js +17 -29
- package/PrintingEffects/EmbroideryEffect.js +251 -362
- package/PrintingEffects/EngravingEffect.js +17 -29
- package/PrintingEffects/PrintingEffects.js +44 -73
- package/PrintingEffects/PrintingEffectsUtils.js +1 -7
- package/React/ReactBase.js +15 -47
- package/Three/Controls/OrbitControls.js +105 -126
- package/Three/Exporters/glTFExporter.js +2 -6
- package/Three/Loaders/ColladaLoader.js +202 -550
- package/Three/Loaders/MTLLoader.js +33 -64
- package/Three/Loaders/OBJLoader.js +48 -80
- package/Three/Three2D.js +750 -1014
- package/Three/Three2DLayers.js +217 -341
- package/Three/Three3D.js +530 -800
- package/Three/Three3DScene.js +484 -780
- package/Three/ThreeBase.js +145 -230
- package/Utils/DesignArea/getDesignAreaCanvasSize.js +3 -11
- package/Utils/TextureBuilder/createTextureBuilder.js +133 -193
- package/Utils/TextureBuilder/textureBuilderFunctions.js +11 -27
- package/Utils/alignToElement.js +13 -24
- package/Utils/canvasBlur.js +27 -45
- package/Utils/createAlphaMapFromAlphaChannel.js +11 -21
- package/Utils/createBakedShadow.js +38 -42
- package/Utils/createCache.js +0 -4
- package/Utils/createCanvas.js +3 -9
- package/Utils/createImageRepository.js +63 -87
- package/Utils/disposeMaterial.js +4 -14
- package/Utils/getImageSize.js +1 -2
- package/Utils/imagePreloader.js +36 -48
- package/Utils/initTextureCanvas.js +6 -18
- package/Utils/isMobileDevice.js +3 -7
- package/Utils/optimizeTextureImage.js +13 -29
- package/Utils/rememberCameraViewOffset.js +8 -11
- package/Utils/removeObject.js +0 -4
- package/Utils/restrictCameraMovement.js +2 -12
- package/Utils/setLightShadow.js +3 -5
- package/Utils/setOrthographicCameraSize.js +0 -1
- package/Utils/updateFitSizeToElement.js +4 -9
- package/VisualizationContainer.js +37 -90
- package/VisualizationInterface.js +32 -67
- package/VisualizationProvider.js +5 -15
- package/index.js +2 -9
- package/package.json +6 -7
- package/scripts/cpPublicLocal.js +7 -2
- package/src/CommonUtils/Observable.js +1 -0
- package/src/CommonUtils/pointerEvent.js +17 -0
- package/src/Constants.js +2 -0
- package/src/DevApp.js +1 -2
- package/src/Three/Three2D.js +105 -1
- package/src/Three/ThreeBase.js +31 -3
- package/src/Utils/TextureBuilder/createTextureBuilder.js +12 -3
- package/src/VisualizationContainer.js +8 -2
- package/src/index.js +2 -3
- package/visualizationAdapterCreator.js +6 -23
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
function _typeof(
|
|
4
|
-
|
|
3
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports["default"] = void 0;
|
|
9
|
-
|
|
10
8
|
var THREE_imp = _interopRequireWildcard(require("three"));
|
|
11
|
-
|
|
12
9
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
13
|
-
|
|
14
10
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
15
|
-
|
|
16
11
|
/* eslint-disable */
|
|
12
|
+
|
|
17
13
|
// original source: three/examples/js/loaders/ColladaLoader
|
|
18
|
-
|
|
14
|
+
|
|
15
|
+
var THREE = THREE_imp;
|
|
16
|
+
|
|
17
|
+
// important: update file from here if needed
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
20
|
* @author mrdoob / http://mrdoob.com/
|
|
@@ -25,7 +24,6 @@ var THREE = THREE_imp; // important: update file from here if needed
|
|
|
25
24
|
THREE.ColladaLoader = function (manager) {
|
|
26
25
|
this.manager = manager !== undefined ? manager : THREE.DefaultLoadingManager;
|
|
27
26
|
};
|
|
28
|
-
|
|
29
27
|
THREE.ColladaLoader.prototype = {
|
|
30
28
|
constructor: THREE.ColladaLoader,
|
|
31
29
|
crossOrigin: "anonymous",
|
|
@@ -50,7 +48,6 @@ THREE.ColladaLoader.prototype = {
|
|
|
50
48
|
set convertUpAxis(value) {
|
|
51
49
|
console.warn("THREE.ColladaLoader: options.convertUpAxis() has been removed. Up axis is converted automatically.");
|
|
52
50
|
}
|
|
53
|
-
|
|
54
51
|
},
|
|
55
52
|
setCrossOrigin: function setCrossOrigin(value) {
|
|
56
53
|
this.crossOrigin = value;
|
|
@@ -59,68 +56,55 @@ THREE.ColladaLoader.prototype = {
|
|
|
59
56
|
parse: function parse(text, path) {
|
|
60
57
|
function getElementsByTagName(xml, name) {
|
|
61
58
|
// Non recursive xml.getElementsByTagName() ...
|
|
59
|
+
|
|
62
60
|
var array = [];
|
|
63
61
|
var childNodes = xml.childNodes;
|
|
64
|
-
|
|
65
62
|
for (var i = 0, l = childNodes.length; i < l; i++) {
|
|
66
63
|
var child = childNodes[i];
|
|
67
|
-
|
|
68
64
|
if (child.nodeName === name) {
|
|
69
65
|
array.push(child);
|
|
70
66
|
}
|
|
71
67
|
}
|
|
72
|
-
|
|
73
68
|
return array;
|
|
74
69
|
}
|
|
75
|
-
|
|
76
70
|
function parseStrings(text) {
|
|
77
71
|
if (text.length === 0) return [];
|
|
78
72
|
var parts = text.trim().split(/\s+/);
|
|
79
73
|
var array = new Array(parts.length);
|
|
80
|
-
|
|
81
74
|
for (var i = 0, l = parts.length; i < l; i++) {
|
|
82
75
|
array[i] = parts[i];
|
|
83
76
|
}
|
|
84
|
-
|
|
85
77
|
return array;
|
|
86
78
|
}
|
|
87
|
-
|
|
88
79
|
function parseFloats(text) {
|
|
89
80
|
if (text.length === 0) return [];
|
|
90
81
|
var parts = text.trim().split(/\s+/);
|
|
91
82
|
var array = new Array(parts.length);
|
|
92
|
-
|
|
93
83
|
for (var i = 0, l = parts.length; i < l; i++) {
|
|
94
84
|
array[i] = parseFloat(parts[i]);
|
|
95
85
|
}
|
|
96
|
-
|
|
97
86
|
return array;
|
|
98
87
|
}
|
|
99
|
-
|
|
100
88
|
function parseInts(text) {
|
|
101
89
|
if (text.length === 0) return [];
|
|
102
90
|
var parts = text.trim().split(/\s+/);
|
|
103
91
|
var array = new Array(parts.length);
|
|
104
|
-
|
|
105
92
|
for (var i = 0, l = parts.length; i < l; i++) {
|
|
106
93
|
array[i] = parseInt(parts[i]);
|
|
107
94
|
}
|
|
108
|
-
|
|
109
95
|
return array;
|
|
110
96
|
}
|
|
111
|
-
|
|
112
97
|
function parseId(text) {
|
|
113
98
|
return text.substring(1);
|
|
114
99
|
}
|
|
115
|
-
|
|
116
100
|
function generateId() {
|
|
117
101
|
return "three_default_" + count++;
|
|
118
102
|
}
|
|
119
|
-
|
|
120
103
|
function isEmpty(object) {
|
|
121
104
|
return Object.keys(object).length === 0;
|
|
122
|
-
}
|
|
105
|
+
}
|
|
123
106
|
|
|
107
|
+
// asset
|
|
124
108
|
|
|
125
109
|
function parseAsset(xml) {
|
|
126
110
|
return {
|
|
@@ -128,7 +112,6 @@ THREE.ColladaLoader.prototype = {
|
|
|
128
112
|
upAxis: parseAssetUpAxis(getElementsByTagName(xml, "up_axis")[0])
|
|
129
113
|
};
|
|
130
114
|
}
|
|
131
|
-
|
|
132
115
|
function parseAssetUnit(xml) {
|
|
133
116
|
if (xml !== undefined && xml.hasAttribute("meter") === true) {
|
|
134
117
|
return parseFloat(xml.getAttribute("meter"));
|
|
@@ -139,35 +122,35 @@ THREE.ColladaLoader.prototype = {
|
|
|
139
122
|
|
|
140
123
|
function parseAssetUpAxis(xml) {
|
|
141
124
|
return xml !== undefined ? xml.textContent : "Y_UP";
|
|
142
|
-
}
|
|
125
|
+
}
|
|
143
126
|
|
|
127
|
+
// library
|
|
144
128
|
|
|
145
129
|
function parseLibrary(xml, libraryName, nodeName, parser) {
|
|
146
130
|
var library = getElementsByTagName(xml, libraryName)[0];
|
|
147
|
-
|
|
148
131
|
if (library !== undefined) {
|
|
149
132
|
var elements = getElementsByTagName(library, nodeName);
|
|
150
|
-
|
|
151
133
|
for (var i = 0; i < elements.length; i++) {
|
|
152
134
|
parser(elements[i]);
|
|
153
135
|
}
|
|
154
136
|
}
|
|
155
137
|
}
|
|
156
|
-
|
|
157
138
|
function buildLibrary(data, builder) {
|
|
158
139
|
for (var name in data) {
|
|
159
140
|
var object = data[name];
|
|
160
141
|
object.build = builder(data[name]);
|
|
161
142
|
}
|
|
162
|
-
}
|
|
143
|
+
}
|
|
163
144
|
|
|
145
|
+
// get
|
|
164
146
|
|
|
165
147
|
function getBuild(data, builder) {
|
|
166
148
|
if (data.build !== undefined) return data.build;
|
|
167
149
|
data.build = builder(data);
|
|
168
150
|
return data.build;
|
|
169
|
-
}
|
|
151
|
+
}
|
|
170
152
|
|
|
153
|
+
// animation
|
|
171
154
|
|
|
172
155
|
function parseAnimation(xml) {
|
|
173
156
|
var data = {
|
|
@@ -175,45 +158,36 @@ THREE.ColladaLoader.prototype = {
|
|
|
175
158
|
samplers: {},
|
|
176
159
|
channels: {}
|
|
177
160
|
};
|
|
178
|
-
|
|
179
161
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
180
162
|
var child = xml.childNodes[i];
|
|
181
163
|
if (child.nodeType !== 1) continue;
|
|
182
164
|
var id;
|
|
183
|
-
|
|
184
165
|
switch (child.nodeName) {
|
|
185
166
|
case "source":
|
|
186
167
|
id = child.getAttribute("id");
|
|
187
168
|
data.sources[id] = parseSource(child);
|
|
188
169
|
break;
|
|
189
|
-
|
|
190
170
|
case "sampler":
|
|
191
171
|
id = child.getAttribute("id");
|
|
192
172
|
data.samplers[id] = parseAnimationSampler(child);
|
|
193
173
|
break;
|
|
194
|
-
|
|
195
174
|
case "channel":
|
|
196
175
|
id = child.getAttribute("target");
|
|
197
176
|
data.channels[id] = parseAnimationChannel(child);
|
|
198
177
|
break;
|
|
199
|
-
|
|
200
178
|
default:
|
|
201
179
|
console.log(child);
|
|
202
180
|
}
|
|
203
181
|
}
|
|
204
|
-
|
|
205
182
|
library.animations[xml.getAttribute("id")] = data;
|
|
206
183
|
}
|
|
207
|
-
|
|
208
184
|
function parseAnimationSampler(xml) {
|
|
209
185
|
var data = {
|
|
210
186
|
inputs: {}
|
|
211
187
|
};
|
|
212
|
-
|
|
213
188
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
214
189
|
var child = xml.childNodes[i];
|
|
215
190
|
if (child.nodeType !== 1) continue;
|
|
216
|
-
|
|
217
191
|
switch (child.nodeName) {
|
|
218
192
|
case "input":
|
|
219
193
|
var id = parseId(child.getAttribute("source"));
|
|
@@ -222,38 +196,38 @@ THREE.ColladaLoader.prototype = {
|
|
|
222
196
|
break;
|
|
223
197
|
}
|
|
224
198
|
}
|
|
225
|
-
|
|
226
199
|
return data;
|
|
227
200
|
}
|
|
228
|
-
|
|
229
201
|
function parseAnimationChannel(xml) {
|
|
230
202
|
var data = {};
|
|
231
|
-
var target = xml.getAttribute("target");
|
|
203
|
+
var target = xml.getAttribute("target");
|
|
204
|
+
|
|
205
|
+
// parsing SID Addressing Syntax
|
|
232
206
|
|
|
233
207
|
var parts = target.split("/");
|
|
234
208
|
var id = parts.shift();
|
|
235
|
-
var sid = parts.shift();
|
|
209
|
+
var sid = parts.shift();
|
|
210
|
+
|
|
211
|
+
// check selection syntax
|
|
236
212
|
|
|
237
213
|
var arraySyntax = sid.indexOf("(") !== -1;
|
|
238
214
|
var memberSyntax = sid.indexOf(".") !== -1;
|
|
239
|
-
|
|
240
215
|
if (memberSyntax) {
|
|
241
216
|
// member selection access
|
|
217
|
+
|
|
242
218
|
parts = sid.split(".");
|
|
243
219
|
sid = parts.shift();
|
|
244
220
|
data.member = parts.shift();
|
|
245
221
|
} else if (arraySyntax) {
|
|
246
222
|
// array-access syntax. can be used to express fields in one-dimensional vectors or two-dimensional matrices.
|
|
223
|
+
|
|
247
224
|
var indices = sid.split("(");
|
|
248
225
|
sid = indices.shift();
|
|
249
|
-
|
|
250
226
|
for (var i = 0; i < indices.length; i++) {
|
|
251
227
|
indices[i] = parseInt(indices[i].replace(/\)/, ""));
|
|
252
228
|
}
|
|
253
|
-
|
|
254
229
|
data.indices = indices;
|
|
255
230
|
}
|
|
256
|
-
|
|
257
231
|
data.id = id;
|
|
258
232
|
data.sid = sid;
|
|
259
233
|
data.arraySyntax = arraySyntax;
|
|
@@ -261,13 +235,11 @@ THREE.ColladaLoader.prototype = {
|
|
|
261
235
|
data.sampler = parseId(xml.getAttribute("source"));
|
|
262
236
|
return data;
|
|
263
237
|
}
|
|
264
|
-
|
|
265
238
|
function buildAnimation(data) {
|
|
266
239
|
var tracks = [];
|
|
267
240
|
var channels = data.channels;
|
|
268
241
|
var samplers = data.samplers;
|
|
269
242
|
var sources = data.sources;
|
|
270
|
-
|
|
271
243
|
for (var target in channels) {
|
|
272
244
|
if (channels.hasOwnProperty(target)) {
|
|
273
245
|
var channel = channels[target];
|
|
@@ -280,14 +252,11 @@ THREE.ColladaLoader.prototype = {
|
|
|
280
252
|
createKeyframeTracks(animation, tracks);
|
|
281
253
|
}
|
|
282
254
|
}
|
|
283
|
-
|
|
284
255
|
return tracks;
|
|
285
256
|
}
|
|
286
|
-
|
|
287
257
|
function getAnimation(id) {
|
|
288
258
|
return getBuild(library.animations[id], buildAnimation);
|
|
289
259
|
}
|
|
290
|
-
|
|
291
260
|
function buildAnimationChannel(channel, inputSource, outputSource) {
|
|
292
261
|
var node = library.nodes[channel.id];
|
|
293
262
|
var object3D = getNode(node.id);
|
|
@@ -295,7 +264,9 @@ THREE.ColladaLoader.prototype = {
|
|
|
295
264
|
var defaultMatrix = node.matrix.clone().transpose();
|
|
296
265
|
var time, stride;
|
|
297
266
|
var i, il, j, jl;
|
|
298
|
-
var data = {};
|
|
267
|
+
var data = {};
|
|
268
|
+
|
|
269
|
+
// the collada spec allows the animation of data in various ways.
|
|
299
270
|
// depending on the transform type (matrix, translate, rotate, scale), we execute different logic
|
|
300
271
|
|
|
301
272
|
switch (transform) {
|
|
@@ -304,7 +275,6 @@ THREE.ColladaLoader.prototype = {
|
|
|
304
275
|
time = inputSource.array[i];
|
|
305
276
|
stride = i * outputSource.stride;
|
|
306
277
|
if (data[time] === undefined) data[time] = {};
|
|
307
|
-
|
|
308
278
|
if (channel.arraySyntax === true) {
|
|
309
279
|
var value = outputSource.array[stride];
|
|
310
280
|
var index = channel.indices[0] + 4 * channel.indices[1];
|
|
@@ -315,22 +285,17 @@ THREE.ColladaLoader.prototype = {
|
|
|
315
285
|
}
|
|
316
286
|
}
|
|
317
287
|
}
|
|
318
|
-
|
|
319
288
|
break;
|
|
320
|
-
|
|
321
289
|
case "translate":
|
|
322
290
|
console.warn('THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform);
|
|
323
291
|
break;
|
|
324
|
-
|
|
325
292
|
case "rotate":
|
|
326
293
|
console.warn('THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform);
|
|
327
294
|
break;
|
|
328
|
-
|
|
329
295
|
case "scale":
|
|
330
296
|
console.warn('THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform);
|
|
331
297
|
break;
|
|
332
298
|
}
|
|
333
|
-
|
|
334
299
|
var keyframes = prepareAnimationData(data, defaultMatrix);
|
|
335
300
|
var animation = {
|
|
336
301
|
name: object3D.uuid,
|
|
@@ -338,35 +303,38 @@ THREE.ColladaLoader.prototype = {
|
|
|
338
303
|
};
|
|
339
304
|
return animation;
|
|
340
305
|
}
|
|
341
|
-
|
|
342
306
|
function prepareAnimationData(data, defaultMatrix) {
|
|
343
|
-
var keyframes = [];
|
|
307
|
+
var keyframes = [];
|
|
308
|
+
|
|
309
|
+
// transfer data into a sortable array
|
|
344
310
|
|
|
345
311
|
for (var time in data) {
|
|
346
312
|
keyframes.push({
|
|
347
313
|
time: parseFloat(time),
|
|
348
314
|
value: data[time]
|
|
349
315
|
});
|
|
350
|
-
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// ensure keyframes are sorted by time
|
|
351
319
|
|
|
320
|
+
keyframes.sort(ascending);
|
|
352
321
|
|
|
353
|
-
|
|
322
|
+
// now we clean up all animation data, so we can use them for keyframe tracks
|
|
354
323
|
|
|
355
324
|
for (var i = 0; i < 16; i++) {
|
|
356
325
|
transformAnimationData(keyframes, i, defaultMatrix.elements[i]);
|
|
357
326
|
}
|
|
327
|
+
return keyframes;
|
|
358
328
|
|
|
359
|
-
|
|
329
|
+
// array sort function
|
|
360
330
|
|
|
361
331
|
function ascending(a, b) {
|
|
362
332
|
return a.time - b.time;
|
|
363
333
|
}
|
|
364
334
|
}
|
|
365
|
-
|
|
366
335
|
var position = new THREE.Vector3();
|
|
367
336
|
var scale = new THREE.Vector3();
|
|
368
337
|
var quaternion = new THREE.Quaternion();
|
|
369
|
-
|
|
370
338
|
function createKeyframeTracks(animation, tracks) {
|
|
371
339
|
var keyframes = animation.keyframes;
|
|
372
340
|
var name = animation.name;
|
|
@@ -374,7 +342,6 @@ THREE.ColladaLoader.prototype = {
|
|
|
374
342
|
var positionData = [];
|
|
375
343
|
var quaternionData = [];
|
|
376
344
|
var scaleData = [];
|
|
377
|
-
|
|
378
345
|
for (var i = 0, l = keyframes.length; i < l; i++) {
|
|
379
346
|
var keyframe = keyframes[i];
|
|
380
347
|
var time = keyframe.time;
|
|
@@ -386,94 +353,83 @@ THREE.ColladaLoader.prototype = {
|
|
|
386
353
|
quaternionData.push(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
|
|
387
354
|
scaleData.push(scale.x, scale.y, scale.z);
|
|
388
355
|
}
|
|
389
|
-
|
|
390
356
|
if (positionData.length > 0) tracks.push(new THREE.VectorKeyframeTrack(name + ".position", times, positionData));
|
|
391
357
|
if (quaternionData.length > 0) tracks.push(new THREE.QuaternionKeyframeTrack(name + ".quaternion", times, quaternionData));
|
|
392
358
|
if (scaleData.length > 0) tracks.push(new THREE.VectorKeyframeTrack(name + ".scale", times, scaleData));
|
|
393
359
|
return tracks;
|
|
394
360
|
}
|
|
395
|
-
|
|
396
361
|
function transformAnimationData(keyframes, property, defaultValue) {
|
|
397
362
|
var keyframe;
|
|
398
363
|
var empty = true;
|
|
399
|
-
var i, l;
|
|
364
|
+
var i, l;
|
|
365
|
+
|
|
366
|
+
// check, if values of a property are missing in our keyframes
|
|
400
367
|
|
|
401
368
|
for (i = 0, l = keyframes.length; i < l; i++) {
|
|
402
369
|
keyframe = keyframes[i];
|
|
403
|
-
|
|
404
370
|
if (keyframe.value[property] === undefined) {
|
|
405
371
|
keyframe.value[property] = null; // mark as missing
|
|
406
372
|
} else {
|
|
407
373
|
empty = false;
|
|
408
374
|
}
|
|
409
375
|
}
|
|
410
|
-
|
|
411
376
|
if (empty === true) {
|
|
412
377
|
// no values at all, so we set a default value
|
|
378
|
+
|
|
413
379
|
for (i = 0, l = keyframes.length; i < l; i++) {
|
|
414
380
|
keyframe = keyframes[i];
|
|
415
381
|
keyframe.value[property] = defaultValue;
|
|
416
382
|
}
|
|
417
383
|
} else {
|
|
418
384
|
// filling gaps
|
|
385
|
+
|
|
419
386
|
createMissingKeyframes(keyframes, property);
|
|
420
387
|
}
|
|
421
388
|
}
|
|
422
|
-
|
|
423
389
|
function createMissingKeyframes(keyframes, property) {
|
|
424
390
|
var prev, next;
|
|
425
|
-
|
|
426
391
|
for (var i = 0, l = keyframes.length; i < l; i++) {
|
|
427
392
|
var keyframe = keyframes[i];
|
|
428
|
-
|
|
429
393
|
if (keyframe.value[property] === null) {
|
|
430
394
|
prev = getPrev(keyframes, i, property);
|
|
431
395
|
next = getNext(keyframes, i, property);
|
|
432
|
-
|
|
433
396
|
if (prev === null) {
|
|
434
397
|
keyframe.value[property] = next.value[property];
|
|
435
398
|
continue;
|
|
436
399
|
}
|
|
437
|
-
|
|
438
400
|
if (next === null) {
|
|
439
401
|
keyframe.value[property] = prev.value[property];
|
|
440
402
|
continue;
|
|
441
403
|
}
|
|
442
|
-
|
|
443
404
|
interpolate(keyframe, prev, next, property);
|
|
444
405
|
}
|
|
445
406
|
}
|
|
446
407
|
}
|
|
447
|
-
|
|
448
408
|
function getPrev(keyframes, i, property) {
|
|
449
409
|
while (i >= 0) {
|
|
450
410
|
var keyframe = keyframes[i];
|
|
451
411
|
if (keyframe.value[property] !== null) return keyframe;
|
|
452
412
|
i--;
|
|
453
413
|
}
|
|
454
|
-
|
|
455
414
|
return null;
|
|
456
415
|
}
|
|
457
|
-
|
|
458
416
|
function getNext(keyframes, i, property) {
|
|
459
417
|
while (i < keyframes.length) {
|
|
460
418
|
var keyframe = keyframes[i];
|
|
461
419
|
if (keyframe.value[property] !== null) return keyframe;
|
|
462
420
|
i++;
|
|
463
421
|
}
|
|
464
|
-
|
|
465
422
|
return null;
|
|
466
423
|
}
|
|
467
|
-
|
|
468
424
|
function interpolate(key, prev, next, property) {
|
|
469
425
|
if (next.time - prev.time === 0) {
|
|
470
426
|
key.value[property] = prev.value[property];
|
|
471
427
|
return;
|
|
472
428
|
}
|
|
473
|
-
|
|
474
429
|
key.value[property] = (key.time - prev.time) * (next.value[property] - prev.value[property]) / (next.time - prev.time) + prev.value[property];
|
|
475
|
-
}
|
|
430
|
+
}
|
|
476
431
|
|
|
432
|
+
// animation clips
|
|
477
433
|
|
|
478
434
|
function parseAnimationClip(xml) {
|
|
479
435
|
var data = {
|
|
@@ -482,108 +438,87 @@ THREE.ColladaLoader.prototype = {
|
|
|
482
438
|
end: parseFloat(xml.getAttribute("end") || 0),
|
|
483
439
|
animations: []
|
|
484
440
|
};
|
|
485
|
-
|
|
486
441
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
487
442
|
var child = xml.childNodes[i];
|
|
488
443
|
if (child.nodeType !== 1) continue;
|
|
489
|
-
|
|
490
444
|
switch (child.nodeName) {
|
|
491
445
|
case "instance_animation":
|
|
492
446
|
data.animations.push(parseId(child.getAttribute("url")));
|
|
493
447
|
break;
|
|
494
448
|
}
|
|
495
449
|
}
|
|
496
|
-
|
|
497
450
|
library.clips[xml.getAttribute("id")] = data;
|
|
498
451
|
}
|
|
499
|
-
|
|
500
452
|
function buildAnimationClip(data) {
|
|
501
453
|
var tracks = [];
|
|
502
454
|
var name = data.name;
|
|
503
455
|
var duration = data.end - data.start || -1;
|
|
504
456
|
var animations = data.animations;
|
|
505
|
-
|
|
506
457
|
for (var i = 0, il = animations.length; i < il; i++) {
|
|
507
458
|
var animationTracks = getAnimation(animations[i]);
|
|
508
|
-
|
|
509
459
|
for (var j = 0, jl = animationTracks.length; j < jl; j++) {
|
|
510
460
|
tracks.push(animationTracks[j]);
|
|
511
461
|
}
|
|
512
462
|
}
|
|
513
|
-
|
|
514
463
|
return new THREE.AnimationClip(name, duration, tracks);
|
|
515
464
|
}
|
|
516
|
-
|
|
517
465
|
function getAnimationClip(id) {
|
|
518
466
|
return getBuild(library.clips[id], buildAnimationClip);
|
|
519
|
-
}
|
|
467
|
+
}
|
|
520
468
|
|
|
469
|
+
// controller
|
|
521
470
|
|
|
522
471
|
function parseController(xml) {
|
|
523
472
|
var data = {};
|
|
524
|
-
|
|
525
473
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
526
474
|
var child = xml.childNodes[i];
|
|
527
475
|
if (child.nodeType !== 1) continue;
|
|
528
|
-
|
|
529
476
|
switch (child.nodeName) {
|
|
530
477
|
case "skin":
|
|
531
478
|
// there is exactly one skin per controller
|
|
532
479
|
data.id = parseId(child.getAttribute("source"));
|
|
533
480
|
data.skin = parseSkin(child);
|
|
534
481
|
break;
|
|
535
|
-
|
|
536
482
|
case "morph":
|
|
537
483
|
data.id = parseId(child.getAttribute("source"));
|
|
538
484
|
console.warn("THREE.ColladaLoader: Morph target animation not supported yet.");
|
|
539
485
|
break;
|
|
540
486
|
}
|
|
541
487
|
}
|
|
542
|
-
|
|
543
488
|
library.controllers[xml.getAttribute("id")] = data;
|
|
544
489
|
}
|
|
545
|
-
|
|
546
490
|
function parseSkin(xml) {
|
|
547
491
|
var data = {
|
|
548
492
|
sources: {}
|
|
549
493
|
};
|
|
550
|
-
|
|
551
494
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
552
495
|
var child = xml.childNodes[i];
|
|
553
496
|
if (child.nodeType !== 1) continue;
|
|
554
|
-
|
|
555
497
|
switch (child.nodeName) {
|
|
556
498
|
case "bind_shape_matrix":
|
|
557
499
|
data.bindShapeMatrix = parseFloats(child.textContent);
|
|
558
500
|
break;
|
|
559
|
-
|
|
560
501
|
case "source":
|
|
561
502
|
var id = child.getAttribute("id");
|
|
562
503
|
data.sources[id] = parseSource(child);
|
|
563
504
|
break;
|
|
564
|
-
|
|
565
505
|
case "joints":
|
|
566
506
|
data.joints = parseJoints(child);
|
|
567
507
|
break;
|
|
568
|
-
|
|
569
508
|
case "vertex_weights":
|
|
570
509
|
data.vertexWeights = parseVertexWeights(child);
|
|
571
510
|
break;
|
|
572
511
|
}
|
|
573
512
|
}
|
|
574
|
-
|
|
575
513
|
return data;
|
|
576
514
|
}
|
|
577
|
-
|
|
578
515
|
function parseJoints(xml) {
|
|
579
516
|
var data = {
|
|
580
517
|
inputs: {}
|
|
581
518
|
};
|
|
582
|
-
|
|
583
519
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
584
520
|
var child = xml.childNodes[i];
|
|
585
521
|
if (child.nodeType !== 1) continue;
|
|
586
|
-
|
|
587
522
|
switch (child.nodeName) {
|
|
588
523
|
case "input":
|
|
589
524
|
var semantic = child.getAttribute("semantic");
|
|
@@ -592,19 +527,15 @@ THREE.ColladaLoader.prototype = {
|
|
|
592
527
|
break;
|
|
593
528
|
}
|
|
594
529
|
}
|
|
595
|
-
|
|
596
530
|
return data;
|
|
597
531
|
}
|
|
598
|
-
|
|
599
532
|
function parseVertexWeights(xml) {
|
|
600
533
|
var data = {
|
|
601
534
|
inputs: {}
|
|
602
535
|
};
|
|
603
|
-
|
|
604
536
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
605
537
|
var child = xml.childNodes[i];
|
|
606
538
|
if (child.nodeType !== 1) continue;
|
|
607
|
-
|
|
608
539
|
switch (child.nodeName) {
|
|
609
540
|
case "input":
|
|
610
541
|
var semantic = child.getAttribute("semantic");
|
|
@@ -615,36 +546,31 @@ THREE.ColladaLoader.prototype = {
|
|
|
615
546
|
offset: offset
|
|
616
547
|
};
|
|
617
548
|
break;
|
|
618
|
-
|
|
619
549
|
case "vcount":
|
|
620
550
|
data.vcount = parseInts(child.textContent);
|
|
621
551
|
break;
|
|
622
|
-
|
|
623
552
|
case "v":
|
|
624
553
|
data.v = parseInts(child.textContent);
|
|
625
554
|
break;
|
|
626
555
|
}
|
|
627
556
|
}
|
|
628
|
-
|
|
629
557
|
return data;
|
|
630
558
|
}
|
|
631
|
-
|
|
632
559
|
function buildController(data) {
|
|
633
560
|
var build = {
|
|
634
561
|
id: data.id
|
|
635
562
|
};
|
|
636
563
|
var geometry = library.geometries[build.id];
|
|
637
|
-
|
|
638
564
|
if (data.skin !== undefined) {
|
|
639
|
-
build.skin = buildSkin(data.skin);
|
|
565
|
+
build.skin = buildSkin(data.skin);
|
|
566
|
+
|
|
567
|
+
// we enhance the 'sources' property of the corresponding geometry with our skin data
|
|
640
568
|
|
|
641
569
|
geometry.sources.skinIndices = build.skin.indices;
|
|
642
570
|
geometry.sources.skinWeights = build.skin.weights;
|
|
643
571
|
}
|
|
644
|
-
|
|
645
572
|
return build;
|
|
646
573
|
}
|
|
647
|
-
|
|
648
574
|
function buildSkin(data) {
|
|
649
575
|
var BONE_LIMIT = 4;
|
|
650
576
|
var build = {
|
|
@@ -669,13 +595,13 @@ THREE.ColladaLoader.prototype = {
|
|
|
669
595
|
var inverseSource = data.sources[data.joints.inputs.INV_BIND_MATRIX];
|
|
670
596
|
var weights = sources[vertexWeights.inputs.WEIGHT.id].array;
|
|
671
597
|
var stride = 0;
|
|
672
|
-
var i, j, l;
|
|
598
|
+
var i, j, l;
|
|
599
|
+
|
|
600
|
+
// procces skin data for each vertex
|
|
673
601
|
|
|
674
602
|
for (i = 0, l = vcount.length; i < l; i++) {
|
|
675
603
|
var jointCount = vcount[i]; // this is the amount of joints that affect a single vertex
|
|
676
|
-
|
|
677
604
|
var vertexSkinData = [];
|
|
678
|
-
|
|
679
605
|
for (j = 0; j < jointCount; j++) {
|
|
680
606
|
var skinIndex = v[stride + jointOffset];
|
|
681
607
|
var weightId = v[stride + weightOffset];
|
|
@@ -685,16 +611,18 @@ THREE.ColladaLoader.prototype = {
|
|
|
685
611
|
weight: skinWeight
|
|
686
612
|
});
|
|
687
613
|
stride += 2;
|
|
688
|
-
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// we sort the joints in descending order based on the weights.
|
|
689
617
|
// this ensures, we only procced the most important joints of the vertex
|
|
690
618
|
|
|
619
|
+
vertexSkinData.sort(descending);
|
|
691
620
|
|
|
692
|
-
|
|
621
|
+
// now we provide for each vertex a set of four index and weight values.
|
|
693
622
|
// the order of the skin data matches the order of vertices
|
|
694
623
|
|
|
695
624
|
for (j = 0; j < BONE_LIMIT; j++) {
|
|
696
625
|
var d = vertexSkinData[j];
|
|
697
|
-
|
|
698
626
|
if (d !== undefined) {
|
|
699
627
|
build.indices.array.push(d.index);
|
|
700
628
|
build.weights.array.push(d.weight);
|
|
@@ -703,15 +631,17 @@ THREE.ColladaLoader.prototype = {
|
|
|
703
631
|
build.weights.array.push(0);
|
|
704
632
|
}
|
|
705
633
|
}
|
|
706
|
-
}
|
|
634
|
+
}
|
|
707
635
|
|
|
636
|
+
// setup bind matrix
|
|
708
637
|
|
|
709
638
|
if (data.bindShapeMatrix) {
|
|
710
639
|
build.bindMatrix = new THREE.Matrix4().fromArray(data.bindShapeMatrix).transpose();
|
|
711
640
|
} else {
|
|
712
641
|
build.bindMatrix = new THREE.Matrix4().identity();
|
|
713
|
-
}
|
|
642
|
+
}
|
|
714
643
|
|
|
644
|
+
// process bones and inverse bind matrix data
|
|
715
645
|
|
|
716
646
|
for (i = 0, l = jointSource.array.length; i < l; i++) {
|
|
717
647
|
var name = jointSource.array[i];
|
|
@@ -721,18 +651,19 @@ THREE.ColladaLoader.prototype = {
|
|
|
721
651
|
boneInverse: boneInverse
|
|
722
652
|
});
|
|
723
653
|
}
|
|
654
|
+
return build;
|
|
724
655
|
|
|
725
|
-
|
|
656
|
+
// array sort function
|
|
726
657
|
|
|
727
658
|
function descending(a, b) {
|
|
728
659
|
return b.weight - a.weight;
|
|
729
660
|
}
|
|
730
661
|
}
|
|
731
|
-
|
|
732
662
|
function getController(id) {
|
|
733
663
|
return getBuild(library.controllers[id], buildController);
|
|
734
|
-
}
|
|
664
|
+
}
|
|
735
665
|
|
|
666
|
+
// image
|
|
736
667
|
|
|
737
668
|
function parseImage(xml) {
|
|
738
669
|
var data = {
|
|
@@ -740,129 +671,102 @@ THREE.ColladaLoader.prototype = {
|
|
|
740
671
|
};
|
|
741
672
|
library.images[xml.getAttribute("id")] = data;
|
|
742
673
|
}
|
|
743
|
-
|
|
744
674
|
function buildImage(data) {
|
|
745
675
|
if (data.build !== undefined) return data.build;
|
|
746
676
|
return data.init_from;
|
|
747
677
|
}
|
|
748
|
-
|
|
749
678
|
function getImage(id) {
|
|
750
679
|
var data = library.images[id];
|
|
751
|
-
|
|
752
680
|
if (data !== undefined) {
|
|
753
681
|
return getBuild(data, buildImage);
|
|
754
682
|
}
|
|
755
|
-
|
|
756
683
|
console.warn("THREE.ColladaLoader: Couldn't find image with ID:", id);
|
|
757
684
|
return null;
|
|
758
|
-
}
|
|
685
|
+
}
|
|
759
686
|
|
|
687
|
+
// effect
|
|
760
688
|
|
|
761
689
|
function parseEffect(xml) {
|
|
762
690
|
var data = {};
|
|
763
|
-
|
|
764
691
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
765
692
|
var child = xml.childNodes[i];
|
|
766
693
|
if (child.nodeType !== 1) continue;
|
|
767
|
-
|
|
768
694
|
switch (child.nodeName) {
|
|
769
695
|
case "profile_COMMON":
|
|
770
696
|
data.profile = parseEffectProfileCOMMON(child);
|
|
771
697
|
break;
|
|
772
698
|
}
|
|
773
699
|
}
|
|
774
|
-
|
|
775
700
|
library.effects[xml.getAttribute("id")] = data;
|
|
776
701
|
}
|
|
777
|
-
|
|
778
702
|
function parseEffectProfileCOMMON(xml) {
|
|
779
703
|
var data = {
|
|
780
704
|
surfaces: {},
|
|
781
705
|
samplers: {}
|
|
782
706
|
};
|
|
783
|
-
|
|
784
707
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
785
708
|
var child = xml.childNodes[i];
|
|
786
709
|
if (child.nodeType !== 1) continue;
|
|
787
|
-
|
|
788
710
|
switch (child.nodeName) {
|
|
789
711
|
case "newparam":
|
|
790
712
|
parseEffectNewparam(child, data);
|
|
791
713
|
break;
|
|
792
|
-
|
|
793
714
|
case "technique":
|
|
794
715
|
data.technique = parseEffectTechnique(child);
|
|
795
716
|
break;
|
|
796
|
-
|
|
797
717
|
case "extra":
|
|
798
718
|
data.extra = parseEffectExtra(child);
|
|
799
719
|
break;
|
|
800
720
|
}
|
|
801
721
|
}
|
|
802
|
-
|
|
803
722
|
return data;
|
|
804
723
|
}
|
|
805
|
-
|
|
806
724
|
function parseEffectNewparam(xml, data) {
|
|
807
725
|
var sid = xml.getAttribute("sid");
|
|
808
|
-
|
|
809
726
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
810
727
|
var child = xml.childNodes[i];
|
|
811
728
|
if (child.nodeType !== 1) continue;
|
|
812
|
-
|
|
813
729
|
switch (child.nodeName) {
|
|
814
730
|
case "surface":
|
|
815
731
|
data.surfaces[sid] = parseEffectSurface(child);
|
|
816
732
|
break;
|
|
817
|
-
|
|
818
733
|
case "sampler2D":
|
|
819
734
|
data.samplers[sid] = parseEffectSampler(child);
|
|
820
735
|
break;
|
|
821
736
|
}
|
|
822
737
|
}
|
|
823
738
|
}
|
|
824
|
-
|
|
825
739
|
function parseEffectSurface(xml) {
|
|
826
740
|
var data = {};
|
|
827
|
-
|
|
828
741
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
829
742
|
var child = xml.childNodes[i];
|
|
830
743
|
if (child.nodeType !== 1) continue;
|
|
831
|
-
|
|
832
744
|
switch (child.nodeName) {
|
|
833
745
|
case "init_from":
|
|
834
746
|
data.init_from = child.textContent;
|
|
835
747
|
break;
|
|
836
748
|
}
|
|
837
749
|
}
|
|
838
|
-
|
|
839
750
|
return data;
|
|
840
751
|
}
|
|
841
|
-
|
|
842
752
|
function parseEffectSampler(xml) {
|
|
843
753
|
var data = {};
|
|
844
|
-
|
|
845
754
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
846
755
|
var child = xml.childNodes[i];
|
|
847
756
|
if (child.nodeType !== 1) continue;
|
|
848
|
-
|
|
849
757
|
switch (child.nodeName) {
|
|
850
758
|
case "source":
|
|
851
759
|
data.source = child.textContent;
|
|
852
760
|
break;
|
|
853
761
|
}
|
|
854
762
|
}
|
|
855
|
-
|
|
856
763
|
return data;
|
|
857
764
|
}
|
|
858
|
-
|
|
859
765
|
function parseEffectTechnique(xml) {
|
|
860
766
|
var data = {};
|
|
861
|
-
|
|
862
767
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
863
768
|
var child = xml.childNodes[i];
|
|
864
769
|
if (child.nodeType !== 1) continue;
|
|
865
|
-
|
|
866
770
|
switch (child.nodeName) {
|
|
867
771
|
case "constant":
|
|
868
772
|
case "lambert":
|
|
@@ -873,17 +777,13 @@ THREE.ColladaLoader.prototype = {
|
|
|
873
777
|
break;
|
|
874
778
|
}
|
|
875
779
|
}
|
|
876
|
-
|
|
877
780
|
return data;
|
|
878
781
|
}
|
|
879
|
-
|
|
880
782
|
function parseEffectParameters(xml) {
|
|
881
783
|
var data = {};
|
|
882
|
-
|
|
883
784
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
884
785
|
var child = xml.childNodes[i];
|
|
885
786
|
if (child.nodeType !== 1) continue;
|
|
886
|
-
|
|
887
787
|
switch (child.nodeName) {
|
|
888
788
|
case "emission":
|
|
889
789
|
case "diffuse":
|
|
@@ -894,7 +794,6 @@ THREE.ColladaLoader.prototype = {
|
|
|
894
794
|
case "transparency":
|
|
895
795
|
data[child.nodeName] = parseEffectParameter(child);
|
|
896
796
|
break;
|
|
897
|
-
|
|
898
797
|
case "transparent":
|
|
899
798
|
data[child.nodeName] = {
|
|
900
799
|
opaque: child.getAttribute("opaque"),
|
|
@@ -903,26 +802,20 @@ THREE.ColladaLoader.prototype = {
|
|
|
903
802
|
break;
|
|
904
803
|
}
|
|
905
804
|
}
|
|
906
|
-
|
|
907
805
|
return data;
|
|
908
806
|
}
|
|
909
|
-
|
|
910
807
|
function parseEffectParameter(xml) {
|
|
911
808
|
var data = {};
|
|
912
|
-
|
|
913
809
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
914
810
|
var child = xml.childNodes[i];
|
|
915
811
|
if (child.nodeType !== 1) continue;
|
|
916
|
-
|
|
917
812
|
switch (child.nodeName) {
|
|
918
813
|
case "color":
|
|
919
814
|
data[child.nodeName] = parseFloats(child.textContent);
|
|
920
815
|
break;
|
|
921
|
-
|
|
922
816
|
case "float":
|
|
923
817
|
data[child.nodeName] = parseFloat(child.textContent);
|
|
924
818
|
break;
|
|
925
|
-
|
|
926
819
|
case "texture":
|
|
927
820
|
data[child.nodeName] = {
|
|
928
821
|
id: child.getAttribute("texture"),
|
|
@@ -931,34 +824,27 @@ THREE.ColladaLoader.prototype = {
|
|
|
931
824
|
break;
|
|
932
825
|
}
|
|
933
826
|
}
|
|
934
|
-
|
|
935
827
|
return data;
|
|
936
828
|
}
|
|
937
|
-
|
|
938
829
|
function parseEffectParameterTexture(xml) {
|
|
939
830
|
var data = {
|
|
940
831
|
technique: {}
|
|
941
832
|
};
|
|
942
|
-
|
|
943
833
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
944
834
|
var child = xml.childNodes[i];
|
|
945
835
|
if (child.nodeType !== 1) continue;
|
|
946
|
-
|
|
947
836
|
switch (child.nodeName) {
|
|
948
837
|
case "extra":
|
|
949
838
|
parseEffectParameterTextureExtra(child, data);
|
|
950
839
|
break;
|
|
951
840
|
}
|
|
952
841
|
}
|
|
953
|
-
|
|
954
842
|
return data;
|
|
955
843
|
}
|
|
956
|
-
|
|
957
844
|
function parseEffectParameterTextureExtra(xml, data) {
|
|
958
845
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
959
846
|
var child = xml.childNodes[i];
|
|
960
847
|
if (child.nodeType !== 1) continue;
|
|
961
|
-
|
|
962
848
|
switch (child.nodeName) {
|
|
963
849
|
case "technique":
|
|
964
850
|
parseEffectParameterTextureExtraTechnique(child, data);
|
|
@@ -966,12 +852,10 @@ THREE.ColladaLoader.prototype = {
|
|
|
966
852
|
}
|
|
967
853
|
}
|
|
968
854
|
}
|
|
969
|
-
|
|
970
855
|
function parseEffectParameterTextureExtraTechnique(xml, data) {
|
|
971
856
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
972
857
|
var child = xml.childNodes[i];
|
|
973
858
|
if (child.nodeType !== 1) continue;
|
|
974
|
-
|
|
975
859
|
switch (child.nodeName) {
|
|
976
860
|
case "repeatU":
|
|
977
861
|
case "repeatV":
|
|
@@ -979,10 +863,10 @@ THREE.ColladaLoader.prototype = {
|
|
|
979
863
|
case "offsetV":
|
|
980
864
|
data.technique[child.nodeName] = parseFloat(child.textContent);
|
|
981
865
|
break;
|
|
982
|
-
|
|
983
866
|
case "wrapU":
|
|
984
867
|
case "wrapV":
|
|
985
868
|
// some files have values for wrapU/wrapV which become NaN via parseInt
|
|
869
|
+
|
|
986
870
|
if (child.textContent.toUpperCase() === "TRUE") {
|
|
987
871
|
data.technique[child.nodeName] = 1;
|
|
988
872
|
} else if (child.textContent.toUpperCase() === "FALSE") {
|
|
@@ -990,118 +874,96 @@ THREE.ColladaLoader.prototype = {
|
|
|
990
874
|
} else {
|
|
991
875
|
data.technique[child.nodeName] = parseInt(child.textContent);
|
|
992
876
|
}
|
|
993
|
-
|
|
994
877
|
break;
|
|
995
878
|
}
|
|
996
879
|
}
|
|
997
880
|
}
|
|
998
|
-
|
|
999
881
|
function parseEffectExtra(xml) {
|
|
1000
882
|
var data = {};
|
|
1001
|
-
|
|
1002
883
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
1003
884
|
var child = xml.childNodes[i];
|
|
1004
885
|
if (child.nodeType !== 1) continue;
|
|
1005
|
-
|
|
1006
886
|
switch (child.nodeName) {
|
|
1007
887
|
case "technique":
|
|
1008
888
|
data.technique = parseEffectExtraTechnique(child);
|
|
1009
889
|
break;
|
|
1010
890
|
}
|
|
1011
891
|
}
|
|
1012
|
-
|
|
1013
892
|
return data;
|
|
1014
893
|
}
|
|
1015
|
-
|
|
1016
894
|
function parseEffectExtraTechnique(xml) {
|
|
1017
895
|
var data = {};
|
|
1018
|
-
|
|
1019
896
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
1020
897
|
var child = xml.childNodes[i];
|
|
1021
898
|
if (child.nodeType !== 1) continue;
|
|
1022
|
-
|
|
1023
899
|
switch (child.nodeName) {
|
|
1024
900
|
case "double_sided":
|
|
1025
901
|
data[child.nodeName] = parseInt(child.textContent);
|
|
1026
902
|
break;
|
|
1027
903
|
}
|
|
1028
904
|
}
|
|
1029
|
-
|
|
1030
905
|
return data;
|
|
1031
906
|
}
|
|
1032
|
-
|
|
1033
907
|
function buildEffect(data) {
|
|
1034
908
|
return data;
|
|
1035
909
|
}
|
|
1036
|
-
|
|
1037
910
|
function getEffect(id) {
|
|
1038
911
|
return getBuild(library.effects[id], buildEffect);
|
|
1039
|
-
}
|
|
912
|
+
}
|
|
1040
913
|
|
|
914
|
+
// material
|
|
1041
915
|
|
|
1042
916
|
function parseMaterial(xml) {
|
|
1043
917
|
var data = {
|
|
1044
918
|
name: xml.getAttribute("name")
|
|
1045
919
|
};
|
|
1046
|
-
|
|
1047
920
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
1048
921
|
var child = xml.childNodes[i];
|
|
1049
922
|
if (child.nodeType !== 1) continue;
|
|
1050
|
-
|
|
1051
923
|
switch (child.nodeName) {
|
|
1052
924
|
case "instance_effect":
|
|
1053
925
|
data.url = parseId(child.getAttribute("url"));
|
|
1054
926
|
break;
|
|
1055
927
|
}
|
|
1056
928
|
}
|
|
1057
|
-
|
|
1058
929
|
library.materials[xml.getAttribute("id")] = data;
|
|
1059
930
|
}
|
|
1060
|
-
|
|
1061
931
|
function getTextureLoader(image) {
|
|
1062
932
|
var loader;
|
|
1063
933
|
var extension = image.slice((image.lastIndexOf(".") - 1 >>> 0) + 2); // http://www.jstips.co/en/javascript/get-file-extension/
|
|
1064
|
-
|
|
1065
934
|
extension = extension.toLowerCase();
|
|
1066
|
-
|
|
1067
935
|
switch (extension) {
|
|
1068
936
|
case "tga":
|
|
1069
937
|
loader = tgaLoader;
|
|
1070
938
|
break;
|
|
1071
|
-
|
|
1072
939
|
default:
|
|
1073
940
|
loader = textureLoader;
|
|
1074
941
|
}
|
|
1075
|
-
|
|
1076
942
|
return loader;
|
|
1077
943
|
}
|
|
1078
|
-
|
|
1079
944
|
function buildMaterial(data) {
|
|
1080
945
|
var effect = getEffect(data.url);
|
|
1081
946
|
var technique = effect.profile.technique;
|
|
1082
947
|
var extra = effect.profile.extra;
|
|
1083
948
|
var material;
|
|
1084
|
-
|
|
1085
949
|
switch (technique.type) {
|
|
1086
950
|
case "phong":
|
|
1087
951
|
case "blinn":
|
|
1088
952
|
material = new THREE.MeshPhongMaterial();
|
|
1089
953
|
break;
|
|
1090
|
-
|
|
1091
954
|
case "lambert":
|
|
1092
955
|
material = new THREE.MeshLambertMaterial();
|
|
1093
956
|
break;
|
|
1094
|
-
|
|
1095
957
|
default:
|
|
1096
958
|
material = new THREE.MeshBasicMaterial();
|
|
1097
959
|
break;
|
|
1098
960
|
}
|
|
1099
|
-
|
|
1100
961
|
material.name = data.name;
|
|
1101
|
-
|
|
1102
962
|
function getTexture(textureObject) {
|
|
1103
963
|
var sampler = effect.profile.samplers[textureObject.id];
|
|
1104
|
-
var image = null;
|
|
964
|
+
var image = null;
|
|
965
|
+
|
|
966
|
+
// get image
|
|
1105
967
|
|
|
1106
968
|
if (sampler !== undefined) {
|
|
1107
969
|
var surface = effect.profile.surfaces[sampler.source];
|
|
@@ -1109,16 +971,15 @@ THREE.ColladaLoader.prototype = {
|
|
|
1109
971
|
} else {
|
|
1110
972
|
console.warn("THREE.ColladaLoader: Undefined sampler. Access image directly (see #12530).");
|
|
1111
973
|
image = getImage(textureObject.id);
|
|
1112
|
-
}
|
|
974
|
+
}
|
|
1113
975
|
|
|
976
|
+
// create texture if image is avaiable
|
|
1114
977
|
|
|
1115
978
|
if (image !== null) {
|
|
1116
979
|
var loader = getTextureLoader(image);
|
|
1117
|
-
|
|
1118
980
|
if (loader !== undefined) {
|
|
1119
981
|
var texture = loader.load(image);
|
|
1120
982
|
var extra = textureObject.extra;
|
|
1121
|
-
|
|
1122
983
|
if (extra !== undefined && extra.technique !== undefined && isEmpty(extra.technique) === false) {
|
|
1123
984
|
var technique = extra.technique;
|
|
1124
985
|
texture.wrapS = technique.wrapU ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
|
|
@@ -1129,7 +990,6 @@ THREE.ColladaLoader.prototype = {
|
|
|
1129
990
|
texture.wrapS = THREE.RepeatWrapping;
|
|
1130
991
|
texture.wrapT = THREE.RepeatWrapping;
|
|
1131
992
|
}
|
|
1132
|
-
|
|
1133
993
|
return texture;
|
|
1134
994
|
} else {
|
|
1135
995
|
console.warn("THREE.ColladaLoader: Loader for texture %s not found.", image);
|
|
@@ -1140,52 +1000,48 @@ THREE.ColladaLoader.prototype = {
|
|
|
1140
1000
|
return null;
|
|
1141
1001
|
}
|
|
1142
1002
|
}
|
|
1143
|
-
|
|
1144
1003
|
var parameters = technique.parameters;
|
|
1145
|
-
|
|
1146
1004
|
for (var key in parameters) {
|
|
1147
1005
|
var parameter = parameters[key];
|
|
1148
|
-
|
|
1149
1006
|
switch (key) {
|
|
1150
1007
|
case "diffuse":
|
|
1151
1008
|
if (parameter.color) material.color.fromArray(parameter.color);
|
|
1152
1009
|
if (parameter.texture) material.map = getTexture(parameter.texture);
|
|
1153
1010
|
break;
|
|
1154
|
-
|
|
1155
1011
|
case "specular":
|
|
1156
1012
|
if (parameter.color && material.specular) material.specular.fromArray(parameter.color);
|
|
1157
1013
|
if (parameter.texture) material.specularMap = getTexture(parameter.texture);
|
|
1158
1014
|
break;
|
|
1159
|
-
|
|
1160
1015
|
case "bump":
|
|
1161
1016
|
if (parameter.texture) material.normalMap = getTexture(parameter.texture);
|
|
1162
1017
|
break;
|
|
1163
|
-
|
|
1164
1018
|
case "ambient":
|
|
1165
1019
|
if (parameter.texture) material.lightMap = getTexture(parameter.texture);
|
|
1166
1020
|
break;
|
|
1167
|
-
|
|
1168
1021
|
case "shininess":
|
|
1169
1022
|
if (parameter["float"] && material.shininess) material.shininess = parameter["float"];
|
|
1170
1023
|
break;
|
|
1171
|
-
|
|
1172
1024
|
case "emission":
|
|
1173
1025
|
if (parameter.color && material.emissive) material.emissive.fromArray(parameter.color);
|
|
1174
1026
|
if (parameter.texture) material.emissiveMap = getTexture(parameter.texture);
|
|
1175
1027
|
break;
|
|
1176
1028
|
}
|
|
1177
|
-
}
|
|
1029
|
+
}
|
|
1178
1030
|
|
|
1031
|
+
//
|
|
1179
1032
|
|
|
1180
1033
|
var transparent = parameters["transparent"];
|
|
1181
|
-
var transparency = parameters["transparency"];
|
|
1034
|
+
var transparency = parameters["transparency"];
|
|
1035
|
+
|
|
1036
|
+
// <transparency> does not exist but <transparent>
|
|
1182
1037
|
|
|
1183
1038
|
if (transparency === undefined && transparent) {
|
|
1184
1039
|
transparency = {
|
|
1185
1040
|
"float": 1
|
|
1186
1041
|
};
|
|
1187
|
-
}
|
|
1042
|
+
}
|
|
1188
1043
|
|
|
1044
|
+
// <transparent> does not exist but <transparency>
|
|
1189
1045
|
|
|
1190
1046
|
if (transparent === undefined && transparency) {
|
|
1191
1047
|
transparent = {
|
|
@@ -1195,91 +1051,77 @@ THREE.ColladaLoader.prototype = {
|
|
|
1195
1051
|
}
|
|
1196
1052
|
};
|
|
1197
1053
|
}
|
|
1198
|
-
|
|
1199
1054
|
if (transparent && transparency) {
|
|
1200
1055
|
// handle case if a texture exists but no color
|
|
1056
|
+
|
|
1201
1057
|
if (transparent.data.texture) {
|
|
1202
1058
|
// we do not set an alpha map (see #13792)
|
|
1059
|
+
|
|
1203
1060
|
material.transparent = true;
|
|
1204
1061
|
} else {
|
|
1205
1062
|
var color = transparent.data.color;
|
|
1206
|
-
|
|
1207
1063
|
switch (transparent.opaque) {
|
|
1208
1064
|
case "A_ONE":
|
|
1209
1065
|
material.opacity = color[3] * transparency["float"];
|
|
1210
1066
|
break;
|
|
1211
|
-
|
|
1212
1067
|
case "RGB_ZERO":
|
|
1213
1068
|
material.opacity = 1 - color[0] * transparency["float"];
|
|
1214
1069
|
break;
|
|
1215
|
-
|
|
1216
1070
|
case "A_ZERO":
|
|
1217
1071
|
material.opacity = 1 - color[3] * transparency["float"];
|
|
1218
1072
|
break;
|
|
1219
|
-
|
|
1220
1073
|
case "RGB_ONE":
|
|
1221
1074
|
material.opacity = color[0] * transparency["float"];
|
|
1222
1075
|
break;
|
|
1223
|
-
|
|
1224
1076
|
default:
|
|
1225
1077
|
console.warn('THREE.ColladaLoader: Invalid opaque type "%s" of transparent tag.', transparent.opaque);
|
|
1226
1078
|
}
|
|
1227
|
-
|
|
1228
1079
|
if (material.opacity < 1) material.transparent = true;
|
|
1229
1080
|
}
|
|
1230
|
-
}
|
|
1081
|
+
}
|
|
1231
1082
|
|
|
1083
|
+
//
|
|
1232
1084
|
|
|
1233
1085
|
if (extra !== undefined && extra.technique !== undefined && extra.technique.double_sided === 1) {
|
|
1234
1086
|
material.side = THREE.DoubleSide;
|
|
1235
1087
|
}
|
|
1236
|
-
|
|
1237
1088
|
return material;
|
|
1238
1089
|
}
|
|
1239
|
-
|
|
1240
1090
|
function getMaterial(id) {
|
|
1241
1091
|
return getBuild(library.materials[id], buildMaterial);
|
|
1242
|
-
}
|
|
1092
|
+
}
|
|
1243
1093
|
|
|
1094
|
+
// camera
|
|
1244
1095
|
|
|
1245
1096
|
function parseCamera(xml) {
|
|
1246
1097
|
var data = {
|
|
1247
1098
|
name: xml.getAttribute("name")
|
|
1248
1099
|
};
|
|
1249
|
-
|
|
1250
1100
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
1251
1101
|
var child = xml.childNodes[i];
|
|
1252
1102
|
if (child.nodeType !== 1) continue;
|
|
1253
|
-
|
|
1254
1103
|
switch (child.nodeName) {
|
|
1255
1104
|
case "optics":
|
|
1256
1105
|
data.optics = parseCameraOptics(child);
|
|
1257
1106
|
break;
|
|
1258
1107
|
}
|
|
1259
1108
|
}
|
|
1260
|
-
|
|
1261
1109
|
library.cameras[xml.getAttribute("id")] = data;
|
|
1262
1110
|
}
|
|
1263
|
-
|
|
1264
1111
|
function parseCameraOptics(xml) {
|
|
1265
1112
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
1266
1113
|
var child = xml.childNodes[i];
|
|
1267
|
-
|
|
1268
1114
|
switch (child.nodeName) {
|
|
1269
1115
|
case "technique_common":
|
|
1270
1116
|
return parseCameraTechnique(child);
|
|
1271
1117
|
}
|
|
1272
1118
|
}
|
|
1273
|
-
|
|
1274
1119
|
return {};
|
|
1275
1120
|
}
|
|
1276
|
-
|
|
1277
1121
|
function parseCameraTechnique(xml) {
|
|
1278
1122
|
var data = {};
|
|
1279
|
-
|
|
1280
1123
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
1281
1124
|
var child = xml.childNodes[i];
|
|
1282
|
-
|
|
1283
1125
|
switch (child.nodeName) {
|
|
1284
1126
|
case "perspective":
|
|
1285
1127
|
case "orthographic":
|
|
@@ -1288,16 +1130,12 @@ THREE.ColladaLoader.prototype = {
|
|
|
1288
1130
|
break;
|
|
1289
1131
|
}
|
|
1290
1132
|
}
|
|
1291
|
-
|
|
1292
1133
|
return data;
|
|
1293
1134
|
}
|
|
1294
|
-
|
|
1295
1135
|
function parseCameraParameters(xml) {
|
|
1296
1136
|
var data = {};
|
|
1297
|
-
|
|
1298
1137
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
1299
1138
|
var child = xml.childNodes[i];
|
|
1300
|
-
|
|
1301
1139
|
switch (child.nodeName) {
|
|
1302
1140
|
case "xfov":
|
|
1303
1141
|
case "yfov":
|
|
@@ -1310,18 +1148,14 @@ THREE.ColladaLoader.prototype = {
|
|
|
1310
1148
|
break;
|
|
1311
1149
|
}
|
|
1312
1150
|
}
|
|
1313
|
-
|
|
1314
1151
|
return data;
|
|
1315
1152
|
}
|
|
1316
|
-
|
|
1317
1153
|
function buildCamera(data) {
|
|
1318
1154
|
var camera;
|
|
1319
|
-
|
|
1320
1155
|
switch (data.optics.technique) {
|
|
1321
1156
|
case "perspective":
|
|
1322
1157
|
camera = new THREE.PerspectiveCamera(data.optics.parameters.yfov, data.optics.parameters.aspect_ratio, data.optics.parameters.znear, data.optics.parameters.zfar);
|
|
1323
1158
|
break;
|
|
1324
|
-
|
|
1325
1159
|
case "orthographic":
|
|
1326
1160
|
var ymag = data.optics.parameters.ymag;
|
|
1327
1161
|
var xmag = data.optics.parameters.xmag;
|
|
@@ -1330,55 +1164,46 @@ THREE.ColladaLoader.prototype = {
|
|
|
1330
1164
|
ymag = ymag === undefined ? xmag / aspectRatio : ymag;
|
|
1331
1165
|
xmag *= 0.5;
|
|
1332
1166
|
ymag *= 0.5;
|
|
1333
|
-
camera = new THREE.OrthographicCamera(-xmag, xmag, ymag, -ymag,
|
|
1167
|
+
camera = new THREE.OrthographicCamera(-xmag, xmag, ymag, -ymag,
|
|
1168
|
+
// left, right, top, bottom
|
|
1334
1169
|
data.optics.parameters.znear, data.optics.parameters.zfar);
|
|
1335
1170
|
break;
|
|
1336
|
-
|
|
1337
1171
|
default:
|
|
1338
1172
|
camera = new THREE.PerspectiveCamera();
|
|
1339
1173
|
break;
|
|
1340
1174
|
}
|
|
1341
|
-
|
|
1342
1175
|
camera.name = data.name;
|
|
1343
1176
|
return camera;
|
|
1344
1177
|
}
|
|
1345
|
-
|
|
1346
1178
|
function getCamera(id) {
|
|
1347
1179
|
var data = library.cameras[id];
|
|
1348
|
-
|
|
1349
1180
|
if (data !== undefined) {
|
|
1350
1181
|
return getBuild(data, buildCamera);
|
|
1351
1182
|
}
|
|
1352
|
-
|
|
1353
1183
|
console.warn("THREE.ColladaLoader: Couldn't find camera with ID:", id);
|
|
1354
1184
|
return null;
|
|
1355
|
-
}
|
|
1185
|
+
}
|
|
1356
1186
|
|
|
1187
|
+
// light
|
|
1357
1188
|
|
|
1358
1189
|
function parseLight(xml) {
|
|
1359
1190
|
var data = {};
|
|
1360
|
-
|
|
1361
1191
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
1362
1192
|
var child = xml.childNodes[i];
|
|
1363
1193
|
if (child.nodeType !== 1) continue;
|
|
1364
|
-
|
|
1365
1194
|
switch (child.nodeName) {
|
|
1366
1195
|
case "technique_common":
|
|
1367
1196
|
data = parseLightTechnique(child);
|
|
1368
1197
|
break;
|
|
1369
1198
|
}
|
|
1370
1199
|
}
|
|
1371
|
-
|
|
1372
1200
|
library.lights[xml.getAttribute("id")] = data;
|
|
1373
1201
|
}
|
|
1374
|
-
|
|
1375
1202
|
function parseLightTechnique(xml) {
|
|
1376
1203
|
var data = {};
|
|
1377
|
-
|
|
1378
1204
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
1379
1205
|
var child = xml.childNodes[i];
|
|
1380
1206
|
if (child.nodeType !== 1) continue;
|
|
1381
|
-
|
|
1382
1207
|
switch (child.nodeName) {
|
|
1383
1208
|
case "directional":
|
|
1384
1209
|
case "point":
|
|
@@ -1388,74 +1213,59 @@ THREE.ColladaLoader.prototype = {
|
|
|
1388
1213
|
data.parameters = parseLightParameters(child);
|
|
1389
1214
|
}
|
|
1390
1215
|
}
|
|
1391
|
-
|
|
1392
1216
|
return data;
|
|
1393
1217
|
}
|
|
1394
|
-
|
|
1395
1218
|
function parseLightParameters(xml) {
|
|
1396
1219
|
var data = {};
|
|
1397
|
-
|
|
1398
1220
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
1399
1221
|
var child = xml.childNodes[i];
|
|
1400
1222
|
if (child.nodeType !== 1) continue;
|
|
1401
|
-
|
|
1402
1223
|
switch (child.nodeName) {
|
|
1403
1224
|
case "color":
|
|
1404
1225
|
var array = parseFloats(child.textContent);
|
|
1405
1226
|
data.color = new THREE.Color().fromArray(array);
|
|
1406
1227
|
break;
|
|
1407
|
-
|
|
1408
1228
|
case "falloff_angle":
|
|
1409
1229
|
data.falloffAngle = parseFloat(child.textContent);
|
|
1410
1230
|
break;
|
|
1411
|
-
|
|
1412
1231
|
case "quadratic_attenuation":
|
|
1413
1232
|
var f = parseFloat(child.textContent);
|
|
1414
1233
|
data.distance = f ? Math.sqrt(1 / f) : 0;
|
|
1415
1234
|
break;
|
|
1416
1235
|
}
|
|
1417
1236
|
}
|
|
1418
|
-
|
|
1419
1237
|
return data;
|
|
1420
1238
|
}
|
|
1421
|
-
|
|
1422
1239
|
function buildLight(data) {
|
|
1423
1240
|
var light;
|
|
1424
|
-
|
|
1425
1241
|
switch (data.technique) {
|
|
1426
1242
|
case "directional":
|
|
1427
1243
|
light = new THREE.DirectionalLight();
|
|
1428
1244
|
break;
|
|
1429
|
-
|
|
1430
1245
|
case "point":
|
|
1431
1246
|
light = new THREE.PointLight();
|
|
1432
1247
|
break;
|
|
1433
|
-
|
|
1434
1248
|
case "spot":
|
|
1435
1249
|
light = new THREE.SpotLight();
|
|
1436
1250
|
break;
|
|
1437
|
-
|
|
1438
1251
|
case "ambient":
|
|
1439
1252
|
light = new THREE.AmbientLight();
|
|
1440
1253
|
break;
|
|
1441
1254
|
}
|
|
1442
|
-
|
|
1443
1255
|
if (data.parameters.color) light.color.copy(data.parameters.color);
|
|
1444
1256
|
if (data.parameters.distance) light.distance = data.parameters.distance;
|
|
1445
1257
|
return light;
|
|
1446
1258
|
}
|
|
1447
|
-
|
|
1448
1259
|
function getLight(id) {
|
|
1449
1260
|
var data = library.lights[id];
|
|
1450
|
-
|
|
1451
1261
|
if (data !== undefined) {
|
|
1452
1262
|
return getBuild(data, buildLight);
|
|
1453
1263
|
}
|
|
1454
|
-
|
|
1455
1264
|
console.warn("THREE.ColladaLoader: Couldn't find light with ID:", id);
|
|
1456
1265
|
return null;
|
|
1457
|
-
}
|
|
1266
|
+
}
|
|
1458
1267
|
|
|
1268
|
+
// geometry
|
|
1459
1269
|
|
|
1460
1270
|
function parseGeometry(xml) {
|
|
1461
1271
|
var data = {
|
|
@@ -1464,89 +1274,71 @@ THREE.ColladaLoader.prototype = {
|
|
|
1464
1274
|
vertices: {},
|
|
1465
1275
|
primitives: []
|
|
1466
1276
|
};
|
|
1467
|
-
var mesh = getElementsByTagName(xml, "mesh")[0];
|
|
1277
|
+
var mesh = getElementsByTagName(xml, "mesh")[0];
|
|
1468
1278
|
|
|
1279
|
+
// the following tags inside geometry are not supported yet (see https://github.com/mrdoob/three.js/pull/12606): convex_mesh, spline, brep
|
|
1469
1280
|
if (mesh === undefined) return;
|
|
1470
|
-
|
|
1471
1281
|
for (var i = 0; i < mesh.childNodes.length; i++) {
|
|
1472
1282
|
var child = mesh.childNodes[i];
|
|
1473
1283
|
if (child.nodeType !== 1) continue;
|
|
1474
1284
|
var id = child.getAttribute("id");
|
|
1475
|
-
|
|
1476
1285
|
switch (child.nodeName) {
|
|
1477
1286
|
case "source":
|
|
1478
1287
|
data.sources[id] = parseSource(child);
|
|
1479
1288
|
break;
|
|
1480
|
-
|
|
1481
1289
|
case "vertices":
|
|
1482
1290
|
// data.sources[ id ] = data.sources[ parseId( getElementsByTagName( child, 'input' )[ 0 ].getAttribute( 'source' ) ) ];
|
|
1483
1291
|
data.vertices = parseGeometryVertices(child);
|
|
1484
1292
|
break;
|
|
1485
|
-
|
|
1486
1293
|
case "polygons":
|
|
1487
1294
|
console.warn("THREE.ColladaLoader: Unsupported primitive type: ", child.nodeName);
|
|
1488
1295
|
break;
|
|
1489
|
-
|
|
1490
1296
|
case "lines":
|
|
1491
1297
|
case "linestrips":
|
|
1492
1298
|
case "polylist":
|
|
1493
1299
|
case "triangles":
|
|
1494
1300
|
data.primitives.push(parseGeometryPrimitive(child));
|
|
1495
1301
|
break;
|
|
1496
|
-
|
|
1497
1302
|
default:
|
|
1498
1303
|
console.log(child);
|
|
1499
1304
|
}
|
|
1500
1305
|
}
|
|
1501
|
-
|
|
1502
1306
|
library.geometries[xml.getAttribute("id")] = data;
|
|
1503
1307
|
}
|
|
1504
|
-
|
|
1505
1308
|
function parseSource(xml) {
|
|
1506
1309
|
var data = {
|
|
1507
1310
|
array: [],
|
|
1508
1311
|
stride: 3
|
|
1509
1312
|
};
|
|
1510
|
-
|
|
1511
1313
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
1512
1314
|
var child = xml.childNodes[i];
|
|
1513
1315
|
if (child.nodeType !== 1) continue;
|
|
1514
|
-
|
|
1515
1316
|
switch (child.nodeName) {
|
|
1516
1317
|
case "float_array":
|
|
1517
1318
|
data.array = parseFloats(child.textContent);
|
|
1518
1319
|
break;
|
|
1519
|
-
|
|
1520
1320
|
case "Name_array":
|
|
1521
1321
|
data.array = parseStrings(child.textContent);
|
|
1522
1322
|
break;
|
|
1523
|
-
|
|
1524
1323
|
case "technique_common":
|
|
1525
1324
|
var accessor = getElementsByTagName(child, "accessor")[0];
|
|
1526
|
-
|
|
1527
1325
|
if (accessor !== undefined) {
|
|
1528
1326
|
data.stride = parseInt(accessor.getAttribute("stride"));
|
|
1529
1327
|
}
|
|
1530
|
-
|
|
1531
1328
|
break;
|
|
1532
1329
|
}
|
|
1533
1330
|
}
|
|
1534
|
-
|
|
1535
1331
|
return data;
|
|
1536
1332
|
}
|
|
1537
|
-
|
|
1538
1333
|
function parseGeometryVertices(xml) {
|
|
1539
1334
|
var data = {};
|
|
1540
|
-
|
|
1541
1335
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
1542
1336
|
var child = xml.childNodes[i];
|
|
1543
1337
|
if (child.nodeType !== 1) continue;
|
|
1544
1338
|
data[child.getAttribute("semantic")] = parseId(child.getAttribute("source"));
|
|
1545
1339
|
}
|
|
1546
|
-
|
|
1547
1340
|
return data;
|
|
1548
1341
|
}
|
|
1549
|
-
|
|
1550
1342
|
function parseGeometryPrimitive(xml) {
|
|
1551
1343
|
var primitive = {
|
|
1552
1344
|
type: xml.nodeName,
|
|
@@ -1556,11 +1348,9 @@ THREE.ColladaLoader.prototype = {
|
|
|
1556
1348
|
stride: 0,
|
|
1557
1349
|
hasUV: false
|
|
1558
1350
|
};
|
|
1559
|
-
|
|
1560
1351
|
for (var i = 0, l = xml.childNodes.length; i < l; i++) {
|
|
1561
1352
|
var child = xml.childNodes[i];
|
|
1562
1353
|
if (child.nodeType !== 1) continue;
|
|
1563
|
-
|
|
1564
1354
|
switch (child.nodeName) {
|
|
1565
1355
|
case "input":
|
|
1566
1356
|
var id = parseId(child.getAttribute("source"));
|
|
@@ -1575,69 +1365,61 @@ THREE.ColladaLoader.prototype = {
|
|
|
1575
1365
|
primitive.stride = Math.max(primitive.stride, offset + 1);
|
|
1576
1366
|
if (semantic === "TEXCOORD") primitive.hasUV = true;
|
|
1577
1367
|
break;
|
|
1578
|
-
|
|
1579
1368
|
case "vcount":
|
|
1580
1369
|
primitive.vcount = parseInts(child.textContent);
|
|
1581
1370
|
break;
|
|
1582
|
-
|
|
1583
1371
|
case "p":
|
|
1584
1372
|
primitive.p = parseInts(child.textContent);
|
|
1585
1373
|
break;
|
|
1586
1374
|
}
|
|
1587
1375
|
}
|
|
1588
|
-
|
|
1589
1376
|
return primitive;
|
|
1590
1377
|
}
|
|
1591
|
-
|
|
1592
1378
|
function groupPrimitives(primitives) {
|
|
1593
1379
|
var build = {};
|
|
1594
|
-
|
|
1595
1380
|
for (var i = 0; i < primitives.length; i++) {
|
|
1596
1381
|
var primitive = primitives[i];
|
|
1597
1382
|
if (build[primitive.type] === undefined) build[primitive.type] = [];
|
|
1598
1383
|
build[primitive.type].push(primitive);
|
|
1599
1384
|
}
|
|
1600
|
-
|
|
1601
1385
|
return build;
|
|
1602
1386
|
}
|
|
1603
|
-
|
|
1604
1387
|
function checkUVCoordinates(primitives) {
|
|
1605
1388
|
var count = 0;
|
|
1606
|
-
|
|
1607
1389
|
for (var i = 0, l = primitives.length; i < l; i++) {
|
|
1608
1390
|
var primitive = primitives[i];
|
|
1609
|
-
|
|
1610
1391
|
if (primitive.hasUV === true) {
|
|
1611
1392
|
count++;
|
|
1612
1393
|
}
|
|
1613
1394
|
}
|
|
1614
|
-
|
|
1615
1395
|
if (count > 0 && count < primitives.length) {
|
|
1616
1396
|
primitives.uvsNeedsFix = true;
|
|
1617
1397
|
}
|
|
1618
1398
|
}
|
|
1619
|
-
|
|
1620
1399
|
function buildGeometry(data) {
|
|
1621
1400
|
var build = {};
|
|
1622
1401
|
var sources = data.sources;
|
|
1623
1402
|
var vertices = data.vertices;
|
|
1624
1403
|
var primitives = data.primitives;
|
|
1625
|
-
if (primitives.length === 0) return {};
|
|
1404
|
+
if (primitives.length === 0) return {};
|
|
1405
|
+
|
|
1406
|
+
// our goal is to create one buffer geometry for a single type of primitives
|
|
1626
1407
|
// first, we group all primitives by their type
|
|
1627
1408
|
|
|
1628
1409
|
var groupedPrimitives = groupPrimitives(primitives);
|
|
1629
|
-
|
|
1630
1410
|
for (var type in groupedPrimitives) {
|
|
1631
|
-
var primitiveType = groupedPrimitives[type];
|
|
1411
|
+
var primitiveType = groupedPrimitives[type];
|
|
1632
1412
|
|
|
1633
|
-
|
|
1413
|
+
// second, ensure consistent uv coordinates for each type of primitives (polylist,triangles or lines)
|
|
1414
|
+
|
|
1415
|
+
checkUVCoordinates(primitiveType);
|
|
1416
|
+
|
|
1417
|
+
// third, create a buffer geometry for each type of primitives
|
|
1634
1418
|
|
|
1635
1419
|
build[type] = buildGeometryType(primitiveType, sources, vertices);
|
|
1636
1420
|
}
|
|
1637
|
-
|
|
1638
1421
|
return build;
|
|
1639
1422
|
}
|
|
1640
|
-
|
|
1641
1423
|
function buildGeometryType(primitives, sources, vertices) {
|
|
1642
1424
|
var build = {};
|
|
1643
1425
|
var position = {
|
|
@@ -1671,140 +1453,120 @@ THREE.ColladaLoader.prototype = {
|
|
|
1671
1453
|
var geometry = new THREE.BufferGeometry();
|
|
1672
1454
|
var materialKeys = [];
|
|
1673
1455
|
var start = 0;
|
|
1674
|
-
|
|
1675
1456
|
for (var p = 0; p < primitives.length; p++) {
|
|
1676
1457
|
var primitive = primitives[p];
|
|
1677
|
-
var inputs = primitive.inputs;
|
|
1458
|
+
var inputs = primitive.inputs;
|
|
1678
1459
|
|
|
1679
|
-
|
|
1460
|
+
// groups
|
|
1680
1461
|
|
|
1462
|
+
var count = 0;
|
|
1681
1463
|
switch (primitive.type) {
|
|
1682
1464
|
case "lines":
|
|
1683
1465
|
case "linestrips":
|
|
1684
1466
|
count = primitive.count * 2;
|
|
1685
1467
|
break;
|
|
1686
|
-
|
|
1687
1468
|
case "triangles":
|
|
1688
1469
|
count = primitive.count * 3;
|
|
1689
1470
|
break;
|
|
1690
|
-
|
|
1691
1471
|
case "polylist":
|
|
1692
1472
|
for (var g = 0; g < primitive.count; g++) {
|
|
1693
1473
|
var vc = primitive.vcount[g];
|
|
1694
|
-
|
|
1695
1474
|
switch (vc) {
|
|
1696
1475
|
case 3:
|
|
1697
1476
|
count += 3; // single triangle
|
|
1698
|
-
|
|
1699
1477
|
break;
|
|
1700
|
-
|
|
1701
1478
|
case 4:
|
|
1702
1479
|
count += 6; // quad, subdivided into two triangles
|
|
1703
|
-
|
|
1704
1480
|
break;
|
|
1705
|
-
|
|
1706
1481
|
default:
|
|
1707
1482
|
count += (vc - 2) * 3; // polylist with more than four vertices
|
|
1708
|
-
|
|
1709
1483
|
break;
|
|
1710
1484
|
}
|
|
1711
1485
|
}
|
|
1712
|
-
|
|
1713
1486
|
break;
|
|
1714
|
-
|
|
1715
1487
|
default:
|
|
1716
1488
|
console.warn("THREE.ColladaLoader: Unknow primitive type:", primitive.type);
|
|
1717
1489
|
}
|
|
1718
|
-
|
|
1719
1490
|
geometry.addGroup(start, count, p);
|
|
1720
|
-
start += count;
|
|
1491
|
+
start += count;
|
|
1492
|
+
|
|
1493
|
+
// material
|
|
1721
1494
|
|
|
1722
1495
|
if (primitive.material) {
|
|
1723
1496
|
materialKeys.push(primitive.material);
|
|
1724
|
-
}
|
|
1497
|
+
}
|
|
1725
1498
|
|
|
1499
|
+
// geometry data
|
|
1726
1500
|
|
|
1727
1501
|
for (var name in inputs) {
|
|
1728
1502
|
var input = inputs[name];
|
|
1729
|
-
|
|
1730
1503
|
switch (name) {
|
|
1731
1504
|
case "VERTEX":
|
|
1732
1505
|
for (var key in vertices) {
|
|
1733
1506
|
var id = vertices[key];
|
|
1734
|
-
|
|
1735
1507
|
switch (key) {
|
|
1736
1508
|
case "POSITION":
|
|
1737
1509
|
var prevLength = position.array.length;
|
|
1738
1510
|
buildGeometryData(primitive, sources[id], input.offset, position.array);
|
|
1739
1511
|
position.stride = sources[id].stride;
|
|
1740
|
-
|
|
1741
1512
|
if (sources.skinWeights && sources.skinIndices) {
|
|
1742
1513
|
buildGeometryData(primitive, sources.skinIndices, input.offset, skinIndex.array);
|
|
1743
1514
|
buildGeometryData(primitive, sources.skinWeights, input.offset, skinWeight.array);
|
|
1744
|
-
}
|
|
1515
|
+
}
|
|
1745
1516
|
|
|
1517
|
+
// see #3803
|
|
1746
1518
|
|
|
1747
1519
|
if (primitive.hasUV === false && primitives.uvsNeedsFix === true) {
|
|
1748
1520
|
var count = (position.array.length - prevLength) / position.stride;
|
|
1749
|
-
|
|
1750
1521
|
for (var i = 0; i < count; i++) {
|
|
1751
1522
|
// fill missing uv coordinates
|
|
1523
|
+
|
|
1752
1524
|
uv.array.push(0, 0);
|
|
1753
1525
|
}
|
|
1754
1526
|
}
|
|
1755
|
-
|
|
1756
1527
|
break;
|
|
1757
|
-
|
|
1758
1528
|
case "NORMAL":
|
|
1759
1529
|
buildGeometryData(primitive, sources[id], input.offset, normal.array);
|
|
1760
1530
|
normal.stride = sources[id].stride;
|
|
1761
1531
|
break;
|
|
1762
|
-
|
|
1763
1532
|
case "COLOR":
|
|
1764
1533
|
buildGeometryData(primitive, sources[id], input.offset, color.array);
|
|
1765
1534
|
color.stride = sources[id].stride;
|
|
1766
1535
|
break;
|
|
1767
|
-
|
|
1768
1536
|
case "TEXCOORD":
|
|
1769
1537
|
buildGeometryData(primitive, sources[id], input.offset, uv.array);
|
|
1770
1538
|
uv.stride = sources[id].stride;
|
|
1771
1539
|
break;
|
|
1772
|
-
|
|
1773
1540
|
case "TEXCOORD1":
|
|
1774
1541
|
buildGeometryData(primitive, sources[id], input.offset, uv2.array);
|
|
1775
1542
|
uv.stride = sources[id].stride;
|
|
1776
1543
|
break;
|
|
1777
|
-
|
|
1778
1544
|
default:
|
|
1779
1545
|
console.warn('THREE.ColladaLoader: Semantic "%s" not handled in geometry build process.', key);
|
|
1780
1546
|
}
|
|
1781
1547
|
}
|
|
1782
|
-
|
|
1783
1548
|
break;
|
|
1784
|
-
|
|
1785
1549
|
case "NORMAL":
|
|
1786
1550
|
buildGeometryData(primitive, sources[input.id], input.offset, normal.array);
|
|
1787
1551
|
normal.stride = sources[input.id].stride;
|
|
1788
1552
|
break;
|
|
1789
|
-
|
|
1790
1553
|
case "COLOR":
|
|
1791
1554
|
buildGeometryData(primitive, sources[input.id], input.offset, color.array);
|
|
1792
1555
|
color.stride = sources[input.id].stride;
|
|
1793
1556
|
break;
|
|
1794
|
-
|
|
1795
1557
|
case "TEXCOORD":
|
|
1796
1558
|
buildGeometryData(primitive, sources[input.id], input.offset, uv.array);
|
|
1797
1559
|
uv.stride = sources[input.id].stride;
|
|
1798
1560
|
break;
|
|
1799
|
-
|
|
1800
1561
|
case "TEXCOORD1":
|
|
1801
1562
|
buildGeometryData(primitive, sources[input.id], input.offset, uv2.array);
|
|
1802
1563
|
uv2.stride = sources[input.id].stride;
|
|
1803
1564
|
break;
|
|
1804
1565
|
}
|
|
1805
1566
|
}
|
|
1806
|
-
}
|
|
1567
|
+
}
|
|
1807
1568
|
|
|
1569
|
+
// build geometry
|
|
1808
1570
|
|
|
1809
1571
|
if (position.array.length > 0) geometry.addAttribute("position", new THREE.Float32BufferAttribute(position.array, position.stride));
|
|
1810
1572
|
if (normal.array.length > 0) geometry.addAttribute("normal", new THREE.Float32BufferAttribute(normal.array, normal.stride));
|
|
@@ -1818,30 +1580,23 @@ THREE.ColladaLoader.prototype = {
|
|
|
1818
1580
|
build.materialKeys = materialKeys;
|
|
1819
1581
|
return build;
|
|
1820
1582
|
}
|
|
1821
|
-
|
|
1822
1583
|
function buildGeometryData(primitive, source, offset, array) {
|
|
1823
1584
|
var indices = primitive.p;
|
|
1824
1585
|
var stride = primitive.stride;
|
|
1825
1586
|
var vcount = primitive.vcount;
|
|
1826
|
-
|
|
1827
1587
|
function pushVector(i) {
|
|
1828
1588
|
var index = indices[i + offset] * sourceStride;
|
|
1829
1589
|
var length = index + sourceStride;
|
|
1830
|
-
|
|
1831
1590
|
for (; index < length; index++) {
|
|
1832
1591
|
array.push(sourceArray[index]);
|
|
1833
1592
|
}
|
|
1834
1593
|
}
|
|
1835
|
-
|
|
1836
1594
|
var sourceArray = source.array;
|
|
1837
1595
|
var sourceStride = source.stride;
|
|
1838
|
-
|
|
1839
1596
|
if (primitive.vcount !== undefined) {
|
|
1840
1597
|
var index = 0;
|
|
1841
|
-
|
|
1842
1598
|
for (var i = 0, l = vcount.length; i < l; i++) {
|
|
1843
1599
|
var count = vcount[i];
|
|
1844
|
-
|
|
1845
1600
|
if (count === 4) {
|
|
1846
1601
|
var a = index + stride * 0;
|
|
1847
1602
|
var b = index + stride * 1;
|
|
@@ -1870,7 +1625,6 @@ THREE.ColladaLoader.prototype = {
|
|
|
1870
1625
|
pushVector(c);
|
|
1871
1626
|
}
|
|
1872
1627
|
}
|
|
1873
|
-
|
|
1874
1628
|
index += stride * count;
|
|
1875
1629
|
}
|
|
1876
1630
|
} else {
|
|
@@ -1879,11 +1633,11 @@ THREE.ColladaLoader.prototype = {
|
|
|
1879
1633
|
}
|
|
1880
1634
|
}
|
|
1881
1635
|
}
|
|
1882
|
-
|
|
1883
1636
|
function getGeometry(id) {
|
|
1884
1637
|
return getBuild(library.geometries[id], buildGeometry);
|
|
1885
|
-
}
|
|
1638
|
+
}
|
|
1886
1639
|
|
|
1640
|
+
// kinematics
|
|
1887
1641
|
|
|
1888
1642
|
function parseKinematicsModel(xml) {
|
|
1889
1643
|
var data = {
|
|
@@ -1891,54 +1645,43 @@ THREE.ColladaLoader.prototype = {
|
|
|
1891
1645
|
joints: {},
|
|
1892
1646
|
links: []
|
|
1893
1647
|
};
|
|
1894
|
-
|
|
1895
1648
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
1896
1649
|
var child = xml.childNodes[i];
|
|
1897
1650
|
if (child.nodeType !== 1) continue;
|
|
1898
|
-
|
|
1899
1651
|
switch (child.nodeName) {
|
|
1900
1652
|
case "technique_common":
|
|
1901
1653
|
parseKinematicsTechniqueCommon(child, data);
|
|
1902
1654
|
break;
|
|
1903
1655
|
}
|
|
1904
1656
|
}
|
|
1905
|
-
|
|
1906
1657
|
library.kinematicsModels[xml.getAttribute("id")] = data;
|
|
1907
1658
|
}
|
|
1908
|
-
|
|
1909
1659
|
function buildKinematicsModel(data) {
|
|
1910
1660
|
if (data.build !== undefined) return data.build;
|
|
1911
1661
|
return data;
|
|
1912
1662
|
}
|
|
1913
|
-
|
|
1914
1663
|
function getKinematicsModel(id) {
|
|
1915
1664
|
return getBuild(library.kinematicsModels[id], buildKinematicsModel);
|
|
1916
1665
|
}
|
|
1917
|
-
|
|
1918
1666
|
function parseKinematicsTechniqueCommon(xml, data) {
|
|
1919
1667
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
1920
1668
|
var child = xml.childNodes[i];
|
|
1921
1669
|
if (child.nodeType !== 1) continue;
|
|
1922
|
-
|
|
1923
1670
|
switch (child.nodeName) {
|
|
1924
1671
|
case "joint":
|
|
1925
1672
|
data.joints[child.getAttribute("sid")] = parseKinematicsJoint(child);
|
|
1926
1673
|
break;
|
|
1927
|
-
|
|
1928
1674
|
case "link":
|
|
1929
1675
|
data.links.push(parseKinematicsLink(child));
|
|
1930
1676
|
break;
|
|
1931
1677
|
}
|
|
1932
1678
|
}
|
|
1933
1679
|
}
|
|
1934
|
-
|
|
1935
1680
|
function parseKinematicsJoint(xml) {
|
|
1936
1681
|
var data;
|
|
1937
|
-
|
|
1938
1682
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
1939
1683
|
var child = xml.childNodes[i];
|
|
1940
1684
|
if (child.nodeType !== 1) continue;
|
|
1941
|
-
|
|
1942
1685
|
switch (child.nodeName) {
|
|
1943
1686
|
case "prismatic":
|
|
1944
1687
|
case "revolute":
|
|
@@ -1946,10 +1689,8 @@ THREE.ColladaLoader.prototype = {
|
|
|
1946
1689
|
break;
|
|
1947
1690
|
}
|
|
1948
1691
|
}
|
|
1949
|
-
|
|
1950
1692
|
return data;
|
|
1951
1693
|
}
|
|
1952
|
-
|
|
1953
1694
|
function parseKinematicsJointParameter(xml, data) {
|
|
1954
1695
|
var data = {
|
|
1955
1696
|
sid: xml.getAttribute("sid"),
|
|
@@ -1964,17 +1705,14 @@ THREE.ColladaLoader.prototype = {
|
|
|
1964
1705
|
zeroPosition: 0,
|
|
1965
1706
|
middlePosition: 0
|
|
1966
1707
|
};
|
|
1967
|
-
|
|
1968
1708
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
1969
1709
|
var child = xml.childNodes[i];
|
|
1970
1710
|
if (child.nodeType !== 1) continue;
|
|
1971
|
-
|
|
1972
1711
|
switch (child.nodeName) {
|
|
1973
1712
|
case "axis":
|
|
1974
1713
|
var array = parseFloats(child.textContent);
|
|
1975
1714
|
data.axis.fromArray(array);
|
|
1976
1715
|
break;
|
|
1977
|
-
|
|
1978
1716
|
case "limits":
|
|
1979
1717
|
var max = child.getElementsByTagName("max")[0];
|
|
1980
1718
|
var min = child.getElementsByTagName("min")[0];
|
|
@@ -1982,18 +1720,19 @@ THREE.ColladaLoader.prototype = {
|
|
|
1982
1720
|
data.limits.min = parseFloat(min.textContent);
|
|
1983
1721
|
break;
|
|
1984
1722
|
}
|
|
1985
|
-
}
|
|
1723
|
+
}
|
|
1986
1724
|
|
|
1725
|
+
// if min is equal to or greater than max, consider the joint static
|
|
1987
1726
|
|
|
1988
1727
|
if (data.limits.min >= data.limits.max) {
|
|
1989
1728
|
data["static"] = true;
|
|
1990
|
-
}
|
|
1729
|
+
}
|
|
1991
1730
|
|
|
1731
|
+
// calculate middle position
|
|
1992
1732
|
|
|
1993
1733
|
data.middlePosition = (data.limits.min + data.limits.max) / 2.0;
|
|
1994
1734
|
return data;
|
|
1995
1735
|
}
|
|
1996
|
-
|
|
1997
1736
|
function parseKinematicsLink(xml) {
|
|
1998
1737
|
var data = {
|
|
1999
1738
|
sid: xml.getAttribute("sid"),
|
|
@@ -2001,16 +1740,13 @@ THREE.ColladaLoader.prototype = {
|
|
|
2001
1740
|
attachments: [],
|
|
2002
1741
|
transforms: []
|
|
2003
1742
|
};
|
|
2004
|
-
|
|
2005
1743
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
2006
1744
|
var child = xml.childNodes[i];
|
|
2007
1745
|
if (child.nodeType !== 1) continue;
|
|
2008
|
-
|
|
2009
1746
|
switch (child.nodeName) {
|
|
2010
1747
|
case "attachment_full":
|
|
2011
1748
|
data.attachments.push(parseKinematicsAttachment(child));
|
|
2012
1749
|
break;
|
|
2013
|
-
|
|
2014
1750
|
case "matrix":
|
|
2015
1751
|
case "translate":
|
|
2016
1752
|
case "rotate":
|
|
@@ -2018,26 +1754,21 @@ THREE.ColladaLoader.prototype = {
|
|
|
2018
1754
|
break;
|
|
2019
1755
|
}
|
|
2020
1756
|
}
|
|
2021
|
-
|
|
2022
1757
|
return data;
|
|
2023
1758
|
}
|
|
2024
|
-
|
|
2025
1759
|
function parseKinematicsAttachment(xml) {
|
|
2026
1760
|
var data = {
|
|
2027
1761
|
joint: xml.getAttribute("joint").split("/").pop(),
|
|
2028
1762
|
transforms: [],
|
|
2029
1763
|
links: []
|
|
2030
1764
|
};
|
|
2031
|
-
|
|
2032
1765
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
2033
1766
|
var child = xml.childNodes[i];
|
|
2034
1767
|
if (child.nodeType !== 1) continue;
|
|
2035
|
-
|
|
2036
1768
|
switch (child.nodeName) {
|
|
2037
1769
|
case "link":
|
|
2038
1770
|
data.links.push(parseKinematicsLink(child));
|
|
2039
1771
|
break;
|
|
2040
|
-
|
|
2041
1772
|
case "matrix":
|
|
2042
1773
|
case "translate":
|
|
2043
1774
|
case "rotate":
|
|
@@ -2045,48 +1776,41 @@ THREE.ColladaLoader.prototype = {
|
|
|
2045
1776
|
break;
|
|
2046
1777
|
}
|
|
2047
1778
|
}
|
|
2048
|
-
|
|
2049
1779
|
return data;
|
|
2050
1780
|
}
|
|
2051
|
-
|
|
2052
1781
|
function parseKinematicsTransform(xml) {
|
|
2053
1782
|
var data = {
|
|
2054
1783
|
type: xml.nodeName
|
|
2055
1784
|
};
|
|
2056
1785
|
var array = parseFloats(xml.textContent);
|
|
2057
|
-
|
|
2058
1786
|
switch (data.type) {
|
|
2059
1787
|
case "matrix":
|
|
2060
1788
|
data.obj = new THREE.Matrix4();
|
|
2061
1789
|
data.obj.fromArray(array).transpose();
|
|
2062
1790
|
break;
|
|
2063
|
-
|
|
2064
1791
|
case "translate":
|
|
2065
1792
|
data.obj = new THREE.Vector3();
|
|
2066
1793
|
data.obj.fromArray(array);
|
|
2067
1794
|
break;
|
|
2068
|
-
|
|
2069
1795
|
case "rotate":
|
|
2070
1796
|
data.obj = new THREE.Vector3();
|
|
2071
1797
|
data.obj.fromArray(array);
|
|
2072
1798
|
data.angle = THREE.Math.degToRad(array[3]);
|
|
2073
1799
|
break;
|
|
2074
1800
|
}
|
|
2075
|
-
|
|
2076
1801
|
return data;
|
|
2077
|
-
}
|
|
1802
|
+
}
|
|
2078
1803
|
|
|
1804
|
+
// physics
|
|
2079
1805
|
|
|
2080
1806
|
function parsePhysicsModel(xml) {
|
|
2081
1807
|
var data = {
|
|
2082
1808
|
name: xml.getAttribute("name") || "",
|
|
2083
1809
|
rigidBodies: {}
|
|
2084
1810
|
};
|
|
2085
|
-
|
|
2086
1811
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
2087
1812
|
var child = xml.childNodes[i];
|
|
2088
1813
|
if (child.nodeType !== 1) continue;
|
|
2089
|
-
|
|
2090
1814
|
switch (child.nodeName) {
|
|
2091
1815
|
case "rigid_body":
|
|
2092
1816
|
data.rigidBodies[child.getAttribute("name")] = {};
|
|
@@ -2094,15 +1818,12 @@ THREE.ColladaLoader.prototype = {
|
|
|
2094
1818
|
break;
|
|
2095
1819
|
}
|
|
2096
1820
|
}
|
|
2097
|
-
|
|
2098
1821
|
library.physicsModels[xml.getAttribute("id")] = data;
|
|
2099
1822
|
}
|
|
2100
|
-
|
|
2101
1823
|
function parsePhysicsRigidBody(xml, data) {
|
|
2102
1824
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
2103
1825
|
var child = xml.childNodes[i];
|
|
2104
1826
|
if (child.nodeType !== 1) continue;
|
|
2105
|
-
|
|
2106
1827
|
switch (child.nodeName) {
|
|
2107
1828
|
case "technique_common":
|
|
2108
1829
|
parsePhysicsTechniqueCommon(child, data);
|
|
@@ -2110,53 +1831,45 @@ THREE.ColladaLoader.prototype = {
|
|
|
2110
1831
|
}
|
|
2111
1832
|
}
|
|
2112
1833
|
}
|
|
2113
|
-
|
|
2114
1834
|
function parsePhysicsTechniqueCommon(xml, data) {
|
|
2115
1835
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
2116
1836
|
var child = xml.childNodes[i];
|
|
2117
1837
|
if (child.nodeType !== 1) continue;
|
|
2118
|
-
|
|
2119
1838
|
switch (child.nodeName) {
|
|
2120
1839
|
case "inertia":
|
|
2121
1840
|
data.inertia = parseFloats(child.textContent);
|
|
2122
1841
|
break;
|
|
2123
|
-
|
|
2124
1842
|
case "mass":
|
|
2125
1843
|
data.mass = parseFloats(child.textContent)[0];
|
|
2126
1844
|
break;
|
|
2127
1845
|
}
|
|
2128
1846
|
}
|
|
2129
|
-
}
|
|
1847
|
+
}
|
|
2130
1848
|
|
|
1849
|
+
// scene
|
|
2131
1850
|
|
|
2132
1851
|
function parseKinematicsScene(xml) {
|
|
2133
1852
|
var data = {
|
|
2134
1853
|
bindJointAxis: []
|
|
2135
1854
|
};
|
|
2136
|
-
|
|
2137
1855
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
2138
1856
|
var child = xml.childNodes[i];
|
|
2139
1857
|
if (child.nodeType !== 1) continue;
|
|
2140
|
-
|
|
2141
1858
|
switch (child.nodeName) {
|
|
2142
1859
|
case "bind_joint_axis":
|
|
2143
1860
|
data.bindJointAxis.push(parseKinematicsBindJointAxis(child));
|
|
2144
1861
|
break;
|
|
2145
1862
|
}
|
|
2146
1863
|
}
|
|
2147
|
-
|
|
2148
1864
|
library.kinematicsScenes[parseId(xml.getAttribute("url"))] = data;
|
|
2149
1865
|
}
|
|
2150
|
-
|
|
2151
1866
|
function parseKinematicsBindJointAxis(xml) {
|
|
2152
1867
|
var data = {
|
|
2153
1868
|
target: xml.getAttribute("target").split("/").pop()
|
|
2154
1869
|
};
|
|
2155
|
-
|
|
2156
1870
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
2157
1871
|
var child = xml.childNodes[i];
|
|
2158
1872
|
if (child.nodeType !== 1) continue;
|
|
2159
|
-
|
|
2160
1873
|
switch (child.nodeName) {
|
|
2161
1874
|
case "axis":
|
|
2162
1875
|
var param = child.getElementsByTagName("param")[0];
|
|
@@ -2166,19 +1879,15 @@ THREE.ColladaLoader.prototype = {
|
|
|
2166
1879
|
break;
|
|
2167
1880
|
}
|
|
2168
1881
|
}
|
|
2169
|
-
|
|
2170
1882
|
return data;
|
|
2171
1883
|
}
|
|
2172
|
-
|
|
2173
1884
|
function buildKinematicsScene(data) {
|
|
2174
1885
|
if (data.build !== undefined) return data.build;
|
|
2175
1886
|
return data;
|
|
2176
1887
|
}
|
|
2177
|
-
|
|
2178
1888
|
function getKinematicsScene(id) {
|
|
2179
1889
|
return getBuild(library.kinematicsScenes[id], buildKinematicsScene);
|
|
2180
1890
|
}
|
|
2181
|
-
|
|
2182
1891
|
function setupKinematics() {
|
|
2183
1892
|
var kinematicsModelId = Object.keys(library.kinematicsModels)[0];
|
|
2184
1893
|
var kinematicsSceneId = Object.keys(library.kinematicsScenes)[0];
|
|
@@ -2189,20 +1898,22 @@ THREE.ColladaLoader.prototype = {
|
|
|
2189
1898
|
var visualScene = getVisualScene(visualSceneId);
|
|
2190
1899
|
var bindJointAxis = kinematicsScene.bindJointAxis;
|
|
2191
1900
|
var jointMap = {};
|
|
2192
|
-
|
|
2193
1901
|
for (var i = 0, l = bindJointAxis.length; i < l; i++) {
|
|
2194
|
-
var axis = bindJointAxis[i];
|
|
1902
|
+
var axis = bindJointAxis[i];
|
|
2195
1903
|
|
|
2196
|
-
|
|
1904
|
+
// the result of the following query is an element of type 'translate', 'rotate','scale' or 'matrix'
|
|
2197
1905
|
|
|
1906
|
+
var targetElement = collada.querySelector('[sid="' + axis.target + '"]');
|
|
2198
1907
|
if (targetElement) {
|
|
2199
1908
|
// get the parent of the transfrom element
|
|
2200
|
-
|
|
1909
|
+
|
|
1910
|
+
var parentVisualElement = targetElement.parentElement;
|
|
1911
|
+
|
|
1912
|
+
// connect the joint of the kinematics model with the element in the visual scene
|
|
2201
1913
|
|
|
2202
1914
|
connect(axis.jointIndex, parentVisualElement);
|
|
2203
1915
|
}
|
|
2204
1916
|
}
|
|
2205
|
-
|
|
2206
1917
|
function connect(jointIndex, visualElement) {
|
|
2207
1918
|
var visualElementName = visualElement.getAttribute("name");
|
|
2208
1919
|
var joint = kinematicsModel.joints[jointIndex];
|
|
@@ -2217,13 +1928,11 @@ THREE.ColladaLoader.prototype = {
|
|
|
2217
1928
|
}
|
|
2218
1929
|
});
|
|
2219
1930
|
}
|
|
2220
|
-
|
|
2221
1931
|
var m0 = new THREE.Matrix4();
|
|
2222
1932
|
kinematics = {
|
|
2223
1933
|
joints: kinematicsModel && kinematicsModel.joints,
|
|
2224
1934
|
getJointValue: function getJointValue(jointIndex) {
|
|
2225
1935
|
var jointData = jointMap[jointIndex];
|
|
2226
|
-
|
|
2227
1936
|
if (jointData) {
|
|
2228
1937
|
return jointData.position;
|
|
2229
1938
|
} else {
|
|
@@ -2232,10 +1941,8 @@ THREE.ColladaLoader.prototype = {
|
|
|
2232
1941
|
},
|
|
2233
1942
|
setJointValue: function setJointValue(jointIndex, value) {
|
|
2234
1943
|
var jointData = jointMap[jointIndex];
|
|
2235
|
-
|
|
2236
1944
|
if (jointData) {
|
|
2237
1945
|
var joint = jointData.joint;
|
|
2238
|
-
|
|
2239
1946
|
if (value > joint.limits.max || value < joint.limits.min) {
|
|
2240
1947
|
console.warn("THREE.ColladaLoader: Joint " + jointIndex + " value " + value + " outside of limits (min: " + joint.limits.min + ", max: " + joint.limits.max + ").");
|
|
2241
1948
|
} else if (joint["static"]) {
|
|
@@ -2244,21 +1951,23 @@ THREE.ColladaLoader.prototype = {
|
|
|
2244
1951
|
var object = jointData.object;
|
|
2245
1952
|
var axis = joint.axis;
|
|
2246
1953
|
var transforms = jointData.transforms;
|
|
2247
|
-
matrix.identity();
|
|
1954
|
+
matrix.identity();
|
|
1955
|
+
|
|
1956
|
+
// each update, we have to apply all transforms in the correct order
|
|
2248
1957
|
|
|
2249
1958
|
for (var i = 0; i < transforms.length; i++) {
|
|
2250
|
-
var transform = transforms[i];
|
|
1959
|
+
var transform = transforms[i];
|
|
1960
|
+
|
|
1961
|
+
// if there is a connection of the transform node with a joint, apply the joint value
|
|
2251
1962
|
|
|
2252
1963
|
if (transform.sid && transform.sid.indexOf(jointIndex) !== -1) {
|
|
2253
1964
|
switch (joint.type) {
|
|
2254
1965
|
case "revolute":
|
|
2255
1966
|
matrix.multiply(m0.makeRotationAxis(axis, THREE.Math.degToRad(value)));
|
|
2256
1967
|
break;
|
|
2257
|
-
|
|
2258
1968
|
case "prismatic":
|
|
2259
1969
|
matrix.multiply(m0.makeTranslation(axis.x * value, axis.y * value, axis.z * value));
|
|
2260
1970
|
break;
|
|
2261
|
-
|
|
2262
1971
|
default:
|
|
2263
1972
|
console.warn("THREE.ColladaLoader: Unknown joint type: " + joint.type);
|
|
2264
1973
|
break;
|
|
@@ -2268,22 +1977,18 @@ THREE.ColladaLoader.prototype = {
|
|
|
2268
1977
|
case "matrix":
|
|
2269
1978
|
matrix.multiply(transform.obj);
|
|
2270
1979
|
break;
|
|
2271
|
-
|
|
2272
1980
|
case "translate":
|
|
2273
1981
|
matrix.multiply(m0.makeTranslation(transform.obj.x, transform.obj.y, transform.obj.z));
|
|
2274
1982
|
break;
|
|
2275
|
-
|
|
2276
1983
|
case "scale":
|
|
2277
1984
|
matrix.scale(transform.obj);
|
|
2278
1985
|
break;
|
|
2279
|
-
|
|
2280
1986
|
case "rotate":
|
|
2281
1987
|
matrix.multiply(m0.makeRotationAxis(transform.obj, transform.angle));
|
|
2282
1988
|
break;
|
|
2283
1989
|
}
|
|
2284
1990
|
}
|
|
2285
1991
|
}
|
|
2286
|
-
|
|
2287
1992
|
object.matrix.copy(matrix);
|
|
2288
1993
|
object.matrix.decompose(object.position, object.quaternion, object.scale);
|
|
2289
1994
|
jointMap[jointIndex].position = value;
|
|
@@ -2294,15 +1999,12 @@ THREE.ColladaLoader.prototype = {
|
|
|
2294
1999
|
}
|
|
2295
2000
|
};
|
|
2296
2001
|
}
|
|
2297
|
-
|
|
2298
2002
|
function buildTransformList(node) {
|
|
2299
2003
|
var transforms = [];
|
|
2300
2004
|
var xml = collada.querySelector('[id="' + node.id + '"]');
|
|
2301
|
-
|
|
2302
2005
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
2303
2006
|
var child = xml.childNodes[i];
|
|
2304
2007
|
if (child.nodeType !== 1) continue;
|
|
2305
|
-
|
|
2306
2008
|
switch (child.nodeName) {
|
|
2307
2009
|
case "matrix":
|
|
2308
2010
|
var array = parseFloats(child.textContent);
|
|
@@ -2313,7 +2015,6 @@ THREE.ColladaLoader.prototype = {
|
|
|
2313
2015
|
obj: matrix
|
|
2314
2016
|
});
|
|
2315
2017
|
break;
|
|
2316
|
-
|
|
2317
2018
|
case "translate":
|
|
2318
2019
|
case "scale":
|
|
2319
2020
|
var array = parseFloats(child.textContent);
|
|
@@ -2324,7 +2025,6 @@ THREE.ColladaLoader.prototype = {
|
|
|
2324
2025
|
obj: vector
|
|
2325
2026
|
});
|
|
2326
2027
|
break;
|
|
2327
|
-
|
|
2328
2028
|
case "rotate":
|
|
2329
2029
|
var array = parseFloats(child.textContent);
|
|
2330
2030
|
var vector = new THREE.Vector3().fromArray(array);
|
|
@@ -2338,26 +2038,25 @@ THREE.ColladaLoader.prototype = {
|
|
|
2338
2038
|
break;
|
|
2339
2039
|
}
|
|
2340
2040
|
}
|
|
2341
|
-
|
|
2342
2041
|
return transforms;
|
|
2343
|
-
}
|
|
2042
|
+
}
|
|
2344
2043
|
|
|
2044
|
+
// nodes
|
|
2345
2045
|
|
|
2346
2046
|
function prepareNodes(xml) {
|
|
2347
|
-
var elements = xml.getElementsByTagName("node");
|
|
2047
|
+
var elements = xml.getElementsByTagName("node");
|
|
2048
|
+
|
|
2049
|
+
// ensure all node elements have id attributes
|
|
2348
2050
|
|
|
2349
2051
|
for (var i = 0; i < elements.length; i++) {
|
|
2350
2052
|
var element = elements[i];
|
|
2351
|
-
|
|
2352
2053
|
if (element.hasAttribute("id") === false) {
|
|
2353
2054
|
element.setAttribute("id", generateId());
|
|
2354
2055
|
}
|
|
2355
2056
|
}
|
|
2356
2057
|
}
|
|
2357
|
-
|
|
2358
2058
|
var matrix = new THREE.Matrix4();
|
|
2359
2059
|
var vector = new THREE.Vector3();
|
|
2360
|
-
|
|
2361
2060
|
function parseNode(xml) {
|
|
2362
2061
|
var data = {
|
|
2363
2062
|
name: xml.getAttribute("name") || "",
|
|
@@ -2373,136 +2072,112 @@ THREE.ColladaLoader.prototype = {
|
|
|
2373
2072
|
instanceNodes: [],
|
|
2374
2073
|
transforms: {}
|
|
2375
2074
|
};
|
|
2376
|
-
|
|
2377
2075
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
2378
2076
|
var child = xml.childNodes[i];
|
|
2379
2077
|
if (child.nodeType !== 1) continue;
|
|
2380
|
-
|
|
2381
2078
|
switch (child.nodeName) {
|
|
2382
2079
|
case "node":
|
|
2383
2080
|
data.nodes.push(child.getAttribute("id"));
|
|
2384
2081
|
parseNode(child);
|
|
2385
2082
|
break;
|
|
2386
|
-
|
|
2387
2083
|
case "instance_camera":
|
|
2388
2084
|
data.instanceCameras.push(parseId(child.getAttribute("url")));
|
|
2389
2085
|
break;
|
|
2390
|
-
|
|
2391
2086
|
case "instance_controller":
|
|
2392
2087
|
data.instanceControllers.push(parseNodeInstance(child));
|
|
2393
2088
|
break;
|
|
2394
|
-
|
|
2395
2089
|
case "instance_light":
|
|
2396
2090
|
data.instanceLights.push(parseId(child.getAttribute("url")));
|
|
2397
2091
|
break;
|
|
2398
|
-
|
|
2399
2092
|
case "instance_geometry":
|
|
2400
2093
|
data.instanceGeometries.push(parseNodeInstance(child));
|
|
2401
2094
|
break;
|
|
2402
|
-
|
|
2403
2095
|
case "instance_node":
|
|
2404
2096
|
data.instanceNodes.push(parseId(child.getAttribute("url")));
|
|
2405
2097
|
break;
|
|
2406
|
-
|
|
2407
2098
|
case "matrix":
|
|
2408
2099
|
var array = parseFloats(child.textContent);
|
|
2409
2100
|
data.matrix.multiply(matrix.fromArray(array).transpose());
|
|
2410
2101
|
data.transforms[child.getAttribute("sid")] = child.nodeName;
|
|
2411
2102
|
break;
|
|
2412
|
-
|
|
2413
2103
|
case "translate":
|
|
2414
2104
|
var array = parseFloats(child.textContent);
|
|
2415
2105
|
vector.fromArray(array);
|
|
2416
2106
|
data.matrix.multiply(matrix.makeTranslation(vector.x, vector.y, vector.z));
|
|
2417
2107
|
data.transforms[child.getAttribute("sid")] = child.nodeName;
|
|
2418
2108
|
break;
|
|
2419
|
-
|
|
2420
2109
|
case "rotate":
|
|
2421
2110
|
var array = parseFloats(child.textContent);
|
|
2422
2111
|
var angle = THREE.Math.degToRad(array[3]);
|
|
2423
2112
|
data.matrix.multiply(matrix.makeRotationAxis(vector.fromArray(array), angle));
|
|
2424
2113
|
data.transforms[child.getAttribute("sid")] = child.nodeName;
|
|
2425
2114
|
break;
|
|
2426
|
-
|
|
2427
2115
|
case "scale":
|
|
2428
2116
|
var array = parseFloats(child.textContent);
|
|
2429
2117
|
data.matrix.scale(vector.fromArray(array));
|
|
2430
2118
|
data.transforms[child.getAttribute("sid")] = child.nodeName;
|
|
2431
2119
|
break;
|
|
2432
|
-
|
|
2433
2120
|
case "extra":
|
|
2434
2121
|
break;
|
|
2435
|
-
|
|
2436
2122
|
default:
|
|
2437
2123
|
console.log(child);
|
|
2438
2124
|
}
|
|
2439
2125
|
}
|
|
2440
|
-
|
|
2441
2126
|
if (hasNode(data.id)) {
|
|
2442
2127
|
console.warn("THREE.ColladaLoader: There is already a node with ID %s. Exclude current node from further processing.", data.id);
|
|
2443
2128
|
} else {
|
|
2444
2129
|
library.nodes[data.id] = data;
|
|
2445
2130
|
}
|
|
2446
|
-
|
|
2447
2131
|
return data;
|
|
2448
2132
|
}
|
|
2449
|
-
|
|
2450
2133
|
function parseNodeInstance(xml) {
|
|
2451
2134
|
var data = {
|
|
2452
2135
|
id: parseId(xml.getAttribute("url")),
|
|
2453
2136
|
materials: {},
|
|
2454
2137
|
skeletons: []
|
|
2455
2138
|
};
|
|
2456
|
-
|
|
2457
2139
|
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
2458
2140
|
var child = xml.childNodes[i];
|
|
2459
|
-
|
|
2460
2141
|
switch (child.nodeName) {
|
|
2461
2142
|
case "bind_material":
|
|
2462
2143
|
var instances = child.getElementsByTagName("instance_material");
|
|
2463
|
-
|
|
2464
2144
|
for (var j = 0; j < instances.length; j++) {
|
|
2465
2145
|
var instance = instances[j];
|
|
2466
2146
|
var symbol = instance.getAttribute("symbol");
|
|
2467
2147
|
var target = instance.getAttribute("target");
|
|
2468
2148
|
data.materials[symbol] = parseId(target);
|
|
2469
2149
|
}
|
|
2470
|
-
|
|
2471
2150
|
break;
|
|
2472
|
-
|
|
2473
2151
|
case "skeleton":
|
|
2474
2152
|
data.skeletons.push(parseId(child.textContent));
|
|
2475
2153
|
break;
|
|
2476
|
-
|
|
2477
2154
|
default:
|
|
2478
2155
|
break;
|
|
2479
2156
|
}
|
|
2480
2157
|
}
|
|
2481
|
-
|
|
2482
2158
|
return data;
|
|
2483
2159
|
}
|
|
2484
|
-
|
|
2485
2160
|
function buildSkeleton(skeletons, joints) {
|
|
2486
2161
|
var boneData = [];
|
|
2487
2162
|
var sortedBoneData = [];
|
|
2488
|
-
var i, j, data;
|
|
2163
|
+
var i, j, data;
|
|
2164
|
+
|
|
2165
|
+
// a skeleton can have multiple root bones. collada expresses this
|
|
2489
2166
|
// situtation with multiple "skeleton" tags per controller instance
|
|
2490
2167
|
|
|
2491
2168
|
for (i = 0; i < skeletons.length; i++) {
|
|
2492
2169
|
var skeleton = skeletons[i];
|
|
2493
2170
|
var root;
|
|
2494
|
-
|
|
2495
2171
|
if (hasNode(skeleton)) {
|
|
2496
2172
|
root = getNode(skeleton);
|
|
2497
2173
|
buildBoneHierarchy(root, joints, boneData);
|
|
2498
2174
|
} else if (hasVisualScene(skeleton)) {
|
|
2499
2175
|
// handle case where the skeleton refers to the visual scene (#13335)
|
|
2176
|
+
|
|
2500
2177
|
var visualScene = library.visualScenes[skeleton];
|
|
2501
2178
|
var children = visualScene.children;
|
|
2502
|
-
|
|
2503
2179
|
for (var j = 0; j < children.length; j++) {
|
|
2504
2180
|
var child = children[j];
|
|
2505
|
-
|
|
2506
2181
|
if (child.type === "JOINT") {
|
|
2507
2182
|
var root = getNode(child.id);
|
|
2508
2183
|
buildBoneHierarchy(root, joints, boneData);
|
|
@@ -2511,68 +2186,67 @@ THREE.ColladaLoader.prototype = {
|
|
|
2511
2186
|
} else {
|
|
2512
2187
|
console.error("THREE.ColladaLoader: Unable to find root bone of skeleton with ID:", skeleton);
|
|
2513
2188
|
}
|
|
2514
|
-
}
|
|
2189
|
+
}
|
|
2515
2190
|
|
|
2191
|
+
// sort bone data (the order is defined in the corresponding controller)
|
|
2516
2192
|
|
|
2517
2193
|
for (i = 0; i < joints.length; i++) {
|
|
2518
2194
|
for (j = 0; j < boneData.length; j++) {
|
|
2519
2195
|
data = boneData[j];
|
|
2520
|
-
|
|
2521
2196
|
if (data.bone.name === joints[i].name) {
|
|
2522
2197
|
sortedBoneData[i] = data;
|
|
2523
2198
|
data.processed = true;
|
|
2524
2199
|
break;
|
|
2525
2200
|
}
|
|
2526
2201
|
}
|
|
2527
|
-
}
|
|
2202
|
+
}
|
|
2528
2203
|
|
|
2204
|
+
// add unprocessed bone data at the end of the list
|
|
2529
2205
|
|
|
2530
2206
|
for (i = 0; i < boneData.length; i++) {
|
|
2531
2207
|
data = boneData[i];
|
|
2532
|
-
|
|
2533
2208
|
if (data.processed === false) {
|
|
2534
2209
|
sortedBoneData.push(data);
|
|
2535
2210
|
data.processed = true;
|
|
2536
2211
|
}
|
|
2537
|
-
}
|
|
2212
|
+
}
|
|
2538
2213
|
|
|
2214
|
+
// setup arrays for skeleton creation
|
|
2539
2215
|
|
|
2540
2216
|
var bones = [];
|
|
2541
2217
|
var boneInverses = [];
|
|
2542
|
-
|
|
2543
2218
|
for (i = 0; i < sortedBoneData.length; i++) {
|
|
2544
2219
|
data = sortedBoneData[i];
|
|
2545
2220
|
bones.push(data.bone);
|
|
2546
2221
|
boneInverses.push(data.boneInverse);
|
|
2547
2222
|
}
|
|
2548
|
-
|
|
2549
2223
|
return new THREE.Skeleton(bones, boneInverses);
|
|
2550
2224
|
}
|
|
2551
|
-
|
|
2552
2225
|
function buildBoneHierarchy(root, joints, boneData) {
|
|
2553
2226
|
// setup bone data from visual scene
|
|
2227
|
+
|
|
2554
2228
|
root.traverse(function (object) {
|
|
2555
2229
|
if (object.isBone === true) {
|
|
2556
|
-
var boneInverse;
|
|
2230
|
+
var boneInverse;
|
|
2231
|
+
|
|
2232
|
+
// retrieve the boneInverse from the controller data
|
|
2557
2233
|
|
|
2558
2234
|
for (var i = 0; i < joints.length; i++) {
|
|
2559
2235
|
var joint = joints[i];
|
|
2560
|
-
|
|
2561
2236
|
if (joint.name === object.name) {
|
|
2562
2237
|
boneInverse = joint.boneInverse;
|
|
2563
2238
|
break;
|
|
2564
2239
|
}
|
|
2565
2240
|
}
|
|
2566
|
-
|
|
2567
2241
|
if (boneInverse === undefined) {
|
|
2568
2242
|
// Unfortunately, there can be joints in the visual scene that are not part of the
|
|
2569
2243
|
// corresponding controller. In this case, we have to create a dummy boneInverse matrix
|
|
2570
2244
|
// for the respective bone. This bone won't affect any vertices, because there are no skin indices
|
|
2571
2245
|
// and weights defined for it. But we still have to add the bone to the sorted bone list in order to
|
|
2572
2246
|
// ensure a correct animation of the model.
|
|
2247
|
+
|
|
2573
2248
|
boneInverse = new THREE.Matrix4();
|
|
2574
2249
|
}
|
|
2575
|
-
|
|
2576
2250
|
boneData.push({
|
|
2577
2251
|
bone: object,
|
|
2578
2252
|
boneInverse: boneInverse,
|
|
@@ -2581,7 +2255,6 @@ THREE.ColladaLoader.prototype = {
|
|
|
2581
2255
|
}
|
|
2582
2256
|
});
|
|
2583
2257
|
}
|
|
2584
|
-
|
|
2585
2258
|
function buildNode(data) {
|
|
2586
2259
|
var objects = [];
|
|
2587
2260
|
var matrix = data.matrix;
|
|
@@ -2591,21 +2264,24 @@ THREE.ColladaLoader.prototype = {
|
|
|
2591
2264
|
var instanceControllers = data.instanceControllers;
|
|
2592
2265
|
var instanceLights = data.instanceLights;
|
|
2593
2266
|
var instanceGeometries = data.instanceGeometries;
|
|
2594
|
-
var instanceNodes = data.instanceNodes;
|
|
2267
|
+
var instanceNodes = data.instanceNodes;
|
|
2268
|
+
|
|
2269
|
+
// nodes
|
|
2595
2270
|
|
|
2596
2271
|
for (var i = 0, l = nodes.length; i < l; i++) {
|
|
2597
2272
|
objects.push(getNode(nodes[i]));
|
|
2598
|
-
}
|
|
2273
|
+
}
|
|
2599
2274
|
|
|
2275
|
+
// instance cameras
|
|
2600
2276
|
|
|
2601
2277
|
for (var i = 0, l = instanceCameras.length; i < l; i++) {
|
|
2602
2278
|
var instanceCamera = getCamera(instanceCameras[i]);
|
|
2603
|
-
|
|
2604
2279
|
if (instanceCamera !== null) {
|
|
2605
2280
|
objects.push(instanceCamera.clone());
|
|
2606
2281
|
}
|
|
2607
|
-
}
|
|
2282
|
+
}
|
|
2608
2283
|
|
|
2284
|
+
// instance controllers
|
|
2609
2285
|
|
|
2610
2286
|
for (var i = 0, l = instanceControllers.length; i < l; i++) {
|
|
2611
2287
|
var instance = instanceControllers[i];
|
|
@@ -2615,77 +2291,68 @@ THREE.ColladaLoader.prototype = {
|
|
|
2615
2291
|
var skeletons = instance.skeletons;
|
|
2616
2292
|
var joints = controller.skin.joints;
|
|
2617
2293
|
var skeleton = buildSkeleton(skeletons, joints);
|
|
2618
|
-
|
|
2619
2294
|
for (var j = 0, jl = newObjects.length; j < jl; j++) {
|
|
2620
2295
|
var object = newObjects[j];
|
|
2621
|
-
|
|
2622
2296
|
if (object.isSkinnedMesh) {
|
|
2623
2297
|
object.bind(skeleton, controller.skin.bindMatrix);
|
|
2624
2298
|
object.normalizeSkinWeights();
|
|
2625
2299
|
}
|
|
2626
|
-
|
|
2627
2300
|
objects.push(object);
|
|
2628
2301
|
}
|
|
2629
|
-
}
|
|
2302
|
+
}
|
|
2630
2303
|
|
|
2304
|
+
// instance lights
|
|
2631
2305
|
|
|
2632
2306
|
for (var i = 0, l = instanceLights.length; i < l; i++) {
|
|
2633
2307
|
var instanceLight = getLight(instanceLights[i]);
|
|
2634
|
-
|
|
2635
2308
|
if (instanceLight !== null) {
|
|
2636
2309
|
objects.push(instanceLight.clone());
|
|
2637
2310
|
}
|
|
2638
|
-
}
|
|
2311
|
+
}
|
|
2639
2312
|
|
|
2313
|
+
// instance geometries
|
|
2640
2314
|
|
|
2641
2315
|
for (var i = 0, l = instanceGeometries.length; i < l; i++) {
|
|
2642
|
-
var instance = instanceGeometries[i];
|
|
2316
|
+
var instance = instanceGeometries[i];
|
|
2317
|
+
|
|
2318
|
+
// a single geometry instance in collada can lead to multiple object3Ds.
|
|
2643
2319
|
// this is the case when primitives are combined like triangles and lines
|
|
2644
2320
|
|
|
2645
2321
|
var geometries = getGeometry(instance.id);
|
|
2646
2322
|
var newObjects = buildObjects(geometries, instance.materials);
|
|
2647
|
-
|
|
2648
2323
|
for (var j = 0, jl = newObjects.length; j < jl; j++) {
|
|
2649
2324
|
objects.push(newObjects[j]);
|
|
2650
2325
|
}
|
|
2651
|
-
}
|
|
2326
|
+
}
|
|
2652
2327
|
|
|
2328
|
+
// instance nodes
|
|
2653
2329
|
|
|
2654
2330
|
for (var i = 0, l = instanceNodes.length; i < l; i++) {
|
|
2655
2331
|
objects.push(getNode(instanceNodes[i]).clone());
|
|
2656
2332
|
}
|
|
2657
|
-
|
|
2658
2333
|
var object;
|
|
2659
|
-
|
|
2660
2334
|
if (nodes.length === 0 && objects.length === 1) {
|
|
2661
2335
|
object = objects[0];
|
|
2662
2336
|
} else {
|
|
2663
2337
|
object = type === "JOINT" ? new THREE.Bone() : new THREE.Group();
|
|
2664
|
-
|
|
2665
2338
|
for (var i = 0; i < objects.length; i++) {
|
|
2666
2339
|
object.add(objects[i]);
|
|
2667
2340
|
}
|
|
2668
2341
|
}
|
|
2669
|
-
|
|
2670
2342
|
if (object.name === "") {
|
|
2671
2343
|
object.name = type === "JOINT" ? data.sid : data.name;
|
|
2672
2344
|
}
|
|
2673
|
-
|
|
2674
2345
|
object.matrix.copy(matrix);
|
|
2675
2346
|
object.matrix.decompose(object.position, object.quaternion, object.scale);
|
|
2676
2347
|
return object;
|
|
2677
2348
|
}
|
|
2678
|
-
|
|
2679
2349
|
var fallbackMaterial = new THREE.MeshBasicMaterial({
|
|
2680
2350
|
color: 0xff00ff
|
|
2681
2351
|
});
|
|
2682
|
-
|
|
2683
2352
|
function resolveMaterialBinding(keys, instanceMaterials) {
|
|
2684
2353
|
var materials = [];
|
|
2685
|
-
|
|
2686
2354
|
for (var i = 0, l = keys.length; i < l; i++) {
|
|
2687
2355
|
var id = instanceMaterials[keys[i]];
|
|
2688
|
-
|
|
2689
2356
|
if (id === undefined) {
|
|
2690
2357
|
console.warn("THREE.ColladaLoader: Material with key %s not found. Apply fallback material.", keys[i]);
|
|
2691
2358
|
materials.push(fallbackMaterial);
|
|
@@ -2693,16 +2360,15 @@ THREE.ColladaLoader.prototype = {
|
|
|
2693
2360
|
materials.push(getMaterial(id));
|
|
2694
2361
|
}
|
|
2695
2362
|
}
|
|
2696
|
-
|
|
2697
2363
|
return materials;
|
|
2698
2364
|
}
|
|
2699
|
-
|
|
2700
2365
|
function buildObjects(geometries, instanceMaterials) {
|
|
2701
2366
|
var objects = [];
|
|
2702
|
-
|
|
2703
2367
|
for (var type in geometries) {
|
|
2704
2368
|
var geometry = geometries[type];
|
|
2705
|
-
var materials = resolveMaterialBinding(geometry.materialKeys, instanceMaterials);
|
|
2369
|
+
var materials = resolveMaterialBinding(geometry.materialKeys, instanceMaterials);
|
|
2370
|
+
|
|
2371
|
+
// handle case if no materials are defined
|
|
2706
2372
|
|
|
2707
2373
|
if (materials.length === 0) {
|
|
2708
2374
|
if (type === "lines" || type === "linestrips") {
|
|
@@ -2710,31 +2376,31 @@ THREE.ColladaLoader.prototype = {
|
|
|
2710
2376
|
} else {
|
|
2711
2377
|
materials.push(new THREE.MeshPhongMaterial());
|
|
2712
2378
|
}
|
|
2713
|
-
}
|
|
2379
|
+
}
|
|
2714
2380
|
|
|
2381
|
+
// regard skinning
|
|
2715
2382
|
|
|
2716
2383
|
var skinning = geometry.data.attributes.skinIndex !== undefined;
|
|
2717
|
-
|
|
2718
2384
|
if (skinning) {
|
|
2719
2385
|
for (var i = 0, l = materials.length; i < l; i++) {
|
|
2720
2386
|
materials[i].skinning = true;
|
|
2721
2387
|
}
|
|
2722
|
-
}
|
|
2388
|
+
}
|
|
2723
2389
|
|
|
2390
|
+
// choose between a single or multi materials (material array)
|
|
2724
2391
|
|
|
2725
|
-
var material = materials.length === 1 ? materials[0] : materials;
|
|
2392
|
+
var material = materials.length === 1 ? materials[0] : materials;
|
|
2726
2393
|
|
|
2727
|
-
|
|
2394
|
+
// now create a specific 3D object
|
|
2728
2395
|
|
|
2396
|
+
var object;
|
|
2729
2397
|
switch (type) {
|
|
2730
2398
|
case "lines":
|
|
2731
2399
|
object = new THREE.LineSegments(geometry.data, material);
|
|
2732
2400
|
break;
|
|
2733
|
-
|
|
2734
2401
|
case "linestrips":
|
|
2735
2402
|
object = new THREE.Line(geometry.data, material);
|
|
2736
2403
|
break;
|
|
2737
|
-
|
|
2738
2404
|
case "triangles":
|
|
2739
2405
|
case "polylist":
|
|
2740
2406
|
if (skinning) {
|
|
@@ -2742,24 +2408,20 @@ THREE.ColladaLoader.prototype = {
|
|
|
2742
2408
|
} else {
|
|
2743
2409
|
object = new THREE.Mesh(geometry.data, material);
|
|
2744
2410
|
}
|
|
2745
|
-
|
|
2746
2411
|
break;
|
|
2747
2412
|
}
|
|
2748
|
-
|
|
2749
2413
|
objects.push(object);
|
|
2750
2414
|
}
|
|
2751
|
-
|
|
2752
2415
|
return objects;
|
|
2753
2416
|
}
|
|
2754
|
-
|
|
2755
2417
|
function hasNode(id) {
|
|
2756
2418
|
return library.nodes[id] !== undefined;
|
|
2757
2419
|
}
|
|
2758
|
-
|
|
2759
2420
|
function getNode(id) {
|
|
2760
2421
|
return getBuild(library.nodes[id], buildNode);
|
|
2761
|
-
}
|
|
2422
|
+
}
|
|
2762
2423
|
|
|
2424
|
+
// visual scenes
|
|
2763
2425
|
|
|
2764
2426
|
function parseVisualScene(xml) {
|
|
2765
2427
|
var data = {
|
|
@@ -2768,57 +2430,47 @@ THREE.ColladaLoader.prototype = {
|
|
|
2768
2430
|
};
|
|
2769
2431
|
prepareNodes(xml);
|
|
2770
2432
|
var elements = getElementsByTagName(xml, "node");
|
|
2771
|
-
|
|
2772
2433
|
for (var i = 0; i < elements.length; i++) {
|
|
2773
2434
|
data.children.push(parseNode(elements[i]));
|
|
2774
2435
|
}
|
|
2775
|
-
|
|
2776
2436
|
library.visualScenes[xml.getAttribute("id")] = data;
|
|
2777
2437
|
}
|
|
2778
|
-
|
|
2779
2438
|
function buildVisualScene(data) {
|
|
2780
2439
|
var group = new THREE.Group();
|
|
2781
2440
|
group.name = data.name;
|
|
2782
2441
|
var children = data.children;
|
|
2783
|
-
|
|
2784
2442
|
for (var i = 0; i < children.length; i++) {
|
|
2785
2443
|
var child = children[i];
|
|
2786
2444
|
group.add(getNode(child.id));
|
|
2787
2445
|
}
|
|
2788
|
-
|
|
2789
2446
|
return group;
|
|
2790
2447
|
}
|
|
2791
|
-
|
|
2792
2448
|
function hasVisualScene(id) {
|
|
2793
2449
|
return library.visualScenes[id] !== undefined;
|
|
2794
2450
|
}
|
|
2795
|
-
|
|
2796
2451
|
function getVisualScene(id) {
|
|
2797
2452
|
return getBuild(library.visualScenes[id], buildVisualScene);
|
|
2798
|
-
}
|
|
2453
|
+
}
|
|
2799
2454
|
|
|
2455
|
+
// scenes
|
|
2800
2456
|
|
|
2801
2457
|
function parseScene(xml) {
|
|
2802
2458
|
var instance = getElementsByTagName(xml, "instance_visual_scene")[0];
|
|
2803
2459
|
return getVisualScene(parseId(instance.getAttribute("url")));
|
|
2804
2460
|
}
|
|
2805
|
-
|
|
2806
2461
|
function setupAnimations() {
|
|
2807
2462
|
var clips = library.clips;
|
|
2808
|
-
|
|
2809
2463
|
if (isEmpty(clips) === true) {
|
|
2810
2464
|
if (isEmpty(library.animations) === false) {
|
|
2811
2465
|
// if there are animations but no clips, we create a default clip for playback
|
|
2812
|
-
var tracks = [];
|
|
2813
2466
|
|
|
2467
|
+
var tracks = [];
|
|
2814
2468
|
for (var id in library.animations) {
|
|
2815
2469
|
var animationTracks = getAnimation(id);
|
|
2816
|
-
|
|
2817
2470
|
for (var i = 0, l = animationTracks.length; i < l; i++) {
|
|
2818
2471
|
tracks.push(animationTracks[i]);
|
|
2819
2472
|
}
|
|
2820
2473
|
}
|
|
2821
|
-
|
|
2822
2474
|
animations.push(new THREE.AnimationClip("default", -1, tracks));
|
|
2823
2475
|
}
|
|
2824
2476
|
} else {
|
|
@@ -2827,15 +2479,15 @@ THREE.ColladaLoader.prototype = {
|
|
|
2827
2479
|
}
|
|
2828
2480
|
}
|
|
2829
2481
|
}
|
|
2830
|
-
|
|
2831
2482
|
if (text.length === 0) {
|
|
2832
2483
|
return {
|
|
2833
2484
|
scene: new THREE.Scene()
|
|
2834
2485
|
};
|
|
2835
2486
|
}
|
|
2836
|
-
|
|
2837
2487
|
var xml = new DOMParser().parseFromString(text, "application/xml");
|
|
2838
|
-
var collada = getElementsByTagName(xml, "COLLADA")[0];
|
|
2488
|
+
var collada = getElementsByTagName(xml, "COLLADA")[0];
|
|
2489
|
+
|
|
2490
|
+
// metadata
|
|
2839
2491
|
|
|
2840
2492
|
var version = collada.getAttribute("version");
|
|
2841
2493
|
console.log("THREE.ColladaLoader: File version", version);
|
|
@@ -2843,16 +2495,18 @@ THREE.ColladaLoader.prototype = {
|
|
|
2843
2495
|
var textureLoader = new THREE.TextureLoader(this.manager);
|
|
2844
2496
|
textureLoader.setPath(this.resourcePath || path).setCrossOrigin(this.crossOrigin);
|
|
2845
2497
|
var tgaLoader;
|
|
2846
|
-
|
|
2847
2498
|
if (THREE.TGALoader) {
|
|
2848
2499
|
tgaLoader = new THREE.TGALoader(this.manager);
|
|
2849
2500
|
tgaLoader.setPath(this.resourcePath || path);
|
|
2850
|
-
}
|
|
2501
|
+
}
|
|
2851
2502
|
|
|
2503
|
+
//
|
|
2852
2504
|
|
|
2853
2505
|
var animations = [];
|
|
2854
2506
|
var kinematics = {};
|
|
2855
|
-
var count = 0;
|
|
2507
|
+
var count = 0;
|
|
2508
|
+
|
|
2509
|
+
//
|
|
2856
2510
|
|
|
2857
2511
|
var library = {
|
|
2858
2512
|
animations: {},
|
|
@@ -2897,11 +2551,9 @@ THREE.ColladaLoader.prototype = {
|
|
|
2897
2551
|
setupAnimations();
|
|
2898
2552
|
setupKinematics();
|
|
2899
2553
|
var scene = parseScene(getElementsByTagName(collada, "scene")[0]);
|
|
2900
|
-
|
|
2901
2554
|
if (asset.upAxis === "Z_UP") {
|
|
2902
2555
|
scene.quaternion.setFromEuler(new THREE.Euler(-Math.PI / 2, 0, 0));
|
|
2903
2556
|
}
|
|
2904
|
-
|
|
2905
2557
|
scene.scale.multiplyScalar(asset.unit);
|
|
2906
2558
|
return {
|
|
2907
2559
|
animations: animations,
|
|
@@ -2910,7 +2562,7 @@ THREE.ColladaLoader.prototype = {
|
|
|
2910
2562
|
scene: scene
|
|
2911
2563
|
};
|
|
2912
2564
|
}
|
|
2913
|
-
};
|
|
2565
|
+
};
|
|
2914
2566
|
|
|
2915
|
-
|
|
2916
|
-
exports["default"] =
|
|
2567
|
+
// important: don't forget to export it
|
|
2568
|
+
var _default = exports["default"] = THREE.ColladaLoader;
|