zincjs 1.0.13 → 1.0.15

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 (45) hide show
  1. package/build/zinc.frontend.js +1 -1
  2. package/build/zinc.js +43 -35
  3. package/build/zinc.js.map +1 -1
  4. package/package.json +3 -3
  5. package/src/assets/disc.png +0 -0
  6. package/src/assets/mapMarker.svg +11 -0
  7. package/src/controls.js +1594 -0
  8. package/src/geometryCSG.js +148 -0
  9. package/src/glyphsetCSG.js +84 -0
  10. package/src/loaders/GLTFToZincJSLoader.js +85 -0
  11. package/src/loaders/JSONLoader.js +697 -0
  12. package/src/loaders/OBJLoader.js +911 -0
  13. package/src/loaders/STLLoader.js +399 -0
  14. package/src/loaders/primitivesLoader.js +46 -0
  15. package/src/minimap.js +82 -0
  16. package/src/primitives/augmentShader.js +22 -0
  17. package/src/primitives/geometry.js +109 -0
  18. package/src/primitives/glyph.js +150 -0
  19. package/src/primitives/glyphset.js +657 -0
  20. package/src/primitives/label.js +51 -0
  21. package/src/primitives/lines.js +35 -0
  22. package/src/primitives/marker.js +88 -0
  23. package/src/primitives/pointset.js +53 -0
  24. package/src/primitives/texturePrimitive.js +16 -0
  25. package/src/primitives/textureSlides.js +118 -0
  26. package/src/primitives/zincObject.js +573 -0
  27. package/src/region.js +554 -0
  28. package/src/renderer.js +612 -0
  29. package/src/scene.js +963 -0
  30. package/src/sceneExporter.js +32 -0
  31. package/src/sceneLoader.js +842 -0
  32. package/src/texture/texture.js +57 -0
  33. package/src/texture/textureArray.js +85 -0
  34. package/src/three/GLTFExporter.js +2448 -0
  35. package/src/three/Geometry.js +2084 -0
  36. package/src/three/Loader.js +344 -0
  37. package/src/three/Points.js +223 -0
  38. package/src/three/line/Line.js +293 -0
  39. package/src/three/line/LineSegments.js +65 -0
  40. package/src/three-js-csg.js +564 -0
  41. package/src/utilities.js +321 -0
  42. package/src/videoHandler.js +92 -0
  43. package/src/workers/geometryCSG.worker.js +73 -0
  44. package/src/workers/geometryCSGInternal.js +58 -0
  45. package/src/zinc.js +38 -0
