x_ite 8.9.0 → 8.9.2

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.
Files changed (66) hide show
  1. package/README.md +3 -7
  2. package/dist/assets/components/Annotation.js +13 -13
  3. package/dist/assets/components/Annotation.min.js +1 -1
  4. package/dist/assets/components/CADGeometry.js +13 -13
  5. package/dist/assets/components/CADGeometry.min.js +1 -1
  6. package/dist/assets/components/CubeMapTexturing.js +25 -25
  7. package/dist/assets/components/CubeMapTexturing.min.js +1 -1
  8. package/dist/assets/components/DIS.js +13 -13
  9. package/dist/assets/components/DIS.min.js +1 -1
  10. package/dist/assets/components/EventUtilities.js +9 -9
  11. package/dist/assets/components/EventUtilities.min.js +1 -1
  12. package/dist/assets/components/Geometry2D.js +19 -19
  13. package/dist/assets/components/Geometry2D.min.js +1 -1
  14. package/dist/assets/components/Geospatial.js +33 -33
  15. package/dist/assets/components/Geospatial.min.js +1 -1
  16. package/dist/assets/components/HAnim.js +129 -90
  17. package/dist/assets/components/HAnim.min.js +1 -1
  18. package/dist/assets/components/KeyDeviceSensor.js +8 -8
  19. package/dist/assets/components/KeyDeviceSensor.min.js +1 -1
  20. package/dist/assets/components/Layout.js +27 -27
  21. package/dist/assets/components/Layout.min.js +1 -1
  22. package/dist/assets/components/NURBS.js +24 -24
  23. package/dist/assets/components/NURBS.min.js +1 -1
  24. package/dist/assets/components/ParticleSystems.js +23 -23
  25. package/dist/assets/components/ParticleSystems.min.js +1 -1
  26. package/dist/assets/components/Picking.js +18 -18
  27. package/dist/assets/components/Picking.min.js +1 -1
  28. package/dist/assets/components/RigidBodyPhysics.js +18 -18
  29. package/dist/assets/components/RigidBodyPhysics.min.js +1 -1
  30. package/dist/assets/components/Scripting.js +37 -37
  31. package/dist/assets/components/Scripting.min.js +1 -1
  32. package/dist/assets/components/Text.js +24 -24
  33. package/dist/assets/components/Text.min.js +1 -1
  34. package/dist/assets/components/TextureProjector.js +14 -14
  35. package/dist/assets/components/TextureProjector.min.js +1 -1
  36. package/dist/assets/components/Texturing3D.js +30 -30
  37. package/dist/assets/components/Texturing3D.min.js +1 -1
  38. package/dist/assets/components/VolumeRendering.js +18 -18
  39. package/dist/assets/components/VolumeRendering.min.js +1 -1
  40. package/dist/assets/components/X_ITE.js +9 -9
  41. package/dist/assets/components/X_ITE.min.js +1 -1
  42. package/dist/x_ite.css +1 -1
  43. package/dist/x_ite.js +415 -130
  44. package/dist/x_ite.min.js +1 -1
  45. package/dist/x_ite.zip +0 -0
  46. package/docs/_config.yml +2 -2
  47. package/docs/_posts/components/HAnim/HAnimDisplacer.md +1 -1
  48. package/docs/_posts/components/HAnim/HAnimHumanoid.md +75 -75
  49. package/docs/_posts/components/HAnim/HAnimJoint.md +2 -2
  50. package/docs/_posts/components/HAnim/HAnimMotion.md +22 -22
  51. package/docs/_posts/components/HAnim/HAnimSegment.md +1 -1
  52. package/docs/_posts/components/HAnim/HAnimSite.md +1 -1
  53. package/docs/_posts/getting-started.md +3 -7
  54. package/docs/laboratory/gltf-sample-viewer.html +52 -4
  55. package/package.json +2 -1
  56. package/src/standard/Math/Geometry/Box2.js +12 -2
  57. package/src/standard/Math/Geometry/Box3.js +12 -2
  58. package/src/x_ite/Base/X3DObjectArrayField.js +3 -2
  59. package/src/x_ite/Base/X3DTypedArrayField.js +3 -2
  60. package/src/x_ite/Browser/VERSION.js +1 -1
  61. package/src/x_ite/Components/HAnim/HAnimHumanoid.js +105 -68
  62. package/src/x_ite/Components/HAnim/HAnimMotion.js +3 -3
  63. package/src/x_ite/Components/Rendering/X3DComposedGeometryNode.js +1 -1
  64. package/src/x_ite/Fields/ArrayFields.js +9 -7
  65. package/src/x_ite/Parser/GLTF2Parser.js +316 -55
  66. package/src/x_ite/Parser/SVGParser.js +1 -1
