zincjs 2.2.1 → 2.3.1-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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zincjs",
3
- "version": "2.2.1",
3
+ "version": "2.3.1-beta.0",
4
4
  "description": "ZincJS (Web-based-Zinc-Visualisation)",
5
5
  "type": "module",
6
6
  "main": "build/zinc.js",
@@ -46,7 +46,11 @@
46
46
  },
47
47
  "homepage": "http://alan-wu.github.io/ZincJS/",
48
48
  "engines": {
49
- "node": ">=20"
49
+ "node": "24.20.0"
50
+ },
51
+ "allowScripts": {
52
+ "gl@8.1.6": true,
53
+ "msw@2.14.6": true
50
54
  },
51
55
  "devDependencies": {
52
56
  "@vitest/coverage-v8": "^4.1.11",
@@ -64,7 +68,7 @@
64
68
  "css-element-queries": "^1.2.2",
65
69
  "lodash": "^4.17.19",
66
70
  "nifti-reader-js": "0.8.0",
67
- "three": "^0.130.1",
71
+ "three": "^0.185.1",
68
72
  "three-spritetext": "1.6.2"
69
73
  }
70
74
  }
@@ -228,7 +228,7 @@ function getTransformationFromHeader(header, options) {
228
228
  }
229
229
 
230
230
  function createDataTexture(data, width, height, depth, isRGB) {
231
- const dataTexture = new THREE.DataTexture2DArray(
231
+ const dataTexture = new THREE.DataArrayTexture(
232
232
  data, width, height, depth);
233
233
  dataTexture.anisotropy = 4;
234
234
  if (!isRGB) {
package/src/minimap.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as THREE from 'three';
2
+ import { copyVector3sArray } from "./utilities";
2
3
 
3
4
  /**
4
5
  * This provide a full scale minimap. It will always
@@ -66,8 +67,7 @@ const Minimap = function (sceneIn) {
66
67
  let v3 = new THREE.Vector3(1, 1, target.z).unproject(targetScene.camera);
67
68
  let v4 = new THREE.Vector3(-1, 1, target.z).unproject(targetScene.camera);
68
69
  let array = [v1, v2, v3, v3, v4, v1];
69
- positionAttributes.copyVector3sArray(array);
70
- positionAttributes.needsUpdate = true;
70
+ copyVector3sArray(positionAttributes, array);
71
71
  }
72
72
 
73
73
  this.updateCamera = () => {
@@ -2,27 +2,44 @@
2
2
  /**
3
3
  * Provide additional shaders to render time dependent color.
4
4
  */
5
- const augmentMorphColor = function() {
6
- return function(shader) {
7
- shader.vertexShader = shader.vertexShader.replace(
8
- '#include <color_pars_vertex>',
9
- [
10
- 'varying vec3 vColor;',
11
- 'attribute vec3 morphColor0;',
12
- 'attribute vec3 morphColor1;'
13
- ].join( '\n' )
14
- );
15
- shader.vertexShader = shader.vertexShader.replace(
16
- '#include <color_vertex>',
17
- [
18
- 'vColor.xyz = color.xyz;',
19
- '#ifdef USE_MORPHTARGETS',
20
- 'vColor = morphColor0 * morphTargetInfluences[ 0 ];',
21
- 'vColor += morphColor1 * morphTargetInfluences[ 1 ];',
22
- '#endif'
23
- ].join( '\n' )
24
- );
25
- };
5
+
6
+ const augmentMorphColor = function(shader) {
7
+ shader.vertexShader = shader.vertexShader.replace(
8
+ '#include <morphcolor_vertex>',
9
+ `
10
+ #if defined( USE_MORPHCOLORS )
11
+
12
+ // morphTargetBaseInfluence is set based on BufferGeometry.morphTargetsRelative value:
13
+ // When morphTargetsRelative is false, this is set to 1 - sum(influences); this results in normal = sum((target - base) * influence)
14
+ // When morphTargetsRelative is true, this is set to 1; as a result, all morph targets are simply added to the base after weighting
15
+ vColor *= morphTargetBaseInfluence;
16
+
17
+ for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {
18
+
19
+ #if defined( USE_COLOR_ALPHA )
20
+
21
+ if ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];
22
+
23
+ #elif defined( USE_COLOR )
24
+
25
+ if ( morphTargetInfluences[ i ] != 0.0 ) {
26
+ vColor.rgb += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];
27
+ vColor.a = 1.0;
28
+ }
29
+
30
+ #endif
31
+
32
+ }
33
+
34
+ #endif
35
+ `
36
+ );
26
37
  }
27
38
 
28
- export { augmentMorphColor };
39
+ const printShader = function (shader) {
40
+ console.log(shader.vertexShader);
41
+ console.log(shader.fragmentShader);
42
+ }
43
+
44
+
45
+ export { augmentMorphColor, printShader };
@@ -8,53 +8,36 @@ const createMeshForGeometry = (geometryIn, materialIn, options) => {
8
8
  let geometry = toBufferGeometry(geometryIn, options);
9
9
 
10
10
  let isTransparent = false;
11
- if (1.0 > options.opacity)
12
- isTransparent = true;
13
-
11
+ if (1.0 > options.opacity) {
12
+ isTransparent = true;
13
+ }
14
14
  let material = undefined;
15
15
  if (geometry._video === undefined) {
16
- const morphTargets = options.localTimeEnabled || options.localMorphColour;
17
16
  if (materialIn) {
18
17
  material = materialIn;
19
- material.morphTargets = morphTargets;
20
- material.morphNormals = options.localTimeEnabled;
21
18
  } else {
22
- if (geometry instanceof THREE.BufferGeometry && geometry.attributes.color === undefined) {
23
- material = new THREE.MeshPhongMaterial({
24
- color : options.colour,
25
- morphTargets : morphTargets,
26
- morphNormals : options.localTimeEnabled,
27
- transparent : isTransparent,
28
- opacity : options.opacity,
29
- side : THREE.DoubleSide
30
- });
31
- } else {
32
- material = new THREE.MeshPhongMaterial({
33
- color : options.colour,
34
- morphTargets : morphTargets,
35
- morphNormals : options.localTimeEnabled,
36
- vertexColors : THREE.VertexColors,
37
- transparent : isTransparent,
38
- opacity : options.opacity,
39
- side : THREE.DoubleSide
40
- });
41
- }
19
+ material = new THREE.MeshPhongMaterial({
20
+ color : options.colour,
21
+ vertexColors : false,
22
+ transparent : isTransparent,
23
+ opacity : options.opacity,
24
+ side : THREE.DoubleSide
25
+ });
42
26
  }
43
27
  //material = PhongToToon(material);
44
28
  if (options.localMorphColour && geometry.morphAttributes[ "color" ]) {
45
- material.onBeforeCompile = augmentMorphColor();
29
+ material.vertexColors = true;
30
+ material.onBeforeCompile = augmentMorphColor;
46
31
  }
47
32
  } else {
48
33
  let videoTexture = geometry._video.createCanvasVideoTexture();
49
34
  material = new THREE.MeshBasicMaterial({
50
- morphTargets : options.localTimeEnabled,
51
35
  color : new THREE.Color(1, 1, 1),
52
36
  transparent : isTransparent,
53
37
  opacity : options.opacity,
54
38
  map : videoTexture,
55
39
  side : THREE.DoubleSide
56
40
  });
57
- this.videoHandler = geometry._video;
58
41
  }
59
42
  return new THREE.Mesh(geometry, material);
60
43
  }
@@ -92,6 +75,7 @@ const Geometry = function () {
92
75
  if (this.morph && this.morph.geometry && (geometryIn != undefined))
93
76
  return;
94
77
  const mesh = createMeshForGeometry(geometryIn, materialIn, options);
78
+ this.videoHandler = mesh.geometry._video;
95
79
  this.setMesh(mesh, options.localTimeEnabled, options.localMorphColour);
96
80
  }
97
81
 
@@ -160,6 +144,17 @@ const Geometry = function () {
160
144
  }
161
145
  }
162
146
 
147
+ /**
148
+ * Check if the geometry is time varying.
149
+ *
150
+ * @return {Boolean}
151
+ */
152
+ this.isTimeVarying = function() {
153
+ if (this.timeEnabled || this.morphColour || this.videoHandler)
154
+ return true;
155
+ return false;
156
+ }
157
+
163
158
 
164
159
  }
165
160
 
@@ -295,6 +295,8 @@ const Glyphset = function () {
295
295
  }
296
296
  }
297
297
  this.morph.instanceMatrix.needsUpdate = true;
298
+ this.boundingBoxUpdateRequired = true;
299
+ this.morph.computeBoundingSphere();
298
300
  };
