Changeset 22894
- Timestamp:
- 07/03/18 01:05:04 (7 years ago)
- Location:
- issm/trunk-jpl/src
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/bamg/BamgGeom.h
r12821 r22894 7 7 class BamgGeom{ 8 8 9 10 // HI DANIEL I'M DANIEL. 11 //FLATTEN THAT ARRAY AND SET THAT SIZE. THANKS. 9 12 public: 10 13 int VerticesSize[2]; -
issm/trunk-jpl/src/m/array/arrayoperations.js
r22878 r22894 258 258 return notarray; 259 259 } //}}} 260 function ArrayFlip(array) { //{{{ 261 262 var notarray=array.slice(); 263 for (var i=0;i<array.length;i++)notarray[i]=array[i]^1; 264 return notarray; 265 } //}}} 260 266 function ArrayCopy(array) { //{{{ 261 267 … … 293 299 for(var i=0;i<array.length;i++){ 294 300 for(var j=0;j<array[0].length;j++){ 295 if ( Number.isNaN(array[i][j])) return 1;301 if (isNaN(array[i][j])) return 1; 296 302 } 297 303 } … … 299 305 else{ 300 306 for(var i=0;i<array.length;i++){ 301 if ( Number.isNaN(array[i])) return 1;307 if (isNaN(array[i])) return 1; 302 308 } 303 309 } … … 333 339 function ArrayAnyEqual(array,value) { //{{{ 334 340 335 if(! Number.isNaN(value)){341 if(!isNaN(value)){ 336 342 for(var i=0;i<array.length;i++){ 337 343 if (array[i]==value)return 1; … … 340 346 else{ 341 347 for(var i=0;i<array.length;i++){ 342 if ( Number.isNaN(array[i]))return 1;348 if (isNaN(array[i]))return 1; 343 349 } 344 350 } … … 553 559 554 560 } //}}} 561 function typedArraySliceSupport() { //{{{ 562 //TypedArray compatibility for Safari/IE 563 if (typeof Int8Array !== 'undefined') { 564 if (!Int8Array.prototype.fill) { Int8Array.prototype.fill = Array.prototype.fill; } 565 if (!Int8Array.prototype.slice) { Int8Array.prototype.slice = Array.prototype.slice; } 566 } 567 if (typeof Uint8Array !== 'undefined') { 568 if (!Uint8Array.prototype.fill) { Uint8Array.prototype.fill = Array.prototype.fill; } 569 if (!Uint8Array.prototype.slice) { Uint8Array.prototype.slice = Array.prototype.slice; } 570 } 571 if (typeof Uint8ClampedArray !== 'undefined') { 572 if (!Uint8ClampedArray.prototype.fill) { Uint8ClampedArray.prototype.fill = Array.prototype.fill; } 573 if (!Uint8ClampedArray.prototype.slice) { Uint8ClampedArray.prototype.slice = Array.prototype.slice; } 574 } 575 if (typeof Int16Array !== 'undefined') { 576 if (!Int16Array.prototype.fill) { Int16Array.prototype.fill = Array.prototype.fill; } 577 if (!Int16Array.prototype.slice) { Int16Array.prototype.slice = Array.prototype.slice; } 578 } 579 if (typeof Uint16Array !== 'undefined') { 580 if (!Uint16Array.prototype.fill) { Uint16Array.prototype.fill = Array.prototype.fill; } 581 if (!Uint16Array.prototype.slice) { Uint16Array.prototype.slice = Array.prototype.slice; } 582 } 583 if (typeof Int32Array !== 'undefined') { 584 if (!Int32Array.prototype.fill) { Int32Array.prototype.fill = Array.prototype.fill; } 585 if (!Int32Array.prototype.slice) { Int32Array.prototype.slice = Array.prototype.slice; } 586 } 587 if (typeof Uint32Array !== 'undefined') { 588 if (!Uint32Array.prototype.fill) { Uint32Array.prototype.fill = Array.prototype.fill; } 589 if (!Uint32Array.prototype.slice) { Uint32Array.prototype.slice = Array.prototype.slice; } 590 } 591 if (typeof Float32Array !== 'undefined') { 592 if (!Float32Array.prototype.fill) { Float32Array.prototype.fill = Array.prototype.fill; } 593 if (!Float32Array.prototype.slice) { Float32Array.prototype.slice = Array.prototype.slice; } 594 } 595 if (typeof Float64Array !== 'undefined') { 596 if (!Float64Array.prototype.fill) { Float64Array.prototype.fill = Array.prototype.fill; } 597 if (!Float64Array.prototype.slice) { Float64Array.prototype.slice = Array.prototype.slice; } 598 } 599 if (typeof TypedArray !== 'undefined') { 600 if (!TypedArray.prototype.fill) { TypedArray.prototype.fill = Array.prototype.fill; } 601 if (!TypedArray.prototype.slice) { TypedArray.prototype.slice = Array.prototype.slice; } 602 } 603 } //}}} -
issm/trunk-jpl/src/m/classes/clusters/generic.js
r21911 r22894 1 //GENERIC class definition 2 // 3 // Usage: 4 // generic=new generic(); 1 // Execute script in strict mode 2 'use strict'; 3 /** 4 * generic - Class that allows for sending requests to server and handling response or errors 5 * 6 * Usage: 7 * generic = new generic(); 8 * 9 * Todo: 10 * Convert to ES6 class 11 */ 12 function generic() { 13 // Retrieve options and apply to properties 14 // {{{ 15 let args = Array.prototype.slice.call(arguments); 16 let options = new pairoptions(args.slice(0, args.length)); 17 18 this.url = options.getfieldvalue('url', ''); 19 this.np = options.getfieldvalue('np', 3); 20 this.codeversion = options.getfieldvalue('codeversion', 20486); 21 this.codepath = options.getfieldvalue('codepath', 'issmdir/bin'); 22 this.executionpath = options.getfieldvalue('executionpath', 'issmdir/execution'); 23 //}}} 24 25 26 // Methods 27 //{{{ 28 this.disp = function() { //{{{ 29 console.log(sprintf(' generic class echo:')); 30 console.log(sprintf(' url: %s', this.url)); 31 console.log(sprintf(' np: %i', this.np)); 32 console.log(sprintf(' codepath: %s', this.codepath)); 33 console.log(sprintf(' executionpath: %s', this.executionpath)); 34 }; //}}} 35 36 this.classname = function() { //{{{ 37 return 'generic'; 38 }; //}}} 39 40 this.checkconsistency = function(md, solution, analyses) { //{{{ 41 if (cluster.np < 1) { 42 md.checkmessage('Number of processors should be at least 1!'); 43 } 44 if (isNaN(cluster.np)) { 45 md.checkmessage('Number of processors NaN!'); 46 } 47 }; //}}} 48 49 this.BuildQueueScript = function(cluster, dirname, modelname, solution, io_gather, isvalgrind, isgprof, isdakota) { //{{{ 50 //write queuing script 51 //what is the executable being called? 52 executable = 'issm.exe'; 53 54 fid = fopen(modelname + '.queue','w'); 55 fprintf(fid, '#!%s\n', cluster.shell); 56 fprintf(fid, 'mpiexec -np %i %s/%s %s %s %s 2> %s.errlog >%s.outlog ', cluster.np, cluster.codepath, executable, EnumToString(solution), cluster.executionpath + '/' + dirname, modelname, modelname, modelname); 57 fclose(fid); 58 }; //}}} 59 60 this.UploadAndRun = function(md, fid, toolkitsstring, solutionstring, name, runtimename, successCallback, errorCallback, solveButtonId, callout, withProgressBar) { //{{{ 61 /* Local constants */ 62 let PROGRESS_BAR_ID = 'solve-progress-bar'; 63 let PROGRESS_BAR_TEXT_PERCENTAGE_ID = 'progress-bar-text-percentage'; 64 65 /* Local variables */ 66 let hasCallout = false; 67 let isProgressBarLoaded = false; 68 let progressBar = {}; 69 let progressBarTextPercentage = {}; 70 let request = {}; 71 let solveButton = $(solveButtonId); 72 let solveButtonText = !vesl.helpers.isEmptyOrUndefined(solveButton) ? solveButton.text() : ''; // Save initial solve button text 73 74 /* Local functions */ 75 // NOTE: After conversion of generic to ES6 class, these should be class methods 76 function loadProgressBar() { 77 callout.setContent('\ 78 <div class="progress-bar-wrapper">\ 79 <progress id="' + PROGRESS_BAR_ID + '" value="0" max="100"></progress>\ 80 <div class="progress-bar-text">\ 81 <span id="' + PROGRESS_BAR_TEXT_PERCENTAGE_ID + '">0</span>\ 82 <span>%</span>\ 83 </div>\ 84 </div>\ 85 '); 86 87 progressBar = $('#' + PROGRESS_BAR_ID); 88 progressBarTextPercentage = $('#' + PROGRESS_BAR_TEXT_PERCENTAGE_ID); 89 isProgressBarLoaded = true; 90 } 91 92 function setProgressBar(progress) { 93 progressBar.val(progress); 94 progressBarTextPercentage.text(progress); 95 } 96 97 // Check certain arguments 98 hasCallout = !vesl.helpers.isEmptyOrUndefined(callout); 99 100 // Check that we have a connection 101 if (!navigator.onLine) { 102 console.log('Error: no connection!'); 103 if (hasCallout) { 104 callout.set('No connection!', ''); 105 } else { 106 solveButton.text('No connection!').prop('disabled', false); 107 } 108 errorCallback(); 109 return; 110 } 111 112 // Create request 113 request = new XMLHttpRequest(); 114 request.open('POST', this.url, true); 115 116 // Set request properties 117 request.position = 0; // Keep track of current parsing position in repsonseText 118 request.timeout = 1000 * 60 * 60 * 3; // 3 hrs (in milliseconds); NOTE: This should match FastCgiServer timeout in Apache conf 119 120 request.ontimeout = function(event) { //{{{ 121 console.log('Error: timeout!'); 122 123 if (hasCallout) { 124 callout.set(vesl.ERROR_HEADER_GENERAL, '<p>Request timeout! ' + vesl.ERROR_CONTENT_TRY_AGAIN + '</p>'); 125 } else { 126 solveButton.text('Timeout!').prop('disabled', false); 127 } 128 129 errorCallback(); 130 }; //}}} 131 132 request.onerror = function(event) { //{{{ 133 console.log('Error: could not run!'); 134 135 if (hasCallout) { 136 callout.set(vesl.ERROR_HEADER_GENERAL, '<p>Something went wrong. ' + vesl.ERROR_CONTENT_TRY_AGAIN + '</p>'); 137 } else { 138 solveButton.text('Could not run!').prop('disabled', false); 139 } 140 141 errorCallback(); 142 }; //}}} 143 144 request.upload.onprogress = function(event) { //{{{ 145 let progress = (event.loaded / event.total * 100).toFixed(0); 146 147 if (hasCallout) { 148 callout.setHeader('Sending request...'); 149 if (withProgressBar) { 150 if (!isProgressBarLoaded) { 151 loadProgressBar(); 152 } 153 setProgressBar(progress); 154 } else { 155 callout.setContent('<p>' + progress + '%</p>'); 156 } 157 } else { 158 solveButton.text('Sending: ' + progress + '%'); 159 } 160 }; //}}} 161 162 request.onprogress = function(event) { //{{{ 163 /* Local variables */ 164 let progress = 0; 5 165 6 function generic (){ 7 //properties 8 // {{{ 9 var args = Array.prototype.slice.call(arguments); 10 var options = new pairoptions(args.slice(0,args.length)); 166 // Receive updates by parsing message length as a 32-bit hex string of form 0x*09ABCDEF)) 167 let startIndex = request.position; 168 let endIndex = request.position + 10; 169 170 if (request.responseText.length >= endIndex) { // Ensure entire hex string is loaded 171 let chunkSize = parseInt(request.responseText.slice(startIndex, endIndex)); 172 173 startIndex = endIndex; 174 endIndex = startIndex + chunkSize; 175 176 if (chunkSize >= 1024) { // Arbitrary maximium size of message (Must be below minimium size of model results) 177 progress = ((request.responseText.length - request.position) / chunkSize * 100).toFixed(0); 178 if (hasCallout) { 179 callout.setHeader('Downloading result...'); 180 if (withProgressBar) { 181 setProgressBar(progress); 182 } else { 183 callout.setContent('<p>' + progress + '%</p>'); 184 } 185 } else { 186 solveButton.text('Downloading: ' + progress + '%').prop('disabled', true); 187 } 188 } else if (request.responseText.length >= endIndex) { // Ensure entire chunk is loaded 189 progress = parseInt(request.responseText.slice(startIndex, endIndex)); 190 if (hasCallout) { 191 callout.setHeader('Computing...'); 192 if (withProgressBar) { 193 setProgressBar(progress); 194 } else { 195 callout.setContent('<p>' + progress + '%</p>'); 196 } 197 } else { 198 solveButton.text('Computing: ' + progress + '%').prop('disabled', true); 199 } 200 request.position = endIndex; 201 } 202 } 203 }; //}}} 204 205 request.onload = function(event) { //{{{ 206 /* Local variables */ 207 //{{{ 208 let buffer = {}; 209 // let bufferInflated = {}; 210 let responseText = ''; 211 //}}} 212 213 // TODO: Get context to this.str2ab or otherwise declare it in order to avoid duplication 214 function str2ab(str) { //{{{ 215 let buffer = new Uint8Array(str.length); 216 for (let i = 0, strLen = str.length; i < strLen; ++i) { 217 buffer[i] = str.charCodeAt(i); 218 } 219 return buffer; 220 } //}}} 221 222 try { 223 /* 224 console.log(request.responseText); 225 console.log('request.position : ' + request.position); 226 console.log('request.responseType : ' + request.responseType); 227 console.log('request.responseText.length : ' + request.responseText.length); 228 */ 229 responseText = window.atob(request.responseText.slice(request.position + 10).replace(/\s/g, '')); 230 // console.log('responseText.length : ' + responseText.length); 231 buffer = str2ab(responseText); 232 // console.log('buffer.length : ' + buffer.length); 233 /* 234 bufferInflated = UZIP.inflate(buffer); 235 console.log('bufferInflated.length : ' + bufferInflated.length); 236 */ 237 238 /* 239 returnBuffer = new Uint8Array(buffer); 240 returnBufferSize = returnBuffer.byteLength; 241 */ 242 243 //Write result buffer to file for debugging. Filename and MIME type are optional. 244 //writetofile(returnBuffer, 'resultBuffer', 'application/octet-stream'); 245 // md.results = parseresultsfrombuffer(md, bufferInflated, bufferInflated.length); 246 md.results = parseresultsfrombuffer(md, buffer, buffer.length); 247 248 // Let front end script handle changes to callout 249 if (hasCallout) { 250 callout.set('Success!', '<p>Solve successful</p>'); 251 } else { 252 solveButton.text(solveButtonText).prop('disabled', false); 253 } 254 successCallback(); 255 } catch (e) { 256 console.log(e); 257 if (vesl.string.startsWith(responseText, 'Error')) { 258 if (hasCallout) { 259 callout.set(vesl.ERROR_HEADER_GENERAL, '<p>Something went wrong. ' + vesl.ERROR_CONTENT_TRY_AGAIN + '</p>'); 260 } else { 261 solveButton.text('ISSM error!').prop('disabled', false); 262 } 263 } else { 264 if (hasCallout) { 265 callout.set(vesl.ERROR_HEADER_GENERAL, '<p>Something went wrong. ' + vesl.ERROR_CONTENT_TRY_AGAIN + '</p>'); 266 } else { 267 solveButton.text('JS error!').prop('disabled', false); 268 } 269 } 270 errorCallback(); 271 } 272 }; //}}} 273 274 request.responseType = 'application/octet-stream'; 275 276 /* Construct request */ 277 let npbuffer = this.str2ab(md.cluster.np.toString()); 278 npbuffer = UZIP.deflate(npbuffer); 279 let nplength = new Uint32Array(1); 280 nplength[0] = npbuffer.byteLength; 281 282 let codeversionbuffer = this.str2ab(md.cluster.codeversion.toString()); 283 codeversionbuffer = UZIP.deflate(codeversionbuffer); 284 let codeversionlength = new Uint32Array(1); 285 codeversionlength[0] = codeversionbuffer.byteLength; 286 287 let runtimenamebuffer = this.str2ab(runtimename); 288 runtimenamebuffer = UZIP.deflate(runtimenamebuffer); 289 let runtimenamelength = new Uint32Array(1); 290 runtimenamelength[0] = runtimenamebuffer.byteLength; 291 292 let namebuffer = this.str2ab(name); 293 namebuffer = UZIP.deflate(namebuffer); 294 let namelength = new Uint32Array(1); 295 namelength[0] = namebuffer.byteLength; 296 297 let toolkitsbuffer = this.str2ab(toolkitsstring); 298 toolkitsbuffer = UZIP.deflate(toolkitsbuffer); 299 let toolkitslength = new Uint32Array(1); 300 toolkitslength[0] = toolkitsbuffer.byteLength; 301 302 let solutionbuffer = this.str2ab(solutionstring); 303 solutionbuffer = UZIP.deflate(solutionbuffer); 304 let solutionlength = new Uint32Array(1); 305 solutionlength[0] = solutionbuffer.byteLength; 306 307 let binbuffer = new Uint8Array(fid.rawbuffer()); //seems that 16 bits length could be incompatible. 308 binbuffer = UZIP.deflate(binbuffer); 309 let binlength = new Uint32Array(1); 310 binlength[0] = binbuffer.byteLength; 311 312 let data = new Blob( 313 [ 314 nplength, 315 npbuffer, 316 codeversionlength, 317 codeversionbuffer, 318 runtimenamelength, 319 runtimenamebuffer, 320 namelength, 321 namebuffer, 322 toolkitslength, 323 toolkitsbuffer, 324 solutionlength, 325 solutionbuffer, 326 binlength, 327 binbuffer 328 ] 329 ); 11 330 12 this.url=options.getfieldvalue('url',''); 13 this.np=options.getfieldvalue('np',3); 14 this.codeversion=options.getfieldvalue('codeversion',20486); 15 this.codepath=options.getfieldvalue('codepath','issmdir/bin'); 16 this.executionpath=options.getfieldvalue('executionpath','issmdir/execution'); 17 //}}} 18 //methods 19 this.disp= function(){// {{{ 20 console.log(sprintf(' generic class echo:')); 21 console.log(sprintf(' url: "%s"',this.url)); 22 console.log(sprintf(' np: %i',this.np)); 23 console.log(sprintf(' codepath: "%s"',this.codepath)); 24 console.log(sprintf(' executionpath: "%s"',this.executionpath)); 25 }// }}} 26 this.classname= function(){// {{{ 27 return "generic"; 28 }// }}} 29 this.checkconsistency = function (md,solution,analyses) { //{{{ 30 if (cluster.np<1){ 31 md.checkmessage('number of processors should be at least 1'); 32 } 33 if (isNaN(cluster.np)){ 34 md.checkmessage('number of processors should not be NaN!'); 35 } 36 } //}}} 37 this.BuildQueueScript = function (cluster,dirname,modelname,solution,io_gather,isvalgrind,isgprof,isdakota) { // {{{ 38 39 //write queuing script 40 //what is the executable being called? 41 executable='issm.exe'; 42 43 fid=fopen(modelname+'.queue','w'); 44 fprintf(fid,'#!%s\n',cluster.shell); 45 fprintf(fid,'mpiexec -np %i %s/%s %s %s %s 2> %s.errlog >%s.outlog ',cluster.np,cluster.codepath,executable,EnumToString(solution),cluster.executionpath+'/'+dirname,modelname,modelname,modelname); 46 fclose(fid); 47 } //}}} 48 this.UploadAndRun = function (md,callbackfunction,callbackerrorfunction,callbackid,fid,toolkitsstring,solutionstring,name,runtimename) { //{{{ 49 if (!navigator.onLine) { //{{{ 50 $(callbackid).html(sprintf("%-16s", "NO CONNECTION")).prop("disabled", false); 51 callbackerrorfunction(); 52 return; 53 } //}}} 54 var request = new XMLHttpRequest(); 55 request.open("POST", this.url, true); 56 $(callbackid).html(sprintf("%-16s", "CONNECTING...")).prop("disabled", true); 57 request.position = 0; //Keep track of current parsing position in repsonseText 58 request.timeout = 180000; 59 request.ontimeout = function (event) { //{{{ 60 $(callbackid).html(sprintf("%-16s", "TIMEOUT")).prop("disabled", false); 61 callbackerrorfunction(); 62 } //}}} 63 request.onerror = function (event) { //{{{ 64 $(callbackid).html(sprintf("%-16s", "COULD NOT RUN")).prop("disabled", false); 65 callbackerrorfunction(); 66 } //}}} 67 request.upload.onprogress = function(event) { //{{{ 68 var progress = (event.loaded / event.total * 100).toFixed(0); 69 $(callbackid).html(sprintf("%-20s", "UPLOADING: " + progress + "%")); 70 } //}}} 71 request.onprogress = function (event) { //{{{ 72 //Receive updates by parsing message length as a 32-bit hex string of form 0x*09ABCDEF)) 73 var startIndex = request.position; 74 var endIndex = request.position + 10; 75 if (request.responseText.length >= endIndex) { //Ensure entire hex string is loaded 76 var chunkSize = parseInt(request.responseText.slice(startIndex, endIndex)); 77 startIndex = endIndex; 78 endIndex = startIndex + chunkSize; 79 if (chunkSize >= 1024) { //Arbitrary maximium size of message (Must be below minimium size of model results) 80 $(callbackid).html(sprintf("%-20s", "DOWNLOADING: " + ((request.responseText.length - request.position) / chunkSize * 100).toFixed(0) + "%")).prop("disabled", true); 81 } 82 else if (request.responseText.length >= endIndex) { //Ensure entire chunk is loaded 83 var responseChunk = request.responseText.slice(startIndex, endIndex); 84 $(callbackid).html(responseChunk); 85 request.position = endIndex; 86 } 87 } 88 }; //}}} 89 request.onload = function (event) { //{{{ 90 //get context to this.str2ab to avoid duplciation 91 function str2ab(str) { 92 var buf = new Uint8Array(str.length); 93 for (var i=0, strLen=str.length; i < strLen; i++) { 94 buf[i] = str.charCodeAt(i); 95 } 96 return buf; 97 } 98 var responseText = window.atob(request.responseText.slice(request.position + 10).replace(/\s/g, '')); 99 var buffer = pako.inflate(str2ab(responseText)); 100 var returnBuffer = new Uint8Array(buffer); 101 var returnBuffer_size = returnBuffer.byteLength; 102 try { 103 //Write result buffer to file for debugging. Filename and MIME type are optional. 104 //writetofile(returnBuffer, "resultBuffer", "application/octet-stream"); 105 md.results = parseresultsfrombuffer(md,returnBuffer,returnBuffer_size); 106 $(callbackid).html(sprintf("%-16s", "RUN")).prop("disabled", false); 107 callbackfunction(); 108 } 109 catch (e) { 110 if (responseText.startsWith('Error')) { 111 console.log(responseText); 112 $(callbackid).html(sprintf("%-16s", "ISSM ERROR")).prop("disabled", false); 113 } 114 else { 115 $(callbackid).html(sprintf("%-16s", "JS ERROR")).prop("disabled", false); 116 console.log(e); 117 } 118 callbackerrorfunction(); 119 } 120 121 }; //}}} 122 123 var npbuffer = this.str2ab(md.cluster.np.toString()); 124 npbuffer = pako.deflate(npbuffer); 125 var nplength = new Uint32Array(1); 126 nplength[0] = npbuffer.byteLength; 127 128 var codeversionbuffer = this.str2ab(md.cluster.codeversion.toString()); 129 codeversionbuffer = pako.deflate(codeversionbuffer); 130 var codeversionlength = new Uint32Array(1); 131 codeversionlength[0] = codeversionbuffer.byteLength; 132 133 var runtimenamebuffer = this.str2ab(runtimename); 134 runtimenamebuffer = pako.deflate(runtimenamebuffer); 135 var runtimenamelength = new Uint32Array(1); 136 runtimenamelength[0] = runtimenamebuffer.byteLength; 137 138 var namebuffer = this.str2ab(name); 139 namebuffer = pako.deflate(namebuffer); 140 var namelength = new Uint32Array(1); 141 namelength[0] = namebuffer.byteLength; 142 143 var toolkitsbuffer = this.str2ab(toolkitsstring); 144 toolkitsbuffer = pako.deflate(toolkitsbuffer); 145 var toolkitslength = new Uint32Array(1); 146 toolkitslength[0] = toolkitsbuffer.byteLength; 147 148 var solutionbuffer = this.str2ab(solutionstring); 149 solutionbuffer = pako.deflate(solutionbuffer); 150 var solutionlength = new Uint32Array(1); 151 solutionlength[0] = solutionbuffer.byteLength; 152 153 var binbuffer = new Uint8Array(fid.rawbuffer()); //seems that 16 bits length could be incompatible. 154 binbuffer = pako.deflate(binbuffer); 155 var binlength = new Uint32Array(1); 156 binlength[0] = binbuffer.byteLength; 157 158 var data = new Blob([nplength,npbuffer,codeversionlength,codeversionbuffer,runtimenamelength,runtimenamebuffer,namelength,namebuffer,toolkitslength,toolkitsbuffer,solutionlength,solutionbuffer,binlength,binbuffer]); 159 160 request.responseType = 'application/octet-stream'; 331 // Send request 161 332 request.send(data); 162 333 163 } //}}} 334 if (hasCallout) { 335 callout.set('Connecting...', ''); 336 } else { 337 solveButton.text('Connecting...').prop('disabled', true); 338 } 339 }; //}}} 340 164 341 this.ab2str = function(buf) { //{{{ 165 342 return String.fromCharCode.apply(null, new Uint16Array(buf)); 166 } //}}} 343 }; //}}} 344 167 345 this.str2ab = function(str) { //{{{ 168 var buf = new Uint8Array(str.length); 169 for (var i=0, strLen=str.length; i < strLen; i++) { 346 let buf = new Uint8Array(str.length); 347 348 for (let i = 0, strLen = str.length; i < strLen; i++) { 170 349 buf[i] = str.charCodeAt(i); 171 350 } 351 172 352 return buf; 173 } //}}}353 }; //}}} 174 354 } -
issm/trunk-jpl/src/m/plot/applyoptions.js
r22434 r22894 13 13 //{{{ Variable options initialization 14 14 var caxis = options.getfieldvalue('caxis'); 15 var colorbarinnerlabels = options.getfieldvalue('colorbarinnerlabels','off');16 15 var ccanvasid, ctitleid, clabelsid, ccanvas, ctitle, clabels, ccontext, cmap, colorbar, cwidth, cheight, cgradient, color, y, x; 17 16 //}}} … … 83 82 clabelsid = options.getfieldvalue('colorbarid', ccanvasid).replace('canvas','labels'); 84 83 clabels = $('#'+clabelsid); 85 if (colorbarinnerlabels=='on') {86 clabels.removeClass('sim-colorbar-labels-outer');87 clabels.addClass('sim-colorbar-labels-inner');88 }89 else {90 clabels.removeClass('sim-colorbar-labels-inner');91 clabels.addClass('sim-colorbar-labels-outer');92 }93 84 var clabelstring = ''; 94 85 clabels.empty(); … … 137 128 if (options.exist('maskregion')) { 138 129 var maskObject = options.getfieldvalue('maskregion',{'enabled':false}); 139 if (maskObject.enabled && ! VESL.Helpers.isEmptyOrUndefined(maskObject.colors)) {130 if (maskObject.enabled && !vesl.helpers.isEmptyOrUndefined(maskObject.colors)) { 140 131 var x = 0; 141 132 var sections = Object.keys(maskObject.colors).length + 1; … … 157 148 //}}} 158 149 //{{{ text display 159 var overlaycanvasid = options.getfieldvalue('overlayid', options.getfieldvalue('canvasid')+'-overlay'); 160 var overlaycanvas = $('#'+overlaycanvasid)[0]; 161 if (!VESL.Helpers.isEmptyOrUndefined(overlaycanvas)) { 150 var ctx; 151 var overlaycanvasid; 152 var overlaycanvas; 153 //Only intialize overlay canvas once by checking if it's already been defined 154 if (vesl.helpers.isEmptyOrUndefined(canvas.overlaycanvas)) { 162 155 //Get drawing context and save reference on main WebGL canvas 163 var ctx = overlaycanvas.getContext('2d'); 156 overlaycanvasid = options.getfieldvalue('overlayid', options.getfieldvalue('canvasid') + '-overlay') 157 overlaycanvas = $('#' + overlaycanvasid)[0]; 158 ctx = overlaycanvas.getContext('2d'); 164 159 canvas.overlaycanvas = overlaycanvas; 165 166 //Resize interal viewport coordinates to match screenspace coordinates167 var rect = overlaycanvas.getBoundingClientRect();168 overlaycanvas.width = rect.width;169 overlaycanvas.height = rect.height;170 171 //Clear canvas each frame for any new drawings172 canvas.overlayHandlers['draw'] = function(overlaycanvas) {173 ctx.clearRect(0, 0, overlaycanvas.width, overlaycanvas.height);174 }175 160 } 176 //{{{ lat long overlay 177 if (options.exist('latlongoverlay')) { 178 var latitudes = { 179 //'-90': 1, 180 //'-65': .999, 181 '-60': 0.994046875, 182 '-45': 0.955729166666666, 183 '-30': 0.9226562500000024, 184 //'-15': 0.830729166666665, 185 '0': 0.74218749999999811, 186 //'15': 0.63932291666666663, 187 '30': 0.523390625000001, 188 '45': 0.4020001, 189 '60': 0.26953124999999978, 190 //'65': 0.225390625, 191 //'90': 0.0, 192 } 193 var longitudes = [-150, -120, -90, -60, -30, 0, 30, 60, 90, 120, 150, 180]; 194 canvas.overlayHandlers['latlong'] = function(canvas) { 195 //Transform from world space to viewport space 196 var centerx = overlaycanvas.width / 2; 197 var centery = overlaycanvas.height / 2; 198 var radius = (overlaycanvas.height) / 2; 199 200 //Draw latitudes 201 ctx.setLineDash([5, 10]); 202 for(latitude in latitudes) { 203 ctx.beginPath(); 204 ctx.arc(centerx, centery, radius * latitudes[latitude], 0, 2 * Math.PI); 205 ctx.stroke(); 206 ctx.font = 'bold ' + String(options.getfieldvalue('colorbarfontsize', 18))+'px "Lato", Helvetica, Arial, sans-serif'; 207 ctx.fillStyle = options.getfieldvalue('colorbarfontcolor','black'); 208 ctx.strokeStyle = options.getfieldvalue('colorbarfontcolor','black'); 209 ctx.textAlign = 'center'; 210 ctx.textBaseline = 'middle'; 211 ctx.fillText(latitude, centerx, centery + radius * latitudes[latitude]); 212 ctx.strokeText(latitude, centerx, centery + radius * latitudes[latitude]); 213 } 214 //Draw longitudes 215 ctx.setLineDash([1, 0]); 216 for (longitude in longitudes) { 217 ctx.beginPath(); 218 ctx.moveTo(centerx, centery); 219 ctx.lineTo(centerx + radius * Math.sin(longitudes[longitude] * DEG2RAD), centery + radius * Math.cos(longitudes[longitude] * DEG2RAD)); 220 ctx.stroke(); 221 } 222 } 223 } //}}} 224 if (options.exist('textlabels')) { 161 overlaycanvas = canvas.overlaycanvas; 162 ctx = overlaycanvas.getContext('2d'); 163 164 if (options.exist('textlabels')) {//{{{ 225 165 //Attatch new overlay handler to display text labels 226 166 var textLabels = options.getfieldvalue('textlabels',[]); … … 239 179 // function declared in slr-gfm sim-front-end-controller.js 240 180 // if labels are behind the globe sphere then skip iteartion and do not display them 241 if ( VESL.UI.isLabelVisible(textLabel)) {181 if (vesl.ui.isLabelVisible(textLabel)) { 242 182 //Transform from world space to viewport space 243 183 var screenPoint = vec3.transformMat4(vec3.create(), textLabel.position, canvas.camera.vpMatrix); … … 256 196 } 257 197 } 258 } //}}} 198 }//}}} 199 259 200 //{{{ additional rendering nodes 260 201 if (options.exist('render')) { … … 275 216 276 217 var renderObjects = options.getfieldvalue('render',{}); 218 277 219 for (var renderObject in renderObjects) { 278 220 //Modify renderObejct? … … 289 231 color: defaultFor(object.color, 'black'), //Diffuse color of object 290 232 height: defaultFor(object.height, 25000), //Height of object along y axis, currently for clouds only 291 range: defaultFor(object.range, 120000), //Range of sz plane to spawn object, currently for clouds only 292 quantity: defaultFor(object.quantity, 15) //Quantity of objects to display, currently for clouds only 233 range: defaultFor(object.range, 120000), //Range of sz plane to spawn object, currently for clouds only 234 quantity: defaultFor(object.quantity, 15), //Quantity of objects to display, currently for clouds only 235 source: defaultFor(object.source, 'NY'), //Quantity of objects to display, currently for clouds only 236 targets: defaultFor(object.targets, ['NY']) //Quantity of objects to display, currently for clouds only 293 237 }; 294 238 if (!object.enabled) { continue; } … … 382 326 node.patch('Vertices', [object.x, object.y, object.z], 'FaceColor', 'none'); 383 327 } 384 if ('city' === renderObject ) {328 if ('city' === renderObject && !vesl.helpers.isEmptyOrUndefined(overlaycanvas)) { 385 329 //city 386 330 var mesh = GL.Mesh.sphere({size: object.size}); … … 436 380 } 437 381 } 382 if ('citylines' === renderObject) { 383 //city 384 node = new Node( 385 'canvas', canvas, 386 'options', options, 387 'renderObject', object, 388 'name', 'citylines', 389 'shaderName', 'ColoredDiffuse', 390 'drawMode', gl.LINES, 391 'diffuseColor', object.color, 392 'lineWidth', options.getfieldvalue('linewidth', 1), 393 'scale', [object.scale, object.scale, object.scale], 394 'rotation', [0, 0, 0] 395 ); 396 397 //For each target city, calculate the shortest line across the earth by performing a quaternion slerp. 398 //Treat source and target city as vectors to rotate to from the north pole. 399 //Then, slerp between the two rotations, and generate points across equidistance points on the earth to create the line. 400 var north = vec3.fromValues(0, 1, 0); 401 var source = object.source; 402 var sourceXYZ = vec3.fromValues(xcity[source], zcity[source], -ycity[source]); 403 var radius = vec3.length(sourceXYZ); 404 var lineSteps = 50; 405 var lineX = []; 406 var lineY = []; 407 var lineZ = []; 408 var lineXYZ = vec3.create(); 409 410 for (var i = 0; i < object.targets.length; i++) { 411 var target = object.targets[i]; 412 var targetXYZ = vec3.fromValues(xcity[target], zcity[target], -ycity[target]); 413 var axis = vec3.cross(vec3.create(), sourceXYZ, targetXYZ); 414 vec3.normalize(axis, axis); 415 416 //Get the total angle between the two cities. 417 var sourceXYZAxis = vec3.normalize(vec3.create(), sourceXYZ); 418 var targetXYZAxis = vec3.normalize(vec3.create(), targetXYZ); 419 var dotProduct = vec3.dot(sourceXYZAxis, targetXYZAxis); 420 var totalAngle = Math.acos(dotProduct); //theta = arccos(u . v / (||u|| * ||v||); in this case, ||u|| and ||v|| are 1, since u and v are unit vectors. 421 422 var lineQuat = quat.create(); 423 for (var j = 1; j <= lineSteps; j++) { 424 //Calculate the partial rotation to obtain points on the line between the two cities. 425 var angle = j / lineSteps * totalAngle; 426 quat.setAxisAngle(lineQuat, axis, angle); 427 quat.normalize(lineQuat, lineQuat); 428 vec3.transformQuat(lineXYZ, sourceXYZ, lineQuat); 429 //GL.LINES needs 2 points for each line - at the beginning, just use the sourceXYZ. 430 //TODO: Eliminate this if statement. 431 if (j === 1) { 432 lineX.push(sourceXYZ[0]); 433 lineY.push(sourceXYZ[1]); 434 lineZ.push(sourceXYZ[2]); 435 } else { 436 lineX.push(lineX[lineX.length - 1]); 437 lineY.push(lineY[lineY.length - 1]); 438 lineZ.push(lineZ[lineZ.length - 1]); 439 } 440 lineX.push(lineXYZ[0]); 441 lineY.push(lineXYZ[1]); 442 lineZ.push(lineXYZ[2]); 443 } 444 } 445 node.patch('Vertices', [lineX, lineY, lineZ]); 446 } 438 447 } 439 448 } //}}} -
issm/trunk-jpl/src/m/plot/plot_mesh.js
r22715 r22894 7 7 // See also: PLOTMODEL, PLOT_MANAGER 8 8 9 //if ('mesh' in canvas.nodes && options.getfieldvalue('cachenodes','on') === 'on') return; 9 // If we already have the overlay and are using caching, short circuit 10 if ('mesh' in canvas.nodes && options.getfieldvalue('cachenodes', 'off') === 'on') { 11 return; 12 } 10 13 11 //{{{ declare variables: 14 /* 15 Local variables 16 */ 17 //{{{ 12 18 //Process data and model 13 19 var meshresults = processmesh(md, [], options); -
issm/trunk-jpl/src/m/plot/plot_overlay.js
r22434 r22894 7 7 // See also: PLOTMODEL, PLOT_MANAGER 8 8 9 if ('overlay' in canvas.nodes && options.getfieldvalue('cachenodes','on') === 'on') return; 9 // If we already have the overlay and are using caching, short circuit 10 if ('overlay' in canvas.nodes && options.getfieldvalue('cachenodes', 'off') === 'on') { 11 return; 12 } 10 13 11 //{{{ declare variables: 14 /* 15 Local variables 16 */ 17 //{{{ 12 18 //Process data and model 13 19 var meshresults = processmesh(md, [], options); -
issm/trunk-jpl/src/m/plot/plot_quiver.js
r22434 r22894 10 10 return; 11 11 12 if ('quiver' in canvas.nodes && noCacheNodesOverride && options.getfieldvalue('cachenodes','on') === 'on') return;12 //if ('quiver' in canvas.nodes && noCacheNodesOverride && options.getfieldvalue('cachenodes','off') === 'on') return; 13 13 14 14 //{{{ declare variables: … … 29 29 30 30 //Only displaying velocity fields for now 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 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; 34 34 35 35 //Handle heightscale -
issm/trunk-jpl/src/m/plot/plot_transient_movie.js
r22434 r22894 81 81 node.updateBuffer('Coords', processedData[frame]); 82 82 canvas.unitData = processedData[frame]; 83 if (canvas. dataMarkers.enabled) {84 updateMarker(canvas, false);83 if (canvas.graph.enabled) { 84 vesl.graph.draw(canvas); 85 85 } 86 86 if (canvas.playbackSlider) { … … 90 90 canvas.playbackTextProgress.html(steps[frame].toFixed(0) + " " + options.getfieldvalue("movietimeunit","yr")); 91 91 } 92 if (! VESL.Helpers.isEmptyOrUndefined(canvas.nodes.quiver)) {92 if (!vesl.helpers.isEmptyOrUndefined(canvas.nodes.quiver)) { 93 93 plot_quiver(md,options,canvas,false); 94 94 } -
issm/trunk-jpl/src/m/plot/plot_unit.js
r22434 r22894 11 11 if (options.getfieldvalue('clf','on')=='on') { 12 12 for (var node in canvas.nodes) { 13 if ( node.startsWith('unit')) {13 if (vesl.string.startsWith(node, 'unit')) { 14 14 delete canvas.octrees[node]; 15 15 delete canvas.nodes[node]; … … 31 31 var is2d = meshresults[4]; 32 32 var isplanet = meshresults[5]; 33 if (md.mesh.classname() !== 'mesh3dsurface') z = md.geometry.surface; 33 if (md.mesh.classname() !== 'mesh3dsurface') { 34 if (vesl.helpers.isNaN(md.geometry.surface) || (md.geometry.surface[0] !== undefined && vesl.helpers.isNaN(md.geometry.surface[0]))) { 35 md.geometry.surface = NewArrayFill(x.length, 0); 36 } 37 z = md.geometry.surface; 38 } 34 39 35 40 //Compute coordinates and data range: … … 48 53 scale = [1, 1, 1]; 49 54 } 50 55 51 56 //Compute gl variables: 52 57 var edgecolor = options.getfieldvalue('edgecolor', [1.0, 1.0, 1.0 ,1.0]); -
issm/trunk-jpl/src/m/plot/plotdoc.js
r22434 r22894 37 37 console.log(' "colormap": same as standard matlab option (default "jet", ex: "hsv","cool","spring","gray","Ala","Rignot",...)'); 38 38 console.log(' "controlsensitivity": sensitivty of view/zoom changes as a percentage of default (default 1, ex: 0.5, 2.75)'); 39 console.log(' "data markers": 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})');39 console.log(' "dataMarker": 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: "/canvas/data-markers/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
r22434 r22894 1 1 function plotmodel(md){ //{{{ 2 3 2 //Convert arguments to array: 4 3 var args = Array.prototype.slice.call(arguments); 5 4 6 5 //First process options 7 var options = new plotoptions(args.slice(1,args.length)); 8 6 var options = new plotoptions(args.slice(1,args.length)); 9 7 10 8 //get number of subplots … … 30 28 31 29 //check that nlines and ncols were given at the same time! 32 if ((options.list[0].exist('ncols') & !options.list[0].exist('nlines')) | (options.list[0].exist('nlines') & !options.list[0].exist('ncols'))) throw Error('plotmodel error message: nlines and ncols 30 if ((options.list[0].exist('ncols') & !options.list[0].exist('nlines')) | (options.list[0].exist('nlines') & !options.list[0].exist('ncols'))) throw Error('plotmodel error message: nlines and ncols need to be specified together, or not at all'); 33 31 34 32 //go through subplots -
issm/trunk-jpl/src/m/plot/webgl.js
r22434 r22894 4 4 //Initialize open Gl for each canvas and clear any previous animation handlers, once per plotmodel call: 5 5 canvas = document.getElementById(options.getfieldvalue('canvasid')); 6 //var canvas = document.getElementById(options.getfieldvalue('canvasid'));6 7 7 if (!canvas.initialized) { 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); }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 draw(canvas); 11 drawCanvas(canvas); 12 12 13 canvas.initialized = true; 13 14 14 //The onStart event triggers once per plotmodel call load after WebGL and canvas initialization are complete15 canvas.selector.trigger('onStart', [canvas]);16 }15 triggerStartEvent(canvas); 16 } 17 17 18 return canvas; 18 19 } … … 20 21 //Initialize canvas.gl on page load, reusing gl context on additional runs 21 22 var gl = canvas.gl; 22 if (VESL.Helpers.isEmptyOrUndefined(gl)) { 23 24 if (vesl.helpers.isEmptyOrUndefined(gl)) { 23 25 gl = GL.create({canvas: canvas}); 24 26 gl.enable(gl.DEPTH_TEST); // Enable depth testing … … 36 38 mc.add(new Hammer.Pan({threshold: 0, pointers: 0})); 37 39 mc.add(new Hammer.Pinch({threshold: 0})).recognizeWith(mc.get('pan')); 38 mc.on('tap', function 39 mc.on('panstart panmove', function 40 mc.on('pinchstart pinchmove', function 41 canvas.addEventListener('mousewheel', function 42 canvas.addEventListener('DOMMouseScroll', function 40 mc.on('tap', function(ev) {onTap(ev, canvas);}); 41 mc.on('panstart panmove', function(ev) {onPan(ev, canvas, displayview);}); 42 mc.on('pinchstart pinchmove', function(ev) {onPinch(ev, canvas, displayview);}); 43 canvas.addEventListener('mousewheel', function(ev) {onZoom(ev, canvas, displayzoom)}, false); 44 canvas.addEventListener('DOMMouseScroll', function(ev) {onZoom(ev, canvas, displayzoom)}, false); 43 45 44 46 //Add persistent state variables … … 60 62 } 61 63 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 = {}; 64 if (options.getfieldvalue('clf', 'on') === 'on') { 65 // Add context state variables 66 canvas.render = options.getfieldvalue('render', {}); 67 canvas.controlSensitivity = options.getfieldvalue('controlsensitivity', 1); 68 canvas.overlayHandlers = {}; 69 67 70 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)); } 71 72 if (backgroundcolor.ok) { 73 canvas.backgroundcolor = [ 74 backgroundcolor.r / 255.0, 75 backgroundcolor.g / 255.0, 76 backgroundcolor.b / 255.0, 77 1.0 78 ]; 79 } else { 80 throw Error(sprintf('s%s%s\n','initWebGL error message: cound not find out background color for current canvas ', canvas)); 81 } 70 82 71 83 //Property intiialization, using values from options first, then from default values. … … 125 137 ready: defaultFor(camera.ready, false) 126 138 }; 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 if (vesl.helpers.isEmptyOrUndefined(canvas.dataMarker)) { 140 var dataMarker = options.getfieldvalue('dataMarker', {}); 141 142 canvas.dataMarker = { 143 enabled: defaultFor(dataMarker.enabled, false), 144 element: defaultFor(dataMarker.element, $('#sim-data-marker-' + canvas.id)), 145 isTooltip: defaultFor(dataMarker.isTooltip, false), 146 handlersReady: defaultFor(dataMarker.handlersReady, false), 147 initialized: defaultFor(dataMarker.initialized, false), 148 visible: defaultFor(dataMarker.visible, false), 149 image: defaultFor(dataMarker.image, canvas.assetsPath + '/data-markers/data-marker.svg'), 150 size: defaultFor(dataMarker.size, [32, 32]), 151 font: defaultFor(dataMarker.font, ''), 152 reposition: defaultFor(dataMarker.reposition, true) 153 }; 154 } 155 var graph = options.getfieldvalue('graph', {}); 156 canvas.graph = { 157 enabled: defaultFor(graph.enabled, false), 158 id: defaultFor(graph.id, 'sim-graph'), 159 animated: defaultFor(graph.animated, false), 160 data: defaultFor(graph.data, []), 161 otherData: defaultFor(graph.otherData, {}) 139 162 }; 140 163 var draw = options.getfieldvalue('draw', {}); … … 159 182 160 183 // Override with parameters from URL, if any 161 VESL.UI.parsePermalinkCanvas(canvas);184 vesl.ui.parsePermalinkCanvas(canvas); 162 185 } 163 186 } //}}} … … 175 198 function initTexture(gl, imageSource) { //{{{ 176 199 //Initialize textures, or load from memory if they already exist. 177 if ( VESL.Helpers.isEmptyOrUndefined(gl.textures[imageSource])) {200 if (vesl.helpers.isEmptyOrUndefined(gl.textures[imageSource])) { 178 201 gl.textures[imageSource] = GL.Texture.fromURL(imageSource, {minFilter: gl.LINEAR_MIPMAP_LINEAR, magFilter: gl.LINEAR}, null, gl); 179 202 } … … 210 233 for (var i = 0; i < properties.length; i++) { 211 234 object = object[properties[i]]; 212 if ( VESL.Helpers.isEmptyOrUndefined(object)) { break; }235 if (vesl.helpers.isEmptyOrUndefined(object)) { break; } 213 236 } 214 237 return defaultFor(object, value); 238 } //}}} 239 function triggerStartEvent(canvas) { //{{{ 240 // If data markers are enabled for this canvas, wait for their handlers to be registered before triggering onStart event 241 if(!vesl.helpers.isEmptyOrUndefined(canvas.dataMarker) && canvas.dataMarker.enabled) { 242 vesl.dataMarker.areHandlersReady( 243 canvas, 244 function() { 245 // The onStart event triggers once per plotmodel call load after WebGL and canvas initialization are complete 246 canvas.selector.trigger('onStart', [canvas]); 247 } 248 ); 249 } 215 250 } //}}} 216 251 //}}} … … 245 280 //TODO: convert canvas.view.rotation from az/el euler to quaternion 246 281 if (canvas.view.twod) { 247 canvas.view.position[0] += Math.cos( DEG2RAD * canvas.view.rotation[0]) * deltaX - Math.sin(DEG2RAD * 0) * deltaY;248 canvas.view.position[2] += Math.sin( DEG2RAD * canvas.view.rotation[0]) * deltaX + Math.cos(DEG2RAD * 0) * deltaY;282 canvas.view.position[0] += Math.cos(vesl.RATIO_DEG_TO_RAD * canvas.view.rotation[0]) * deltaX - Math.sin(vesl.RATIO_DEG_TO_RAD * 0) * deltaY; 283 canvas.view.position[2] += Math.sin(vesl.RATIO_DEG_TO_RAD * canvas.view.rotation[0]) * deltaX + Math.cos(vesl.RATIO_DEG_TO_RAD * 0) * deltaY; 249 284 } 250 285 else { 251 canvas.view.position[0] += Math.cos( DEG2RAD * canvas.view.rotation[0]) * deltaX - Math.sin(DEG2RAD * canvas.view.rotation[0]) * deltaY;252 canvas.view.position[2] += Math.sin( DEG2RAD * canvas.view.rotation[0]) * deltaX + Math.cos(DEG2RAD * canvas.view.rotation[0]) * deltaY;286 canvas.view.position[0] += Math.cos(vesl.RATIO_DEG_TO_RAD * canvas.view.rotation[0]) * deltaX - Math.sin(vesl.RATIO_DEG_TO_RAD * canvas.view.rotation[0]) * deltaY; 287 canvas.view.position[2] += Math.sin(vesl.RATIO_DEG_TO_RAD * canvas.view.rotation[0]) * deltaX + Math.cos(vesl.RATIO_DEG_TO_RAD * canvas.view.rotation[0]) * deltaY; 253 288 } 254 289 } … … 256 291 //Else, rotate around camera center 257 292 else { 258 canvas.view.rotation[0] += (canvas.lastDeltaX - ev.deltaX) / canvas.clientWidth * 2 * canvas.controlSensitivity * RAD2DEG;259 canvas.view.rotation[1] += (canvas.lastDeltaY - ev.deltaY) / canvas.clientHeight * -2 * canvas.controlSensitivity * RAD2DEG;293 canvas.view.rotation[0] += (canvas.lastDeltaX - ev.deltaX) / canvas.clientWidth * 2 * canvas.controlSensitivity * vesl.RATIO_RAD_TO_DEG; 294 canvas.view.rotation[1] += (canvas.lastDeltaY - ev.deltaY) / canvas.clientHeight * -2 * canvas.controlSensitivity * vesl.RATIO_RAD_TO_DEG; 260 295 261 296 if (canvas.view.rotation[0] > 360) { canvas.view.rotation[0] -= 360; }; … … 277 312 function onPinch(ev, canvas, displaylog) { //{{{ 278 313 ev.preventDefault(); 279 if (ev.type === 'pinchstart') { canvas.view.lastZoom = canvas.view.zoom; } 280 else { 314 315 if (ev.type === 'pinchstart') { 316 canvas.view.lastZoom = canvas.view.zoom; 317 } else { 281 318 canvas.view.zoom = ev.scale * canvas.view.lastZoom; 282 if (displaylog) { console.log(canvas.view.zoom); } 319 320 if (displaylog) { 321 console.log(canvas.view.zoom); 322 } 283 323 } 284 324 } //}}} 285 325 function onZoom(ev, canvas, displaylog) { //{{{ 286 326 ev.preventDefault(); 287 var delta = clamp(ev.scale || ev.wheelDelta || -ev.detail, -1, 1) * canvas.controlSensitivity * canvas.view.zoom / 2; 327 328 var delta = clamp(ev.scale || ev.wheelDelta || -ev.detail, -1, 1) * canvas.controlSensitivity * canvas.view.zoom / 4; 329 288 330 modifyZoom(canvas.view.zoom + delta, canvas, displaylog, ev, 0); 289 331 } //}}} 290 332 function modifyZoom(value, canvas, displaylog, ev, duration) { //{{{ 291 if (VESL.Helpers.isEmptyOrUndefined(duration)) duration = 200; 292 var targetZoom = clamp(value, canvas.view.zoomLimits[0], canvas.view.zoomLimits[1]); 333 if (vesl.helpers.isEmptyOrUndefined(duration)) { 334 duration = 200; 335 } 336 337 var targetZoom = clamp(value, canvas.view.zoomLimits[0], canvas.view.zoomLimits[1]); 293 338 var currentZoom = canvas.view.zoom; 339 294 340 animateValue( 295 341 0, … … 299 345 function(value, info) { 300 346 canvas.view.zoom = currentZoom * (1 - value) + targetZoom * value; 301 if (displaylog) { console.log(canvas.view.zoom); } 347 348 if (displaylog) { 349 console.log(canvas.view.zoom); 350 } 302 351 303 352 //Trigger any handlers attatched to this canvas event. … … 310 359 } //}}} 311 360 function screenToWorldPoint(canvas, x, y) { //{{{ 312 var viewportX = (x - canvas.width / 2) / (canvas.width / 2);313 var viewportY = (canvas.height / 2 - y) / (canvas.height / 2);314 var origin = vec3.transformMat4(vec3.create(), [viewportX, viewportY, 0], canvas.camera.vpInverseMatrix);315 return origin;361 var viewportX = (x - canvas.width / 2) / (canvas.width / 2); 362 var viewportY = (canvas.height / 2 - y) / (canvas.height / 2); 363 364 return vec3.transformMat4(vec3.create(), [viewportX, viewportY, 0], canvas.camera.vpInverseMatrix); 316 365 } //}}} 317 366 function screenToModelRay(canvas, x, y, node) { //{{{ 318 var inverseMVPMatrix = mat4.invert(mat4.create(), mat4.multiply(mat4.create(), canvas.camera.vpMatrix, node.modelMatrix)); 319 var viewportX = (x - canvas.width / 2) / (canvas.width / 2); 320 var viewportY = (canvas.height / 2 - y) / (canvas.height / 2); 321 var origin = vec3.transformMat4(vec3.create(), [viewportX, viewportY, 0], inverseMVPMatrix); 322 var far = vec3.transformMat4(vec3.create(), [viewportX, viewportY, 1.0], inverseMVPMatrix); 323 var direction = vec3.normalize(vec3.create(), vec3.subtract(vec3.create(), far, origin)); 324 return {'origin':origin, 'direction':direction}; 367 var inverseMVPMatrix = mat4.invert(mat4.create(), mat4.multiply(mat4.create(), canvas.camera.vpMatrix, node.modelMatrix)); 368 var viewportX = (x - canvas.width / 2) / (canvas.width / 2); 369 var viewportY = (canvas.height / 2 - y) / (canvas.height / 2); 370 var origin = vec3.transformMat4(vec3.create(), [viewportX, viewportY, 0], inverseMVPMatrix); 371 var far = vec3.transformMat4(vec3.create(), [viewportX, viewportY, 1.0], inverseMVPMatrix); 372 var direction = vec3.normalize(vec3.create(), vec3.subtract(vec3.create(), far, origin)); 373 374 return { 375 'origin' : origin, 376 'direction' : direction 377 }; 325 378 } //}}} 326 379 function raycast(canvas, origin, direction, node) { //{{{ … … 328 381 //Returns hit objects with hit position, normals, barycentric coordinates, element number, and indices of ray-triangle intersection. 329 382 //TODO: Diagnose marker issues with orthographic views and slr-eustatic updates when switching between basins. 330 if (!node.octree) { node.octree = new GL.Octree(node.mesh); } 383 if (!node.octree) { 384 node.octree = new GL.Octree(node.mesh); 385 } 331 386 332 387 var hit = node.octree.testRay(origin, direction, 1e3, 1e10); 333 if (!hit) { return; } 388 389 if (!hit) { 390 return; 391 } 334 392 335 393 hit.modelPos = vec3.copy(vec3.create(), hit.pos); 394 336 395 vec3.transformMat4(hit.pos, hit.pos, node.modelMatrix); 337 396 … … 343 402 //TODO: Diagnose marker issues with orthographic views and slr-eustatic updates when switching between basins. 344 403 var ray = screenToModelRay(canvas, x, y, node); 404 345 405 return raycast(canvas, ray.origin, ray.direction, node); 346 406 } //}}} 347 407 function animateValue(current, target, duration, easing, stepCallback, doneCallback) { //{{{ 348 408 //Animates scalar value for length duration, calling callback each step. Specify smooth easing as a string ('swing', 'linear'). 349 $({'value':current}).animate({'value' :target}, {350 duration : duration,351 easing : easing,352 step : stepCallback,353 done : doneCallback409 $({'value':current}).animate({'value' : target}, { 410 duration : duration, 411 easing : easing, 412 step : stepCallback, 413 done : doneCallback 354 414 }); 355 415 } //}}} … … 358 418 function updateCameraMatrix(canvas) { //{{{ 359 419 //Update view matrix and multiply with projection matrix to get the view-projection matrix. 360 var vMatrix = mat4.create();361 var pMatrix = mat4.create();362 var translateMatrix = mat4.create();363 var rotationMatrix = mat4.create();364 var azimuthRotationMatrix = mat4.create();365 var elevationRotationMatrix = mat4.create();366 var aspectRatio = canvas.clientWidth / canvas.clientHeight;367 var camera = canvas.camera;368 var view = canvas.view;420 var vMatrix = mat4.create(); 421 var pMatrix = mat4.create(); 422 var translateMatrix = mat4.create(); 423 var rotationMatrix = mat4.create(); 424 var azimuthRotationMatrix = mat4.create(); 425 var elevationRotationMatrix = mat4.create(); 426 var aspectRatio = canvas.clientWidth / canvas.clientHeight; 427 var camera = canvas.camera; 428 var view = canvas.view; 369 429 370 if (view.twod) { mat4.ortho(pMatrix, -aspectRatio*6.371e6/view.zoom, aspectRatio*6.371e6/view.zoom, -6.371e6/view.zoom, 6.371e6/view.zoom, camera.near, camera.far); } 371 else { mat4.perspective(pMatrix, camera.fov * DEG2RAD, aspectRatio, camera.near, camera.far); } 430 if (view.twod) { 431 mat4.ortho( 432 pMatrix, -aspectRatio * 6.371e6 / view.zoom, 433 aspectRatio * 6.371e6 / view.zoom, 434 -6.371e6 / view.zoom, 435 6.371e6 / view.zoom, 436 camera.near, 437 camera.far 438 ); 439 } else { 440 mat4.perspective( 441 pMatrix, 442 camera.fov * vesl.RATIO_DEG_TO_RAD, 443 aspectRatio, 444 camera.near, 445 camera.far 446 ); 447 } 372 448 373 449 //Apply worldspace translation … … 376 452 //Calculate rotation around camera focal point about worldspace origin 377 453 if (view.twod) { 378 mat4.rotate(azimuthRotationMatrix, azimuthRotationMatrix, - DEG2RAD * 0, [0, 1, 0]);379 mat4.rotate(elevationRotationMatrix, elevationRotationMatrix, DEG2RAD * 90, [1, 0, 0]);454 mat4.rotate(azimuthRotationMatrix, azimuthRotationMatrix, -vesl.RATIO_DEG_TO_RAD * 0, [0, 1, 0]); 455 mat4.rotate(elevationRotationMatrix, elevationRotationMatrix, vesl.RATIO_DEG_TO_RAD * 90, [1, 0, 0]); 380 456 mat4.multiply(rotationMatrix, elevationRotationMatrix, azimuthRotationMatrix); 381 } 382 else { 383 mat4.rotate(azimuthRotationMatrix, azimuthRotationMatrix, -DEG2RAD * (view.rotation[0] + 90), [0, 1, 0]); 384 mat4.rotate(elevationRotationMatrix, elevationRotationMatrix, DEG2RAD * view.rotation[1], [1, 0, 0]); 457 } else { 458 mat4.rotate(azimuthRotationMatrix, azimuthRotationMatrix, -vesl.RATIO_DEG_TO_RAD * (view.rotation[0] + 90), [0, 1, 0]); 459 mat4.rotate(elevationRotationMatrix, elevationRotationMatrix, vesl.RATIO_DEG_TO_RAD * view.rotation[1], [1, 0, 0]); 385 460 mat4.multiply(rotationMatrix, elevationRotationMatrix, azimuthRotationMatrix); 386 //var quaternionWorldX = Node.prototype.eulerToQuaternion(0, 0, DEG2RAD * (view.rotation[0]));387 //var quaternionWorldY = Node.prototype.eulerToQuaternion(0, DEG2RAD * (view.rotation[1]), 0);388 //var quaternionWorldZ = Node.prototype.eulerToQuaternion( DEG2RAD * (view.rotation[2]), 0, 0);461 //var quaternionWorldX = Node.prototype.eulerToQuaternion(0, 0, vesl.RATIO_DEG_TO_RAD * (view.rotation[0])); 462 //var quaternionWorldY = Node.prototype.eulerToQuaternion(0, vesl.RATIO_DEG_TO_RAD * (view.rotation[1]), 0); 463 //var quaternionWorldZ = Node.prototype.eulerToQuaternion(vesl.RATIO_DEG_TO_RAD * (view.rotation[2]), 0, 0); 389 464 //var quaternionTemp = quat.multiply(quat.create(), quaternionWorldY, quaternionWorldX); 390 465 //quat.multiply(camera.rotation, quaternionWorldZ, quaternionTemp); … … 397 472 //Apply screenspace translation to emulate rotation around point 398 473 mat4.identity(translateMatrix); 399 mat4.translate(translateMatrix, translateMatrix, [0.0, 0.0, -6.371e6 /view.zoom]);474 mat4.translate(translateMatrix, translateMatrix, [0.0, 0.0, -6.371e6 / view.zoom]); 400 475 mat4.multiply(vMatrix, translateMatrix, vMatrix); 401 476 … … 415 490 }//}}} 416 491 function drawSceneGraphNode(canvas, node) { //{{{ 417 if (!node.enabled) { return; } 492 if (!node.enabled) { 493 return; 494 } 418 495 419 496 var gl = canvas.gl; 497 420 498 gl.makeCurrent(); 421 499 422 500 var mvpMatrix = mat4.create(); 501 423 502 mat4.multiply(mvpMatrix, canvas.camera.vpMatrix, node.modelMatrix); 424 503 425 var normalMatrix = mat3.create(); 426 var tempMatrix = mat4.create(); 504 var normalMatrix = mat3.create(); 505 var tempMatrix = mat4.create(); 506 427 507 mat4.invert(tempMatrix, node.modelMatrix); 428 508 mat4.transpose(tempMatrix, tempMatrix); 429 509 mat3.fromMat4(normalMatrix, tempMatrix); 430 510 431 if (node.texture) { node.texture.bind(0); } 432 if (node.disableDepthTest) { gl.disable(gl.DEPTH_TEST); } 433 if (node.enableCullFace) { gl.enable(gl.CULL_FACE); } 511 if (node.texture) { 512 node.texture.bind(0); 513 } 514 515 if (node.disableDepthTest) { 516 gl.disable(gl.DEPTH_TEST); 517 } 518 519 if (node.enableCullFace) { 520 gl.enable(gl.CULL_FACE); 521 } 434 522 435 523 gl.cullFace(node.cullFace); … … 438 526 439 527 //Setup for light that originates from camera 440 var atm = canvas.atmosphere;528 var atm = canvas.atmosphere; 441 529 var lightOrigin = vec3.create(); 442 530 … … 495 583 function canvasResize(canvas) { 496 584 var rect = canvas.getBoundingClientRect(); 585 497 586 canvas.width = rect.width; 498 587 canvas.height = rect.height; 588 499 589 canvas.gl.viewport(0, 0, canvas.width, canvas.height); 500 590 501 if (!VESL.Helpers.isEmptyOrUndefined(canvas.overlaycanvas)) { 502 rect = canvas.overlaycanvas.getBoundingClientRect(); 503 canvas.overlaycanvas.width = rect.width; 504 canvas.overlaycanvas.height = rect.height; 591 var overlaycanvas = canvas.overlaycanvas; 592 593 if (!vesl.helpers.isEmptyOrUndefined(overlaycanvas)) { 594 rect = overlaycanvas.getBoundingClientRect(); 595 overlaycanvas.width = rect.width; 596 overlaycanvas.height = rect.height; 597 overlaycanvas.getContext('2d').clearRect(0, 0, overlaycanvas.width, overlaycanvas.height); 505 598 } 506 599 } 507 function draw (canvas) { //{{{600 function drawCanvas(canvas) { //{{{ 508 601 //Ensure all nodes are ready to render 509 602 //TODO: Come up with better way to check if shaders are ready, or move outside of main draw function 510 603 var nodes = canvas.nodes; 604 511 605 if (!canvas.draw.ready) { 512 606 if (Object.keys(nodes).length !== 0) { 513 607 canvas.draw.ready = true; 608 514 609 for (var node in nodes) { 515 610 if (nodes[node].shader.ready === false) { 516 611 canvas.draw.ready = false; 612 517 613 break; 518 614 } 519 615 } 520 521 616 } 522 617 } … … 528 623 529 624 var gl = canvas.gl; 625 530 626 gl.makeCurrent(); //litegl function to handle switching between multiple canvases 531 627 gl.clearColor(canvas.backgroundcolor[0], canvas.backgroundcolor[1], canvas.backgroundcolor[2], canvas.backgroundcolor[3]); … … 537 633 canvas.selector.trigger('onPreRender', [canvas]); 538 634 539 for (var handler in canvas.overlayHandlers) { canvas.overlayHandlers[handler](canvas); } 635 for (var handler in canvas.overlayHandlers) { 636 canvas.overlayHandlers[handler](canvas); 637 } 540 638 541 639 var drawPassNumber = 3; 640 641 // NOTE: For large value of drawPassNumber/nodes.length, could copy nodes to a new array and pop elements as each drawOrder is found 542 642 for (var i = drawPassNumber - 1; i >= 0; --i) { 543 643 for (var node in nodes) { 544 if (nodes[node].drawOrder === i) { drawSceneGraphNode(canvas, nodes[node]); } 644 if (nodes[node].drawOrder === i) { 645 drawSceneGraphNode(canvas, nodes[node]); 646 } 545 647 } 546 648 } … … 548 650 549 651 //Regardless of ready state, schedule next frame to check for ready state and render 550 canvas.draw.handler = window.requestAnimationFrame(function(time) { draw (canvas); });652 canvas.draw.handler = window.requestAnimationFrame(function(time) { drawCanvas(canvas); }); 551 653 } //}}} 552 654 //}}} -
issm/trunk-jpl/src/m/plot/webgl_node.js
r22434 r22894 106 106 var yaw = Math.atan2(t3, t4); 107 107 108 return [pitch * RAD2DEG, roll * RAD2DEG, yaw * RAD2DEG];108 return [pitch * vesl.RATIO_RAD_TO_DEG, roll * vesl.RATIO_RAD_TO_DEG, yaw * vesl.RATIO_RAD_TO_DEG]; 109 109 } //}}} 110 110 Node.prototype.updateModelMatrix = function() { //{{{ … … 122 122 var rotationMatrix = mat4.create(); 123 123 var zRotationMatrix = mat4.create(); 124 mat4.rotate(zRotationMatrix, zRotationMatrix, DEG2RAD * this.rotation[2], [0.0, 0.0, 1.0]);124 mat4.rotate(zRotationMatrix, zRotationMatrix, vesl.RATIO_DEG_TO_RAD * this.rotation[2], [0.0, 0.0, 1.0]); 125 125 mat4.multiply(rotationMatrix, zRotationMatrix, rotationMatrix); 126 126 var yRotationMatrix = mat4.create(); 127 mat4.rotate(yRotationMatrix, yRotationMatrix, DEG2RAD * this.rotation[1], [0.0, 1.0, 0.0]);127 mat4.rotate(yRotationMatrix, yRotationMatrix, vesl.RATIO_DEG_TO_RAD * this.rotation[1], [0.0, 1.0, 0.0]); 128 128 mat4.multiply(rotationMatrix, yRotationMatrix, rotationMatrix); 129 129 var xRotationMatrix = mat4.create(); 130 mat4.rotate(xRotationMatrix, xRotationMatrix, DEG2RAD * this.rotation[0], [1.0, 0.0, 0.0]);130 mat4.rotate(xRotationMatrix, xRotationMatrix, vesl.RATIO_DEG_TO_RAD * this.rotation[0], [1.0, 0.0, 0.0]); 131 131 mat4.multiply(rotationMatrix, xRotationMatrix, rotationMatrix); 132 132 mat4.multiply(modelMatrix, rotationMatrix, modelMatrix); 133 133 134 //var rotationQuaternionX = this.eulerToQuaternion(0, - DEG2RAD * this.rotation[0], 0);135 //var rotationQuaternionY = this.eulerToQuaternion( DEG2RAD * this.rotation[1], 0, 0);134 //var rotationQuaternionX = this.eulerToQuaternion(0, -vesl.RATIO_DEG_TO_RAD * this.rotation[0], 0); 135 //var rotationQuaternionY = this.eulerToQuaternion(vesl.RATIO_DEG_TO_RAD * this.rotation[1], 0, 0); 136 136 //mat4.fromQuat(this.rotationMatrix, quat.multiply(quat.create(), rotationQuaternionY, rotationQuaternionX)); 137 137 … … 163 163 } //}}} 164 164 Node.prototype.transform = function() { //{{{ 165 //Transforms the translation, rotation, or sc le fothe node and updates the model matrix.165 //Transforms the translation, rotation, or scale of the node and updates the model matrix. 166 166 var args = Array.prototype.slice.call(arguments); 167 167 var options = new pairoptions(args.slice(0,args.length)); … … 171 171 var scale = options.getfieldvalue('scale', undefined); 172 172 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 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; 176 176 this.updateModelMatrix(); 177 177 } //}}} … … 212 212 var face; 213 213 214 if ( VESL.Helpers.isEmptyOrUndefined(faceVertexCData)) {214 if (vesl.helpers.isEmptyOrUndefined(faceVertexCData)) { 215 215 vertexArray = new Float32Array(vertices[0].length * 3); 216 216 for(var i = 0, v = 0; i < vertices[0].length; i++) { … … 289 289 var face; 290 290 291 if ( VESL.Helpers.isEmptyOrUndefined(faceVertexCData)) { return; }291 if (vesl.helpers.isEmptyOrUndefined(faceVertexCData)) { return; } 292 292 293 293 //Use logarithmic scaling if it is valid … … 368 368 } 369 369 370 if (this.computeIndices === true && ! VESL.Helpers.isEmptyOrUndefined(faces)) {371 if (! VESL.Helpers.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 372 372 if (faceColor !== 'none') { //Check for triangle rendering 373 373 indexArray = new Uint16Array(faces.length * 3); … … 405 405 406 406 var coords = options.getfieldvalue('Coords', undefined); 407 if (! VESL.Helpers.isEmptyOrUndefined(coords)) {407 if (!vesl.helpers.isEmptyOrUndefined(coords)) { 408 408 this.patchCoords(coords, this.faces, this.vertices); 409 409 var buffer = this.mesh.getBuffer("coords"); … … 415 415 //Computes and caches octrees for a node. 416 416 var octree = this.canvas.octrees[this.name]; 417 if ( VESL.Helpers.isEmptyOrUndefined(octree)) {417 if (vesl.helpers.isEmptyOrUndefined(octree)) { 418 418 octree = new GL.Octree(this.mesh); 419 419 } … … 441 441 var coordinateObject = vertices[i]; 442 442 var j = 0; 443 if ( VESL.Helpers.isEmptyOrUndefined(indices)) {443 if (vesl.helpers.isEmptyOrUndefined(indices)) { 444 444 for (var key in coordinateObject) { 445 445 console.log(key); … … 486 486 //Scales and returns vertices x, y, and z by factor scale. Uses md.geometry.scale for heightscaling in 3d meshes. 487 487 var region = maskObject.region; 488 var mask = maskObject.enabled ? maskObject.heightmask[region] : [];488 var mask; 489 489 var maskScale = maskObject.enabled ? maskObject.scale : 1; 490 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); 491 //The maskScaleField is the height scaling array. 492 var maskScaleField = maskObject.scaleField; 493 if (Array.isArray(md.geometry.surface) && md.geometry.surface[0] === undefined) { 494 md.geometry.surface = NewArrayFill(x.length, 1); 495 } 496 if (vesl.helpers.isNaN(maskScaleField) || maskScaleField === undefined || (Array.isArray(maskScaleField) && maskScaleField[0] === undefined)) { 496 497 maskScaleField = md.geometry.surface; 497 498 } 498 499 499 500 //Scale in 3D if using globe model, or in 2D otherwise. 500 501 if (md.mesh.classname() === 'mesh3dsurface') { 501 502 var element; 502 503 if (x.length === md.mesh.numberofelements) { //element plot 504 mask = maskObject.enabled ? maskObject.heightmask[region] : NewArrayFill(elements.length, 1); 503 505 for (var i = 0; i < x.length; i++) { 504 506 if (maskObject.enabled) { //Scale the element if mask is not enabled, or if it is, only if it is also in the mask … … 517 519 } 518 520 else if (x.length === md.mesh.numberofvertices) { //node plot 521 mask = maskObject.enabled ? maskObject.heightmask[region] : NewArrayFill(x.length, 1); 519 522 for (var i = 0; i < x.length; i++) { 520 523 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 … … 530 533 } else { 531 534 z = z.slice(); 535 mask = maskObject.enabled ? maskObject.heightmask[region] : NewArrayFill(z.length, 1); 532 536 var zMin = ArrayMin(maskScaleField); 533 537 for(var i = 0; i < z.length; i++) {
Note:
See TracChangeset
for help on using the changeset viewer.