@@ -55,8 +55,9 @@ import X3DBoundedObject from "../Grouping/X3DBoundedObject.js";
55
55
  import TraverseType from "../../Rendering/TraverseType.js";
56
56
  import X3DConstants from "../../Base/X3DConstants.js";
57
57
  import X3DCast from "../../Base/X3DCast.js";
58
- import Matrix4 from "../../../standard/Math/Numbers/Matrix4.js";
59
58
  import Vector3 from "../../../standard/Math/Numbers/Vector3.js";
59
+ import Rotation4 from "../../../standard/Math/Numbers/Rotation4.js";
60
+ import Matrix4 from "../../../standard/Math/Numbers/Matrix4.js";
60
61
 
61
62
  function HAnimHumanoid (executionContext)
62
63
  {
@@ -70,16 +71,17 @@ function HAnimHumanoid (executionContext)
70
71
  this ._bboxSize .setUnit ("length");
71
72
  this ._bboxCenter .setUnit ("length");
72
73
 
73
- this .skeletonNode = new Group (executionContext);
74
- this .viewpointsNode = new Group (executionContext);
75
- this .skinNode = new Group (executionContext);
76
- this .transformNode = new Transform (executionContext);
77
- this .jointNodes = [ ];
78
- this .skinNormalNode = null;
79
- this .skinCoordNode = null;
80
- this .restNormalNode = null;
81
- this .restCoordNode = null;
82
- this .changed = false;
74
+ this .skeletonNode = new Group (executionContext);
75
+ this .viewpointsNode = new Group (executionContext);
76
+ this .skinNode = new Group (executionContext);
77
+ this .transformNode = new Transform (executionContext);
78
+ this .jointNodes = [ ];
79
+ this .jointBindingMatrices = [ ];
80
+ this .skinBindingNormal = null;
81
+ this .skinBindingCoord = null;
82
+ this .skinNormalNode = null;
83
+ this .skinCoordNode = null;
84
+ this .changed = false;
83
85
  }
84
86
 
