zincjs 1.2.0 → 1.4.0-beta.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.
@@ -1,5 +1,4 @@
1
1
  const THREE = require('three');
2
- const THREEGeometry = require('../three/Geometry').Geometry;
3
2
 
4
3
  let uniqueiId = 0;
5
4
 
@@ -20,9 +19,8 @@ const ZincObject = function() {
20
19
  this.geometry = undefined;
21
20
  // THREE.Mesh
22
21
  this.morph = undefined;
23
- // THREE.Mesh - for utilities purpose such as rendering
24
- // transparent surfaces - one for front face and one for back face.
25
- this.secondaryMesh = undefined;
22
+ this.group = new THREE.Group();
23
+ this._lod = new (require("./lod").LOD)(this);
26
24
  /**
27
25
  * Groupname given to this geometry.
28
26
  */
@@ -46,12 +44,17 @@ const ZincObject = function() {
46
44
  this.closestVertexIndex = -1;
47
45
  this.boundingBoxUpdateRequired = true;
48
46
  this.cachedBoundingBox = new THREE.Box3();
49
- this._vertex = new THREE.Vector3();
50
47
  this.anatomicalId = undefined;
51
48
  this.region = undefined;
52
49
  this.animationClip = undefined;
53
50
  this.markerMode = "inherited";
54
51
  this.uuid = getUniqueId();
52
+ this._v1 = new THREE.Vector3();
53
+ this._v2 = new THREE.Vector3();
54
+ this._b1 = new THREE.Box3();
55
+ this.center = new THREE.Vector3();
56
+ this.radius = 0;
57
+ this.visible = true;
55
58
  }
56
59
 
57
60
  /**
@@ -77,7 +80,7 @@ ZincObject.prototype.getDuration = function() {
77
80
 
78
81
  /**
79
82
  * Set the region this object belongs to.
80
- *
83
+ *
81
84
  * @param {Region} region
82
85
  */
83
86
  ZincObject.prototype.setRegion = function(region) {
@@ -94,61 +97,42 @@ ZincObject.prototype.getRegion = function() {
94
97
  }
95
98
 
96
99
  /**
97
- * Convert a {THREE.Geometry} into a {THREE.BufferGeometry}.
100
+ * Get the threejs object3D.
101
+ *
102
+ * @return {Object}
98
103
  */
99
- ZincObject.prototype.toBufferGeometry = function(geometryIn, options) {
100
- let geometry = undefined;
101
- if (geometryIn instanceof THREEGeometry) {
102
- if (options.localTimeEnabled && !geometryIn.morphNormalsReady &&
103
- (geometryIn.morphNormals == undefined || geometryIn.morphNormals.length == 0))
104
- geometryIn.computeMorphNormals();
105
- geometry = geometryIn.toIndexedBufferGeometry();
106
- if (options.localMorphColour) {
107
- require("../utilities").copyMorphColorsToIndexedBufferGeometry(geometryIn, geometry);
108
- }
109
- } else if (geometryIn instanceof THREE.BufferGeometry) {
110
- geometry = geometryIn.clone();
111
- }
112
- geometry.colorsNeedUpdate = true;
113
- geometry.computeBoundingBox();
114
- geometry.computeBoundingSphere();
115
- if (geometryIn._video)
116
- geometry._video = geometryIn._video;
117
- return geometry;
104
+ ZincObject.prototype.getMorph = function() {
105
+ const morph = this._lod.getCurrentMorph();
106
+ return morph ? morph : this.morph;
118
107
  }
119
108
 
120
109
  /**
121
- * Handle transparent mesh, create a clone for backside rendering if it is
122
- * transparent.
110
+ * Get the threejs object3D.
111
+ *
112
+ * @return {Object}
123
113
  */
124
- ZincObject.prototype.checkAndCreateTransparentMesh = function() {
125
- if (this.isGeometry && this.morph.material && this.morph.material.transparent) {
126
- if (!this.secondaryMesh) {
127
- let secondaryMaterial = this.morph.material.clone();
128
- secondaryMaterial.side = THREE.FrontSide;
129
- this.secondaryMesh = new THREE.Mesh(this.morph.geometry, secondaryMaterial);
130
- this.secondaryMesh.renderOrder = this.morph.renderOrder + 1;
131
- this.secondaryMesh.userData = this;
132
- this.secondaryMesh.name = this.groupName;
133
- }
134
- this.morph.material.side = THREE.BackSide;
135
- this.morph.material.needsUpdate = true;
136
- this.morph.add(this.secondaryMesh);
137
- this.animationGroup.add(this.secondaryMesh);
138
- }
114
+ ZincObject.prototype.getGroup = function() {
115
+ return this.group;
139
116
  }
140
117
 
141
118
  /**
142
- * Handle transparent mesh, remove a clone for backside rendering if it is
119
+ * Set the internal threejs object3D.
120
+ */
121
+ ZincObject.prototype.setMorph = function(mesh) {
122
+ this.morph = mesh;
123
+ this.group.add(this.morph);
124
+ //this is the base level object
125
+ const distance = this._lod.calculateDistance("far");
126
+ this._lod.addLevel(mesh, distance);
127
+ this._lod.setMaterial(mesh.material);
128
+ }
129
+
130
+ /**
131
+ * Handle transparent mesh, create a clone for backside rendering if it is
143
132
  * transparent.
144
133
  */
145
- ZincObject.prototype.checkAndRemoveTransparentMesh = function() {
146
- if (this.isGeometry && this.secondaryMesh) {
147
- this.morph.remove(this.secondaryMesh);
148
- this.animationGroup.uncache(this.secondaryMesh);
149
- this.animationGroup.remove(this.secondaryMesh);
150
- }
151
- this.morph.material.side = THREE.DoubleSide;
134
+ ZincObject.prototype.checkTransparentMesh = function(transparentChanged) {
135
+ return;
152
136
  }
153
137
 
154
138
  /**
@@ -161,16 +145,20 @@ ZincObject.prototype.checkAndRemoveTransparentMesh = function() {
161
145
  * time dependent.
162
146
  */
163
147
  ZincObject.prototype.setMesh = function(mesh, localTimeEnabled, localMorphColour) {
148
+ //Note: we assume all layers are consistent with time frame
149
+ //Thus adding them to the same animation group should work.
150
+ //This step is only required for the primary (level 0) mesh.
164
151
  this.animationGroup = new THREE.AnimationObjectGroup(mesh);
165
152
  this.mixer = new THREE.AnimationMixer(this.animationGroup);
153
+ const geometry = mesh.geometry;
166
154
  this.geometry = mesh.geometry;
167
155
  this.clipAction = undefined;
168
- if (this.geometry && this.geometry.morphAttributes) {
169
- let morphAttribute = this.geometry.morphAttributes.position;
156
+ if (geometry && geometry.morphAttributes) {
157
+ let morphAttribute = geometry.morphAttributes.position;
170
158
  if (!morphAttribute) {
171
- morphAttribute = this.geometry.morphAttributes.color ?
172
- this.geometry.morphAttributes.color :
173
- this.geometry.morphAttributes.normal;
159
+ morphAttribute = geometry.morphAttributes.color ?
160
+ geometry.morphAttributes.color :
161
+ geometry.morphAttributes.normal;
174
162
  }
175
163
  if (morphAttribute) {
176
164
  this.animationClip = THREE.AnimationClip.CreateClipsFromMorphTargetSequences(
@@ -186,16 +174,16 @@ ZincObject.prototype.setMesh = function(mesh, localTimeEnabled, localMorphColour
186
174
  }
187
175
  this.timeEnabled = localTimeEnabled;
188
176
  this.morphColour = localMorphColour;
189
- this.morph = mesh;
190
- this.morph.userData = this;
191
- this.morph.matrixAutoUpdate = false;
192
- this.checkAndCreateTransparentMesh();
177
+ mesh.userData = this;
178
+ mesh.matrixAutoUpdate = false;
179
+ this.setMorph(mesh);
180
+ this.checkTransparentMesh(true);
193
181
  if (this.timeEnabled) {
194
182
  this.setFrustumCulled(false);
195
183
  } else {
196
184
  if (this.morphColour) {
197
- this.geometry.setAttribute('morphTarget0', this.geometry.getAttribute( 'position' ) );
198
- this.geometry.setAttribute('morphTarget1', this.geometry.getAttribute( 'position' ) );
185
+ geometry.setAttribute('morphTarget0', geometry.getAttribute( 'position' ) );
186
+ geometry.setAttribute('morphTarget1', geometry.getAttribute( 'position' ) );
199
187
  }
200
188
  }
201
189
  this.boundingBoxUpdateRequired = true;
@@ -208,12 +196,7 @@ ZincObject.prototype.setMesh = function(mesh, localTimeEnabled, localMorphColour
208
196
  */
209
197
  ZincObject.prototype.setName = function(groupNameIn) {
210
198
  this.groupName = groupNameIn;
211
- if (this.morph) {
212
- this.morph.name = this.groupName;
213
- }
214
- if (this.secondaryMesh) {
215
- this.secondaryMesh.name = this.groupName;
216
- }
199
+ this._lod.setName(groupNameIn);
217
200
  }
218
201
 
219
202
  /**
@@ -231,32 +214,6 @@ ZincObject.prototype.getCurrentTime = function() {
231
214
  }
232
215
  }
233
216
 
234
- const updateMorphColorAttribute = function(targetGeometry, morph) {
235
- if (morph && targetGeometry && targetGeometry.morphAttributes &&
236
- targetGeometry.morphAttributes[ "color" ]) {
237
- const morphColors = targetGeometry.morphAttributes[ "color" ];
238
- const influences = morph.morphTargetInfluences;
239
- const length = influences.length;
240
- targetGeometry.deleteAttribute( 'morphColor0' );
241
- targetGeometry.deleteAttribute( 'morphColor1' );
242
- let bound = 0;
243
- let morphArray = [];
244
- for (let i = 0; (1 > bound) || (i < length); i++) {
245
- if (influences[i] > 0) {
246
- bound++;
247
- morphArray.push([i, influences[i]]);
248
- }
249
- }
250
- if (morphArray.length == 2) {
251
- targetGeometry.setAttribute('morphColor0', morphColors[ morphArray[0][0] ] );
252
- targetGeometry.setAttribute('morphColor1', morphColors[ morphArray[1][0] ] );
253
- } else if (morphArray.length == 1) {
254
- targetGeometry.setAttribute('morphColor0', morphColors[ morphArray[0][0] ] );
255
- targetGeometry.setAttribute('morphColor1', morphColors[ morphArray[0][0] ] );
256
- }
257
- }
258
- }
259
-
260
217
  /**
261
218
  * Set the local time of this geometry.
262
219
  *
@@ -290,7 +247,8 @@ ZincObject.prototype.setMorphTime = function(time) {
290
247
  }
291
248
  if (timeChanged) {
292
249
  this.boundingBoxUpdateRequired = true;
293
- updateMorphColorAttribute(this.geometry, this.morph);
250
+ const morph = this._lod.getCurrentMorph();
251
+ this._lod.updateMorphColorAttribute(true);
294
252
  if (this.timeEnabled)
295
253
  this.markerUpdateRequired = true;
296
254
  }
@@ -312,7 +270,7 @@ ZincObject.prototype.isTimeVarying = function() {
312
270
  *
313
271
  */
314
272
  ZincObject.prototype.getVisibility = function() {
315
- return this.morph.visible;
273
+ return this.visible;
316
274
  }
317
275
 
318
276
  /**
@@ -321,10 +279,15 @@ ZincObject.prototype.getVisibility = function() {
321
279
  * @param {Boolean} visible - a boolean flag indicate the visibility to be set
322
280
  */
323
281
  ZincObject.prototype.setVisibility = function(visible) {
324
- if (this.morph.visible !== visible) {
325
- this.morph.visible = visible;
282
+ this.visible = visible;
283
+ this.group.visible = visible;
284
+ /*
285
+ const morph = this.getMorph();
286
+ if (morph.visible !== visible) {
287
+ morph.visible = visible;
326
288
  if (this.region) this.region.pickableUpdateRequired = true;
327
289
  }
290
+ */
328
291
  }
329
292
 
330
293
  /**
@@ -335,20 +298,14 @@ ZincObject.prototype.setVisibility = function(visible) {
335
298
  * can be any value between from 0 to 1.0.
336
299
  */
337
300
  ZincObject.prototype.setAlpha = function(alpha) {
338
- const material = this.morph.material;
301
+ const material = this._lod._material;
339
302
  let isTransparent = false;
340
303
  if (alpha < 1.0)
341
304
  isTransparent = true;
342
305
  let transparentChanged = material.transparent == isTransparent ? false : true;
343
306
  material.opacity = alpha;
344
307
  material.transparent = isTransparent;
345
- if (transparentChanged)
346
- if (isTransparent)
347
- this.checkAndCreateTransparentMesh();
348
- else
349
- this.checkAndRemoveTransparentMesh();
350
- if (this.secondaryMesh && this.secondaryMesh.material)
351
- this.secondaryMesh.material.opacity = alpha;
308
+ this.checkTransparentMesh(transparentChanged);
352
309
  }
353
310
 
354
311
  /**
@@ -359,9 +316,8 @@ ZincObject.prototype.setAlpha = function(alpha) {
359
316
  * @param {Boolean} flag - Set frustrum culling on/off based on this flag.
360
317
  */
361
318
  ZincObject.prototype.setFrustumCulled = function(flag) {
362
- if (this.morph) {
363
- this.morph.frustumCulled = flag;
364
- }
319
+ //multilayers - set for all layers
320
+ this._lod.setFrustumCulled(flag);
365
321
  }
366
322
 
367
323
  /**
@@ -371,10 +327,9 @@ ZincObject.prototype.setFrustumCulled = function(flag) {
371
327
  * @param {Boolean} vertexColors - Set display with vertex color on/off.
372
328
  */
373
329
  ZincObject.prototype.setVertexColors = function(vertexColors) {
374
- this.morph.material.vertexColors = vertexColors;
375
- this.geometry.colorsNeedUpdate = true;
376
- if (this.secondaryMesh && this.secondaryMesh.material)
377
- this.secondaryMesh.material.vertexColors = vertexColors;
330
+ //multilayers - set for all
331
+ this._lod.setVertexColors(vertexColors);
332
+
378
333
  }
379
334
 
380
335
  /**
@@ -383,8 +338,8 @@ ZincObject.prototype.setVertexColors = function(vertexColors) {
383
338
  * @return {THREE.Color}
384
339
  */
385
340
  ZincObject.prototype.getColour = function() {
386
- if (this.morph && this.morph.material)
387
- return this.morph.material.color;
341
+ if (this._lod._material)
342
+ return this._lod._material.color;
388
343
  return undefined;
389
344
  }
390
345
 
@@ -394,10 +349,7 @@ ZincObject.prototype.getColour = function() {
394
349
  * @param {THREE.Color} colour - Colour to be set for this geometry.
395
350
  */
396
351
  ZincObject.prototype.setColour = function(colour) {
397
- this.morph.material.color = colour;
398
- if (this.secondaryMesh && this.secondaryMesh.material)
399
- this.secondaryMesh.material.color = colour;
400
- this.geometry.colorsNeedUpdate = true;
352
+ this._lod.setColour(colour);
401
353
  }
402
354
 
403
355
  /**
@@ -407,8 +359,8 @@ ZincObject.prototype.setColour = function(colour) {
407
359
  */
408
360
  ZincObject.prototype.getColourHex = function() {
409
361
  if (!this.morphColour) {
410
- if (this.morph && this.morph.material && this.morph.material.color)
411
- return this.morph.material.color.getHexString();
362
+ if (this._lod._material && this._lod._material.color)
363
+ return this._lod._material.color.getHexString();
412
364
  }
413
365
  return undefined;
414
366
  }
@@ -419,9 +371,10 @@ ZincObject.prototype.getColourHex = function() {
419
371
  * @param {String} hex - The colour value in hex form.
420
372
  */
421
373
  ZincObject.prototype.setColourHex = function(hex) {
422
- this.morph.material.color.setHex(hex);
423
- if (this.secondaryMesh && this.secondaryMesh.material)
424
- this.secondaryMesh.material.color.setHex(hex);
374
+ this._lod._material.color.setHex(hex);
375
+ if (this._lod._secondaryMaterial) {
376
+ this._lod._secondaryMaterial.color.setHex(hex);
377
+ }
425
378
  }
426
379
 
427
380
  /**
@@ -430,13 +383,7 @@ ZincObject.prototype.setColourHex = function(hex) {
430
383
  * @param {THREE.Material} material - Material to be set for this geometry.
431
384
  */
432
385
  ZincObject.prototype.setMaterial = function(material) {
433
- this.morph.material = material;
434
- this.geometry.colorsNeedUpdate = true;
435
- if (this.secondaryMesh && this.secondaryMesh.material) {
436
- this.secondaryMesh.material.dispose();
437
- this.secondaryMesh.material = material.clone()
438
- this.secondaryMesh.material.side = THREE.FrontSide;
439
- }
386
+ this._lod.setMaterial(material);
440
387
  }
441
388
 
442
389
  /**
@@ -446,18 +393,17 @@ ZincObject.prototype.setMaterial = function(material) {
446
393
  */
447
394
  ZincObject.prototype.getClosestVertexIndex = function() {
448
395
  let closestIndex = -1;
449
- if (this.morph) {
450
- let position = this.morph.geometry.attributes.position;
451
- let boundingBox = new THREE.Box3().setFromBufferAttribute(position);
452
- let center = new THREE.Vector3();
453
- boundingBox.getCenter(center);
454
- if (position && boundingBox) {
396
+ const morph = this.getMorph();
397
+ if (morph) {
398
+ let position = morph.geometry.attributes.position;
399
+ this._b1.setFromBufferAttribute(position);
400
+ this._b1.getCenter(this._v1);
401
+ if (position) {
455
402
  let distance = -1;
456
403
  let currentDistance = 0;
457
- let current = new THREE.Vector3();
458
404
  for (let i = 0; i < position.count; i++) {
459
- current.fromArray(position.array, i * 3);
460
- currentDistance = current.distanceTo(center);
405
+ this._v2.fromArray(position.array, i * 3);
406
+ currentDistance = this._v2.distanceTo(this._v1);
461
407
  if (distance == -1)
462
408
  distance = currentDistance;
463
409
  else if (distance > (currentDistance)) {
@@ -488,9 +434,9 @@ ZincObject.prototype.getClosestVertex = function(applyMatrixWorld) {
488
434
  for (let i = 0; i < influences.length; i++) {
489
435
  if (influences[i] > 0) {
490
436
  found = true;
491
- this._vertex.fromArray(
437
+ this._v1.fromArray(
492
438
  attributes.position[i].array, this.closestVertexIndex * 3);
493
- position.add(this._vertex.multiplyScalar(influences[i]));
439
+ position.add(this._v1.multiplyScalar(influences[i]));
494
440
  }
495
441
  }
496
442
  if (found) {
@@ -502,7 +448,8 @@ ZincObject.prototype.getClosestVertex = function(applyMatrixWorld) {
502
448
  return applyMatrixWorld ? position.applyMatrix4(this.morph.matrixWorld) : position;
503
449
  }
504
450
  }
505
- this.getBoundingBox().getCenter(position);
451
+ this.getBoundingBox();
452
+ position.copy(this.center);
506
453
  return applyMatrixWorld ? position.applyMatrix4(this.morph.matrixWorld) : position;
507
454
  }
508
455
 
@@ -512,34 +459,13 @@ ZincObject.prototype.getClosestVertex = function(applyMatrixWorld) {
512
459
  * @return {THREE.Box3}.
513
460
  */
514
461
  ZincObject.prototype.getBoundingBox = function() {
515
- if (this.morph && this.morph.visible) {
462
+ let morph = this._lod.getCurrentMorph();
463
+ if (morph && morph.visible) {
516
464
  if (this.boundingBoxUpdateRequired) {
517
- let influences = this.morph.morphTargetInfluences;
518
- let attributes = undefined;
519
- if (this.morph.geometry)
520
- attributes = this.morph.geometry.morphAttributes;
521
- let found = false;
522
- if (influences && attributes && attributes.position) {
523
- let min = new THREE.Vector3();
524
- let max = new THREE.Vector3();
525
- let box = new THREE.Box3();
526
- for (let i = 0; i < influences.length; i++) {
527
- if (influences[i] > 0) {
528
- found = true;
529
- box.setFromArray(attributes.position[i].array);
530
- min.add(box.min.multiplyScalar(influences[i]));
531
- max.add(box.max.multiplyScalar(influences[i]));
532
- }
533
- }
534
- if (found)
535
- this.cachedBoundingBox.set(min, max);
536
- }
537
- if (!found) {
538
- this.cachedBoundingBox.setFromBufferAttribute(
539
- this.morph.geometry.attributes.position);
540
- }
541
- this.morph.updateWorldMatrix();
542
- this.cachedBoundingBox.applyMatrix4(this.morph.matrixWorld);
465
+ require("../utilities").getBoundingBox(morph, this.cachedBoundingBox,
466
+ this._b1, this._v1, this._v2);
467
+ this.cachedBoundingBox.getCenter(this.center);
468
+ this.radius = this.center.distanceTo(this.cachedBoundingBox.max);
543
469
  this.boundingBoxUpdateRequired = false;
544
470
  }
545
471
  return this.cachedBoundingBox;
@@ -551,17 +477,12 @@ ZincObject.prototype.getBoundingBox = function() {
551
477
  * Clear this geometry and free the memory.
552
478
  */
553
479
  ZincObject.prototype.dispose = function() {
554
- if (this.morph && this.morph.geometry)
555
- this.morph.geometry.dispose();
556
- if (this.morph && this.morph.material)
557
- this.morph.material.dispose();
558
- if (this.secondaryMesh && this.secondaryMesh.material)
559
- this.secondaryMesh.material.dispose();
560
- if (this.geometry)
561
- this.geometry.dispose();
480
+ //multilayyers
481
+ this._lod.dispose();
562
482
  this.animationGroup = undefined;
563
483
  this.mixer = undefined;
564
484
  this.morph = undefined;
485
+ this.group = undefined;
565
486
  this.clipAction = undefined;
566
487
  this.groupName = undefined;
567
488
  }
@@ -606,13 +527,15 @@ ZincObject.prototype.updateMarker = function(playAnimation, options) {
606
527
  }
607
528
  if (!this.marker.isEnabled()) {
608
529
  this.marker.enable();
609
- this.morph.add(this.marker.morph);
530
+ this.group.add(this.marker.morph);
531
+ //this._lod.toggleMarker(this.marker.morph, true);
610
532
  }
611
533
  }
612
534
  } else {
613
535
  if (this.marker && this.marker.isEnabled()) {
614
536
  this.marker.disable();
615
- this.morph.remove(this.marker.morph);
537
+ this.group.remove(this.marker.morph);
538
+ //this._lod.toggleMarker(this.marker.morph, false);
616
539
  }
617
540
  this.markerUpdateRequired = true;
618
541
  }
@@ -625,19 +548,15 @@ ZincObject.prototype.processMarkerVisual = function(min, max) {
625
548
  }
626
549
 
627
550
  ZincObject.prototype.initiateMorphColor = function() {
628
- if ((this.morphColour == 1) && (typeof this.geometry !== "undefined") &&
629
- ((this.morph.material.vertexColors == THREE.VertexColors) ||
630
- (this.morph.material.vertexColors == true))) {
631
- updateMorphColorAttribute(this.geometry, this.morph);
632
- }
551
+ //Multilayers - set all
552
+ if (this.morphColour == 1) {
553
+ this._lod.updateMorphColorAttribute(false);
554
+ }
633
555
  }
634
556
 
635
557
  ZincObject.prototype.setRenderOrder = function(renderOrder) {
636
- if (this.morph && (renderOrder !== undefined)) {
637
- this.morph.renderOrder = renderOrder;
638
- if (this.secondaryMesh)
639
- this.secondaryMesh.renderOrder = this.morph.renderOrder + 1;
640
- }
558
+ //multiilayers
559
+ this._lod.setRenderOrder(renderOrder);
641
560
  }
642
561
 
643
562
  /**
@@ -680,12 +599,18 @@ ZincObject.prototype.getClosestVertexDOMElementCoords = function(scene) {
680
599
  } else {
681
600
  this.markerMode = "inherited";
682
601
  }
683
- if (this.region) this.region.pickableUpdateRequired = true;
602
+ if (this.region) {
603
+ this.region.pickableUpdateRequired = true;
604
+ }
684
605
  }
685
606
  }
686
607
 
687
608
  //Update the geometry and colours depending on the morph.
688
- ZincObject.prototype.render = function(delta, playAnimation, options) {
609
+ ZincObject.prototype.render = function(delta, playAnimation,
610
+ cameraControls, options) {
611
+ if (this.visible && !(this.timeEnabled && playAnimation)) {
612
+ this._lod.update(cameraControls, this.center);
613
+ }
689
614
  if (playAnimation == true)
690
615
  {
691
616
  if ((this.clipAction) && this.isTimeVarying()) {
@@ -697,15 +622,25 @@ ZincObject.prototype.render = function(delta, playAnimation, options) {
697
622
  targetTime = targetTime - this.duration;
698
623
  this.inbuildTime = targetTime;
699
624
  }
700
- if (delta != 0) {
625
+ //multilayers
626
+ if (this.visible && delta != 0) {
701
627
  this.boundingBoxUpdateRequired = true;
702
- if ((this.morphColour == 1) && (typeof this.geometry !== "undefined") &&
703
- ((this.morph.material.vertexColors == THREE.VertexColors) ||
704
- (this.morph.material.vertexColors == true)))
705
- updateMorphColorAttribute(this.geometry, this.morph);
628
+ if (this.morphColour == 1) {
629
+ this._lod.updateMorphColorAttribute(true);
630
+ }
706
631
  }
707
632
  }
708
633
  this.updateMarker(playAnimation, options);
709
634
  }
710
635
 
636
+
637
+ /**
638
+ * Add lod from an url into the lod object.
639
+ */
640
+ ZincObject.prototype.addLOD = function(loader, level, url, preload) {
641
+ this._lod.addLevelFromURL(loader, level, url, preload);
642
+ }
643
+
644
+
645
+
711
646
  exports.ZincObject = ZincObject;
package/src/region.js CHANGED
@@ -292,12 +292,14 @@ let Region = function (parentIn) {
292
292
  this.addZincObject = zincObject => {
293
293
  if (zincObject) {
294
294
  zincObject.setRegion(this);
295
- group.add(zincObject.morph);
295
+ //group.add(zincObject.getMorph());
296
+ group.add(zincObject.getGroup());
296
297
  zincObjects.push(zincObject);
297
298
  this.pickableUpdateRequired = true;
298
299
  }
299
300
  }
300
301
 
302
+
301
303
  /**
302
304
  * Remove a ZincObject from this region if it presents. This will eventually
303
305
  * destroy the object and free up the memory.
@@ -307,7 +309,7 @@ let Region = function (parentIn) {
307
309
  this.removeZincObject = zincObject => {
308
310
  for (let i = 0; i < zincObjects.length; i++) {
309
311
  if (zincObject === zincObjects[i]) {
310
- group.remove(zincObject.morph);
312
+ group.remove(zincObject.getGroup());
311
313
  zincObjects.splice(i, 1);
312
314
  zincObject.dispose();
313
315
  return;
@@ -340,12 +342,12 @@ let Region = function (parentIn) {
340
342
  */
341
343
  this.getPickableThreeJSObjects = (objectsList, transverse) => {
342
344
  zincObjects.forEach(zincObject => {
343
- if (zincObject.morph && zincObject.morph.visible) {
345
+ if (zincObject.getGroup() && zincObject.getGroup().visible) {
344
346
  let marker = zincObject.marker;
345
347
  if (marker && marker.isEnabled()) {
346
- objectsList.push(marker.morph);
348
+ objectsList.push(marker.getMorph());
347
349
  }
348
- objectsList.push(zincObject.morph);
350
+ objectsList.push(zincObject.getGroup());
349
351
  }
350
352
  });
351
353
  if (transverse) {
@@ -422,7 +424,7 @@ let Region = function (parentIn) {
422
424
  children.forEach(childRegion => childRegion.clear(transverse));
423
425
  }
424
426
  zincObjects.forEach(zincObject => {
425
- group.remove(zincObject.morph);
427
+ group.remove(zincObject.getMorph());
426
428
  zincObject.dispose();
427
429
  });
428
430
  children = [];
@@ -727,11 +729,11 @@ let Region = function (parentIn) {
727
729
  * Update geometries and glyphsets based on the calculated time.
728
730
  * @private
729
731
  */
730
- this.renderGeometries = (playRate, delta, playAnimation, options, transverse) => {
732
+ this.renderGeometries = (playRate, delta, playAnimation, cameraControls, options, transverse) => {
731
733
  // Let video dictates the progress if one is present
732
734
  const allObjects = this.getAllObjects(transverse);
733
735
  allObjects.forEach(zincObject => {
734
- zincObject.render(playRate * delta, playAnimation, options);
736
+ zincObject.render(playRate * delta, playAnimation, cameraControls, options);
735
737
  });
736
738
  //process markers visibility and size
737
739
  if (options && options.displayMarkers && (playAnimation === false)) {
package/src/scene.js CHANGED
@@ -581,7 +581,7 @@ exports.Scene = function (containerIn, rendererIn) {
581
581
  zincCameraControls.setTime(currentTime);
582
582
  zincCameraControls.update(0);
583
583
  rootRegion.setMorphTime(currentTime, true);
584
- rootRegion.renderGeometries(0, 0, playAnimation, undefined, true);
584
+ rootRegion.renderGeometries(0, 0, playAnimation, zincCameraControls, undefined, true);
585
585
  } else {
586
586
  zincCameraControls.update(0);
587
587
  }
@@ -592,7 +592,7 @@ exports.Scene = function (containerIn, rendererIn) {
592
592
  } else {
593
593
  if (0 == sceneLoader.toBeDownloaded) {
594
594
  zincCameraControls.update(delta);
595
- rootRegion.renderGeometries(playRate, delta, playAnimation, options, true);
595
+ rootRegion.renderGeometries(playRate, delta, playAnimation, zincCameraControls, options, true);
596
596
  } else {
597
597
  zincCameraControls.update(0);
598
598
  }
@@ -16,7 +16,7 @@ const SceneExporter = function (sceneIn) {
16
16
  const animations = [];
17
17
  zincObjects.forEach(zincObject => {
18
18
  if (zincObject.animationClip) {
19
- animations.push({clip: zincObject.animationClip[0], mesh: zincObject.morph});
19
+ animations.push({clip: zincObject.animationClip[0], mesh: zincObject.getMorph()});
20
20
  }
21
21
  });
22
22
  const exporter = new GLTFExporter();