@@ -0,0 +1,321 @@
1
+ const THREE = require('three');
2
+
3
+ function resolveURL(url) {
4
+ let actualURL = url;
5
+ const prefix = (require("./zinc").modelPrefix);
6
+
7
+ if (prefix) {
8
+ if (prefix[prefix.length -1] != '/')
9
+ prefix = prefix + '/';
10
+ const r = new RegExp('^(?:[a-z]+:)?//', 'i');
11
+ if (!r.test(url)) {
12
+ actualURL = prefix + url;
13
+ }
14
+ }
15
+
16
+ return actualURL;
17
+ }
18
+
19
+ //Convenient function
20
+ function loadExternalFile(url, data, callback, errorCallback) {
21
+ // Set up an asynchronous request
22
+ const request = new XMLHttpRequest();
23
+ request.open('GET', resolveURL(url), true);
24
+
25
+ // Hook the event that gets called as the request progresses
26
+ request.onreadystatechange = () => {
27
+ // If the request is "DONE" (completed or failed)
28
+ if (request.readyState == 4) {
29
+ // If we got HTTP status 200 (OK)
30
+ if (request.status == 200) {
31
+ callback(request.responseText, data)
32
+ } else { // Failed
33
+ errorCallback(url);
34
+ }
35
+ }
36
+ };
37
+
38
+ request.send(null);
39
+ }
40
+
41
+ function loadExternalFiles(urls, callback, errorCallback) {
42
+ const numUrls = urls.length;
43
+ let numComplete = 0;
44
+ const result = [];
45
+
46
+ // Callback for a single file
47
+ function partialCallback(text, urlIndex) {
48
+ result[urlIndex] = text;
49
+ numComplete++;
50
+
51
+ // When all files have downloaded
52
+ if (numComplete == numUrls) {
53
+ callback(result);
54
+ }
55
+ }
56
+
57
+ for (let i = 0; i < numUrls; i++) {
58
+ loadExternalFile(urls[i], i, partialCallback, errorCallback);
59
+ }
60
+ }
61
+
62
+
63
+ //Get the colours at index
64
+ exports.getColorsRGB = (colors, index) => {
65
+ const index_in_colors = Math.floor(index/3);
66
+ const remainder = index%3;
67
+ let hex_value = 0;
68
+ if (remainder == 0)
69
+ {
70
+ hex_value = colors[index_in_colors].r;
71
+ }
72
+ else if (remainder == 1)
73
+ {
74
+ hex_value = colors[index_in_colors].g;
75
+ }
76
+ else if (remainder == 2)
77
+ {
78
+ hex_value = colors[index_in_colors].b;
79
+ }
80
+ const mycolor = new THREE.Color(hex_value);
81
+ return [mycolor.r, mycolor.g, mycolor.b];
82
+ }
83
+
84
+
85
+ exports.copyMorphColorsToBufferGeometry = (geometry, bufferGeometry) => {
86
+ if (geometry && geometry.morphColors && geometry.morphColors.length > 0 ) {
87
+ let array = [];
88
+ let morphColors = geometry.morphColors;
89
+ const getColorsRGB = require("./utilities").getColorsRGB;
90
+ for ( var i = 0, l = morphColors.length; i < l; i ++ ) {
91
+ let morphColor = morphColors[ i ];
92
+ let colorArray = [];
93
+ for ( var j = 0; j < geometry.faces.length; j ++ ) {
94
+ let face = geometry.faces[j];
95
+ let color = getColorsRGB(morphColor.colors, face.a);
96
+ colorArray.push(color[0], color[1], color[2]);
97
+ color = getColorsRGB(morphColor.colors, face.b);
98
+ colorArray.push(color[0], color[1], color[2]);
99
+ color = getColorsRGB(morphColor.colors, face.c);
100
+ colorArray.push(color[0], color[1], color[2]);
101
+ }
102
+ var attribute = new THREE.Float32BufferAttribute( geometry.faces.length * 3 * 3, 3 );
103
+ attribute.name = morphColor.name;
104
+ array.push( attribute.copyArray( colorArray ) );
105
+ }
106
+ bufferGeometry.morphAttributes[ "color" ] = array;
107
+ }
108
+ }
109
+
110
+
111
+ exports.copyMorphColorsToIndexedBufferGeometry = (geometry, bufferGeometry) => {
112
+ if (geometry && geometry.morphColors && geometry.morphColors.length > 0 ) {
113
+ let array = [];
114
+ let morphColors = geometry.morphColors;
115
+ const getColorsRGB = require("./utilities").getColorsRGB;
116
+ for ( let i = 0, l = morphColors.length; i < l; i ++ ) {
117
+ const morphColor = morphColors[ i ];
118
+ const colorArray = [];
119
+ for ( let j = 0; j < morphColor.colors.length * 3; j ++ ) {
120
+ let color = getColorsRGB(morphColor.colors, j);
121
+ colorArray.push(color[0], color[1], color[2]);
122
+ }
123
+ const attribute = new THREE.Float32BufferAttribute( colorArray, 3 );
124
+ attribute.name = morphColor.name;
125
+ array.push( attribute );
126
+ }
127
+ bufferGeometry.morphAttributes[ "color" ] = array;
128
+ }
129
+ }
130
+
131
+ exports.mergeVertices = ( geometry, tolerance = 1e-4 ) => {
132
+
133
+ tolerance = Math.max( tolerance, Number.EPSILON );
134
+
135
+ // Generate an index buffer if the geometry doesn't have one, or optimize it
136
+ // if it's already available.
137
+ var hashToIndex = {};
138
+ var indices = geometry.getIndex();
139
+ var positions = geometry.getAttribute( 'position' );
140
+ var vertexCount = indices ? indices.count : positions.count;
141
+
142
+ // next value for triangle indices
143
+ var nextIndex = 0;
144
+
145
+ // attributes and new attribute arrays
146
+ var attributeNames = Object.keys( geometry.attributes );
147
+ var attrArrays = {};
148
+ var morphAttrsArrays = {};
149
+ var newIndices = [];
150
+ var getters = [ 'getX', 'getY', 'getZ', 'getW' ];
151
+
152
+ // initialize the arrays
153
+ for ( var i = 0, l = attributeNames.length; i < l; i ++ ) {
154
+ var name = attributeNames[ i ];
155
+
156
+ attrArrays[ name ] = [];
157
+
158
+ var morphAttr = geometry.morphAttributes[ name ];
159
+ if ( morphAttr ) {
160
+
161
+ morphAttrsArrays[ name ] = new Array( morphAttr.length ).fill().map( () => [] );
162
+
163
+ }
164
+
165
+ }
166
+
167
+ // convert the error tolerance to an amount of decimal places to truncate to
168
+ var decimalShift = Math.log10( 1 / tolerance );
169
+ var shiftMultiplier = Math.pow( 10, decimalShift );
170
+ for ( var i = 0; i < vertexCount; i ++ ) {
171
+
172
+ var index = indices ? indices.getX( i ) : i;
173
+
174
+ // Generate a hash for the vertex attributes at the current index 'i'
175
+ var hash = '';
176
+ for ( var j = 0, l = attributeNames.length; j < l; j ++ ) {
177
+
178
+ var name = attributeNames[ j ];
179
+ var attribute = geometry.getAttribute( name );
180
+ var itemSize = attribute.itemSize;
181
+
182
+ for ( var k = 0; k < itemSize; k ++ ) {
183
+
184
+ // double tilde truncates the decimal value
185
+ hash += `${ ~ ~ ( attribute[ getters[ k ] ]( index ) * shiftMultiplier ) },`;
186
+
187
+ }
188
+
189
+ }
190
+
191
+ // Add another reference to the vertex if it's already
192
+ // used by another index
193
+ if ( hash in hashToIndex ) {
194
+
195
+ newIndices.push( hashToIndex[ hash ] );
196
+
197
+ } else {
198
+
199
+ // copy data to the new index in the attribute arrays
200
+ for ( var j = 0, l = attributeNames.length; j < l; j ++ ) {
201
+
202
+ var name = attributeNames[ j ];
203
+ var attribute = geometry.getAttribute( name );
204
+ var morphAttr = geometry.morphAttributes[ name ];
205
+ var itemSize = attribute.itemSize;
206
+ var newarray = attrArrays[ name ];
207
+ var newMorphArrays = morphAttrsArrays[ name ];
208
+
209
+ for ( var k = 0; k < itemSize; k ++ ) {
210
+
211
+ var getterFunc = getters[ k ];
212
+ newarray.push( attribute[ getterFunc ]( index ) );
213
+
214
+ if ( morphAttr ) {
215
+
216
+ for ( var m = 0, ml = morphAttr.length; m < ml; m ++ ) {
217
+
218
+ newMorphArrays[ m ].push( morphAttr[ m ][ getterFunc ]( index ) );
219
+
220
+ }
221
+
222
+ }
223
+
224
+ }
225
+
226
+ }
227
+
228
+ hashToIndex[ hash ] = nextIndex;
229
+ newIndices.push( nextIndex );
230
+ nextIndex ++;
231
+
232
+ }
233
+
234
+ }
235
+
236
+ // Generate typed arrays from new attribute arrays and update
237
+ // the attributeBuffers
238
+ const result = geometry.clone();
239
+ for ( var i = 0, l = attributeNames.length; i < l; i ++ ) {
240
+
241
+ var name = attributeNames[ i ];
242
+ var oldAttribute = geometry.getAttribute( name );
243
+ var attribute;
244
+
245
+ var buffer = new oldAttribute.array.constructor( attrArrays[ name ] );
246
+ if ( oldAttribute.isInterleavedBufferAttribute ) {
247
+
248
+ attribute = new THREE.BufferAttribute( buffer, oldAttribute.itemSize, oldAttribute.itemSize );
249
+
250
+ } else {
251
+
252
+ attribute = geometry.getAttribute( name ).clone();
253
+ attribute.setArray( buffer );
254
+
255
+ }
256
+
257
+ result.setAttribute( name, attribute );
258
+
259
+ // Update the attribute arrays
260
+ if ( name in morphAttrsArrays ) {
261
+
262
+ for ( var j = 0; j < morphAttrsArrays[ name ].length; j ++ ) {
263
+
264
+ var morphAttribute = geometry.morphAttributes[ name ][ j ].clone();
265
+ morphAttribute.setArray( new morphAttribute.array.constructor( morphAttrsArrays[ name ][ j ] ) );
266
+ result.morphAttributes[ name ][ j ] = morphAttribute;
267
+
268
+ }
269
+
270
+ }
271
+
272
+ }
273
+
274
+ // Generate an index buffer typed array
275
+ var cons = Uint8Array;
276
+ if ( newIndices.length >= Math.pow( 2, 8 ) ) cons = Uint16Array;
277
+ if ( newIndices.length >= Math.pow( 2, 16 ) ) cons = Uint32Array;
278
+
279
+ var newIndexBuffer = new cons( newIndices );
280
+ var newIndices = null;
281
+ if ( indices === null ) {
282
+
283
+ newIndices = new THREE.BufferAttribute( newIndexBuffer, 1 );
284
+
285
+ } else {
286
+
287
+ newIndices = geometry.getIndex().clone();
288
+ newIndices.setArray( newIndexBuffer );
289
+
290
+ }
291
+
292
+ result.setIndex( newIndices );
293
+
294
+ return result;
295
+
296
+ }
297
+
298
+ function PhongToToon(materialIn) {
299
+ if (materialIn.isMeshPhongMaterial) {
300
+ let material = new THREE.MeshToonMaterial({
301
+ color : materialIn.color.clone(),
302
+ morphTargets : materialIn.morphTargets,
303
+ morphNormals : materialIn.morphNormals,
304
+ vertexColors : materialIn.vertexColors,
305
+ transparent : materialIn.transparent,
306
+ opacity : materialIn.opacity,
307
+ side : materialIn.side
308
+ });
309
+ if (materialIn.map)
310
+ material.map = materialIn.map;
311
+ return material;
312
+ }
313
+
314
+ return materialIn;
315
+ }
316
+
317
+
318
+ exports.resolveURL = resolveURL;
319
+ exports.loadExternalFile = loadExternalFile;
320
+ exports.loadExternalFiles = loadExternalFiles;
321
+ exports.PhongToToon = PhongToToon;
@@ -0,0 +1,92 @@
1
+ var THREE = require('three');
2
+
3
+
4
+ // Alan notes: pause video when stuck
5
+ //VideoTexture is used for creating and updating a video projected onto a Three.js texture
6
+ exports.VideoHandler = function(srcIn) {
7
+
8
+ var _this = this;
9
+ this.video = undefined;
10
+ this.videoTexture = undefined;
11
+ var src = srcIn;
12
+ var lastTime = 0;
13
+ var lastUpdate = 0;
14
+ var frameRate = 30;
15
+ var videoPlaneLoadedFlag = false;
16
+ var lastPlayPos = 0;
17
+ var currentPlayPos = 0;
18
+ var bufferingDetected = false;
19
+
20
+ var checkBuffering = function(delta, playAnimation) {
21
+ currentPlayPos = _this.video.currentTime;
22
+
23
+ // checking offset should be at most the check interval
24
+ // but allow for some margin
25
+ var offset = delta - 0.02;
26
+
27
+ // if no buffering is currently detected,
28
+ // and the position does not seem to increase
29
+ // and the _this.video isn't manually paused...
30
+ if (!bufferingDetected && (currentPlayPos < (lastPlayPos + offset)) &&
31
+ !_this.video.paused) {
32
+ bufferingDetected = true;
33
+ }
34
+
35
+ // if we were buffering but the _this.video has advanced,
36
+ // then there is no buffering
37
+ if (bufferingDetected && (currentPlayPos > (lastPlayPos + offset)) &&
38
+ !_this.video.paused) {
39
+ bufferingDetected = false;
40
+ }
41
+ lastPlayPos = currentPlayPos;
42
+ }
43
+
44
+ var initialise = function(){
45
+ if (document) {
46
+ _this.video = document.createElement( 'video' );
47
+ _this.video.crossOrigin = "anonymous";
48
+ _this.video.src = src;
49
+ _this.video.load();
50
+ _this.video.loop = true;
51
+
52
+ }
53
+ }
54
+
55
+ this.setMorphTime = function(time, duration){
56
+ var actualTime = time / duration * _this.video.duration;
57
+ _this.video.currentTime = actualTime;
58
+ }
59
+
60
+ // videoPlaneLoaded connects the video to the video texture once it has loaded
61
+ this.getVideoDuration = function() {
62
+ return _this.video.duration;
63
+ }
64
+
65
+ this.createCanvasVideoTexture = function(){
66
+ _this.videoTexture = new THREE.VideoTexture( _this.video );
67
+ _this.videoTexture.minFilter = THREE.LinearFilter;
68
+ _this.videoTexture.magFilter = THREE.LinearFilter;
69
+ _this.videoTexture.format = THREE.RGBFormat;
70
+ _this.video.currentTime = 0;
71
+ return _this.videoTexture;
72
+ }
73
+
74
+ this.getCurrentTime = function(duration) {
75
+ if (_this.video)
76
+ return duration * (_this.video.currentTime / _this.video.duration);
77
+ else
78
+ return 0;
79
+ }
80
+
81
+ this.isReadyToPlay = function(){
82
+ // video.readyState 3 means we have data to load for the current time and foreseeable future
83
+ if (_this.video && _this.video.readyState >= 3){
84
+ return true;
85
+ }
86
+ return false;
87
+ }
88
+
89
+ //this should be handle by scene... check the sync at
90
+ initialise();
91
+
92
+ }
@@ -0,0 +1,73 @@
1
+ const Geometry = require('../primitives/geometry').Geometry;
2
+ const THREE = require('three');
3
+ const JSONLoader = THREE.BufferGeometryLoader;
4
+
5
+ module.exports = function (self) {
6
+ let core = undefined;
7
+
8
+ var geometryFromJSON = function(object) {
9
+ var JSONParser = new JSONLoader();
10
+ var geometry = JSONParser.parse(object);
11
+ var material = new THREE.MeshPhongMaterial();
12
+ var mesh = new THREE.Mesh(geometry.geometry, material);
13
+ var host = new Geometry();
14
+ host.morph = mesh;
15
+ return host;
16
+ }
17
+
18
+ var initialise = function(object) {
19
+ var host = geometryFromJSON(object);
20
+ core = new (require('./geometryCSGInternal').GeometryCSGInternal)(host);
21
+ self.postMessage({action:"message", message: "Initialised"});
22
+ }
23
+
24
+ var intersect = function(object) {
25
+ if (core) {
26
+ var guest = geometryFromJSON(object);
27
+ var result = core.intersect(guest);
28
+ var json = result.toBufferGeometry().toJSON();
29
+ self.postMessage({action: "result", object: json});
30
+ }
31
+ }
32
+
33
+ var subtract = function(object) {
34
+ if (core) {
35
+ var guest = geometryFromJSON(object);
36
+ var result = core.subtract(guest);
37
+ var json = result.toBufferGeometry().toJSON();
38
+ self.postMessage({action: "result", object: json});
39
+ }
40
+ }
41
+
42
+ var union = function(object) {
43
+ if (core) {
44
+ var guest = geometryFromJSON(object);
45
+ var result = core.union(guest);
46
+ var json = result.toBufferGeometry().toJSON();
47
+ self.postMessage({action: "result", object: json});
48
+ }
49
+ }
50
+
51
+ self.addEventListener('message',function (ev){
52
+ switch (ev.data.action) {
53
+ case 'initialise':
54
+ initialise(ev.data.object);
55
+ break;
56
+ case 'intersect':
57
+ intersect(ev.data.object);
58
+ break;
59
+ case 'subtract':
60
+ subtract(ev.data.object);
61
+ break;
62
+ case 'union':
63
+ union(ev.data.object);
64
+ break;
65
+ default:
66
+ throw 'Cannot handle specified action.';
67
+ }
68
+ });
69
+
70
+ //var test = ev.data;
71
+ //self.postMessage(test, [test]);
72
+ };
73
+
@@ -0,0 +1,58 @@
1
+ const THREE = require('three');
2
+ const ThreeBSP = require('../three-js-csg')(THREE);
3
+ const Geometry = require('../primitives/geometry').Geometry;
4
+ const GeometryCSG = require('../geometryCSG').GeometryCSG;
5
+
6
+ const GeometryCSGInternal = function (hostIn) {
7
+ //ZincGeoemtry of the main geometry
8
+ let host = undefined;
9
+ if (hostIn && hostIn.isGeometry)
10
+ host = hostIn;
11
+ let hostCSG = undefined;
12
+
13
+ this.setGeometry = hostIn => {
14
+ if (hostIn && hostIn.isGeometry)
15
+ host = hostIn;
16
+ hostCSG = undefined;
17
+ }
18
+
19
+ this.setCSG = csg => {
20
+ hostCSG = csg;
21
+ }
22
+
23
+ const prepareCSG = guestGeometry => {
24
+ if (host && host.morph && guestGeometry && guestGeometry.morph) {
25
+ if (hostCSG === undefined)
26
+ hostCSG = new ThreeBSP(host.morph);
27
+ const guestCSG = new ThreeBSP(guestGeometry.morph);
28
+ return guestCSG;
29
+ }
30
+ return undefined;
31
+ };
32
+
33
+ this.intersect = guestGeometry => {
34
+ const guestCSG = prepareCSG(guestGeometry);
35
+ if (hostCSG && guestCSG) {
36
+ return hostCSG.intersect(guestCSG);
37
+ }
38
+ return undefined;
39
+ }
40
+
41
+ this.subtract = guestGeometry => {
42
+ const guestCSG = prepareCSG(guestGeometry);
43
+ if (hostCSG && guestCSG) {
44
+ return hostCSG.subtract(guestCSG);
45
+ }
46
+ return undefined;
47
+ }
48
+
49
+ this.union = guestGeometry => {
50
+ const guestCSG = prepareCSG(guestGeometry);
51
+ if (hostCSG && guestCSG) {
52
+ return hostCSG.union(guestCSG);
53
+ }
54
+ return undefined;
55
+ }
56
+ };
57
+
58
+ exports.GeometryCSGInternal = GeometryCSGInternal;
package/src/zinc.js ADDED
@@ -0,0 +1,38 @@
1
+ require("url-polyfill");
2
+
3
+ /**
4
+ * Provides a global namespace for the Zinc javascript library and some default parameters for it.
5
+ *
6
+ * @namespace
7
+ * @author Alan Wu
8
+ */
9
+
10
+ const Zinc = function() {
11
+ this.Revision = "1.0.12";
12
+ this.defaultMaterialColor = 0xFFFFFF;
13
+ this.defaultOpacity = 1.0;
14
+ this.modelPrefix = undefined;
15
+ this.Geometry = require('./primitives/geometry').Geometry;
16
+ this.Glyph = require('./primitives/glyph').Glyph;
17
+ this.Glyphset = require('./primitives/glyphset').Glyphset;
18
+ this.Pointset = require('./primitives/pointset').Pointset;
19
+ this.Lines = require('./primitives/lines').Lines;
20
+ this.TextureArray = require('./texture/textureArray').TextureArray;
21
+ this.TextureSlides = require('./primitives/textureSlides').TextureSlides;
22
+ this.Renderer = require('./renderer').Renderer;
23
+ this.Scene = require('./scene').Scene;
24
+ this.GeometryCSG = require('./geometryCSG').GeometryCSG;
25
+ this.GlyphsetCSG = require('./glyphsetCSG').GlyphsetCSG;
26
+ this.Viewport = require('./controls').Viewport;
27
+ this.CameraControls = require('./controls').CameraControls;
28
+ this.SmoothCameraTransition = require('./controls').SmoothCameraTransition;
29
+ this.RayCaster = require('./controls').RayCaster;
30
+ this.CameraAutoTumble = require('./controls').CameraAutoTumble;
31
+ this.StereoEffect = require('./controls').StereoEffect;
32
+ this.loadExternalFile = require('./utilities').loadExternalFile;
33
+ this.loadExternalFiles = require('./utilities').loadExternalFiles;
34
+ this.THREE = require('three');
35
+
36
+ };
37
+
38
+ module.exports = new Zinc();