299
301
 
300
302
  /**
@@ -372,7 +374,6 @@ const Glyphset = function () {
372
374
  }
373
375
  updateGlyphsetTransformation(current_positions, current_axis1s, current_axis2s, current_axis3s,
374
376
  current_scales);
375
- this.boundingBoxUpdateRequired = true;
376
377
  if (colors != undefined) {
377
378
  if (morphColours) {
378
379
  const bottom_colors = colors[bottom_frame.toString()];
@@ -472,7 +473,6 @@ const Glyphset = function () {
472
473
  updateGlyphsetHexColors(colors["0"]);
473
474
  }
474
475
  this.ready = true;
475
- this.boundingBoxUpdateRequired = true;
476
476
  };
477
477
 
478
478
  /**
@@ -1,3 +1,4 @@
1
+ import * as THREE from 'three';
1
2
  import SpriteTextModule from 'three-spritetext';
2
3
  const SpriteText = SpriteTextModule.default || SpriteTextModule;
3
4
 
@@ -24,8 +25,12 @@ const Label = function (textIn, colourIn) {
24
25
  else
25
26
  sprite = new SpriteText(text, 0.012);
26
27
  sprite.fontFace = "Asap";
28
+ sprite.fontSize = 90;
27
29
  sprite.fontWeight = fontWeight;
28
- sprite.material.map.generateMipmaps = false;
30
+ sprite.material.map.generateMipmaps = true;
31
+ sprite.material.map.anisotropy = 4;
32
+ sprite.material.minFilter = THREE.LinearMipmapLinearFilter; // Smooth downscaling
33
+ sprite.material.magFilter = THREE.LinearFilter;
29
34
  sprite.material.sizeAttenuation = false;
30
35
  sprite.center.x = -0.05;
31
36
  sprite.center.y = 0;
@@ -31,8 +31,10 @@ const Lines = function () {
31
31
  this.createLineSegment = (geometryIn, materialIn, options) => {
32
32
  if (geometryIn && materialIn) {
33
33
  let geometry = toBufferGeometry(geometryIn, options);
34
- if (options.localMorphColour && geometry.morphAttributes[ "color" ])
35
- materialIn.onBeforeCompile = augmentMorphColor();
34
+ if (options.localMorphColour && geometry.morphAttributes[ "color" ]) {
35
+ materialIn.vertexColors = true;
36
+ materialIn.onBeforeCompile = augmentMorphColor;
37
+ }
36
38
  let line = new LineSegments(geometry, materialIn);
37
39
  this.setMesh(line, options.localTimeEnabled, options.localMorphColour);
38
40
  }
@@ -3,6 +3,7 @@ import { Label } from './label';
3
3
  import { Points } from '../three/Points';
4
4
  import { ZincObject } from './zincObject';
5
5
  import { getCircularTexture, toBufferGeometry } from '../utilities';
6
+ import { augmentMorphColor } from './augmentShader';
6
7
 
7
8
  /**
8
9
  * Provides an object which stores points and provides method which controls its position.
@@ -36,11 +37,15 @@ const Pointset = function () {
36
37
  this.createMesh = (geometryIn, materialIn, options) => {
37
38
  if (geometryIn && materialIn) {
38
39
  let geometry = toBufferGeometry(geometryIn, options);
40
+ console.log(geometry, options)
41
+ if (options.localMorphColour && geometry.morphAttributes[ "color" ]) {
42
+ materialIn.vertexColors = true;
43
+ materialIn.onBeforeCompile = augmentMorphColor;
44
+ }
39
45
  const texture = getCircularTexture();
40
46
  materialIn.map = texture;
41
47
  let point = new Points(geometry, materialIn);
42
- this.setMesh(point, options.localTimeEnabled,
43
- options.localMorphColour);
48
+ this.setMesh(point, options.localTimeEnabled, options.localMorphColour);
44
49
  }
45
50
  }
46
51
 
@@ -45,7 +45,6 @@ const ZincObject = function() {
45
45
  this.duration = 6000;
46
46
  this.clipAction = undefined;
47
47
  this.userData = {};
48
- this.videoHandler = undefined;
49
48
  this.marker = undefined;
50
49
  this.markerNumber = undefined;
51
50
  this.markerUpdateRequired = true;
package/src/region.js CHANGED
@@ -816,8 +816,6 @@ let Region = function (parentIn, sceneIn) {
816
816
  const zincGeometry = new Geometry();
817
817
  const material = new THREE.MeshPhongMaterial({
818
818
  color : colour,
819
- morphTargets : false,
820
- morphNormals : false,
821
819
  transparent : true,
822
820
  opacity : opacity,
823
821
  side : THREE.DoubleSide
package/src/renderer.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as THREE from 'three';
2
+ //import { WebGPURenderer } from 'three/webgpu';
2
3
  import { ResizeSensor } from 'css-element-queries';
3
4
  import { Scene } from './scene';
4
5
  /**
@@ -130,7 +131,11 @@ const Renderer = function (containerIn) {
130
131
  container = undefined;
131
132
  canvas = parameters["canvas"];
132
133
  }
133
- renderer = new THREE.WebGLRenderer(parameters);
134
+ //parameters["forceWebGL"] = true;
135
+ //renderer = new WebGPURenderer(parameters);
136
+ //await renderer.init();
137
+
138
+ renderer = new THREE.WebGLRenderer(parameters);
134
139
  if (container !== undefined) {
135
140
  container.appendChild( renderer.domElement );
136
141
  }
package/src/scene.js CHANGED
@@ -157,7 +157,7 @@ const Scene = function (containerIn, rendererIn) {
157
157
  this.ambient = new THREE.AmbientLight(0xffffff, 0.2);
158
158
  scene.add(this.ambient);
159
159
 
160
- this.directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
160
+ this.directionalLight = new THREE.DirectionalLight(0xffffff, 0.7 * Math.PI);
161
161
  scene.add(this.directionalLight);
162
162
  zincCameraControls = new CameraControls(this.camera, rendererIn.domElement, rendererIn, this);
163
163
 
@@ -625,8 +625,6 @@ const Scene = function (containerIn, rendererIn) {
625
625
  zincCameraControls.update(0);
626
626
  }
627
627
  //console.log(videoHandler.video.currentTime / videoHandler.getVideoDuration() * 6000);
628
- } else {
629
- myPlayRate = 0;
630
628
  }
631
629
  } else {
632
630
  if (0 == sceneLoader.toBeDownloaded) {
@@ -158,7 +158,7 @@ const SceneLoader = function (sceneIn) {
158
158
  let localTimeEnabled = 0;
159
159
  if (timeEnabled != undefined && timeEnabled[i] != undefined)
160
160
  localTimeEnabled = timeEnabled[i] ? true : false;
161
- let localMorphColour = 0;
161
+ let localMorphColour = false;
162
162
  if (morphColour != undefined && morphColour[i] != undefined)
163
163
  localMorphColour = morphColour[i] ? true : false;
164
164
  primitivesLoader.load(filename, meshloader(region, colour, opacity, localTimeEnabled, localMorphColour, undefined, undefined,
@@ -218,7 +218,6 @@ const SceneLoader = function (sceneIn) {
218
218
  material.transparent = true;
219
219
  }
220
220
  material.opacity = materials[0].opacity;
221
- material.morphTargets = localTimeEnabled;
222
221
  material.vertexColors = materials[0].vertexColors;
223
222
  }
224
223
  let options = {};
@@ -361,15 +360,19 @@ const SceneLoader = function (sceneIn) {
361
360
  const pointsetloader = (region, localTimeEnabled, localMorphColour, groupName, anatomicalId, renderOrder, finishCallback) => {
362
361
  return (geometry, materials) => {
363
362
  const newPointset = new Pointset();
364
- let material = new THREE.PointsMaterial({ alphaTest: 0.5, size: 10, sizeAttenuation: false });
363
+ let material = new THREE.PointsMaterial(
364
+ {
365
+ alphaTest: 0.05,
366
+ size: 10,
367
+ sizeAttenuation: false,
368
+ });
365
369
  if (materials && materials[0]) {
366
370
  if (1.0 > materials[0].opacity) {
367
371
  material.transparent = true;
368
372
  }
369
373
  material.opacity = materials[0].opacity;
370
374
  material.color = materials[0].color;
371
- material.morphTargets = localTimeEnabled;
372
- material.vertexColors = materials[0].vertexColors;
375
+ material.vertexColors = false;
373
376
  }
374
377
  let options = {};
375
378
  options.localTimeEnabled = localTimeEnabled;
@@ -638,8 +641,9 @@ const SceneLoader = function (sceneIn) {
638
641
  newGeometry.setDuration(scene.getDuration());
639
642
  if (finishCallback != undefined && (typeof finishCallback == 'function'))
640
643
  finishCallback(newGeometry);
641
- if (newGeometry.videoHandler)
644
+ if (newGeometry.videoHandler) {
642
645
  scene.setVideoHandler(newGeometry.videoHandler);
646
+ }
643
647
  return newGeometry;
644
648
  }
645
649
  return undefined;
@@ -48,7 +48,7 @@ const TextureArray = function () {
48
48
  length += data.length;
49
49
  });
50
50
 
51
- this.impl = new THREE.DataTexture2DArray(fullArray, w, h, d);
51
+ this.impl = new THREE.DataArrayTexture(fullArray, w, h, d);
52
52
  this.size = {
53
53
  width: w,
54
54
  height: h,
@@ -13,6 +13,12 @@ import {
13
13
  Vector2,
14
14
  Vector3
15
15
  } from 'three';
16
+ import {
17
+ copyColorsArray,
18
+ copyVector2sArray,
19
+ copyVector3sArray,
20
+ copyVector4sArray
21
+ } from "../utilities";
16
22
 
17
23
  const _m1 = new Matrix4();
18
24
  const _obj = new Object3D();
@@ -585,9 +591,9 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
585
591
  this.morphTargets[i].normals = new Array( this.vertices.length );
586
592
 
587
593
  for ( let v = 0; v < vertexNormals.length; v ++ ) {
588
-
594
+
589
595
  this.morphTargets[i].normals[ v ] = vertexNormals[v].clone();
590
-
596
+
591
597
  }
592
598
  }
593
599
 
@@ -668,25 +674,25 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
668
674
  for ( let k = 0, kl = morphTarget2.vertices.length; k < kl; k ++ ) {
669
675
 
670
676
  const vertex = morphTarget2.vertices[ k ];
671
-
677
+
672
678
  const vertexCopy = vertex.clone();
673
-
679
+
674
680
  if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );
675
-
681
+
676
682
  morphTarget1.vertices.push( vertexCopy );
677
-
683
+
678
684
  }
679
685
 
680
686
  if ( morphTarget1.normals && morphTarget2.normals ) {
681
-
687
+
682
688
  for ( let k = 0; k < morphTarget2.normals.length; k = k + 3) {
683
689
 
684
690
  _temp.set(morphTarget2.normals2[k], morphTarget2.normals2[k + 1], morphTarget2.normals2[k + 2]);
685
-
691
+
686
692
  if ( matrix !== undefined ) _temp.applyMatrix4( matrix );
687
-
693
+
688
694
  morphTarget1.normals.push(_temp.x, _temp.y, _temp.z);
689
-
695
+
690
696
  }
691
697
 
692
698
  }
@@ -705,7 +711,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
705
711
  for ( let k = 0, kl = morphColor2.colors; k < kl; k ++ ) {
706
712
 
707
713
  morphColor1.colors.push( morphColor2.colors[ k ].clone() );
708
-
714
+
709
715
  }
710
716
 
711
717
  }
@@ -1519,33 +1525,33 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
1519
1525
  const buffergeometry = new BufferGeometry();
1520
1526
 
1521
1527
  const positions = new Float32Array( geometry.vertices.length * 3 );
1522
- buffergeometry.setAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );
1528
+ buffergeometry.setAttribute( 'position', copyVector3sArray(new BufferAttribute( positions, 3 ), geometry.vertices ) );
1523
1529
 
1524
1530
  if ( geometry.normals.length > 0 ) {
1525
1531
 
1526
1532
  const normals = new Float32Array( geometry.normals.length * 3 );
1527
- buffergeometry.setAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );
1533
+ buffergeometry.setAttribute( 'normal', copyVector3sArray(new BufferAttribute( normals, 3 ), geometry.normals ) );
1528
1534
 
1529
1535
  }
1530
1536
 
1531
1537
  if ( geometry.colors.length > 0 ) {
1532
1538
 
1533
1539
  const colors = new Float32Array( geometry.colors.length * 3 );
1534
- buffergeometry.setAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );
1540
+ buffergeometry.setAttribute( 'color', copyVector3sArray(new BufferAttribute( colors, 3 ), geometry.colors ) );
1535
1541
 
1536
1542
  }
1537
1543
 
1538
1544
  if ( geometry.uvs.length > 0 ) {
1539
1545
 
1540
1546
  const uvs = new Float32Array( geometry.uvs.length * 2 );
1541
- buffergeometry.setAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );
1547
+ buffergeometry.setAttribute( 'uv', copyVector2sArray(new BufferAttribute( uvs, 2 ), geometry.uvs ) );
1542
1548
 
1543
1549
  }
1544
1550
 
1545
1551
  if ( geometry.uvs2.length > 0 ) {
1546
1552
 
1547
1553
  const uvs2 = new Float32Array( geometry.uvs2.length * 2 );
1548
- buffergeometry.setAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );
1554
+ buffergeometry.setAttribute( 'uv2', copyVector2sArray(new BufferAttribute( uvs2, 2 ), geometry.uvs2 ) );
1549
1555
 
1550
1556
  }
1551
1557
 
@@ -1567,7 +1573,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
1567
1573
  const attribute = new Float32BufferAttribute( morphTarget.data.length * 3, 3 );
1568
1574
  attribute.name = morphTarget.name;
1569
1575
 
1570
- array.push( attribute.copyVector3sArray( morphTarget.data ) );
1576
+ array.push( copyVector3sArray(attribute, morphTarget.data ) );
1571
1577
 
1572
1578
  }
1573
1579
 
@@ -1580,14 +1586,16 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
1580
1586
  if ( geometry.skinIndices.length > 0 ) {
1581
1587
 
1582
1588
  const skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );
1583
- buffergeometry.setAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );
1589
+ copyVector4sArray(skinIndices, geometry.skinIndices);
1590
+ buffergeometry.setAttribute( 'skinIndex', skinIndices);
1584
1591
 
1585
1592
  }
1586
1593
 
1587
1594
  if ( geometry.skinWeights.length > 0 ) {
1588
1595
 
1589
1596
  const skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );
1590
- buffergeometry.setAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );
1597
+ copyVector4sArray(skinWeights, geometry.skinWeights);
1598
+ buffergeometry.setAttribute( 'skinWeight', skinWeights );
1591
1599
 
1592
1600
  }
1593
1601
 
@@ -1616,7 +1624,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
1616
1624
  const buffergeometry = new BufferGeometry();
1617
1625
 
1618
1626
  const positions = new Float32Array( this.vertices.length * 3 );
1619
- buffergeometry.setAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( this.vertices ) );
1627
+ buffergeometry.setAttribute( 'position', copyVector3sArray(new BufferAttribute( positions, 3 ), this.vertices ) );
1620
1628
 
1621
1629
  if ( this.normals.length > 0 ) {
1622
1630
  const normals = new Float32Array( this.normals.length );
@@ -1641,7 +1649,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
1641
1649
  colorArray.push(new Color( this.colors[ i ] ));
1642
1650
  }
1643
1651
  const colors = new Float32Array( colorArray.length * 3 );
1644
- buffergeometry.setAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( colorArray ) );
1652
+ buffergeometry.setAttribute( 'color', copyColorsArray(new BufferAttribute( colors, 3 ), colorArray ) );
1645
1653
 
1646
1654
  } else {
1647
1655
 
@@ -1650,7 +1658,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
1650
1658
  colorsArray[i] = 1.0;
1651
1659
  }
1652
1660
  buffergeometry.setAttribute( 'color', new BufferAttribute( colorsArray, 3 ) );
1653
-
1661
+
1654
1662
  }
1655
1663
 
1656
1664
  if (this.faces.length > 0) {
@@ -1664,17 +1672,17 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
1664
1672
  indices.push(this.faces[i].a, this.faces[i].b, this.faces[i].c);
1665
1673
 
1666
1674
  const vertexColors = this.faces[i].vertexColors;
1667
-
1675
+
1668
1676
  if ( vertexColors.length === 3 ) {
1669
-
1677
+
1670
1678
  colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );
1671
-
1679
+
1672
1680
  } else {
1673
-
1681
+
1674
1682
  const color = this.faces[i].color;
1675
-
1683
+
1676
1684
  colors.push( color, color, color );
1677
-
1685
+
1678
1686
  }
1679
1687
 
1680
1688
  }
@@ -1683,7 +1691,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
1683
1691
 
1684
1692
  // const colorsArray = new Float32Array( colors.length * 3 );
1685
1693
  // buffergeometry.setAttribute( 'color', new BufferAttribute( colorsArray, 3 ).copyColorsArray( colors ) );
1686
-
1694
+
1687
1695
  // }
1688
1696
 
1689
1697
  buffergeometry.setIndex( indices );
@@ -1706,7 +1714,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
1706
1714
  const attribute = new Float32BufferAttribute( morphTarget.vertices.length * 3, 3 );
1707
1715
  attribute.name = morphTarget.name;
1708
1716
 
1709
- array.push( attribute.copyVector3sArray( morphTarget.vertices ) );
1717
+ array.push( copyVector3sArray(attribute, morphTarget.vertices ) );
1710
1718
 
1711
1719
  if (morphTarget.normals) {
1712
1720
 
@@ -1714,8 +1722,8 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
1714
1722
  const attribute = new Float32BufferAttribute( morphTarget.normals.length * 3, 3 );
1715
1723
  attribute.name = morphTarget.name;
1716
1724
 
1717
- normalsArray.push( attribute.copyVector3sArray( morphTarget.normals ) );
1718
-
1725
+ normalsArray.push( copyVector3sArray(attribute, morphTarget.normals ) );
1726
+
1719
1727
  }
1720
1728
 
1721
1729
  }
@@ -1795,10 +1803,13 @@ Geometry.createBufferGeometryFromObject = function ( object ) {
1795
1803
  if ( object.isPoints || object.isLine ) {
1796
1804
 
1797
1805
  const positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );
1806
+ copyVector3sArray(positions, geometry.vertices );
1807
+
1798
1808
  const colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );
1809
+ copyColorsArray(colors, geometry.colors);
1799
1810
 
1800
- buffergeometry.setAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );
1801
- buffergeometry.setAttribute( 'color', colors.copyColorsArray( geometry.colors ) );
1811
+ buffergeometry.setAttribute( 'position', positions );
1812
+ buffergeometry.setAttribute( 'color', colors );
1802
1813
 
1803
1814
  if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {
1804
1815
 
@@ -308,6 +308,7 @@ Object.assign( Loader.prototype, {
308
308
  case 'opacity':
309
309
  case 'reflectivity':
310
310
  case 'transparent':
311
+ case 'video':
311
312
  case 'visible':
312
313
  case 'wireframe':
313
314
  json[ name ] = value;