85
87
  Object .assign (Object .setPrototypeOf (HAnimHumanoid .prototype, X3DChildNode .prototype),
@@ -145,13 +147,18 @@ Object .assign (Object .setPrototypeOf (HAnimHumanoid .prototype, X3DChildNode .
145
147
 
146
148
  // Skinning
147
149
 
148
- this ._joints .addInterest ("set_joints__", this);
149
- this ._skinNormal .addInterest ("set_skinNormal__", this);
150
- this ._skinCoord .addInterest ("set_skinCoord__", this);
150
+ this ._joints .addInterest ("set_joints__", this);
151
+ this ._jointBindingPositions .addInterest ("set_joints__", this);
152
+ this ._jointBindingRotations .addInterest ("set_joints__", this);
153
+ this ._jointBindingScales .addInterest ("set_joints__", this);
154
+ this ._skinBindingNormal .addInterest ("set_skinBindingNormal__", this);
155
+ this ._skinBindingCoord .addInterest ("set_skinBindingCoord__", this);
156
+ this ._skinNormal .addInterest ("set_skinNormal__", this);
157
+ this ._skinCoord .addInterest ("set_skinCoord__", this);
151
158
 
152
159
  this .set_joints__ ();
153
- this .set_skinNormal__ ();
154
- this .set_skinCoord__ ();
160
+ this .set_skinBindingNormal__ ();
161
+ this .set_skinBindingCoord__ ();
155
162
  },
156
163
  getBBox (bbox, shadows)
157
164
  {
@@ -159,19 +166,39 @@ Object .assign (Object .setPrototypeOf (HAnimHumanoid .prototype, X3DChildNode .
159
166
  },
160
167
  set_joints__ ()
161
168
  {
162
- const jointNodes = this .jointNodes;
169
+ const
170
+ jointNodes = this .jointNodes,
171
+ jointBindingMatrices = this .jointBindingMatrices,
172
+ jointBindingPositions = this ._jointBindingPositions,
173
+ jointBindingRotations = this ._jointBindingRotations,
174
+ jointBindingScales = this ._jointBindingScales;
163
175
 
164
176
  for (const jointNode of jointNodes)
165
177
  jointNode .removeInterest ("set_joint__", this);
166
178
 
167
- jointNodes .length = 0;
179
+ jointNodes .length = 0;
180
+ jointBindingMatrices .length = 0;
168
181
 
169
- for (const node of this ._joints)
182
+ for (const [i, node] of this ._joints .entries ())
170
183
  {
171
184
  const jointNode = X3DCast (X3DConstants .HAnimJoint, node);
172
185
 
173
186
  if (jointNode)
174
- jointNodes .push (jointNode);
187
+ {
188
+ const jointBindingMatrix = new Matrix4 ();
189
+
190
+ if (jointBindingPositions .length)
191
+ jointBindingMatrix .translate (jointBindingPositions [Math .min (i, jointBindingPositions .length - 1)] .getValue ());
192
+
193
+ if (jointBindingRotations .length)
194
+ jointBindingMatrix .rotate (jointBindingRotations [Math .min (i, jointBindingRotations .length - 1)] .getValue ());
195
+
196
+ if (jointBindingScales .length)
197
+ jointBindingMatrix .scale (jointBindingScales [Math .min (i, jointBindingScales .length - 1)] .getValue ());
198
+
199
+ jointNodes .push (jointNode);
200
+ jointBindingMatrices .push (jointBindingMatrix);
201
+ }
175
202
  }
176
203
 
177
204
  for (const jointNode of jointNodes)
@@ -183,33 +210,38 @@ Object .assign (Object .setPrototypeOf (HAnimHumanoid .prototype, X3DChildNode .
183
210
  {
184
211
  this .changed = true;
185
212
  },
186
- set_skinNormal__ ()
213
+ set_skinBindingNormal__ ()
187
214
  {
188
- this .restNormalNode = null;
215
+ this .skinBindingNormal = X3DCast (X3DConstants .X3DNormalNode, this ._skinBindingNormal);
189
216
 
217
+ this .set_skinNormal__ ();
218
+ },
219
+ set_skinBindingCoord__ ()
220
+ {
221
+ this .skinBindingCoord = X3DCast (X3DConstants .X3DCoordinateNode, this ._skinBindingCoord);
222
+
223
+ this .set_skinCoord__ ();
224
+ },
225
+ set_skinNormal__ ()
226
+ {
190
227
  this .skinNormalNode = X3DCast (X3DConstants .X3DNormalNode, this ._skinNormal);
191
228
 
192
- if (this .skinNormalNode)
193
- this .restNormalNode = this .skinNormalNode .copy ();
229
+ if (!this .skinBindingNormal && this .skinNormalNode)
230
+ this .skinBindingNormal = this .skinNormalNode .copy ();
194
231
 
195
232
  this .changed = true;
196
233
  },
197
234
  set_skinCoord__ ()
198
235
  {
199
- this .restCoordNode = null;
200
-
201
236
  this .skinCoordNode = X3DCast (X3DConstants .X3DCoordinateNode, this ._skinCoord);
202
237
 
203
- if (this .skinCoordNode)
204
- {
205
- this .restCoordNode = this .skinCoordNode .copy ();
238
+ if (!this .skinBindingCoord && this .skinCoordNode)
239
+ this .skinBindingCoord = this .skinCoordNode .copy ();
206
240
 
241
+ if (this .skinCoordNode)
207
242
  delete this .skinning;
208
- }
209
243
  else
210
- {
211
244
  this .skinning = Function .prototype
212
- }
213
245
 
214
246
  this .changed = true;
215
247
  },
@@ -223,9 +255,9 @@ Object .assign (Object .setPrototypeOf (HAnimHumanoid .prototype, X3DChildNode .
223
255
  {
224
256
  const
225
257
  invModelMatrix = new Matrix4 (),
226
- vector = new Vector3 (0, 0, 0),
227
258
  rest = new Vector3 (0, 0, 0),
228
259
  skin = new Vector3 (0, 0, 0),
260
+ vector = new Vector3 (0, 0, 0),
229
261
  point = new Vector3 (0, 0, 0);
230
262
 
231
263
  return function (type, renderObject)
@@ -239,31 +271,36 @@ Object .assign (Object .setPrototypeOf (HAnimHumanoid .prototype, X3DChildNode .
239
271
  this .changed = false;
240
272
 
241
273
  const
242
- jointNodes = this .jointNodes,
243
- skinNormalNode = this .skinNormalNode,
244
- skinCoordNode = this .skinCoordNode,
245
- restNormalNode = this .restNormalNode,
246
- restCoordNode = this .restCoordNode;
274
+ jointNodes = this .jointNodes,
275
+ jointNodesLength = jointNodes .length,
276
+ jointBindingMatrices = this .jointBindingMatrices,
277
+ skinBindingNormal = this .skinBindingNormal,
278
+ skinBindingCoord = this .skinBindingCoord,
279
+ skinNormalNode = this .skinNormalNode,
280
+ skinCoordNode = this .skinCoordNode;
247
281
 
248
282
  // Reset skin normals and coords.
249
283
 
250
284
  if (skinNormalNode)
251
- skinNormalNode ._vector .assign (restNormalNode ._vector);
285
+ skinNormalNode ._vector .assign (skinBindingNormal ._vector);
252
286
 
253
- skinCoordNode ._point .assign (restCoordNode ._point);
287
+ skinCoordNode ._point .assign (skinBindingCoord ._point);
254
288
 
255
289
  // Determine inverse model matrix of humanoid.
256
290
 
257
- invModelMatrix .assign (this .transformNode .getMatrix ()) .multRight (renderObject .getModelViewMatrix () .get ()) .inverse ();
291
+ invModelMatrix .assign (this .transformNode .getMatrix ())
292
+ .multRight (renderObject .getModelViewMatrix () .get ()) .inverse ();
258
293
 
259
294
  // Apply joint transformations.
260
295
 
261
- for (const jointNode of jointNodes)
296
+ for (let i = 0; i < jointNodesLength; ++ i)
262
297
  {
263
298
  const
264
- skinCoordIndexLength = jointNode ._skinCoordIndex .length,
265
- jointMatrix = jointNode .getModelMatrix () .multRight (invModelMatrix),
266
- displacerNodes = jointNode .getDisplacers ();
299
+ jointNode = jointNodes [i],
300
+ jointBindingMatrix = jointBindingMatrices [i],
301
+ jointMatrix = jointNode .getModelMatrix () .multRight (invModelMatrix) .multLeft (jointBindingMatrix),
302
+ displacerNodes = jointNode .getDisplacers (),
303
+ skinCoordIndexLength = jointNode ._skinCoordIndex .length;
267
304
 
268
305
  for (const displacerNode of displacerNodes)
269
306
  {
@@ -301,15 +338,15 @@ Object .assign (Object .setPrototypeOf (HAnimHumanoid .prototype, X3DChildNode .
301
338
 
302
339
  if (skinNormalNode)
303
340
  {
304
- rest .assign (restNormalNode .get1Vector (index, vector));
341
+ rest .assign (skinBindingNormal .get1Vector (index, vector));
305
342
  skinNormalNode .get1Vector (index, skin);
306
343
  normalMatrix .multVecMatrix (vector) .subtract (rest) .multiply (weight) .add (skin);
307
344
  skinNormalNode .set1Vector (index, vector);
308
- // Should the normals be normalized at end, or let it the shader do?
345
+ // Let the shader normalize the normals.
309
346
  }
310
347
 
311
348
  //skin += (rest * J - rest) * weight
312
- rest .assign (restCoordNode .get1Point (index, point));
349
+ rest .assign (skinBindingCoord .get1Point (index, point));
313
350
  skinCoordNode .get1Point (index, skin);
314
351
  jointMatrix .multVecMatrix (point) .subtract (rest) .multiply (weight) .add (skin);
315
352
  skinCoordNode .set1Point (index, point);
@@ -319,31 +356,31 @@ Object .assign (Object .setPrototypeOf (HAnimHumanoid .prototype, X3DChildNode .
319
356
  })(),
320
357
  toVRMLStream (generator)
321
358
  {
322
- if (this .skinCoordNode)
323
- this .skinCoordNode ._point = this .restCoordNode ._point;
324
-
325
359
  if (this .skinNormalNode)
326
- this .skinNormalNode ._vector = this .restNormalNode ._vector;
360
+ this .skinNormalNode ._vector = this .skinBindingNormal ._vector;
361
+
362
+ if (this .skinCoordNode)
363
+ this .skinCoordNode ._point = this .skinBindingCoord ._point;
327
364
 
328
365
  X3DChildNode .prototype .toVRMLStream .call (this, generator);
329
366
  },
330
367
  toXMLStream (generator)
331
368
  {
332
- if (this .skinCoordNode)
333
- this .skinCoordNode ._point = this .restCoordNode ._point;
334
-
335
369
  if (this .skinNormalNode)
336
- this .skinNormalNode ._vector = this .restNormalNode ._vector;
370
+ this .skinNormalNode ._vector = this .skinBindingNormal ._vector;
371
+
372
+ if (this .skinCoordNode)
373
+ this .skinCoordNode ._point = this .skinBindingCoord ._point;
337
374
 
338
375
  X3DChildNode .prototype .toXMLStream .call (this, generator);
339
376
  },
340
377
  toJSONStream (generator)
341
378
  {
342
- if (this .skinCoordNode)
343
- this .skinCoordNode ._point = this .restCoordNode ._point;
344
-
345
379
  if (this .skinNormalNode)
346
- this .skinNormalNode ._vector = this .restNormalNode ._vector;
380
+ this .skinNormalNode ._vector = this .skinBindingNormal ._vector;
381
+
382
+ if (this .skinCoordNode)
383
+ this .skinCoordNode ._point = this .skinBindingCoord ._point;
347
384
 
348
385
  X3DChildNode .prototype .toJSONStream .call (this, generator);
349
386
  },
@@ -380,31 +417,31 @@ Object .defineProperties (HAnimHumanoid,
380
417
  {
381
418
  value: new FieldDefinitionArray ([
382
419
  new X3DFieldDefinition (X3DConstants .inputOutput, "metadata", new Fields .SFNode ()),
420
+ new X3DFieldDefinition (X3DConstants .inputOutput, "version", new Fields .SFString ()),
383
421
  new X3DFieldDefinition (X3DConstants .inputOutput, "description", new Fields .SFString ()),
384
422
  new X3DFieldDefinition (X3DConstants .inputOutput, "name", new Fields .SFString ()),
385
- new X3DFieldDefinition (X3DConstants .inputOutput, "version", new Fields .SFString ()),
386
423
  new X3DFieldDefinition (X3DConstants .inputOutput, "info", new Fields .MFString ()),
387
424
  new X3DFieldDefinition (X3DConstants .inputOutput, "translation", new Fields .SFVec3f ()),
388
425
  new X3DFieldDefinition (X3DConstants .inputOutput, "rotation", new Fields .SFRotation ()),
389
426
  new X3DFieldDefinition (X3DConstants .inputOutput, "scale", new Fields .SFVec3f (1, 1, 1)),
390
427
  new X3DFieldDefinition (X3DConstants .inputOutput, "scaleOrientation", new Fields .SFRotation ()),
391
428
  new X3DFieldDefinition (X3DConstants .inputOutput, "center", new Fields .SFVec3f ()),
392
- new X3DFieldDefinition (X3DConstants .inputOutput, "jointBindingPositions", new Fields .MFVec3f ()),
393
- new X3DFieldDefinition (X3DConstants .inputOutput, "jointBindingRotations", new Fields .MFRotation ()),
394
- new X3DFieldDefinition (X3DConstants .inputOutput, "jointBindingScales", new Fields .MFVec3f ()),
395
- new X3DFieldDefinition (X3DConstants .inputOutput, "motionsEnabled", new Fields .MFBool ()),
396
- new X3DFieldDefinition (X3DConstants .inputOutput, "loa", new Fields .SFInt32 (-1)),
397
- new X3DFieldDefinition (X3DConstants .inputOutput, "skeletalConfiguration", new Fields .SFString ("BASIC")),
398
429
  new X3DFieldDefinition (X3DConstants .inputOutput, "visible", new Fields .SFBool (true)),
399
430
  new X3DFieldDefinition (X3DConstants .inputOutput, "bboxDisplay", new Fields .SFBool ()),
400
431
  new X3DFieldDefinition (X3DConstants .initializeOnly, "bboxSize", new Fields .SFVec3f (-1, -1, -1)),
401
432
  new X3DFieldDefinition (X3DConstants .initializeOnly, "bboxCenter", new Fields .SFVec3f ()),
433
+ new X3DFieldDefinition (X3DConstants .inputOutput, "loa", new Fields .SFInt32 (-1)),
434
+ new X3DFieldDefinition (X3DConstants .inputOutput, "skeletalConfiguration", new Fields .SFString ("BASIC")),
402
435
  new X3DFieldDefinition (X3DConstants .inputOutput, "skeleton", new Fields .MFNode ()),
403
436
  new X3DFieldDefinition (X3DConstants .inputOutput, "viewpoints", new Fields .MFNode ()),
404
437
  new X3DFieldDefinition (X3DConstants .inputOutput, "sites", new Fields .MFNode ()),
405
438
  new X3DFieldDefinition (X3DConstants .inputOutput, "segments", new Fields .MFNode ()),
406
- new X3DFieldDefinition (X3DConstants .inputOutput, "joints", new Fields .MFNode ()),
439
+ new X3DFieldDefinition (X3DConstants .inputOutput, "motionsEnabled", new Fields .MFBool ()),
407
440
  new X3DFieldDefinition (X3DConstants .inputOutput, "motions", new Fields .MFNode ()),
441
+ new X3DFieldDefinition (X3DConstants .inputOutput, "jointBindingPositions", new Fields .MFVec3f ()),
442
+ new X3DFieldDefinition (X3DConstants .inputOutput, "jointBindingRotations", new Fields .MFRotation ()),
443
+ new X3DFieldDefinition (X3DConstants .inputOutput, "jointBindingScales", new Fields .MFVec3f ()),
444
+ new X3DFieldDefinition (X3DConstants .inputOutput, "joints", new Fields .MFNode ()),
408
445
  new X3DFieldDefinition (X3DConstants .inputOutput, "skinBindingNormal", new Fields .SFNode ()),
409
446
  new X3DFieldDefinition (X3DConstants .inputOutput, "skinBindingCoord", new Fields .SFNode ()),
410
447
  new X3DFieldDefinition (X3DConstants .inputOutput, "skinNormal", new Fields .SFNode ()),
@@ -96,16 +96,16 @@ Object .defineProperties (HAnimMotion,
96
96
  new X3DFieldDefinition (X3DConstants .inputOutput, "enabled", new Fields .SFBool (true)),
97
97
  new X3DFieldDefinition (X3DConstants .inputOnly, "next", new Fields .SFBool ()),
98
98
  new X3DFieldDefinition (X3DConstants .inputOnly, "previous", new Fields .SFBool ()),
99
+ new X3DFieldDefinition (X3DConstants .inputOutput, "startFrame", new Fields .SFInt32 ()),
100
+ new X3DFieldDefinition (X3DConstants .inputOutput, "endFrame", new Fields .SFInt32 ()),
99
101
  new X3DFieldDefinition (X3DConstants .inputOutput, "frameDuration", new Fields .SFTime (0.1)),
100
102
  new X3DFieldDefinition (X3DConstants .inputOutput, "frameIncrement", new Fields .SFInt32 (1)),
101
103
  new X3DFieldDefinition (X3DConstants .inputOutput, "frameIndex", new Fields .SFInt32 (0)),
102
104
  new X3DFieldDefinition (X3DConstants .inputOutput, "loop", new Fields .SFBool ()),
103
- new X3DFieldDefinition (X3DConstants .inputOutput, "channels", new Fields .SFString ()),
104
105
  new X3DFieldDefinition (X3DConstants .inputOutput, "channelsEnabled", new Fields .MFBool ()),
106
+ new X3DFieldDefinition (X3DConstants .inputOutput, "channels", new Fields .SFString ()),
105
107
  new X3DFieldDefinition (X3DConstants .inputOutput, "joints", new Fields .SFString ()),
106
108
  new X3DFieldDefinition (X3DConstants .inputOutput, "loa", new Fields .SFInt32 (-1)),
107
- new X3DFieldDefinition (X3DConstants .inputOutput, "startFrame", new Fields .SFInt32 ()),
108
- new X3DFieldDefinition (X3DConstants .inputOutput, "endFrame", new Fields .SFInt32 ()),
109
109
  new X3DFieldDefinition (X3DConstants .inputOutput, "values", new Fields .MFFloat ()),
110
110
  new X3DFieldDefinition (X3DConstants .outputOnly, "cycleTime", new Fields .SFTime ()),
111
111
  new X3DFieldDefinition (X3DConstants .outputOnly, "elapsedTime", new Fields .SFTime ()),
@@ -190,7 +190,7 @@ Object .assign (Object .setPrototypeOf (X3DComposedGeometryNode .prototype, X3DG
190
190
 
191
191
  // Set size to a multiple of verticesPerPolygon.
192
192
 
193
- polygonsSize -= polygonsSize % verticesPerPolygon;
193
+ polygonsSize -= polygonsSize % verticesPerPolygon;
194
194
  trianglesSize -= trianglesSize % verticesPerFace;
195
195
 
196
196
  const
@@ -108,9 +108,10 @@ Object .assign (Object .setPrototypeOf (MFNode .prototype, X3DObjectArrayField .
108
108
  {
109
109
  const
110
110
  target = this .getTarget (),
111
- array = target .getValue ();
111
+ array = target .getValue (),
112
+ length = array .length;
112
113
 
113
- switch (array .length)
114
+ switch (length)
114
115
  {
115
116
  case 0:
116
117
  {
@@ -136,11 +137,11 @@ Object .assign (Object .setPrototypeOf (MFNode .prototype, X3DObjectArrayField .
136
137
  generator .string += generator .TidyBreak ();
137
138
  generator .IncIndent ();
138
139
 
139
- for (let i = 0, length = array .length; i < length; ++ i)
140
+ for (let i = 0; i < length; ++ i)
140
141
  {
141
142
  generator .string += generator .Indent ();
142
143
  array [i] .toStream (generator);
143
- generator .string += generator .Break ();
144
+ generator .string += generator .string .at (-1) === "}" ? generator .TidyBreak () : generator .Break ();
144
145
  }
145
146
 
146
147
  generator .DecIndent ();
@@ -156,9 +157,10 @@ Object .assign (Object .setPrototypeOf (MFNode .prototype, X3DObjectArrayField .
156
157
  {
157
158
  const
158
159
  target = this .getTarget (),
159
- array = target .getValue ();
160
+ array = target .getValue (),
161
+ length = array .length;
160
162
 
161
- switch (array .length)
163
+ switch (length)
162
164
  {
163
165
  case 0:
164
166
  {
@@ -188,7 +190,7 @@ Object .assign (Object .setPrototypeOf (MFNode .prototype, X3DObjectArrayField .
188
190
  {
189
191
  generator .string += generator .Indent ();
190
192
  element .toVRMLStream (generator);
191
- generator .string += generator .Break ();
193
+ generator .string += generator .string .at (-1) === "}" ? generator .TidyBreak () : generator .Break ();
192
194
  }
193
195
 
194
196
  generator .DecIndent ();