Changeset 22434
- Timestamp:
- 02/20/18 16:27:26 (7 years ago)
- Location:
- issm/trunk-jpl/src/m/plot
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/m/plot/applyoptions.js
r21911 r22434 61 61 //}}} 62 62 //{{{ Draw colorbar gradient 63 var position; 64 var offset = 1 / (colorbar.length - 1) / 2; 65 var scaling = 1 - 2 * offset; 63 66 for (var i=0; i < colorbar.length; i++) { 64 67 color = colorbar[colorbar.length-i-1]; 65 68 color = [Math.round(color[0]*255), Math.round(color[1]*255), Math.round(color[2]*255)]; 66 cgradient.addColorStop(i/colorbar.length*(cdivisions/(cdivisions+1.0))+(1.0/(cdivisions+1.0)),'rgba('+color.toString()+', 1.0)'); 69 position = (i / (colorbar.length - 1) * scaling) + offset; 70 cgradient.addColorStop(position, 'rgba(' + color.toString() + ', 1.0)'); 67 71 } 68 72 ccontext.fillStyle=cgradient; … … 119 123 tcontext = tcanvas.getContext('2d'); 120 124 tgradient = tcontext.createLinearGradient(0, 0, 0, 256); 121 125 122 126 var cmap = options.getfieldvalue('colormap','jet'); 123 127 var colorbar = colorbars[cmap]; 124 for (var i =0; i < colorbar.length; i++) {125 color = colorbar[colorbar.length -i-1];126 color = [Math.round(color[0] *255), Math.round(color[1]*255), Math.round(color[2]*255)];127 tgradient.addColorStop(i /colorbar.length,'rgba('+color.toString()+', 1.0)');128 for (var i = 0; i < colorbar.length; i++) { 129 color = colorbar[colorbar.length - i - 1]; 130 color = [Math.round(color[0] * 255), Math.round(color[1] * 255), Math.round(color[2] * 255)]; 131 tgradient.addColorStop(i / (colorbar.length - 1), 'rgba(' + color.toString() + ', 1.0)'); 128 132 } 129 130 133 tcontext.fillStyle = tgradient; 131 134 tcontext.fillRect(0, 0, 256, 256); 135 136 //Allow for special texture colors, drawing each color in equal width vertical rectangles. The last rectanglar section is reserved for the colormap. 137 if (options.exist('maskregion')) { 138 var maskObject = options.getfieldvalue('maskregion',{'enabled':false}); 139 if (maskObject.enabled && !VESL.Helpers.isEmptyOrUndefined(maskObject.colors)) { 140 var x = 0; 141 var sections = Object.keys(maskObject.colors).length + 1; 142 var size = 256; 143 var width = Math.floor(1 / sections * size); 144 for (var color in maskObject.colors) { 145 tcontext.fillStyle = maskObject.colors[color]; 146 tcontext.fillRect(x++ * width, 0, width, size); 147 } 148 } 149 } 150 132 151 tURL = tcanvas.toDataURL(); 133 canvas.unitNode.texture = initTexture(canvas.gl, tURL); 152 if (options.getfieldvalue('clf','on')=='off') { 153 canvas.nodes['unit' + (Object.keys(canvas.nodes).length - 1)].texture = initTexture(canvas.gl, tURL); 154 } else { 155 canvas.nodes.unit.texture = initTexture(canvas.gl, tURL); 156 } 134 157 //}}} 135 158 //{{{ text display 136 159 var overlaycanvasid = options.getfieldvalue('overlayid', options.getfieldvalue('canvasid')+'-overlay'); 137 160 var overlaycanvas = $('#'+overlaycanvasid)[0]; 138 if (! isEmptyOrUndefined(overlaycanvas)) {161 if (!VESL.Helpers.isEmptyOrUndefined(overlaycanvas)) { 139 162 //Get drawing context and save reference on main WebGL canvas 140 163 var ctx = overlaycanvas.getContext('2d'); … … 216 239 // function declared in slr-gfm sim-front-end-controller.js 217 240 // if labels are behind the globe sphere then skip iteartion and do not display them 218 if ( isLabelVisible(textLabel)) {241 if (VESL.UI.isLabelVisible(textLabel)) { 219 242 //Transform from world space to viewport space 220 243 var screenPoint = vec3.transformMat4(vec3.create(), textLabel.position, canvas.camera.vpMatrix); … … 272 295 if ('sky' === renderObject && !('sky' in canvas.nodes)) { 273 296 var mesh = GL.Mesh.icosahedron({size: 6371000 * canvas.atmosphere.scaleHeight, subdivisions: 5}); 274 var texture = initTexture(gl, canvas. rootPath + 'textures/TychoSkymapII_t4_2k.jpg');297 var texture = initTexture(gl, canvas.assetsPath + '/textures/TychoSkymapII_t4_2k.jpg'); 275 298 node = new Node( 276 299 'canvas', canvas, … … 287 310 if ('space' === renderObject && !('space' in canvas.nodes)) { 288 311 var mesh = GL.Mesh.sphere({size: 6371000 * 20}); 289 var texture = initTexture(gl, canvas. rootPath + 'textures/TychoSkymapII_t4_2k.jpg');312 var texture = initTexture(gl, canvas.assetsPath + '/textures/TychoSkymapII_t4_2k.jpg'); 290 313 node = new Node( 291 314 'canvas', canvas, … … 301 324 ); 302 325 } 303 if ('coastlines' === renderObject && !('coastlines' in canvas.nodes)) {326 if ('coastlines' === renderObject) { 304 327 node = new Node( 305 328 'canvas', canvas, … … 352 375 'shaderName', 'Colored', 353 376 'drawMode', gl.LINES, 377 'diffuseColor', [1.0, 0.0, 0.0, 1.0], 354 378 'lineWidth', options.getfieldvalue('linewidth', 1), 355 379 'scale', [object.scale, object.scale, object.scale], … … 390 414 if ('clouds' === renderObject && !('clouds0' in canvas.nodes)) { 391 415 //clouds 392 var mesh = GL.Mesh.fromURL(canvas. rootPath+'obj/cloud.obj');416 var mesh = GL.Mesh.fromURL(canvas.assetsPath + '/obj/cloud.obj'); 393 417 for (var i = 0; i < object.quantity; i++) { 394 418 //TODO: More options, less magic numbers. Add animation. Better shading. 395 var offset = [ translation[0] + (Math.random() - 0.5) * 2 * object.range, 396 translation[1] + object.height + (Math.random() - 0.5) * 0.2 * object.range, 397 translation[2] + (Math.random() - 0.5) * 2 * object.range]; 419 var offset = [randomizeAxis(translation[0], object.range), 420 randomizeCloudHeight(translation[1], object), 421 randomizeAxis(translation[2], object.range)]; 422 var randomSize = randomizeCloudSize(object.scale); 423 var randomColor = randomizeCloudColor(); 398 424 node = new Node( 399 425 'canvas', canvas, … … 402 428 'name', 'clouds' + i, 403 429 'shaderName', 'ColoredDiffuse', 404 'animation', {'time': Date.now(),'target': translation,'current': translation}, 405 'diffuseColor', [0.7,0.7,0.7,1.0], 406 'specularColor', [0.0,0.0,0.0,1.0], 430 'diffuseColor', [randomColor, randomColor, randomColor, 1.0], 431 'specularColor', [0.1, 0.1, 0.1, 1.0], 407 432 'mesh', mesh, 408 'scale', [ object.scale, object.scale, object.scale],433 'scale', [randomSize, randomSize, randomSize], 409 434 'translation', offset 410 435 ); … … 414 439 } //}}} 415 440 } //}}} 441 442 function randomizeCloudHeight(canvasGroundHeight, object) { 443 // -+7000 seems a reasonable range 444 var maxHeight = object.height + 7000; 445 var minHeigth = object.height - 7000; 446 var randomHeight = (Math.random() * (maxHeight - minHeigth)) + minHeigth; 447 448 return canvasGroundHeight + randomHeight; 449 } 450 451 // assumes that originAxisValue is the mid-value between min and max. 452 function randomizeAxis(originAxisValue, range) { 453 return originAxisValue + (Math.random() - 0.5) * (range * 2); 454 } 455 456 function randomizeCloudSize(scale) { 457 var maxResize = 1.3; 458 var minResize = 0.5; 459 var randomizationFactor = Math.random() * (maxResize - minResize) + minResize; 460 return scale * randomizationFactor; 461 } 462 463 function randomizeCloudColor() { 464 var lighestColor = 1; 465 var darkestColor = 0.9; 466 var randomColor = Math.random() * (lighestColor - darkestColor) + darkestColor; 467 return randomColor; 468 } -
issm/trunk-jpl/src/m/plot/plot_mesh.js
r21911 r22434 31 31 } 32 32 else { 33 vertices = Node.prototype.scaleVertices(md, x, y, z, elements, options.getfieldvalue('heightscale', 1), options.getfieldvalue('mask scale',{}));33 vertices = Node.prototype.scaleVertices(md, x, y, z, elements, options.getfieldvalue('heightscale', 1), options.getfieldvalue('maskregion',{'enabled':false})); 34 34 scale = [1, 1, 1]; 35 35 } -
issm/trunk-jpl/src/m/plot/plot_overlay.js
r21911 r22434 41 41 } 42 42 else { 43 vertices = Node.prototype.scaleVertices(md, x, y, z, elements, options.getfieldvalue('heightscale', 1), options.getfieldvalue('mask scale',{}));43 vertices = Node.prototype.scaleVertices(md, x, y, z, elements, options.getfieldvalue('heightscale', 1), options.getfieldvalue('maskregion',{'enabled':false})); 44 44 scale = [1, 1, 1]; 45 45 } -
issm/trunk-jpl/src/m/plot/plot_quiver.js
r21911 r22434 7 7 // See also: PLOTMODEL, PLOT_MANAGER 8 8 9 //Disabling for now, since quivers are "sticky" - once turned on, they won't turn off. This is due to cachenodes, but should find better way to handle it. 10 return; 11 9 12 if ('quiver' in canvas.nodes && noCacheNodesOverride && options.getfieldvalue('cachenodes','on') === 'on') return; 10 13 … … 26 29 27 30 //Only displaying velocity fields for now 28 var v = isEmptyOrUndefined(md.results) ? md.initialization.vel : md.results[canvas.animation.frame].Vel;29 var vx = isEmptyOrUndefined(md.results) ? md.initialization.vx : md.results[canvas.animation.frame].Vx;30 var vy = isEmptyOrUndefined(md.results) ? md.initialization.vy : md.results[canvas.animation.frame].Vy;31 var v = VESL.Helpers.isEmptyOrUndefined(md.results) ? md.initialization.vel : md.results[canvas.animation.frame].Vel; 32 var vx = VESL.Helpers.isEmptyOrUndefined(md.results) ? md.initialization.vx : md.results[canvas.animation.frame].Vx; 33 var vy = VESL.Helpers.isEmptyOrUndefined(md.results) ? md.initialization.vy : md.results[canvas.animation.frame].Vy; 31 34 32 35 //Handle heightscale … … 37 40 } 38 41 else { 39 vertices = Node.prototype.scaleVertices(md, x, y, z, elements, options.getfieldvalue('heightscale', 1), options.getfieldvalue('mask scale',{}));42 vertices = Node.prototype.scaleVertices(md, x, y, z, elements, options.getfieldvalue('heightscale', 1), options.getfieldvalue('maskregion',{'enabled':false})); 40 43 scale = [1, 1, 1]; 41 44 } -
issm/trunk-jpl/src/m/plot/plot_transient_movie.js
r21768 r22434 21 21 for (var i in steps) { 22 22 dataresults = processdata(md, data[i], options); 23 range[ 1] = Math.min(range[0], ArrayMin(dataresults[0]));24 range[ 2] = Math.max(range[1], ArrayMax(dataresults[0]));23 range[0] = Math.min(range[0], ArrayMin(dataresults[1])); 24 range[1] = Math.max(range[1], ArrayMax(dataresults[1])); 25 25 } 26 26 datatype = dataresults[1]; … … 31 31 //Create unit node if it does not already exist 32 32 if (!('unit' in canvas.nodes)) { 33 var dataresults = processdata(md, data[ i],options);33 var dataresults = processdata(md, data[0],options); 34 34 var data2 = dataresults[0]; 35 35 var datatype = dataresults[1]; … … 39 39 } 40 40 41 // display movie41 //Setup rendering node 42 42 var node = canvas.nodes.unit; 43 43 node.options = options; … … 46 46 node.enabled = options.getfieldvalue('nodata', 'off') == 'off'; 47 47 node.log = options.getfieldvalue('log', false); 48 canvas.unitMovieData = data; 48 49 //process data 50 var dataresults; 51 var processedData = []; 52 for (var i in steps) { 53 dataresults = processdata(md, data[i].slice(), options); 54 processedData[i] = dataresults[0]; 55 } 56 57 //display movie 58 canvas.unitMovieData = processedData; 49 59 canvas.animation.frame = 0; 50 60 canvas.animation.handler = setInterval(function () { … … 53 63 if (canvas.animation.play) { 54 64 if (canvas.animation.increment) { 55 if (frame > steps.length - 1) {56 if ( node.movieLoop) {65 if (frame >= steps.length - 1) { 66 if (canvas.animation.loop) { 57 67 frame = 0; 58 68 } … … 69 79 //If frame has changed, update unit node and data marker display. 70 80 if (frame !== canvas.animation.lastFrame) { 71 node.updateBuffer('Coords', data[frame]);72 canvas.unitData = data[frame];81 node.updateBuffer('Coords', processedData[frame]); 82 canvas.unitData = processedData[frame]; 73 83 if (canvas.dataMarkers.enabled) { 74 84 updateMarker(canvas, false); 75 85 } 76 if (canvas.p rogressBar) {77 canvas.p rogressBar.val(frame).slider('refresh');86 if (canvas.playbackSlider) { 87 canvas.playbackSlider.val(frame).slider('refresh'); 78 88 } 79 if (canvas. timeLabel) {80 canvas. timeLabel.html(steps[frame].toFixed(0) + " " + options.getfieldvalue("movietimeunit","yr"));89 if (canvas.playbackTextProgress) { 90 canvas.playbackTextProgress.html(steps[frame].toFixed(0) + " " + options.getfieldvalue("movietimeunit","yr")); 81 91 } 82 if (! isEmptyOrUndefined(canvas.nodes.quiver)) {92 if (!VESL.Helpers.isEmptyOrUndefined(canvas.nodes.quiver)) { 83 93 plot_quiver(md,options,canvas,false); 84 94 } … … 91 101 92 102 //Update progress bar with new frame info. 93 if (canvas.p rogressBar) {94 canvas.p rogressBar.val(canvas.animation.frame);95 canvas.p rogressBar.attr('max', steps.length - 1);96 canvas.p rogressBar.slider('refresh');103 if (canvas.playbackSlider) { 104 canvas.playbackSlider.val(canvas.animation.frame); 105 canvas.playbackSlider.attr('max', steps.length - 1); 106 canvas.playbackSlider.slider('refresh'); 97 107 } 98 108 -
issm/trunk-jpl/src/m/plot/plot_unit.js
r21911 r22434 7 7 // See also: PLOTMODEL, PLOT_MANAGER 8 8 9 //if ('unit' in canvas.nodes) { 10 // if ( 11 // canvas.nodes.unit.updateBuffer('Coords', data); 12 // return; 13 //} 14 //else { 9 var name = 'unit'; 10 if ('unit' in canvas.nodes) { 11 if (options.getfieldvalue('clf','on')=='on') { 12 for (var node in canvas.nodes) { 13 if (node.startsWith('unit')) { 14 delete canvas.octrees[node]; 15 delete canvas.nodes[node]; 16 } 17 } 18 } 19 else { 20 name = 'unit' + Object.keys(canvas.nodes).length; 21 } 22 } 15 23 16 24 //{{{ declare variables: … … 37 45 } 38 46 else { 39 vertices = Node.prototype.scaleVertices(md, x, y, z, elements, options.getfieldvalue('heightscale', 1), options.getfieldvalue('mask scale',{}));47 vertices = Node.prototype.scaleVertices(md, x, y, z, elements, options.getfieldvalue('heightscale', 1), options.getfieldvalue('maskregion',{'enabled':false})); 40 48 scale = [1, 1, 1]; 41 49 } … … 44 52 var edgecolor = options.getfieldvalue('edgecolor', [1.0, 1.0, 1.0 ,1.0]); 45 53 var maskzeros = options.getfieldvalue('maskzeros', {}); 54 var render = options.getfieldvalue('render', {}); 55 var cullFace = ("unit" in render) ? canvas.gl[render.unit.cullFace] : canvas.gl.BACK; 46 56 var node = new Node( 47 57 'canvas', canvas, 48 58 'options', options, 49 'name', 'unit',59 'name', name, 50 60 'shaderName', 'TexturedDiffuse', 51 61 'alpha', options.getfieldvalue('alpha', 1.0), 52 62 'caxis', options.getfieldvalue('caxis',[ArrayMin(data), ArrayMax(data)]), 53 //'center', [(xlim[0] + xlim[1]) / 2, (ylim[0] + ylim[1]) / 2, md.mesh.classname() === 'mesh3dsurface' ? (zlim[0] + zlim[1]) / 2 : zlim[0]],54 63 'center', [(xlim[0] + xlim[1]) / 2, (ylim[0] + ylim[1]) / 2, (zlim[0] + zlim[1]) / 2], 55 'lightingBias', 0.8, 64 'cullFace', cullFace, 65 'lightingBias', canvas.view.lightingBias, 56 66 'diffuseColor', edgecolor, 57 67 'specularStrength', 0.0, 58 'enabled', options.getfieldvalue('nodata','off') == 'off' ,68 'enabled', options.getfieldvalue('nodata','off') == 'off' || (("unit" in render) && render.unit.enabled), 59 69 'log', options.getfieldvalue('log',false), 60 70 'maskEnabled', options.getfieldvalue('innermask','off') == 'on', 61 71 'maskHeight', options.getfieldvalue('innermaskheight', 150.0) / options.getfieldvalue('heightscale', 1), 62 72 'maskColor', options.getfieldvalue('innermaskcolor',[0.0, 0.0, 1.0, 1.0]), 73 'maskObject', options.getfieldvalue('maskregion',{'enabled':false}), 63 74 'maskZerosColor', defaultFor(maskzeros.color,[1.0, 1.0, 1.0, 1.0]), 64 75 'maskZerosEnabled', defaultFor(maskzeros.enabled,false), … … 66 77 'maskZerosZeroValue', defaultFor(maskzeros.zeroValue,0.5), 67 78 'rotation', [-90, 0, 0], 68 'scale', scale79 'scale', ("unit" in render) ? [render.unit.scale, render.unit.scale, render.unit.scale] : scale 69 80 ); 70 81 //} 71 canvas.unitNode = node; 72 canvas.unitData = data; 82 if (options.getfieldvalue('clf','on')=='on') { 83 canvas.unitNode = node; 84 canvas.unitData = data; 85 } 73 86 //}}} 74 87 switch(datatype){ -
issm/trunk-jpl/src/m/plot/plotdoc.js
r21768 r22434 39 39 console.log(' "datamarkers": object cotaining data marker parameters. See webgl.js for defaults. (ex: {"enabled":true,"format":["<div id="sim-plot"></div>"],"labels":["thickness","velocity","value"],"animated":true})'); 40 40 console.log(' "enabled": toggle data marker displays (default true, ex: false)'); 41 console.log(' "image": image used for marking the clicked point (ex: "/ textures/data_marker.svg")');41 console.log(' "image": image used for marking the clicked point (ex: "/canvas/data-markers/data_marker.svg")'); 42 42 console.log(' "labels": when displaying a sim-plot graph, display these model fields. (ex: ["thickness","velocity","value"])'); 43 43 console.log(' "font": font to be used for display (ex: "24px "Comic Sans MS", cursive")'); -
issm/trunk-jpl/src/m/plot/plotmodel.js
r21300 r22434 36 36 //Reinitialize all canvases 37 37 for (var i=0;i<numberofplots;i++){ 38 document.getElementById(options.list[i].getfieldvalue('canvasid')).initialized = false;38 if (options.list[i].getfieldvalue('clf','on')!='off') document.getElementById(options.list[i].getfieldvalue('canvasid')).initialized = false; 39 39 } 40 40 //Go through all data plottable and close window if an error occurs -
issm/trunk-jpl/src/m/plot/webgl.js
r21911 r22434 6 6 //var canvas = document.getElementById(options.getfieldvalue('canvasid')); 7 7 if (!canvas.initialized) { 8 if (! isEmptyOrUndefined(canvas.draw) && canvas.draw.handler !== 0) { window.cancelAnimationFrame(canvas.draw.handler); }9 if (! isEmptyOrUndefined(canvas.animation) && canvas.animation.handler !== 0) { clearInterval(canvas.animation.handler); }8 if (!VESL.Helpers.isEmptyOrUndefined(canvas.draw) && canvas.draw.handler !== 0) { window.cancelAnimationFrame(canvas.draw.handler); } 9 if (!VESL.Helpers.isEmptyOrUndefined(canvas.animation) && canvas.animation.handler !== 0) { clearInterval(canvas.animation.handler); } 10 10 initWebGL(canvas, options); 11 11 draw(canvas); … … 20 20 //Initialize canvas.gl on page load, reusing gl context on additional runs 21 21 var gl = canvas.gl; 22 if ( isEmptyOrUndefined(gl)) {22 if (VESL.Helpers.isEmptyOrUndefined(gl)) { 23 23 gl = GL.create({canvas: canvas}); 24 24 gl.enable(gl.DEPTH_TEST); // Enable depth testing … … 27 27 gl.enable(gl.CULL_FACE); // Enable face culling 28 28 gl.cullFace(gl.FRONT); 29 gl.shaders = loadShaders(gl, options.getfieldvalue('rootpath', ' ../../../js/')); // Load shaders and store them in gl object29 gl.shaders = loadShaders(gl, options.getfieldvalue('rootpath', '/canvas')); // Load shaders and store them in gl object. 30 30 gl.textures = {}; 31 31 … … 50 50 51 51 canvas.gl = gl; 52 canvas. rootPath = options.getfieldvalue('rootpath', '../../../js/');52 canvas.assetsPath = options.getfieldvalue('rootpath', '/canvas'); 53 53 canvas.id = options.getfieldvalue('canvasid', '.sim-canvas'); 54 54 canvas.selector = $('#' + canvas.id); 55 55 canvas.textcanvas = null; 56 56 canvas.overlaycanvas = null; 57 canvas.permalinkUsed = false; 57 58 58 59 typedArraySliceSupport(); 59 60 } 60 61 61 //Add context state variables 62 canvas.render = options.getfieldvalue('render', {}); 63 canvas.controlSensitivity = options.getfieldvalue('controlsensitivity', 1); 64 canvas.overlayHandlers = {}; 65 var backgroundcolor = new RGBColor(options.getfieldvalue('backgroundcolor', 'lightcyan')); 66 if (backgroundcolor.ok) { canvas.backgroundcolor = [backgroundcolor.r/255.0, backgroundcolor.g/255.0, backgroundcolor.b/255.0, 1.0]; } 67 else { throw Error(sprintf('s%s%s\n','initWebGL error message: cound not find out background color for curent canvas ', canvas)); } 68 69 //Property intiialization, using values from options first, then from default values. 70 var atmosphere = options.getfieldvalue('atmosphere', {}); 71 canvas.atmosphere = { //Default Values 72 wavelength_r: defaultFor(atmosphere.wavelength_r, 0.65), //0.65 Red wavelength (micrometers) 73 wavelength_g: defaultFor(atmosphere.wavelength_g, 0.57), //0.57 Green wavelength (micrometers) 74 wavelength_b: defaultFor(atmosphere.wavelength_b, 0.475), //0.475 Green wavelength (micrometers) 75 eSun: defaultFor(atmosphere.eSun, 100.0), //20.0 Sun intensity 76 kRayleigh: defaultFor(atmosphere.kRayleigh, 0.0025), //0.0025 Rayleigh scattering amount 77 kMie: defaultFor(atmosphere.kMie, 0.000), //0.01 Mie scattering amount 78 g: defaultFor(atmosphere.g, -0.99), //-0.99 Mie phase asymmetry/direction factor 79 hdr_exposure: defaultFor(atmosphere.hdr_exposure, 0.8), //0.8 High Dynamic Range Exposure 80 scaleHeight: defaultFor(atmosphere.scaleHeight, 1.25), //1.025 Scale of height of atmosphere to earth radius. 81 scaleDepth: defaultFor(atmosphere.scaleDepth, 0.25), //0.25 Percentage altitude at which the atmosphere's average density is found 82 a: defaultFor(atmosphere.a, -0.00287), //-0.00287 Scaling constant a 83 b: defaultFor(atmosphere.b, 0.459), //0.459 Scaling constant b 84 c: defaultFor(atmosphere.c, 3.83), //3.83 Scaling constant c 85 d: defaultFor(atmosphere.d, -6.80), //-6.80 Scaling constant d 86 e: defaultFor(atmosphere.e, 3.6), //5.25 Scaling constant e. Lower when increasing atmosphere scale. 87 attenuation: defaultFor(atmosphere.attenuation, 0.5) //0.5 Strength of atmospheric scattering on ground shading. 88 }; 89 updateAtmosphereParameters(canvas); 90 var animation = options.getfieldvalue('movies', {}); 91 canvas.animation = { 92 frame: defaultFor(animation.frame, 0), 93 play: defaultFor(animation.play, true), 94 increment: defaultFor(animation.increment, true), 95 fps: defaultFor(animation.fps, 4), 96 interval: defaultFor(animation.interval, 1000 / defaultFor(animation.fps, 4)), 97 loop: defaultFor(animation.loop, true), 98 handler: defaultFor(animation.handler, 0) 99 } 100 var brush = options.getfieldvalue('brush', {}); 101 canvas.brush = { 102 enabled: defaultFor(brush.enabled, false), 103 strength: defaultFor(brush.strength, 0.075), 104 falloff: defaultFor(brush.falloff, 0.5), 105 hit: defaultFor(brush.hit, {}) 106 }; 107 var camera = options.getfieldvalue('camera', {}); 108 canvas.camera = { 109 position: defaultFor(camera.position, vec3.create()), 110 rotation: defaultFor(camera.rotation, quat.create()), 111 relativePosition: defaultFor(camera.relativePosition, vec3.create()), 112 direction: defaultFor(camera.direction, vec3.create()), 113 near: defaultFor(camera.near, 1e3), 114 far: defaultFor(camera.far, 1e10), 115 fov: defaultFor(camera.fov, 45), 116 vMatrix: defaultFor(camera.vMatrix, mat4.create()), 117 pMatrix: defaultFor(camera.pMatrix, mat4.create()), 118 vpMatrix: defaultFor(camera.vpMatrix, mat4.create()), 119 vInverseMatrix: defaultFor(camera.vInverseMatrix, mat4.create()), 120 pInverseMatrix: defaultFor(camera.pInverseMatrix, mat4.create()), 121 vpInverseMatrix: defaultFor(camera.vpInverseMatrix, mat4.create()), 122 ready: defaultFor(camera.ready, false) 123 }; 124 var dataMarkers = options.getfieldvalue('datamarkers', {}); 125 canvas.dataMarkers = { 126 enabled: defaultFor(dataMarkers.enabled, true), 127 values: defaultFor(dataMarkers.values, []), 128 image: defaultFor(dataMarkers.image, canvas.rootPath + 'textures/data_marker.svg'), 129 size: defaultFor(dataMarkers.size, [32, 32]), 130 format: defaultFor(dataMarkers.format, ['X: %.2e<br>Y: %.2e<br>Z: %.2e<br>Value: %0.1f', 'x', 'y', 'z', 'value']), 131 animated: defaultFor(dataMarkers.animated, false), 132 labels: defaultFor(dataMarkers.labels, []), 133 font: defaultFor(dataMarkers.font, ''), 134 marker: defaultFor(dataMarkers.marker, document.getElementById('sim-data-marker-' + canvas.id)), 135 reposition: defaultFor(dataMarkers.reposition, true) 136 }; 137 var draw = options.getfieldvalue('draw', {}); 138 canvas.draw = { 139 ready: defaultFor(draw.ready, false), 140 handler: defaultFor(draw.handler, null) 141 }; 142 var view = options.getfieldvalue('view', {}); 143 canvas.view = { 144 position: defaultFor(view.position, [0.0, 0.0, 0.0]), 145 rotation: defaultFor(view.rotation, [0, 90]), 146 zoom: defaultFor(view.zoom, 1.0), 147 zoomLimits: defaultFor(view.zoomLimits, [0.001, 100.0]), 148 lastZoom: defaultFor(view.lastZoom, 1.0), 149 azimuthLimits: defaultFor(view.azimuthLimits, [0, 360]), 150 elevationLimits: defaultFor(view.elevationLimits, [-180, 180]), 151 panningEnabled: defaultFor(view.panningEnabled, false), 152 preventDefaultOnPan: defaultFor(view.preventDefaultOnPan, false), 153 twod: defaultFor(view.twod, false) 154 }; 155 156 //Override with parameters from URL, if any 157 //TODO: Make permalinks more robust and less interdependent on UI 158 if (!canvas.usedparemters) { 159 var parameters = {}; 160 location.search.substr(1).split('&').forEach(function(part) { 161 var item = part.split('='); 162 parameters[item[0]] = decodeURIComponent(item[1]); 163 }); 164 165 if (parameters['pos']) { canvas.view.position = JSON.parse(parameters['pos']); } 166 if (parameters['rot']) { canvas.view.rotation = JSON.parse(parameters['rot']); } 167 if (parameters['zoom']) { canvas.view.zoom = JSON.parse(parameters['zoom']); } 168 if (parameters['twod']) { canvas.view.twod = JSON.parse(parameters['twod']); } 169 if (parameters['initial']) { 170 initial = JSON.parse(parameters['initial']); 171 if (!initial) { 172 if (typeof SolveGlacier === 'function') { 173 SolveGlacier(); 174 } 175 if (typeof SolveSlr === 'function') { 176 SolveSlr(); 177 } 178 } 62 if (options.getfieldvalue('clf','on')=='on') { 63 //Add context state variables 64 canvas.render = options.getfieldvalue('render', {}); 65 canvas.controlSensitivity = options.getfieldvalue('controlsensitivity', 1); 66 if (options.getfieldvalue('clf','on')=='on') canvas.overlayHandlers = {}; 67 var backgroundcolor = new RGBColor(options.getfieldvalue('backgroundcolor', 'lightcyan')); 68 if (backgroundcolor.ok) { canvas.backgroundcolor = [backgroundcolor.r/255.0, backgroundcolor.g/255.0, backgroundcolor.b/255.0, 1.0]; } 69 else { throw Error(sprintf('s%s%s\n','initWebGL error message: cound not find out background color for current canvas ', canvas)); } 70 71 //Property intiialization, using values from options first, then from default values. 72 var atmosphere = options.getfieldvalue('atmosphere', {}); 73 canvas.atmosphere = { //Default Values 74 wavelength_r: defaultFor(atmosphere.wavelength_r, 0.65), //0.65 Red wavelength (micrometers) 75 wavelength_g: defaultFor(atmosphere.wavelength_g, 0.57), //0.57 Green wavelength (micrometers) 76 wavelength_b: defaultFor(atmosphere.wavelength_b, 0.475), //0.475 Green wavelength (micrometers) 77 eSun: defaultFor(atmosphere.eSun, 100.0), //20.0 Sun intensity 78 kRayleigh: defaultFor(atmosphere.kRayleigh, 0.0025), //0.0025 Rayleigh scattering amount 79 kMie: defaultFor(atmosphere.kMie, 0.000), //0.01 Mie scattering amount 80 g: defaultFor(atmosphere.g, -0.99), //-0.99 Mie phase asymmetry/direction factor 81 hdr_exposure: defaultFor(atmosphere.hdr_exposure, 0.8), //0.8 High Dynamic Range Exposure 82 scaleHeight: defaultFor(atmosphere.scaleHeight, 1.25), //1.025 Scale of height of atmosphere to earth radius. 83 scaleDepth: defaultFor(atmosphere.scaleDepth, 0.25), //0.25 Percentage altitude at which the atmosphere's average density is found 84 a: defaultFor(atmosphere.a, -0.00287), //-0.00287 Scaling constant a 85 b: defaultFor(atmosphere.b, 0.459), //0.459 Scaling constant b 86 c: defaultFor(atmosphere.c, 3.83), //3.83 Scaling constant c 87 d: defaultFor(atmosphere.d, -6.80), //-6.80 Scaling constant d 88 e: defaultFor(atmosphere.e, 3.6), //5.25 Scaling constant e. Lower when increasing atmosphere scale. 89 attenuation: defaultFor(atmosphere.attenuation, 0.5) //0.5 Strength of atmospheric scattering on ground shading. 90 }; 91 updateAtmosphereParameters(canvas); 92 93 var animation = options.getfieldvalue('movies', {}); 94 canvas.animation = { 95 frame: defaultFor(animation.frame, 0), 96 play: defaultFor(animation.play, true), 97 increment: defaultFor(animation.increment, true), 98 fps: defaultFor(animation.fps, 4), 99 interval: defaultFor(animation.interval, 1000 / defaultFor(animation.fps, 4)), 100 loop: defaultFor(animation.loop, true), 101 handler: defaultFor(animation.handler, 0) 179 102 } 180 canvas.usedparemters = true; 181 } 182 } //}}} 183 function generatePermalink() { //{{{ 184 var permalink = window.location.origin + window.location.pathname + '?' 185 + '&pos=' + encodeURIComponent(JSON.stringify(canvas.view.position)) 186 + '&rot=' + encodeURIComponent(JSON.stringify(canvas.view.rotation)) 187 + '&zoom=' + encodeURIComponent(JSON.stringify(canvas.view.zoom)) 188 + '&twod=' + encodeURIComponent(JSON.stringify(canvas.view.twod)); 189 window.prompt('Share this simulation: ', permalink); 190 } //}}} 191 function loadShaders(gl, rootPath) { //{{{ 103 var brush = options.getfieldvalue('brush', {}); 104 canvas.brush = { 105 enabled: defaultFor(brush.enabled, false), 106 strength: defaultFor(brush.strength, 0.075), 107 falloff: defaultFor(brush.falloff, 0.5), 108 hit: defaultFor(brush.hit, {}) 109 }; 110 var camera = options.getfieldvalue('camera', {}); 111 canvas.camera = { 112 position: defaultFor(camera.position, vec3.create()), 113 rotation: defaultFor(camera.rotation, quat.create()), 114 relativePosition: defaultFor(camera.relativePosition, vec3.create()), 115 direction: defaultFor(camera.direction, vec3.create()), 116 near: defaultFor(camera.near, 1e3), 117 far: defaultFor(camera.far, 1e10), 118 fov: defaultFor(camera.fov, 45), 119 vMatrix: defaultFor(camera.vMatrix, mat4.create()), 120 pMatrix: defaultFor(camera.pMatrix, mat4.create()), 121 vpMatrix: defaultFor(camera.vpMatrix, mat4.create()), 122 vInverseMatrix: defaultFor(camera.vInverseMatrix, mat4.create()), 123 pInverseMatrix: defaultFor(camera.pInverseMatrix, mat4.create()), 124 vpInverseMatrix: defaultFor(camera.vpInverseMatrix, mat4.create()), 125 ready: defaultFor(camera.ready, false) 126 }; 127 var dataMarkers = options.getfieldvalue('datamarkers', {}); 128 canvas.dataMarkers = { 129 enabled: defaultFor(dataMarkers.enabled, true), 130 values: defaultFor(dataMarkers.values, []), 131 image: defaultFor(dataMarkers.image, canvas.assetsPath + '/data-markers/data_marker.svg'), 132 size: defaultFor(dataMarkers.size, [32, 32]), 133 format: defaultFor(dataMarkers.format, ['X: %.2em<br>Y: %.2em<br>Z: %.2em<br>Value: %0.1f']), 134 animated: defaultFor(dataMarkers.animated, false), 135 labels: defaultFor(dataMarkers.labels, ['x', 'y', 'z', 'value']), 136 font: defaultFor(dataMarkers.font, ''), 137 marker: defaultFor(dataMarkers.marker, document.getElementById('sim-data-marker-' + canvas.id)), 138 reposition: defaultFor(dataMarkers.reposition, true) 139 }; 140 var draw = options.getfieldvalue('draw', {}); 141 canvas.draw = { 142 ready: defaultFor(draw.ready, false), 143 handler: defaultFor(draw.handler, null) 144 }; 145 var view = options.getfieldvalue('view', {}); 146 canvas.view = { 147 position: defaultFor(view.position, [0.0, 0.0, 0.0]), 148 rotation: defaultFor(view.rotation, [0, 90]), 149 zoom: defaultFor(view.zoom, 1.0), 150 zoomLimits: defaultFor(view.zoomLimits, [0.001, 100.0]), 151 lastZoom: defaultFor(view.lastZoom, 1.0), 152 lightingBias: defaultFor(view.lightingBias, 0.75), 153 azimuthLimits: defaultFor(view.azimuthLimits, [0, 360]), 154 elevationLimits: defaultFor(view.elevationLimits, [-180, 180]), 155 panningEnabled: defaultFor(view.panningEnabled, false), 156 preventDefaultOnPan: defaultFor(view.preventDefaultOnPan, false), 157 twod: defaultFor(view.twod, false) 158 }; 159 160 // Override with parameters from URL, if any 161 VESL.UI.parsePermalinkCanvas(canvas); 162 } 163 } //}}} 164 function loadShaders(gl, assetsPath) { //{{{ 192 165 var shaders = {}; 193 shaders.Colored = new GL.Shader.fromURL(rootPath+'shaders/Colored.vsh', rootPath+'shaders/Colored.fsh', null, gl); 194 shaders.ColoredDiffuse = new GL.Shader.fromURL(rootPath+'shaders/ColoredDiffuse.vsh', rootPath+'shaders/ColoredDiffuse.fsh', null, gl); 195 shaders.Textured = new GL.Shader.fromURL(rootPath+'shaders/Textured.vsh', rootPath+'shaders/Textured.fsh', null, gl); 196 shaders.TexturedDiffuse = new GL.Shader.fromURL(rootPath+'shaders/TexturedDiffuse.vsh', rootPath+'shaders/TexturedDiffuse.fsh', null, gl); 197 shaders.SkyFromSpace = new GL.Shader.fromURL(rootPath+'shaders/SkyFromSpace.vert', rootPath+'shaders/SkyFromSpace.frag', null, gl); 198 shaders.GroundFromSpace = new GL.Shader.fromURL(rootPath+'shaders/GroundFromSpace.vert', rootPath+'shaders/GroundFromSpace.frag', null, gl); 166 // NOTE: Consider changing fromURL() to XMLHttpRequest with responseType = 'text' to avoid XML Parsing Error (shader files are not encoded as XML). 167 shaders.Colored = new GL.Shader.fromURL(assetsPath + '/shaders/Colored.vsh', assetsPath + '/shaders/Colored.fsh', null, gl); 168 shaders.ColoredDiffuse = new GL.Shader.fromURL(assetsPath + '/shaders/ColoredDiffuse.vsh', assetsPath + '/shaders/ColoredDiffuse.fsh', null, gl); 169 shaders.Textured = new GL.Shader.fromURL(assetsPath + '/shaders/Textured.vsh', assetsPath + '/shaders/Textured.fsh', null, gl); 170 shaders.TexturedDiffuse = new GL.Shader.fromURL(assetsPath + '/shaders/TexturedDiffuse.vsh', assetsPath + '/shaders/TexturedDiffuse.fsh', null, gl); 171 shaders.SkyFromSpace = new GL.Shader.fromURL(assetsPath + '/shaders/SkyFromSpace.vert', assetsPath + '/shaders/SkyFromSpace.frag', null, gl); 172 shaders.GroundFromSpace = new GL.Shader.fromURL(assetsPath + '/shaders/GroundFromSpace.vert', assetsPath + '/shaders/GroundFromSpace.frag', null, gl); 199 173 return shaders; 200 174 } //}}} 201 175 function initTexture(gl, imageSource) { //{{{ 202 176 //Initialize textures, or load from memory if they already exist. 203 if ( isEmptyOrUndefined(gl.textures[imageSource])) {177 if (VESL.Helpers.isEmptyOrUndefined(gl.textures[imageSource])) { 204 178 gl.textures[imageSource] = GL.Texture.fromURL(imageSource, {minFilter: gl.LINEAR_MIPMAP_LINEAR, magFilter: gl.LINEAR}, null, gl); 205 179 } … … 230 204 return typeof name !== 'undefined' ? name : value; 231 205 } //}}} 232 function isEmptyOrUndefined(object) { //{{{233 return object === undefined || isEmpty(object);234 } //}}}235 function isEmpty(object) { //{{{236 for (var key in object) {237 return false;238 }239 return true;240 } //}}}241 206 function recover(canvasid, name, value) { //{{{ 242 207 //Traverse canvas object tree for property defined by dot delimited string, returning it, or a default value if it is not found. … … 245 210 for (var i = 0; i < properties.length; i++) { 246 211 object = object[properties[i]]; 247 if ( isEmptyOrUndefined(object)) { break; }212 if (VESL.Helpers.isEmptyOrUndefined(object)) { break; } 248 213 } 249 214 return defaultFor(object, value); 250 } //}}}251 function typedArraySliceSupport() { //{{{252 //TypedArray compatibility for Safari/IE253 if (typeof Int8Array !== 'undefined') {254 if (!Int8Array.prototype.fill) { Int8Array.prototype.fill = Array.prototype.fill; }255 if (!Int8Array.prototype.slice) { Int8Array.prototype.slice = Array.prototype.slice; }256 }257 if (typeof Uint8Array !== 'undefined') {258 if (!Uint8Array.prototype.fill) { Uint8Array.prototype.fill = Array.prototype.fill; }259 if (!Uint8Array.prototype.slice) { Uint8Array.prototype.slice = Array.prototype.slice; }260 }261 if (typeof Uint8ClampedArray !== 'undefined') {262 if (!Uint8ClampedArray.prototype.fill) { Uint8ClampedArray.prototype.fill = Array.prototype.fill; }263 if (!Uint8ClampedArray.prototype.slice) { Uint8ClampedArray.prototype.slice = Array.prototype.slice; }264 }265 if (typeof Int16Array !== 'undefined') {266 if (!Int16Array.prototype.fill) { Int16Array.prototype.fill = Array.prototype.fill; }267 if (!Int16Array.prototype.slice) { Int16Array.prototype.slice = Array.prototype.slice; }268 }269 if (typeof Uint16Array !== 'undefined') {270 if (!Uint16Array.prototype.fill) { Uint16Array.prototype.fill = Array.prototype.fill; }271 if (!Uint16Array.prototype.slice) { Uint16Array.prototype.slice = Array.prototype.slice; }272 }273 if (typeof Int32Array !== 'undefined') {274 if (!Int32Array.prototype.fill) { Int32Array.prototype.fill = Array.prototype.fill; }275 if (!Int32Array.prototype.slice) { Int32Array.prototype.slice = Array.prototype.slice; }276 }277 if (typeof Uint32Array !== 'undefined') {278 if (!Uint32Array.prototype.fill) { Uint32Array.prototype.fill = Array.prototype.fill; }279 if (!Uint32Array.prototype.slice) { Uint32Array.prototype.slice = Array.prototype.slice; }280 }281 if (typeof Float32Array !== 'undefined') {282 if (!Float32Array.prototype.fill) { Float32Array.prototype.fill = Array.prototype.fill; }283 if (!Float32Array.prototype.slice) { Float32Array.prototype.slice = Array.prototype.slice; }284 }285 if (typeof Float64Array !== 'undefined') {286 if (!Float64Array.prototype.fill) { Float64Array.prototype.fill = Array.prototype.fill; }287 if (!Float64Array.prototype.slice) { Float64Array.prototype.slice = Array.prototype.slice; }288 }289 if (typeof TypedArray !== 'undefined') {290 if (!TypedArray.prototype.fill) { TypedArray.prototype.fill = Array.prototype.fill; }291 if (!TypedArray.prototype.slice) { TypedArray.prototype.slice = Array.prototype.slice; }292 }293 215 } //}}} 294 216 //}}} … … 356 278 ev.preventDefault(); 357 279 if (ev.type === 'pinchstart') { canvas.view.lastZoom = canvas.view.zoom; } 358 else { modifyZoom(ev.scale * canvas.view.lastZoom, canvas, displaylog, ev, 0); } 280 else { 281 canvas.view.zoom = ev.scale * canvas.view.lastZoom; 282 if (displaylog) { console.log(canvas.view.zoom); } 283 } 359 284 } //}}} 360 285 function onZoom(ev, canvas, displaylog) { //{{{ … … 364 289 } //}}} 365 290 function modifyZoom(value, canvas, displaylog, ev, duration) { //{{{ 366 if ( isEmptyOrUndefined(duration)) duration = 200;291 if (VESL.Helpers.isEmptyOrUndefined(duration)) duration = 200; 367 292 var targetZoom = clamp(value, canvas.view.zoomLimits[0], canvas.view.zoomLimits[1]); 368 293 var currentZoom = canvas.view.zoom; … … 371 296 1.0, 372 297 duration, 298 'swing', 373 299 function(value, info) { 374 300 canvas.view.zoom = currentZoom * (1 - value) + targetZoom * value; … … 382 308 function toggleMoviePlay(canvas) { //{{{ 383 309 canvas.animation.play = !canvas.animation.play; 384 if (canvas.animation.play){385 canvas.playButton.find('span').removeClass('fa-play');386 canvas.playButton.find('span').addClass('fa-pause');387 }388 else{389 canvas.playButton.find('span').removeClass('fa-pause');390 canvas.playButton.find('span').addClass('fa-play');391 }392 310 } //}}} 393 311 function screenToWorldPoint(canvas, x, y) { //{{{ … … 403 321 var origin = vec3.transformMat4(vec3.create(), [viewportX, viewportY, 0], inverseMVPMatrix); 404 322 var far = vec3.transformMat4(vec3.create(), [viewportX, viewportY, 1.0], inverseMVPMatrix); 405 var direction = vec3. subtract(vec3.create(), far, origin);323 var direction = vec3.normalize(vec3.create(), vec3.subtract(vec3.create(), far, origin)); 406 324 return {'origin':origin, 'direction':direction}; 407 325 } //}}} … … 420 338 return hit; 421 339 } //}}} 422 function raycastXY(canvas, x, y, node ) { //{{{340 function raycastXY(canvas, x, y, node, faceWinding) { //{{{ 423 341 //Performs raycast on given node using x and y screenspace coordinates. 424 342 //Returns hit objects with hit position, normals, barycentric coordinates, element number, and indices of ray-triangle intersection. … … 427 345 return raycast(canvas, ray.origin, ray.direction, node); 428 346 } //}}} 429 function animateValue(current, target, duration, stepCallback, doneCallback) { //{{{ 430 //Animates scalar value for length duration, calling callback each step. 431 //TODO: Specify lerp easing as option (cubic, linear, cosine). 347 function animateValue(current, target, duration, easing, stepCallback, doneCallback) { //{{{ 348 //Animates scalar value for length duration, calling callback each step. Specify smooth easing as a string ('swing', 'linear'). 432 349 $({'value':current}).animate({'value':target}, { 433 350 duration: duration, 351 easing: easing, 434 352 step: stepCallback, 435 353 done: doneCallback … … 581 499 canvas.gl.viewport(0, 0, canvas.width, canvas.height); 582 500 583 if (! isEmptyOrUndefined(canvas.overlaycanvas)) {501 if (!VESL.Helpers.isEmptyOrUndefined(canvas.overlaycanvas)) { 584 502 rect = canvas.overlaycanvas.getBoundingClientRect(); 585 503 canvas.overlaycanvas.width = rect.width; -
issm/trunk-jpl/src/m/plot/webgl_node.js
r21911 r22434 33 33 this.lightingBias = options.getfieldvalue('lightingBias', 0.0); //Controls width of gl lines. No reliable support across windows platforms. 34 34 this.log = options.getfieldvalue('log', false); //Controls logarithmic color axis scaling for texturing. 35 this.maskAll = options.getfieldvalue('maskAll', []); //Masking array used for marking all region elements. 36 this.maskBoundary = options.getfieldvalue('maskBoundary', []); //Masking array used for marking region boundary edges. 35 37 this.maskColor = options.getfieldvalue('maskColor', vec4.fromValues(0.0, 0.0, 1.0, 1.0)); //ISSM shader uniform controlling ocean masking color. 36 38 this.maskEnabled = options.getfieldvalue('maskEnabled', false); //ISSM shader uniform toggling ocean masking. 37 39 this.maskHeight = options.getfieldvalue('maskHeight', 150.0); //ISSM shader uniform controlling height at which ocean masking is cut off. 40 this.maskObject = options.getfieldvalue('maskObject', {'enabled':false}); //Masking array options object. 38 41 this.maskZerosColor = options.getfieldvalue('maskZerosColor', [1.0, 1.0, 1.0, 1.0]); //ISSM shader uniform controlling value masking color. 39 42 this.maskZerosEnabled = options.getfieldvalue('maskZerosEnabled', false); //ISSM shader uniform toggling value masking. … … 168 171 var scale = options.getfieldvalue('scale', undefined); 169 172 170 if (! isEmptyOrUndefined(translation)) this.translation = translation;171 if (! isEmptyOrUndefined(rotation)) this.rotation = rotation;172 if (! isEmptyOrUndefined(scale)) this.scale = scale;173 if (!VESL.Helpers.isEmptyOrUndefined(translation)) this.translation = translation; 174 if (!VESL.Helpers.isEmptyOrUndefined(rotation)) this.rotation = rotation; 175 if (!VESL.Helpers.isEmptyOrUndefined(scale)) this.scale = scale; 173 176 this.updateModelMatrix(); 174 177 } //}}} … … 194 197 this.diffuseColor = edgeColor; 195 198 this.updateDiffuseColor(); 199 this.computeMasks(); 196 200 197 201 this.patchVertices(faceVertexCData, faces, vertices); … … 208 212 var face; 209 213 210 if ( isEmptyOrUndefined(faceVertexCData)) {214 if (VESL.Helpers.isEmptyOrUndefined(faceVertexCData)) { 211 215 vertexArray = new Float32Array(vertices[0].length * 3); 212 216 for(var i = 0, v = 0; i < vertices[0].length; i++) { … … 285 289 var face; 286 290 287 if ( isEmptyOrUndefined(faceVertexCData)) { return; }291 if (VESL.Helpers.isEmptyOrUndefined(faceVertexCData)) { return; } 288 292 289 293 //Use logarithmic scaling if it is valid … … 308 312 } 309 313 else { 310 coordArray[t++] = 0.5;314 coordArray[t++] = this.queryCoordMask(i); //Account for special texturing 311 315 coordArray[t++] = clamp((faceVertexCData[i] - caxis[0]) / crange, 0.0, 1.0); 312 316 } … … 325 329 } 326 330 else { 327 coordArray[t++] = 0.5;331 coordArray[t++] = this.queryCoordMask(i); //Account for special texturing 328 332 coordArray[t++] = clamp((faceVertexCData[i] - caxis[0]) / crange, 0.0, 1.0); 329 333 } … … 364 368 } 365 369 366 if (this.computeIndices === true && ! isEmptyOrUndefined(faces)) {367 if (! isEmptyOrUndefined(faces[0])) { //Check for 2D format and process if needed370 if (this.computeIndices === true && !VESL.Helpers.isEmptyOrUndefined(faces)) { 371 if (!VESL.Helpers.isEmptyOrUndefined(faces[0])) { //Check for 2D format and process if needed 368 372 if (faceColor !== 'none') { //Check for triangle rendering 369 373 indexArray = new Uint16Array(faces.length * 3); … … 399 403 var args = Array.prototype.slice.call(arguments); 400 404 var options = new pairoptions(args.slice(0,args.length)); 401 405 402 406 var coords = options.getfieldvalue('Coords', undefined); 403 var cacheIndex = options.getfieldvalue('CacheIndex', false); 404 405 if (!isEmptyOrUndefined(coords)) { 407 if (!VESL.Helpers.isEmptyOrUndefined(coords)) { 406 408 this.patchCoords(coords, this.faces, this.vertices); 407 409 var buffer = this.mesh.getBuffer("coords"); … … 413 415 //Computes and caches octrees for a node. 414 416 var octree = this.canvas.octrees[this.name]; 415 if ( isEmptyOrUndefined(octree)) {417 if (VESL.Helpers.isEmptyOrUndefined(octree)) { 416 418 octree = new GL.Octree(this.mesh); 417 419 } … … 439 441 var coordinateObject = vertices[i]; 440 442 var j = 0; 441 if ( isEmptyOrUndefined(indices)) {443 if (VESL.Helpers.isEmptyOrUndefined(indices)) { 442 444 for (var key in coordinateObject) { 443 445 console.log(key); … … 483 485 Node.prototype.scaleVertices = function(md, x, y, z, elements, scale, maskObject) { //{{{ 484 486 //Scales and returns vertices x, y, and z by factor scale. Uses md.geometry.scale for heightscaling in 3d meshes. 487 var region = maskObject.region; 488 var mask = maskObject.enabled ? maskObject.heightmask[region] : []; 489 var maskScale = maskObject.enabled ? maskObject.scale : 1; 490 491 //The maskScaleField is the height scaling array. Use one if provided by maskObject.field, otherwise use md.geometry.surface 492 var maskScaleField = !VESL.Helpers.isEmptyOrUndefined(maskObject.scaleField) ? maskObject.scaleField : md.geometry.surface; 493 //If md.geometry.surface was empty and was used as maskScaleField, assign an empty array to both. 494 if (!maskScaleField) { 495 md.geometry.surface = NewArrayFill(md.mesh.x.length,0); 496 maskScaleField = md.geometry.surface; 497 } 498 499 //Scale in 3D if using globe model, or in 2D otherwise. 485 500 if (md.mesh.classname() === 'mesh3dsurface') { 486 if (!maskObject.enabled) { 487 var xyz, magnitude; 488 x = x.slice(); 489 y = y.slice(); 490 z = z.slice(); 491 for(var i = 0; i < x.length; i++) { 492 xyz = vec3.fromValues(x[i], y[i], z[i]); 493 magnitude = 1 + md.geometry.surface[i] * scale / vec3.length(xyz); 494 vec3.scale(xyz, xyz, magnitude); 495 x[i] = xyz[0]; 496 y[i] = xyz[1]; 497 z[i] = xyz[2]; 498 } 499 } 500 else { 501 var mask = maskObject.mask; 502 var maskScale = maskObject.scale; 503 var element; 504 for (var i = 0; i < mask.length; i++) { 505 if (mask[i] === 1) { 501 var element; 502 if (x.length === md.mesh.numberofelements) { //element plot 503 for (var i = 0; i < x.length; i++) { 504 if (maskObject.enabled) { //Scale the element if mask is not enabled, or if it is, only if it is also in the mask 506 505 element = elements[i]; 507 506 for (var j = 0; j < 3; j++) { 508 507 xyz = vec3.fromValues(x[element[j] - 1], y[element[j] - 1], z[element[j] - 1]); 509 magnitude = 1 + m d.geometry.surface[element[j] - 1] * scale * maskScale / vec3.length(xyz);508 magnitude = 1 + maskScaleField[element[j] - 1] * mask[i] * scale * maskScale / vec3.length(xyz); 510 509 vec3.scale(xyz, xyz, magnitude); 511 510 x[element[j] - 1] = xyz[0]; … … 517 516 } 518 517 } 518 else if (x.length === md.mesh.numberofvertices) { //node plot 519 for (var i = 0; i < x.length; i++) { 520 if (!maskObject.enabled || mask[i] === 1) { //Scale the node if mask is not enabled, or if it is, only if it is also in the mask 521 xyz = vec3.fromValues(x[i], y[i], z[i]); 522 magnitude = 1 + maskScaleField[i] * scale * maskScale / vec3.length(xyz); 523 vec3.scale(xyz, xyz, magnitude); 524 x[i] = xyz[0]; 525 y[i] = xyz[1]; 526 z[i] = xyz[2]; 527 } 528 } 529 } 530 } else { 531 z = z.slice(); 532 var zMin = ArrayMin(maskScaleField); 533 for(var i = 0; i < z.length; i++) { 534 if (!maskObject.enabled || mask[i] === 1) { //Scale the element if mask is not enabled, or if it is, only if it is also in the mask 535 z[i] = (z[i] - zMin) * scale + zMin; 536 } 537 } 538 } 539 return [x, y, z]; 540 } //}}} 541 Node.prototype.computeMasks = function() { //{{{ 542 //NOTE: Since sets are not yet widely supported, use array with binary values to represent if object is in set. 543 //NOTE: Only support element wise masks for now. 544 var maskObject = this.maskObject; 545 if (!maskObject.enabled) { return; } 546 var region = maskObject.region; 547 var mask = maskObject.mask[region]; 548 var maskRegion = []; //new Set() 549 var maskAdjacency = []; //new Set() 550 var adjacentElements; 551 var adjacentElements2; 552 var adjacentNodes; 553 var adjacentNodes2; 554 var adjacencyLength; //length of connectivity array - 3 for elements, many for nodes 555 var index; 556 //For each element in the mask elements array, 557 if (mask.length === md.mesh.numberofelements) { //element plot 558 if (md.mesh.elementconnectivity) { 559 var adjacencyLength = 3; 560 for (var i = 0; i < mask.length; i++) { 561 //Determine if element is in the mask 562 if (mask[i] === 1) { 563 //Then add each element to the adjacency set and mask region set 564 adjacentElements = md.mesh.elementconnectivity[i]; 565 for (var j = 0; j < adjacencyLength; j++) { 566 index = adjacentElements[j] - 1; 567 maskAdjacency[index] = true; 568 569 //Get second level of adjacent elemnents to form solid boundary (first layer look like this: /\/\/\/\/\; second layer looks like this \/\/\/\/\/; combined = | | 570 adjacentElements2 = md.mesh.elementconnectivity[index]; 571 for (var k = 0; k < adjacencyLength; k++) { 572 index = adjacentElements2[k] - 1; 573 maskAdjacency[index] = true; 574 } 575 } 576 maskRegion[i] = true; 577 } 578 } 579 } 580 } 581 else if (mask.length === md.mesh.numberofvertices) { //node plot 582 if (md.mesh.nodeconnectivity) { 583 var adjacencyLength = md.mesh.nodeconnectivity[0].length; 584 for (var i = 0; i < mask.length; i++) { 585 //Determine if node is in the mask 586 if (mask[i] === 1) { 587 //Then add each node to the adjacency set and mask region set 588 adjacentNodes = md.mesh.nodeconnectivity[i]; 589 for (var j = 0; j < adjacencyLength; j++) { 590 index = adjacentNode[j]; 591 maskAdjacency[index] = true; 592 593 //Get second level of adjacent elemnents to form solid boundary (first layer look like this: /\/\/\/\/\; second layer looks like this \/\/\/\/\/; combined = | | 594 adjacentNodes2 = md.mesh.nodeconnectivity[index]; 595 for (var k = 0; k < adjacencyLength; k++) { 596 index = adjacentNodes2[k]; 597 maskAdjacency[index] = true; 598 } 599 } 600 maskRegion[i] = true; 601 } 602 } 603 } 604 } 605 606 //Then subtract the mask elements array from the mask adjacency array. 607 var maskBoundary = []; 608 for (var i in maskAdjacency) { 609 if (!(i in maskRegion)) { 610 maskBoundary[i] = true; 611 } 612 } 613 this.maskBoundary = maskBoundary; 614 615 //For each element not in any mask region (default to mask[0] in slr-gfm), change color to mask color. 616 var maskAll = maskObject.mask[0]; 617 this.maskAll = maskAll; 618 } //}}} 619 Node.prototype.queryCoordMask = function(index) { //{{{ 620 //Calculate UV coordinate offsets for special color texture lookup. 621 if (!this.maskObject.enabled) { 622 return 1.0 519 623 } 520 624 else { 521 z = z.slice(); 522 var zMin = ArrayMin(md.geometry.surface); 523 for(var i = 0; i < z.length; i++) { 524 z[i] = (z[i] - zMin) * scale + zMin; 525 } 526 } 527 return [x, y, z]; 625 //var sections = 3; //Object.keys(maskObject.colors).length + 1 626 //var boundaryCoord = 0.5 / sections; 627 //var maskCoord = 1.5 / sections; 628 //var textureCoord = 2.5 / sections; 629 if (index in this.maskBoundary) { 630 return 0.166666667; //boundaryCoord - edge color 631 } 632 else if (this.maskAll[index] === 0) { 633 return 0.5; //maskCoord - masked color 634 } 635 else { 636 return 0.833333333; //textureCoord - default colormap 637 } 638 } 528 639 } //}}} 529 640 Node.prototype.mergeVertices = function(x1, y1, z1, elements1, x2, y2, z2, elements2) { //{{{
Note:
See TracChangeset
for help on using the changeset viewer.