Changeset 21231


Ignore:
Timestamp:
09/27/16 10:10:21 (8 years ago)
Author:
dlcheng
Message:

CHG (JS): data markers and displays now uses 2d map marker and is more accurate.

Location:
issm/trunk-jpl/src/m/plot
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/m/plot/applyoptions.js

    r21205 r21231  
    3535                        } //}}}
    3636                        //Initialize colorbar canvas {{{
    37                        
    3837                        ccanvasid = options.getfieldvalue('colorbarid',options.getfieldvalue('canvasid').replace('canvas','colorbar-canvas'));                 
    3938                        ccanvas = $('#'+ccanvasid)[0];
    4039                        cwidth = ccanvas.width*options.getfieldvalue('colorbarwidth',1);
    4140                        cheight = ccanvas.height*options.getfieldvalue('colorbarheight',1);
    42                         //ccanvas.width = cwidth;
    43                         //ccanvas.height = cheight;
    4441                        ccontext = ccanvas.getContext('2d');
    4542                        ccontext.clearRect(0,0, cwidth, cheight);
     
    6865                        clabelsid = options.getfieldvalue('colorbarid', ccanvasid).replace('canvas','labels');
    6966                        clabels = $('#'+clabelsid);
    70                         //clabels.height(cheight);
    71                         //clabels.css({'color':options.getfieldvalue('colorbarfontcolor','black'), 'font-size':options.getfieldvalue('colorbarfontsize',18)+'px'});
    7267                        if (colorbarinnerlabels=='on') {
    7368                                clabels.removeClass('sim-colorbar-labels-outer');
     
    9691                        ctitleid = options.getfieldvalue('colorbarid', ccanvasid).replace('canvas','heading');
    9792                        ctitle = $('#'+ctitleid);
    98                         //ctitle.width(cwidth);
    99                         if (options.exist('colorbartitle')) {
    100                                 ctitle.html(options.getfieldvalue('colorbartitle'));
    101                                 //ctitle.css({'color':options.getfieldvalue('colorbarfontcolor','black'), 'font-size':options.getfieldvalue('colorbarfontsize',18)+'px'});
    102                         } //}}}
     93                        if (options.exist('colorbartitle')) { ctitle.html(options.getfieldvalue('colorbartitle')); }
     94                        //}}}
    10395                }
    10496        } //}}}
    10597        //texture canvas //{{{
    106         var tcontext,tcanvas,tcanvasid,tcanvashtml,tURL,tgradient;
     98        var tcontext,tcanvas,tcanvasid,tURL,tgradient;
    10799        tcanvasid = 'texturecanvas';
    108         var tcanvashtml = document.getElementById(tcanvasid);
    109         if (tcanvashtml == null) {
    110                 tcanvas = $('<canvas id="texturecanvas" width="256" height="256"></canvas>').insertAfter('#'+String(options.getfieldvalue('canvasid')));
    111                 tcanvas.css({'display':'none'});
    112                 tcanvashtml = document.getElementById(tcanvasid);
     100        var tcanvas = document.getElementById(tcanvasid);
     101        if (tcanvas == null) {
     102                $('<canvas id="texturecanvas" width="256" height="256" style="display: none;"></canvas>').insertAfter('#'+String(options.getfieldvalue('canvasid')));
     103                tcanvas = document.getElementById(tcanvasid);
    113104        }
    114         else {
    115                 tcanvas = $('#' + tcanvasid);
    116         }
    117         tcontext = tcanvashtml.getContext('2d');
     105        tcontext = tcanvas.getContext('2d');
    118106        tgradient = tcontext.createLinearGradient(0,0,0,256);
    119107               
     
    128116        tcontext.fillStyle = tgradient;
    129117        tcontext.fillRect(0,0,256,256);
    130         tURL = tcanvashtml.toDataURL();
    131         node['texture'] = initTexture(gl,tURL);
     118        tURL = tcanvas.toDataURL();
     119        node.texture = initTexture(gl,tURL);
     120        node.textureCanvas = tcanvas;
     121        node.caxis = options.getfieldvalue('caxis',[ArrayMin(data),ArrayMax(data)]);
    132122        //}}}
    133123        //expdisp contours {{{
    134124        if (options.exist('expdisp')) {
    135                 canvas.nodes['expdisp'] = Node(gl,options);
    136                 var node = canvas.nodes['expdisp'];
     125                canvas.nodes.expdisp = Node(gl,options);
     126                var node = canvas.nodes.expdisp;
    137127               
    138128                //declare variables:  {{{
     
    147137               
    148138                //Process data and model
    149                 var x = options.getfieldvalue('expdisp')['x'];
    150                 var y = options.getfieldvalue('expdisp')['y'];
     139                var x = options.getfieldvalue('expdisp').x;
     140                var y = options.getfieldvalue('expdisp').y;
    151141                var z = Array.apply(null, Array(x.length)).map(Number.prototype.valueOf,0);
    152142               
    153                 if (options.getfieldvalue('expdisp')['z']) {
    154                         z = options.getfieldvalue('expdisp')['z'];
     143                if (options.getfieldvalue('expdisp').z) {
     144                        z = options.getfieldvalue('expdisp').z;
    155145                }
    156146                //}}}
     
    173163                //Compute scaling: //{{{
    174164                var scale = 1 / (xmax - xmin);
    175                 node['shaderName'] = 'colored';
    176                 node['shader'] = gl['shaders'][node['shaderName']]['program'];
    177                 node['scale'] = [scale, scale, scale*options.getfieldvalue('heightscale',1)];
    178                 node['translation'] = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (-2 / scale)];
    179                 node['modelMatrix'] = recalculateModelMatrix(node);
    180                 node['drawMode'] = gl.LINE_LOOP;
    181                 node['drawOrder'] = 0;
    182                 node['useIndexBuffer'] = false;
    183                 node['disableDepthTest'] = true;
     165                node.shaderName = 'colored';
     166                node.shader = gl.shaders[node.shaderName].program;
     167                node.scale = [scale, scale, scale*options.getfieldvalue('heightscale',1)];
     168                node.translation = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (-2 / scale)];
     169                node.modelMatrix = updateModelMatrix(node);
     170                node.drawMode = gl.LINE_LOOP;
     171                node.drawOrder = 0;
     172                node.useIndexBuffer = false;
     173                node.disableDepthTest = true;
    184174                //}}}
    185175
     
    206196
    207197                //Initalize buffers:
    208                 node['arrays'] = [vertices, colors];
    209                 node['buffers'] = initBuffers(gl, node['arrays']);
     198                node.arrays = [vertices, colors];
     199                node.buffers = initBuffers(gl, node.arrays);
    210200        } //}}}
    211201        //cloud of points {{{
    212202        if (options.exist('cloud')) {
    213                 canvas.nodes['cloud'] = Node(gl,options);
    214                 var node = canvas.nodes['cloud'];
     203                canvas.nodes.cloud = Node(gl,options);
     204                var node = canvas.nodes.cloud;
    215205
    216206                //declare variables:  {{{
     
    225215               
    226216                //Process data and model
    227                 var x = options.getfieldvalue('cloud')['x'];
    228                 var y = options.getfieldvalue('cloud')['y'];
     217                var x = options.getfieldvalue('cloud').x;
     218                var y = options.getfieldvalue('cloud').y;
    229219                var z = Array.apply(null, Array(x.length)).map(Number.prototype.valueOf,0);
    230220               
    231                 if (options.getfieldvalue('cloud')['z']) {
    232                         z = options.getfieldvalue('cloud')['z'];
     221                if (options.getfieldvalue('cloud').z) {
     222                        z = options.getfieldvalue('cloud').z;
    233223                }
    234224                //}}}
     
    251241                //Compute scaling: //{{{
    252242                var scale = 1 / (xmax - xmin);
    253                 node['shaderName'] = 'colored';
    254                 node['shader'] = gl['shaders'][node['shaderName']]['program'];
    255                 node['scale'] = [scale, scale, scale*options.getfieldvalue('heightscale',1)];
    256                 node['translation'] = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (-2 / scale)];
    257                 node['modelMatrix'] = recalculateModelMatrix(node);
    258                 node['drawMode'] = gl.POINTS;
    259                 node['drawOrder'] = 0;
    260                 node['useIndexBuffer'] = false;
    261                 node['disableDepthTest'] = true;
     243                node.shaderName = 'colored';
     244                node.shader = gl.shaders[node.shaderName].program;
     245                node.scale = [scale, scale, scale*options.getfieldvalue('heightscale',1)];
     246                node.translation = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (-2 / scale)];
     247                node.modelMatrix = updateModelMatrix(node);
     248                node.drawMode = gl.POINTS;
     249                node.drawOrder = 0;
     250                node.useIndexBuffer = false;
     251                node.disableDepthTest = true;
    262252                //}}}
    263253
     
    284274
    285275                //Initalize buffers:
    286                 node['arrays'] = [vertices, colors];
    287                 node['buffers'] = initBuffers(gl, node['arrays']);
     276                node.arrays = [vertices, colors];
     277                node.buffers = initBuffers(gl, node.arrays);
    288278        } //}}}
    289279       
     
    314304                        for (text in textlabels) {
    315305                                textlabel = textlabels[text];
    316                                 mat4.multiply(mvpMatrix, canvas.cameraMatrix, canvas.nodes['overlay']['modelMatrix']);
    317                                 textposition = vec3.transformMat4(textposition, textlabel['pos'], mvpMatrix);
     306                                mat4.multiply(mvpMatrix, canvas.cameraMatrix, canvas.nodes.overlay.modelMatrix);
     307                                textposition = vec3.transformMat4(textposition, textlabel.pos, mvpMatrix);
    318308                                if (textposition[2] > 1) { //clip coordinates with z > 1
    319309                                        continue;
     
    325315                                textcontext.textAlign = 'center';
    326316                                textcontext.textBaseline = 'middle';
    327                                 textcontext.fillText(textlabel['text'], textcoordinates[0], textcoordinates[1]);
    328                                 textcontext.strokeText(textlabel['text'], textcoordinates[0], textcoordinates[1]);
     317                                textcontext.fillText(textlabel.text, textcoordinates[0], textcoordinates[1]);
     318                                textcontext.strokeText(textlabel.text, textcoordinates[0], textcoordinates[1]);
    329319                        }
    330320                }
     
    362352                        var node = Node(gl);
    363353                        canvas.nodes[canvas.nodes.length] = node;
    364                         node["name"] = "atmosphere";
    365                         node["shaderName"] = "SkyFromSpace";
    366                         node["shader"] = gl["shaders"][node["shaderName"]];
    367                         node["drawOrder"] = 1;
    368                         node["enableCullFace"] = true;
    369                         node["mesh"] = GL.Mesh.icosahedron({size:6371000*atmosphereScale,subdivisions:6});
    370                         node["useIndexBuffer"] = false;
    371                         node["rotation"] = [0, 0, 0];
    372                         node["translation"] = translation;
    373                         node["center"] = [0, 0, 0];
    374                         node["modelMatrix"] = recalculateModelMatrix(node);
     354                        node.name = "atmosphere";
     355                        node.shaderName = "SkyFromSpace";
     356                        node.shader = gl.shaders[node.shaderName];
     357                        node.drawOrder = 1;
     358                        node.enableCullFace = true;
     359                        node.mesh = GL.Mesh.icosahedron({size:6371000*atmosphereScale,subdivisions:6});
     360                        node.useIndexBuffer = false;
     361                        node.rotation = [0, 0, 0];
     362                        node.translation = translation;
     363                        node.center = [0, 0, 0];
     364                        updateModelMatrix(node);
    375365                }
    376366                if (options.getfieldvalue('render',[]).indexOf('space')!=-1) { 
     
    378368                        node = Node(gl);
    379369                        canvas.nodes[canvas.nodes.length] = node;
    380                         node["name"] = "skysphere";
    381                         node["shaderName"] = "Textured";
    382                         node["shader"] = gl["shaders"][node["shaderName"]];
    383                         node["drawOrder"] = 2;
    384                         node["enableCullFace"] = true;
    385                         node["mesh"] = GL.Mesh.sphere({size:6371000*10});
    386                         node["texture"] = initTexture(gl,'../../../js/textures/TychoSkymapII_t4_2k.jpg');
    387                         node["useIndexBuffer"] = false;
    388                         node["rotation"] = [0, 0, 0];
    389                         node["translation"] = translation;
    390                         node["center"] = [0, 0, 0];
    391                         node["modelMatrix"] = recalculateModelMatrix(node);
     370                        node.name = "skysphere";
     371                        node.shaderName = "Textured";
     372                        node.shader = gl.shaders[node.shaderName];
     373                        node.drawOrder = 2;
     374                        node.enableCullFace = true;
     375                        node.mesh = GL.Mesh.sphere({size:6371000*10});
     376                        node.texture = initTexture(gl,'../../../js/textures/TychoSkymapII_t4_2k.jpg');
     377                        node.useIndexBuffer = false;
     378                        node.rotation = [0, 0, 0];
     379                        node.translation = translation;
     380                        node.center = [0, 0, 0];
     381                        updateModelMatrix(node);
    392382                }
    393383        } //}}}
  • issm/trunk-jpl/src/m/plot/plot_mesh.js

    r21205 r21231  
    6262        var node = Node(gl);
    6363        canvas.nodes[canvas.nodes.length] = node;
    64         node["name"] = "mesh";
    65         node["shaderName"] = "Colored";
    66         node["shader"] = gl["shaders"][node["shaderName"]];
    67         node["lineWidth"] = options.getfieldvalue('linewidth',1);
    68         node["scale"] = [1, 1, matrixscale];
    69         node["rotation"] = [-90, 0, 0];
    70         node["translation"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
    71         node["center"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
    72         node["modelMatrix"] = recalculateModelMatrix(node);
    73         node["drawMode"] = gl.LINES;
    74         node["drawOrder"] = 0;
    75         node["maskEnabled"] = options.getfieldvalue('innermask','off') == 'on';
    76         node["maskHeight"] = options.getfieldvalue('innermaskheight',150.0)*options.getfieldvalue('heightscale',1);
    77         node["maskColor"] = options.getfieldvalue('innermaskcolor',[0.0,0.0,1.0,1.0]);
     64        node.name = "mesh";
     65        node.shaderName = "Colored";
     66        node.shader = gl.shaders[node.shaderName];
     67        node.lineWidth = options.getfieldvalue('linewidth',1);
     68        node.scale = [1, 1, matrixscale];
     69        node.rotation = [-90, 0, 0];
     70        node.translation = [0, 0, 0];
     71        node.center = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
     72        node.drawMode = gl.LINES;
     73        node.drawOrder = 0;
     74        node.maskEnabled = options.getfieldvalue('innermask','off') == 'on';
     75        node.maskHeight = options.getfieldvalue('innermaskheight',150.0)*options.getfieldvalue('heightscale',1);
     76        node.maskColor = options.getfieldvalue('innermaskcolor',[0.0,0.0,1.0,1.0]);
     77        updateModelMatrix(node);
    7878
    7979        //retrieve some options
     
    136136        }
    137137        //}}}
    138         node["mesh"] = GL.Mesh.load({vertices:vertices, colors:colors, indices:indices}, null, null, gl);
     138        node.mesh = GL.Mesh.load({vertices:vertices, colors:colors, triangles:indices}, null, null, gl);
    139139}
  • issm/trunk-jpl/src/m/plot/plot_overlay.js

    r21205 r21231  
    6161        var node = Node(gl);
    6262        canvas.nodes[canvas.nodes.length] = node;
    63         node["name"] = "overlay";
    64         node["shaderName"] = (options.getfieldvalue('render',[]).indexOf('ground')!=-1) ? "GroundFromSpace" : "Textured";
    65         node["shader"] = gl["shaders"][node["shaderName"]];
    66         node["scale"] = [1, 1, matrixscale];
    67         node["rotation"] = [-90, 0, 0];
    68         node["translation"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
    69         node["center"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
    70         node["modelMatrix"] = recalculateModelMatrix(node);
    71         node["texture"] = initTexture(gl,options.getfieldvalue('overlay_image'));
    72         node["alpha"] = options.getfieldvalue('outeralpha',1.0);
    73         node["drawOrder"] = 1;
    74         node["maskEnabled"] = options.getfieldvalue('outermask','off') == 'on';
    75         node["maskHeight"] = options.getfieldvalue('outermaskheight',150.0);
    76         node["maskColor"] = options.getfieldvalue('outermaskcolor',[0.0,0.0,1.0,1.0]);
     63        node.name = "overlay";
     64        node.shaderName = (options.getfieldvalue('render',[]).indexOf('ground')!=-1) ? "GroundFromSpace" : "Textured";
     65        node.shader = gl.shaders[node.shaderName];
     66        node.scale = [1, 1, matrixscale];
     67        node.rotation = [-90, 0, 0];
     68        node.translation = [0, 0, 0];
     69        node.center = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
     70        node.texture = initTexture(gl,options.getfieldvalue('overlay_image'));
     71        node.alpha = options.getfieldvalue('outeralpha',1.0);
     72        node.drawOrder = 1;
     73        node.maskEnabled = options.getfieldvalue('outermask','off') == 'on';
     74        node.maskHeight = options.getfieldvalue('outermaskheight',150.0);
     75        node.maskColor = options.getfieldvalue('outermaskcolor',[0.0,0.0,1.0,1.0]);
     76        updateModelMatrix(node);
    7777       
    7878        //Handle outer radaroverlay
     
    9898                zmax = zlim[1];
    9999               
    100                 node["center"] = [node["center"][0], node["center"][1], -zmax];
     100                node.center = [node.center[0], node.center[1], -zmax];
    101101        }
    102102       
     
    133133                        vertices[vertices.length] = vertex[2];
    134134                       
    135                         texcoords[texcoords.length] = degrees(Math.atan2(vertex[1], vertex[0])) / 360 + 0.5;
    136                         texcoords[texcoords.length] = degrees(Math.asin(vertex[2] / magnitude)) / 180 + 0.5;
     135                        texcoords[texcoords.length] = Math.atan2(vertex[1], vertex[0]) / (2 * Math.PI) + 0.5;
     136                        texcoords[texcoords.length] = Math.asin(vertex[2] / magnitude) / Math.PI + 0.5;
    137137                }
    138138                else {
     
    159159                indices[indices.length] = element[2];
    160160        }
    161         node["mesh"] = GL.Mesh.load({vertices:vertices, coords:texcoords, indices:indices}, null, null, gl);
     161        node.mesh = GL.Mesh.load({vertices:vertices, coords:texcoords, triangles:indices}, null, null, gl);
    162162}
  • issm/trunk-jpl/src/m/plot/plot_quiver.js

    r21205 r21231  
    6363        var node = Node(gl);
    6464        canvas.nodes[canvas.nodes.length] = node;
    65         node["name"] = "quiver";
    66         node["shaderName"] = "Colored";
    67         node["shader"] = gl["shaders"][node["shaderName"]];
    68         node["lineWidth"] = options.getfieldvalue('linewidth',1);
    69         node["scale"] = [1, 1, matrixscale];
    70         node["rotation"] = [-90, 0, 0];
    71         node["translation"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
    72         node["center"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
    73         node["modelMatrix"] = recalculateModelMatrix(node);
    74         node["drawMode"] = gl.LINES;
    75         node["useIndexBuffer"] = false;
    76         node["drawOrder"] = 0;
    77         node["maskEnabled"] = options.getfieldvalue('innermask','off') == 'on';
    78         node["maskHeight"] = options.getfieldvalue('innermaskheight',150.0)*options.getfieldvalue('heightscale',1);
    79         node["maskColor"] = options.getfieldvalue('innermaskcolor',[0.0,0.0,1.0,1.0]);
     65        node.name = "quiver";
     66        node.shaderName = "Colored";
     67        node.shader = gl.shaders[node.shaderName];
     68        node.lineWidth = options.getfieldvalue('linewidth',1);
     69        node.scale = [1, 1, matrixscale];
     70        node.rotation = [-90, 0, 0];
     71        node.translation = [0, 0, 0];
     72        node.center = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
     73        node.drawMode = gl.LINES;
     74        node.useIndexBuffer = false;
     75        node.drawOrder = 0;
     76        node.maskEnabled = options.getfieldvalue('innermask','off') == 'on';
     77        node.maskHeight = options.getfieldvalue('innermaskheight',150.0)*options.getfieldvalue('heightscale',1);
     78        node.maskColor = options.getfieldvalue('innermaskcolor',[0.0,0.0,1.0,1.0]);
     79        updateModelMatrix(node);
    8080
    8181        //retrieve some options
     
    134134        }
    135135        //}}}
    136         node["mesh"] = GL.Mesh.load({vertices:vertices, colors:colors}, null, null, gl);
     136        node.mesh = GL.Mesh.load({vertices:vertices, colors:colors}, null, null, gl);
    137137}
  • issm/trunk-jpl/src/m/plot/plot_unit.js

    r21205 r21231  
    6363        var node = Node(gl);
    6464        canvas.nodes[canvas.nodes.length] = node;
    65         node["name"] = "unit";
    66         node["shaderName"] = "Textured";
    67         node["shader"] = gl["shaders"][node["shaderName"]];
    68         node["scale"] = [1, 1, matrixscale];
    69         node["rotation"] = [-90, 0, 0];
    70         node["translation"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
    71         node["center"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
    72         node["modelMatrix"] = recalculateModelMatrix(node);
    73         node["alpha"] = options.getfieldvalue('alpha',1.0);
    74         node["drawOrder"] = 0;
    75         node["maskEnabled"] = options.getfieldvalue('innermask','off') == 'on';
    76         node["maskHeight"] = options.getfieldvalue('innermaskheight',150.0);
    77         node["maskColor"] = options.getfieldvalue('innermaskcolor',[0.0,0.0,1.0,1.0]);
    78         node["enabled"] = options.getfieldvalue('nodata','off') == 'off';
    79         vec3.add(canvas.translation, canvas.translation, node["center"]);
    80        
     65        canvas.unitNode = node;
     66        node.name = "unit";
     67        node.shaderName = "Textured";
     68        node.shader = gl.shaders[node.shaderName];
     69        node.scale = [1, 1, matrixscale];
     70        node.rotation = [-90, 0, 0];
     71        node.translation = [0, 0, 0];
     72        node.center = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
     73        node.alpha = options.getfieldvalue('alpha',1.0);
     74        node.drawOrder = 1;
     75        node.maskEnabled = options.getfieldvalue('innermask','off') == 'on';
     76        node.maskHeight = options.getfieldvalue('innermaskheight',150.0);
     77        node.maskColor = options.getfieldvalue('innermaskcolor',[0.0,0.0,1.0,1.0]);
     78        node.enabled = options.getfieldvalue('nodata','off') == 'off';
     79        updateModelMatrix(node);
     80
    8181        switch(datatype){
    8282                //element plot {{{
     
    133133                                        texcoords[tindex++] = 0.5;
    134134                                        texcoords[tindex++] = clamp((data[i] - datamin) / datadelta, 0.0, 1.0);
    135                                        
    136135                                }
    137136
     
    146145                                }
    147146                        }
    148                         node["mesh"] = GL.Mesh.load({vertices:vertices, coords:texcoords, indices:indices});
     147                        node.mesh = GL.Mesh.load({vertices:vertices, coords:texcoords, triangles:indices}, null, null, gl);
     148                        node.mesh.octree = new GL.Octree(node.mesh);
    149149                        break;
    150150                //}}}
     
    222222                       
    223223                                //Initialize movie loop
    224                                 node["movieInterval"] = 1000 / canvas.moviefps;
    225                                 node["movieTimestamps"] = timestamps;
    226                                 node["movieLength"] = timestamps.length;
    227                                 node["movieFrame"] = 0;
    228                                 if (canvas["movieHandler"])     clearInterval(canvas["movieHandler"]);
    229                                 canvas["movieHandler"] = setInterval(function () {
    230                                                 node["movieFrame"] = canvas["movieFrame"];
    231                                                 if (canvas["moviePlay"] && canvas["movieIncrement"]) {
    232                                                         if (canvas["movieReverse"]) node["movieFrame"] = (((node["movieFrame"] - 1) % node["movieLength"]) + node["movieLength"]) % node["movieLength"]; //Handle negative modulus
    233                                                         else node["movieFrame"] = (((node["movieFrame"] + 1) % node["movieLength"]) + node["movieLength"]) % node["movieLength"]; //Handle negative modulus
     224                                node.movieInterval = 1000 / canvas.moviefps;
     225                                node.movieTimestamps = timestamps;
     226                                node.movieLength = timestamps.length;
     227                                node.movieFrame = 0;
     228                                if (canvas.movieHandler) { clearInterval(canvas.movieHandler); }
     229                                canvas.movieHandler = setInterval(function () {
     230                                                node.movieFrame = canvas.movieFrame;
     231                                                if (canvas.moviePlay && canvas.movieIncrement) {
     232                                                        if (canvas.movieReverse) {node.movieFrame = (((node.movieFrame - 1) % node.movieLength) + node.movieLength) % node.movieLength; }
     233                                                        else { node.movieFrame = (((node.movieFrame + 1) % node.movieLength) + node.movieLength) % node.movieLength; }
    234234                                                }
    235                                                 if (canvas["timeLabel"]) canvas["timeLabel"].html(node["movieTimestamps"][node["movieFrame"]].toFixed(0) + " " + options.getfieldvalue("movietimeunit","yr"));
    236                                                 if (canvas["progressBar"]) {
    237                                                         canvas["progressBar"].val(node["movieFrame"]);
    238                                                         canvas["progressBar"].slider('refresh');
     235                                                if (canvas.progressBar) {
     236                                                        canvas.progressBar.val(node.movieFrame);
     237                                                        canvas.progressBar.slider('refresh');
    239238                                                }
    240                                                 canvas["movieFrame"] = node["movieFrame"];
    241                                                 var buffer = node["mesh"].getBuffer("coords");
    242                                                 buffer.data = texcoords[node["movieFrame"]];
     239                                                if (canvas.timeLabel) { canvas.timeLabel.html(node.movieTimestamps[node.movieFrame].toFixed(0) + " " + options.getfieldvalue("movietimeunit","yr")); }
     240
     241                                                var buffer = node.mesh.getBuffer("coords");
     242                                                buffer.data = texcoords[node.movieFrame];
    243243                                                buffer.upload(canvas.gl.DYNAMIC_DRAW);
    244                                         }, node["movieInterval"]);
    245                                 if (canvas["progressBar"]) {
    246                                         canvas["movieFrame"] = 0;
    247                                         canvas["progressBar"].val(0);
    248                                         canvas["progressBar"].attr('max', node["movieLength"]-1);
    249                                         canvas["progressBar"].slider('refresh');
    250                                 }
    251                         }
    252                         node["mesh"] = GL.Mesh.load({vertices:vertices, coords:texcoords[0], indices:indices}, null, null, gl);
     244                                                node.mesh.octree = new GL.Octree(node.mesh);
     245
     246                                                canvas.movieFrame = node.movieFrame;
     247                                        }, node.movieInterval);
     248                                if (canvas.progressBar) {
     249                                        canvas.movieFrame = 0;
     250                                        canvas.progressBar.val(0);
     251                                        canvas.progressBar.attr('max', node.movieLength-1);
     252                                        canvas.progressBar.slider('refresh');
     253                                }
     254                               
     255                        }
     256                        node.mesh = GL.Mesh.load({vertices:vertices, coords:texcoords[0], triangles:indices}, null, null, gl);
     257                        node.mesh.octree = new GL.Octree(node.mesh);
    253258                        break;
    254259                //}}}
  • issm/trunk-jpl/src/m/plot/plotdoc.js

    r21173 r21231  
    3131        console.log('       "colormap": same as standard matlab option (default "jet", ex: "hsv","cool","spring","gray","Ala","Rignot",...)');
    3232        console.log('       "controlsensitivity": sensitivty of view/zoom changes as a percentage of default (default 1, ex: 0.5, 2.75)');
     33        console.log('       "datamarkers": toggle data marker displays (default "on", ex: "on", "off")');
    3334        console.log('       "displayview": print view value to console (default "off", ex: "on", "off")');
    3435        console.log('       "displayzoom": print zoom value to console (default "off", ex: "on", "off")');
  • issm/trunk-jpl/src/m/plot/webgl.js

    r21205 r21231  
    1010                canvas.gl = initWebGL(canvas,options);
    1111                canvas.nodes = [];
    12                 if (canvas.drawHandler) window.cancelAnimationFrame(canvas.drawHandler);
     12                if (canvas.drawHandler) { window.cancelAnimationFrame(canvas.drawHandler); }
    1313                draw(canvas,options);
    1414                canvas.initialized = true;
     
    2121                if (!canvas.gl) {
    2222                        gl = GL.create({canvas:canvas});
     23                        // Enable depth testing
     24                        gl.enable(gl.DEPTH_TEST);
     25                        // Near things obscure far things
     26                        gl.depthFunc(gl.LEQUAL);
     27                        // Enable color blending/overlay
     28                        gl.enable(gl.BLEND);
     29                        // Enable face culling
     30                        gl.enable(gl.CULL_FACE);
     31                        gl.cullFace(gl.FRONT);
     32                        // Load shaders and store them in gl object
     33                        gl.shaders = loadShaders(gl);
     34                       
     35                        // Add event listeners for canvas
     36                        var displayview = options.getfieldvalue('displayview','off') == 'on';
     37                        var displayzoom = options.getfieldvalue('displayzoom','off') == 'on';
     38                        var mc = new Hammer.Manager(canvas);
     39                       
     40                        mc.add( new Hammer.Tap({ event: 'singletap' }) );
     41                        mc.add(new Hammer.Pan({threshold:0, pointers:0}));
     42                        mc.add(new Hammer.Pinch({threshold:0})).recognizeWith(mc.get('pan'));
     43                        mc.on('singletap', function (ev) {onTap(ev,canvas);});
     44                        mc.on('panstart panmove', function (ev) {onPan(ev,canvas,displayview);});
     45                        mc.on('pinchstart pinchmove', function (ev) {onPinch(ev,canvas,displayview);});
     46                       
     47                        //canvas.addEventListener('mousemove', function (ev) {onTap(ev,canvas);}, false);
     48                        canvas.addEventListener('mousewheel', function (ev) {onZoom(ev,canvas,displayzoom)}, false);
     49                        canvas.addEventListener('DOMMouseScroll', function (ev) {onZoom(ev,canvas,displayzoom)}, false);
    2350                }
    2451                else {
     
    3158        }
    3259       
    33         // Enable depth testing
    34         gl.enable(gl.DEPTH_TEST);
    35         // Near things obscure far things
    36         gl.depthFunc(gl.LEQUAL);
    37         // Enable color blending/overlay
    38         gl.enable(gl.BLEND);
    39         // Enable face culling
    40         gl.enable(gl.CULL_FACE);
    41         gl.cullFace(gl.FRONT);
    42        
    43         // Load shaders and store them in gl object
    44         gl.shaders = loadShaders(gl);
    45        
    4660        // Add context state variables
    4761        //TODO:Group variables in objects for organization and naming
    4862        canvas.gl = gl;
    49         canvas.zoomBounds = options.getfieldvalue('zoomlim',[0.001,100.0]);
    50         canvas.zoom = clamp(options.getfieldvalue('zoom',1.0), canvas.zoomBounds[0], canvas.zoomBounds[1]);
    51         canvas.zoomLast = canvas.zoom;
    5263        canvas.cameraPosition = vec3.create();
    5364        canvas.cameraMatrix = mat4.create();
    54         canvas.vInverseMatrix = mat4.create();
    55         canvas.translation = options.getfieldvalue('origin',[0,0,0]);
    56         canvas.viewPanning = options.getfieldvalue('enablepanning','off') == 'on';
    57         canvas.view = options.getfieldvalue('view',[0,90]); //0 azimuth - up is north, 90 elevation - looking straight down
    58         canvas.rotation = canvas.view;
    59         canvas.rotationAzimuthBounds = options.getfieldvalue('azlim',[0,360]);
    60         canvas.rotationElevationBounds = options.getfieldvalue('ellim',[-180,180]);
    6165        canvas.controlSensitivity = options.getfieldvalue('controlsensitivity',1);
    62         canvas.twod = options.getfieldvalue('2d','off') == 'on';
     66        canvas.dataMarkersAllowed = options.getfieldvalue('datamarkers','off') == 'on';
     67        canvas.dataMarkersEnabled = true; //if data marker feature is on, user can toggle feature on and off
     68        canvas.inverseCameraMatrix = mat4.create();
     69        canvas.id = options.getfieldvalue('canvasid','.sim-canvas');
    6370        canvas.moviePlay = true;
    6471        canvas.movieReverse = false;
    6572        canvas.movieIncrement = true;
    6673        canvas.moviefps = options.getfieldvalue('moviefps',5);
     74        canvas.rotation = options.getfieldvalue('view',[0,90]); //0 azimuth, 90 elevation
     75        canvas.rotationAzimuthBounds = options.getfieldvalue('azlim',[0,360]);
     76        canvas.rotationElevationBounds = options.getfieldvalue('ellim',[-180,180]);
     77        canvas.translation = options.getfieldvalue('origin',[0,0,0]);
     78        canvas.twod = options.getfieldvalue('2d','off') == 'on';
     79        canvas.view = options.getfieldvalue('view',[0,90]);
     80        canvas.viewPanning = options.getfieldvalue('enablepanning','off') == 'on';
     81        canvas.vInverseMatrix = mat4.create();
     82        canvas.zoomBounds = options.getfieldvalue('zoomlim',[0.001,100.0]);
     83        canvas.zoom = clamp(options.getfieldvalue('zoom',1.0), canvas.zoomBounds[0], canvas.zoomBounds[1]);
     84        canvas.zoomLast = canvas.zoom;
    6785        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 curent canvas ",canvas));
    70        
    71         // Add event listeners for canvas
    72         var displayview = options.getfieldvalue('displayview','off') == 'on';
    73         var displayzoom = options.getfieldvalue('displayzoom','off') == 'on';
    74         var mc = new Hammer.Manager(canvas);
    75        
    76         mc.add(new Hammer.Tap());
    77     mc.add(new Hammer.Pan({threshold:0, pointers:0}));
    78     mc.add(new Hammer.Pinch({threshold:0})).recognizeWith(mc.get('pan'));
    79         mc.on("tap", function (ev) {onTap(ev,canvas);});
    80     mc.on("panstart panmove", function (ev) {onPan(ev,canvas,displayview);});
    81     mc.on("pinchstart pinchmove", function (ev) {onPinch(ev,canvas,displayview);});
    82        
    83         canvas.addEventListener("mousewheel", function (ev) {onZoom(ev,canvas,displayzoom)}, false);
    84         canvas.addEventListener("DOMMouseScroll", function (ev) {onZoom(ev,canvas,displayzoom)}, false);
     86        if (backgroundcolor.ok) { canvas.backgroundcolor = [backgroundcolor.r/255.0, backgroundcolor.g/255.0, backgroundcolor.b/255.0, 1.0]; }
     87        else { throw Error(sprintf('s%s%s\n','initWebGL error message: cound not find out background color for curent canvas ',canvas)); }
    8588       
    8689        return gl;
     90} //}}}
     91function loadShaders(gl) { //{{{
     92        var shaders = {};
     93        shaders.Colored = new GL.Shader.fromURL('../../../js/shaders/Colored.vsh', '../../../js/shaders/Colored.fsh', null, gl);
     94        shaders.Textured = new GL.Shader.fromURL('../../../js/shaders/Textured.vsh', '../../../js/shaders/Textured.fsh', null, gl);
     95        shaders.SkyFromSpace = new GL.Shader.fromURL('../../../js/shaders/SkyFromSpace.vert', '../../../js/shaders/SkyFromSpace.frag', null, gl);
     96        shaders.GroundFromSpace = new GL.Shader.fromURL('../../../js/shaders/GroundFromSpace.vert', '../../../js/shaders/GroundFromSpace.frag', null, gl);
     97        return shaders;
    8798} //}}}
    8899function initTexture(gl,imageSource) { //{{{
     
    106117                maskColor:vec4.fromValues(0.0, 0.0, 1.0, 1.0),
    107118                mesh:null,
    108                 name:"node",
    109                 shaderName:"Colored",
    110                 shader:gl.shaders["Colored"],
     119                name:'node',
     120                shaderName:'Colored',
     121                shader:gl.shaders.Colored,
    111122                texture:null,
    112123                useIndexBuffer:true,
     
    115126                rotation:vec3.create(),
    116127                translation:vec3.create(),
    117                 modelMatrix:mat4.create()
     128                modelMatrix:mat4.create(),
     129                rotationMatrix:mat4.create(),
     130                inverseModelMatrix:mat4.create(),
     131                inverseRotationMatrix:mat4.create()
    118132        };
    119133} //}}}
    120 function debugNodes(canvasid) {
     134function debugNodes(canvasid) { //{{{
     135        var canvasid = canvasid || '.sim-canvas';
    121136        var nodes = $(canvasid)[0].nodes;
    122         console.log(canvasid, "Nodes:");
     137        console.log(canvasid, 'Nodes:');
    123138        for (var node in nodes) {
    124                 console.log("name", nodes[node]["name"], "translation", nodes[node]["translation"], "center", nodes[node]["center"], "rotation", nodes[node]["rotation"]);
     139                console.log('name: ', nodes[node].name, ' node: ', nodes[node], ' mesh: ', nodes[node].mesh, ' translation: ', nodes[node].translation, ' center:', nodes[node].center, ' rotation:', nodes[node].rotation);
    125140        }
    126141        return nodes;
    127 }
    128 function recalculateModelMatrix(node) { //{{{
     142} //}}}
     143function updateModelMatrix(node) { //{{{
    129144        var modelMatrix = mat4.create();
    130145
    131146        var translationMatrix = mat4.create();
    132         mat4.translate(translationMatrix, translationMatrix, [-node["center"][0],-node["center"][1],-node["center"][2]]); //scale/rotation centering
     147        mat4.translate(translationMatrix, translationMatrix, [-node.center[0],-node.center[1],-node.center[2]]); //scale/rotation centering
    133148        mat4.multiply(modelMatrix, translationMatrix, modelMatrix);
    134149       
    135150        var scaleMatrix = mat4.create();
    136         mat4.scale(scaleMatrix, scaleMatrix, node["scale"]);
     151        mat4.scale(scaleMatrix, scaleMatrix, node.scale);
    137152        mat4.multiply(modelMatrix, scaleMatrix, modelMatrix);
    138153       
     154        var rotationMatrix = mat4.create();
    139155        var zRotationMatrix = mat4.create();   
    140         mat4.rotate(zRotationMatrix, zRotationMatrix, radians(node["rotation"][2]), [0.0, 0.0, 1.0]);
    141         mat4.multiply(modelMatrix, zRotationMatrix, modelMatrix);
     156        mat4.rotate(zRotationMatrix, zRotationMatrix, DEG2RAD * node.rotation[2], [0.0, 0.0, 1.0]);
     157        mat4.multiply(rotationMatrix, zRotationMatrix, rotationMatrix);
    142158        var yRotationMatrix = mat4.create();   
    143         mat4.rotate(yRotationMatrix, yRotationMatrix, radians(node["rotation"][1]), [0.0, 1.0, 0.0]);
    144         mat4.multiply(modelMatrix, yRotationMatrix, modelMatrix);
     159        mat4.rotate(yRotationMatrix, yRotationMatrix, DEG2RAD * node.rotation[1], [0.0, 1.0, 0.0]);
     160        mat4.multiply(rotationMatrix, yRotationMatrix, rotationMatrix);
    145161        var xRotationMatrix = mat4.create();   
    146         mat4.rotate(xRotationMatrix, xRotationMatrix, radians(node["rotation"][0]), [1.0, 0.0, 0.0]);
    147         mat4.multiply(modelMatrix, xRotationMatrix, modelMatrix);
     162        mat4.rotate(xRotationMatrix, xRotationMatrix, DEG2RAD * node.rotation[0], [1.0, 0.0, 0.0]);
     163        mat4.multiply(rotationMatrix, xRotationMatrix, rotationMatrix);
     164        mat4.multiply(modelMatrix, rotationMatrix, modelMatrix);       
    148165       
    149166        mat4.identity(translationMatrix);
    150         mat4.translate(translationMatrix, translationMatrix, node["center"]); //relative translation
     167        mat4.translate(translationMatrix, translationMatrix, node.center); //relative translation
    151168        mat4.multiply(modelMatrix, translationMatrix, modelMatrix);
    152169       
    153170        mat4.identity(translationMatrix);
    154         mat4.translate(translationMatrix, translationMatrix, node["translation"]); //absolute translation
     171        mat4.translate(translationMatrix, translationMatrix, node.translation); //absolute translation
    155172        mat4.multiply(modelMatrix, translationMatrix, modelMatrix);
    156         return modelMatrix;
    157 } //}}}
    158 function raycast(canvas,mesh,x,y) { //{{{
    159         var raytracer = new GL.Raytracer(canvas.cameraMatrix);
    160         var ray = raytracer.getRayForPixel(x, y);
    161         if(!mesh || mesh.ready == false) return;
    162         if(!mesh.octree) mesh.octree = new GL.Octree(mesh);
    163 
    164         var hit = mesh.octree.testRay(canvas.cameraPosition, ray, 1e2, 1e10);
    165        
    166         if(!hit) return;
    167         return hit.pos;
    168 }
    169 function radians (degrees) { //{{{
    170   return degrees * Math.PI / 180;
    171 } //}}}
    172 function degrees (radians) { //{{{
    173   return radians * 180 / Math.PI;
     173       
     174        node.modelMatrix = modelMatrix;
     175        node.inverseModelMatrix = mat4.invert(mat4.create(), modelMatrix);
     176        node.rotationMatrix = rotationMatrix;
     177        node.inverseRotationMatrix = mat4.invert(mat4.create(), rotationMatrix);;
    174178} //}}}
    175179function clamp(value, min, max) { //{{{
     
    177181} //}}}
    178182function recover(canvasid,name,defaultvalue) { //{{{
    179         var canvas  = document.getElementById(canvasid);
    180         if (canvas && canvas.hasOwnProperty(name)) {
    181                 return canvas[name];
    182         }
     183        var canvas = document.getElementById(canvasid);
     184        if (canvas && canvas.hasOwnProperty(name)) { return canvas[name]; }
    183185        return defaultvalue;
    184186} //}}}
     
    186188        //TypedArray compatibility for Safari/IE
    187189        if (typeof Int8Array !== 'undefined') {
    188                 if (!Int8Array.prototype.fill) Int8Array.prototype.fill = Array.prototype.fill;
    189                 if (!Int8Array.prototype.slice) Int8Array.prototype.slice = Array.prototype.slice;
     190                if (!Int8Array.prototype.fill) { Int8Array.prototype.fill = Array.prototype.fill; }
     191                if (!Int8Array.prototype.slice) { Int8Array.prototype.slice = Array.prototype.slice; }
    190192        }
    191193        if (typeof Uint8Array !== 'undefined') {
    192                 if (!Uint8Array.prototype.fill) Uint8Array.prototype.fill = Array.prototype.fill;
    193                 if (!Uint8Array.prototype.slice) Uint8Array.prototype.slice = Array.prototype.slice;
     194                if (!Uint8Array.prototype.fill) { Uint8Array.prototype.fill = Array.prototype.fill; }
     195                if (!Uint8Array.prototype.slice) { Uint8Array.prototype.slice = Array.prototype.slice; }
    194196        }
    195197        if (typeof Uint8ClampedArray !== 'undefined') {
    196                 if (!Uint8ClampedArray.prototype.fill) Uint8ClampedArray.prototype.fill = Array.prototype.fill;
    197                 if (!Uint8ClampedArray.prototype.slice) Uint8ClampedArray.prototype.slice = Array.prototype.slice;
     198                if (!Uint8ClampedArray.prototype.fill) { Uint8ClampedArray.prototype.fill = Array.prototype.fill; }
     199                if (!Uint8ClampedArray.prototype.slice) { Uint8ClampedArray.prototype.slice = Array.prototype.slice; }
    198200        }
    199201        if (typeof Int16Array !== 'undefined') {
    200                 if (!Int16Array.prototype.fill) Int16Array.prototype.fill = Array.prototype.fill;
    201                 if (!Int16Array.prototype.slice) Int16Array.prototype.slice = Array.prototype.slice;
     202                if (!Int16Array.prototype.fill) { Int16Array.prototype.fill = Array.prototype.fill; }
     203                if (!Int16Array.prototype.slice) { Int16Array.prototype.slice = Array.prototype.slice; }
    202204        }
    203205        if (typeof Uint16Array !== 'undefined') {
    204                 if (!Uint16Array.prototype.fill) Uint16Array.prototype.fill = Array.prototype.fill;
    205                 if (!Uint16Array.prototype.slice) Uint16Array.prototype.slice = Array.prototype.slice;
     206                if (!Uint16Array.prototype.fill) { Uint16Array.prototype.fill = Array.prototype.fill; }
     207                if (!Uint16Array.prototype.slice) { Uint16Array.prototype.slice = Array.prototype.slice; }
    206208        }
    207209        if (typeof Int32Array !== 'undefined') {
    208                 if (!Int32Array.prototype.fill) Int32Array.prototype.fill = Array.prototype.fill;
    209                 if (!Int32Array.prototype.slice) Int32Array.prototype.slice = Array.prototype.slice;
     210                if (!Int32Array.prototype.fill) { Int32Array.prototype.fill = Array.prototype.fill; }
     211                if (!Int32Array.prototype.slice) { Int32Array.prototype.slice = Array.prototype.slice; }
    210212        }
    211213        if (typeof Uint32Array !== 'undefined') {
    212                 if (!Uint32Array.prototype.fill) Uint32Array.prototype.fill = Array.prototype.fill;
    213                 if (!Uint32Array.prototype.slice) Uint32Array.prototype.slice = Array.prototype.slice;
     214                if (!Uint32Array.prototype.fill) { Uint32Array.prototype.fill = Array.prototype.fill; }
     215                if (!Uint32Array.prototype.slice) { Uint32Array.prototype.slice = Array.prototype.slice; }
    214216        }
    215217        if (typeof Float32Array !== 'undefined') {
    216                 if (!Float32Array.prototype.fill) Float32Array.prototype.fill = Array.prototype.fill;
    217                 if (!Float32Array.prototype.slice) Float32Array.prototype.slice = Array.prototype.slice;
     218                if (!Float32Array.prototype.fill) { Float32Array.prototype.fill = Array.prototype.fill; }
     219                if (!Float32Array.prototype.slice) { Float32Array.prototype.slice = Array.prototype.slice; }
    218220        }
    219221        if (typeof Float64Array !== 'undefined') {
    220                 if (!Float64Array.prototype.fill) Float64Array.prototype.fill = Array.prototype.fill;
    221                 if (!Float64Array.prototype.slice) Float64Array.prototype.slice = Array.prototype.slice;
     222                if (!Float64Array.prototype.fill) { Float64Array.prototype.fill = Array.prototype.fill; }
     223                if (!Float64Array.prototype.slice) { Float64Array.prototype.slice = Array.prototype.slice; }
    222224        }
    223225        if (typeof TypedArray !== 'undefined') {
    224                 if (!TypedArray.prototype.fill) TypedArray.prototype.fill = Array.prototype.fill;
    225                 if (!TypedArray.prototype.slice) TypedArray.prototype.slice = Array.prototype.slice;
    226         }
     226                if (!TypedArray.prototype.fill) { TypedArray.prototype.fill = Array.prototype.fill; }
     227                if (!TypedArray.prototype.slice) { TypedArray.prototype.slice = Array.prototype.slice; }
     228        }
     229} //}}}
     230function raycast(canvas, origin, ray) { //{{{
     231        var mesh = canvas.unitNode.mesh;
     232        if (!mesh || mesh.ready == false) { return; }
     233        if (!mesh.octree) { mesh.octree = new GL.Octree(mesh); }
     234       
     235        var hit = mesh.octree.testRay(origin, ray, 1e3, 1e10);
     236       
     237        if(!hit) { return; }
     238       
     239        hit.modelPos = vec3.copy(vec3.create(), hit.pos);
     240        vec3.transformMat4(hit.pos, hit.pos, canvas.unitNode.modelMatrix);
     241        vec3.transformMat4(hit.normal, hit.normal, canvas.unitNode.modelMatrix);
     242
     243        return hit;
    227244} //}}}
    228245//}}}
    229 //{{{ Shader Loading
    230 function loadShaders(gl) { //{{{
    231         var shaders = {};
    232         shaders["Colored"] = new GL.Shader.fromURL("../../../js/shaders/Colored.vsh", "../../../js/shaders/Colored.fsh", null, gl);
    233         shaders["Textured"] = new GL.Shader.fromURL("../../../js/shaders/Textured.vsh", "../../../js/shaders/Textured.fsh", null, gl);
    234         shaders["SkyFromSpace"] = new GL.Shader.fromURL("../../../js/shaders/SkyFromSpace.vert", "../../../js/shaders/SkyFromSpace.frag", null, gl);
    235         shaders["GroundFromSpace"] = new GL.Shader.fromURL("../../../js/shaders/GroundFromSpace.vert", "../../../js/shaders/GroundFromSpace.frag", null, gl);
    236         return shaders;
    237 } //}}}
    238246//{{{ Interface Functions
    239 function onTap(ev,canvas) { //{{{
     247function onTap(ev, canvas) { //{{{
     248        //Sets up a marker on a canvas that will track a point on the mesh. Can be dismissed by closing the display or clicking the marker.
    240249        ev.preventDefault();
    241         if (ev.type == 'panstart') {
    242                 canvas.lastDeltaX = 0;
    243                 canvas.lastDeltaY = 0;
    244         }
    245 }
     250        if (!(canvas.dataMarkersAllowed && canvas.dataMarkersEnabled)) { return; }
     251       
     252        var rect = canvas.getBoundingClientRect();
     253        var x = ev.srcEvent.clientX - rect.left;
     254        var y = ev.srcEvent.clientY - rect.top;
     255       
     256        updateMarker(canvas, x, y, true);
     257} //}}}
     258function updateMarker(canvas, x, y, reset, origin, far) { //{{{
     259        //Can be called by onTap to create/reuse a marker, or by the marker's update function. Origin and far are optional and only used by the update function for recreating the raycast.
     260        if (!canvas.unitNode) { return; }
     261       
     262        var inverseMVPMatrix = mat4.invert(mat4.create(), mat4.multiply(mat4.create(), canvas.cameraMatrix, canvas.unitNode.modelMatrix));
     263        var origin = origin || vec3.transformMat4(vec3.create(), [(x - canvas.width / 2) / (canvas.width / 2), (canvas.height / 2 - y) / (canvas.height / 2), 0], inverseMVPMatrix);
     264        var far = far || vec3.transformMat4(vec3.create(), [(x - canvas.width / 2) / (canvas.width / 2), (canvas.height / 2 - y) / (canvas.height / 2), 1.0], inverseMVPMatrix);
     265        var ray = vec3.subtract(vec3.create(), far, origin);
     266        var hit = raycast(canvas, origin, ray);
     267       
     268        if (hit) {
     269                var u = hit.coords[0][0] * hit.uvw[0] + hit.coords[1][0] * hit.uvw[1] + hit.coords[2][0] * hit.uvw[2];
     270                var v = hit.coords[0][1] * hit.uvw[0] + hit.coords[1][1] * hit.uvw[1] + hit.coords[2][1] * hit.uvw[2];
     271                var value = canvas.unitNode.caxis[0] * (1.0 - v) + canvas.unitNode.caxis[1] * v;
     272               
     273                var rect = canvas.getBoundingClientRect();
     274                var dataMarkerSize = 32;
     275                if (!canvas.marker) {
     276                        $('#' + canvas.id).after( '<img src="../../../js/textures/data-marker.svg" alt="data marker" width="' + dataMarkerSize + '" height="' + dataMarkerSize + '" id="sim-data-marker-' + canvas.id + '" class="sim-data-marker noselect"></img>' );
     277                        $('#sim-data-marker-' + canvas.id).css({
     278                                'position': 'absolute',
     279                                'left': (Math.round(x + rect.left) - dataMarkerSize / 2) + 'px',
     280                                'top': (Math.round(y + rect.top) - dataMarkerSize) + 'px',
     281                                'width': dataMarkerSize + 'px',
     282                                'height': dataMarkerSize + 'px',
     283                                'pointer-events': 'all',
     284                                'cursor': 'pointer',
     285                                'display': 'none'
     286                        });
     287                        canvas.marker = $('#sim-data-marker-' + canvas.id);
     288                        canvas.marker.on('click touch', function () {
     289                                canvas.marker.fadeOut(175);
     290                                canvas.dataMarkerDisplay.stop();
     291                        });
     292                        canvas.marker.fadeIn(175);
     293                }
     294               
     295               
     296                canvas.marker.hit = hit;
     297                canvas.marker.update = function() {
     298                        if (!canvas.unitNode) { return; }
     299                        var screenPoint = vec3.transformMat4(vec3.create(), canvas.marker.hit.pos, canvas.cameraMatrix);
     300                        var x = screenPoint[0] * (canvas.width / 2) + canvas.width / 2;
     301                        var y = -screenPoint[1] * (canvas.height / 2) + canvas.height / 2;
     302                        updateMarker(canvas, Math.round(x), Math.round(y), false, origin, far);
     303                        canvas.marker.css({
     304                                'left': (Math.round(x + rect.left) - dataMarkerSize / 2) + 'px',
     305                                'top': (Math.round(y + rect.top) - dataMarkerSize) + 'px'
     306                        });
     307                };
     308               
     309                if (!canvas.dataMarkerDisplay) {
     310                        var tripToShowData = new Trip([
     311                        {
     312                                content : '<div id="sim-data-marker-content-' + canvas.id + '" class="sim-data-marker-content"><p>X: ' + hit.modelPos [0].toPrecision(3) + ' </p><p>Y: ' + hit.modelPos [1].toPrecision(3) + ' </p><p>Z: ' + hit.modelPos [2].toPrecision(3) + '</p><p>Value: ' + (Math.round(value * 1000) / 1000).toPrecision(3) + '</p></div>',
     313                                position : 'screen-se'
     314                        }],
     315                        {
     316                                onEnd : function(tripIndex) {
     317                                        canvas.marker.fadeOut(175);
     318                                },
     319                                tripTheme : 'dark',
     320                                showCloseBox : true,
     321                                delay: -1
     322                        });
     323                        canvas.dataMarkerDisplay = tripToShowData;
     324                        canvas.dataMarkerDisplay.start();
     325                }
     326                $('#sim-data-marker-content-' + canvas.id).html('<p>X: ' + hit.modelPos [0].toPrecision(3) + ' </p><p>Y: ' + hit.modelPos [1].toPrecision(3) + ' </p><p>Z: ' + hit.modelPos [2].toPrecision(3) + '</p><p>Value: ' + (Math.round(value * 1000) / 1000).toPrecision(3) + '</p>');
     327                               
     328                if (reset) { modifyDataMarkersEnabled(true,canvas); }
     329        }
     330} //}}}
    246331function onPan(ev,canvas,displaylog) { //{{{
    247332        ev.preventDefault();
     
    256341               
    257342                if (canvas.twod) {
    258                         canvas.translation[0] += Math.cos(radians(canvas.rotation[0])) * deltaX - Math.sin(radians(0)) * deltaY;
    259                         canvas.translation[2] += Math.sin(radians(canvas.rotation[0])) * deltaX + Math.cos(radians(0)) * deltaY;
     343                        canvas.translation[0] += Math.cos(DEG2RAD * canvas.rotation[0]) * deltaX - Math.sin(DEG2RAD * 0) * deltaY;
     344                        canvas.translation[2] += Math.sin(DEG2RAD * canvas.rotation[0]) * deltaX + Math.cos(DEG2RAD * 0) * deltaY;
    260345                }
    261346                else {
    262                         canvas.translation[0] += Math.cos(radians(canvas.rotation[0])) * deltaX - Math.sin(radians(canvas.rotation[0])) * deltaY;
    263                         canvas.translation[2] += Math.sin(radians(canvas.rotation[0])) * deltaX + Math.cos(radians(canvas.rotation[0])) * deltaY;
     347                        canvas.translation[0] += Math.cos(DEG2RAD * canvas.rotation[0]) * deltaX - Math.sin(DEG2RAD * canvas.rotation[0]) * deltaY;
     348                        canvas.translation[2] += Math.sin(DEG2RAD * canvas.rotation[0]) * deltaX + Math.cos(DEG2RAD * canvas.rotation[0]) * deltaY;
    264349                }
    265350        }
    266351        else {
    267                 canvas.rotation[0] += degrees((canvas.lastDeltaX - ev.deltaX) / canvas.clientWidth * -2 * canvas.controlSensitivity);
    268                 canvas.rotation[1] += degrees((canvas.lastDeltaY - ev.deltaY) / canvas.clientHeight * -2 * canvas.controlSensitivity);
    269                
    270                 if (canvas.rotation[0] > 360) {canvas.rotation[0] -= 360};
    271                 if (canvas.rotation[0] < -360) {canvas.rotation[0] += 360};
    272                 if (canvas.rotation[1] > 180) {canvas.rotation[1] -= 360};
    273                 if (canvas.rotation[1] < -180) {canvas.rotation[1] += 360};
     352                canvas.rotation[0] += (canvas.lastDeltaX - ev.deltaX) / canvas.clientWidth * -2 * canvas.controlSensitivity * RAD2DEG;
     353                canvas.rotation[1] += (canvas.lastDeltaY - ev.deltaY) / canvas.clientHeight * -2 * canvas.controlSensitivity * RAD2DEG;
     354               
     355                if (canvas.rotation[0] > 360) { canvas.rotation[0] -= 360; };
     356                if (canvas.rotation[0] < -360) { canvas.rotation[0] += 360; };
     357                if (canvas.rotation[1] > 180) { canvas.rotation[1] -= 360; };
     358                if (canvas.rotation[1] < -180) { canvas.rotation[1] += 360; };
    274359               
    275360                canvas.rotation[0] = clamp(canvas.rotation[0], canvas.rotationAzimuthBounds[0], canvas.rotationAzimuthBounds[1]);
     
    279364        canvas.lastDeltaY = ev.deltaY;
    280365
    281         if (displaylog) console.log(canvas.rotation);
     366        if (displaylog) { console.log(canvas.rotation); }
    282367} //}}}
    283368function onPinch(ev,canvas,displaylog) { //{{{
    284369        ev.preventDefault();
    285         if (ev.type == 'pinchstart') {
    286                 canvas.zoomLast = canvas.zoom;
    287         }
    288         else {
    289                 modifyZoom(ev.scale * canvas.zoomLast, canvas, displaylog);
    290         }
     370        if (ev.type == 'pinchstart') { canvas.zoomLast = canvas.zoom; }
     371        else { modifyZoom(ev.scale * canvas.zoomLast, canvas, displaylog); }
    291372} //}}}
    292373function onZoom(ev,canvas,displaylog) { //{{{
     
    297378function modifyZoom(value,canvas,displaylog) { //{{{
    298379        canvas.zoom = clamp(value, canvas.zoomBounds[0], canvas.zoomBounds[1]);
    299         if (displaylog) console.log(canvas.zoom);
     380        if (displaylog) { console.log(canvas.zoom); }
     381} //}}}
     382function modifyDataMarkersEnabled(value,canvas) { //{{{
     383        canvas.dataMarkersEnabled = value;
     384        if (!canvas.dataMarkersEnabled && canvas.marker) {
     385                canvas.marker.fadeOut(175);
     386                canvas.dataMarkerDisplay.stop();
     387        }
     388        else if (canvas.dataMarkersEnabled && canvas.marker) {
     389                canvas.marker.fadeIn(175);
     390                canvas.dataMarkerDisplay.start();
     391        }
    300392} //}}}
    301393//}}}
     
    312404        var cameraPosition = vec3.create();
    313405
    314         if (canvas.twod) {
    315                 mat4.ortho(pMatrix, -aspectRatio*6.371e6/canvas.zoom, aspectRatio*6.371e6/canvas.zoom, -6.371e6/canvas.zoom, 6.371e6/canvas.zoom, -1.0, 1e10);
    316         }
    317         else {
    318                 mat4.perspective(pMatrix, 60 * Math.PI / 180, aspectRatio, 1e2, 1e10);
    319         }
     406        if (canvas.twod) { mat4.ortho(pMatrix, -aspectRatio*6.371e6/canvas.zoom, aspectRatio*6.371e6/canvas.zoom, -6.371e6/canvas.zoom, 6.371e6/canvas.zoom, -1.0, 1e10); }
     407        else { mat4.perspective(pMatrix, 45 * DEG2RAD, aspectRatio, 1e3, 1e10); }
    320408       
    321409        //Apply worldspace translation
    322         mat4.translate(translateMatrix, translateMatrix, [-canvas["translation"][0],-canvas["translation"][1],-canvas["translation"][2]]);
     410        mat4.translate(translateMatrix, translateMatrix, [-canvas.translation[0],-canvas.translation[1],-canvas.translation[2]]);
    323411        mat4.multiply(vMatrix, translateMatrix, vMatrix);
    324412       
    325413        //Calculate rotation around camera focal point about worldspace origin
    326414        if (canvas.twod) {
    327                 mat4.rotate(azimuthRotationMatrix, azimuthRotationMatrix, radians(0), [0, 1, 0]);
    328                 mat4.rotate(elevationRotationMatrix, elevationRotationMatrix, radians(90), [1, 0, 0]);
     415                mat4.rotate(azimuthRotationMatrix, azimuthRotationMatrix, DEG2RAD * 0, [0, 1, 0]);
     416                mat4.rotate(elevationRotationMatrix, elevationRotationMatrix, DEG2RAD * 90, [1, 0, 0]);
    329417                mat4.multiply(rotationMatrix, elevationRotationMatrix, azimuthRotationMatrix);
    330418        }
    331419        else {
    332                 mat4.rotate(azimuthRotationMatrix, azimuthRotationMatrix, radians(canvas.rotation[0]), [0, 1, 0]);
    333                 mat4.rotate(elevationRotationMatrix, elevationRotationMatrix, radians(canvas.rotation[1]), [1, 0, 0]);
     420                mat4.rotate(azimuthRotationMatrix, azimuthRotationMatrix, DEG2RAD * canvas.rotation[0], [0, 1, 0]);
     421                mat4.rotate(elevationRotationMatrix, elevationRotationMatrix, DEG2RAD * canvas.rotation[1], [1, 0, 0]);
    334422                mat4.multiply(rotationMatrix, elevationRotationMatrix, azimuthRotationMatrix);
    335423        }
    336424       
    337         //Apply rotation and scaling transform
     425        //Apply rotation transform
    338426        mat4.multiply(vMatrix, rotationMatrix, vMatrix);
    339427
     
    345433        //Calculate fields for lighting and raycasts
    346434        mat4.invert(canvas.vInverseMatrix, vMatrix);
    347         vec3.transformMat4(canvas.cameraPosition, cameraPosition, canvas.vInverseMatrix);
    348 
     435       
    349436        //Apply projection matrix to get camera matrix
    350437        mat4.multiply(canvas.cameraMatrix, pMatrix, vMatrix);
     438        mat4.invert(canvas.inverseCameraMatrix, canvas.cameraMatrix);
     439        vec3.transformMat4(canvas.cameraPosition, cameraPosition, canvas.inverseCameraMatrix);
    351440}//}}}
    352441function drawSceneGraphNode(canvas,node) { //{{{
    353         if (!node["enabled"]) return;
     442        if (!node.enabled) { return; }
    354443
    355444        var gl = canvas.gl;
     
    357446       
    358447        var mvpMatrix = mat4.create();
    359         mat4.multiply(mvpMatrix, canvas.cameraMatrix, node["modelMatrix"]);
    360        
    361         if (node["texture"]) node["texture"].bind(0);
    362         if (node["disableDepthTest"]) gl.disable(gl.DEPTH_TEST);
    363         if (node["enableCullFace"]) gl.enable(gl.CULL_FACE);
    364 
    365         gl.cullFace(node["cullFace"]);
    366         gl.lineWidth(node["lineWidth"]);
     448        mat4.multiply(mvpMatrix, canvas.cameraMatrix, node.modelMatrix);
     449       
     450        if (node.texture) { node.texture.bind(0); }
     451        if (node.disableDepthTest) { gl.disable(gl.DEPTH_TEST); }
     452        if (node.enableCullFace) { gl.enable(gl.CULL_FACE); }
     453
     454        gl.cullFace(node.cullFace);
     455        gl.lineWidth(node.lineWidth);
    367456        gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    368457
     
    373462        vec3.transformMat4(origin, origin, canvas.vInverseMatrix);
    374463        vec3.normalize(lightOrigin, lightOrigin);
    375         vec3.sub(cameraPositionRelative, origin, node["translation"]);
     464        vec3.sub(cameraPositionRelative, origin, node.translation);
    376465        cameraHeight = vec3.length(cameraPositionRelative);
    377466       
     
    401490        var scaleDepth = atm.scaleDepth;
    402491       
    403         node["shader"].uniforms({
     492        node.shader.uniforms({
    404493                m4MVP: mvpMatrix,
    405                 m4Model: node["modelMatrix"],
     494                m4Model: node.modelMatrix,
    406495                u_texture: 0,
    407                 u_alpha: node["alpha"],
    408                 u_maskEnabled: node["maskEnabled"],
    409                 u_maskHeight: node["maskHeight"],
    410                 u_maskColor: node["maskColor"],
     496                u_alpha: node.alpha,
     497                u_maskEnabled: node.maskEnabled,
     498                u_maskHeight: node.maskHeight,
     499                u_maskColor: node.maskColor,
    411500                v3CameraPosition: origin,
    412                 v3Translate: node["translation"],
     501                v3Translate: node.translation,
    413502                v3LightPos: lightOrigin,
    414503                v3InvWavelength: inv_wavelength4,
     
    434523                e: atm.e,
    435524                attenuation: atm.attenuation
    436         });
    437         if (node["useIndexBuffer"] == true) node["shader"].draw(node["mesh"], node["drawMode"], "indices");
    438         else node["shader"].draw(node["mesh"], node["drawMode"]);
    439 
     525        }).draw(node.mesh, node.drawMode, 'triangles');
     526       
    440527        gl.enable(gl.DEPTH_TEST);
    441528        gl.disable(gl.CULL_FACE);
    442529} //}}}
    443530function draw(canvas,options) { //{{{
    444 
    445         // Ensure canvas and gl viewport sizes are the same
    446         if (canvas.width  != canvas.clientWidth || canvas.height != canvas.clientHeight) {
    447                 canvas.width  = canvas.clientWidth;
    448                 canvas.height = canvas.clientHeight;
    449                 canvas.gl.viewport(0, 0, canvas.width, canvas.height);
    450         }
    451        
    452         if (canvas.textcanvas) canvas.textcanvas.draw(canvas);
     531        if (canvas.textcanvas) { canvas.textcanvas.draw(canvas); }
    453532
    454533        var nodes = canvas.nodes;
    455534        if (nodes.length < 1) {
    456                 canvas.drawHandler = window.requestAnimationFrame(function(time) {draw(canvas,options)});
     535                canvas.drawHandler = window.requestAnimationFrame(function(time) { draw(canvas,options); });
    457536                return;
    458537        }
    459         for (var node in nodes) {
    460                 if (nodes[node]["texture"] && nodes[node]["texture"]["ready"] == false || nodes[node]["shader"]["ready"] == false) {
    461                         canvas.drawHandler = window.requestAnimationFrame(function(time) {draw(canvas,options)});
     538        for (var node in nodes) {       
     539                if ((nodes[node].texture && nodes[node].texture.ready == false) || nodes[node].shader.ready == false || nodes[node].mesh.ready == false) {
     540                        canvas.drawHandler = window.requestAnimationFrame(function(time) { draw(canvas,options); });
    462541                        return;
    463542                }
    464543        }
    465544       
     545        var rect = canvas.getBoundingClientRect();
     546        canvas.width  = rect.width;
     547        canvas.height = rect.height;
     548       
    466549        var gl = canvas.gl;
     550        gl.makeCurrent(); //litegl function to handle switching between multiple canvases
     551        gl.viewport(0, 0, rect.width, rect.height);
    467552        gl.clearColor(canvas.backgroundcolor[0], canvas.backgroundcolor[1], canvas.backgroundcolor[2], canvas.backgroundcolor[3]);
    468553        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    469         gl.makeCurrent();
    470554       
    471555        updateCameraMatrix(canvas);
     556       
     557        if (canvas.marker) { canvas.marker.update(); }
    472558       
    473559        var drawPassNumber = 3;
    474560        for (var i = drawPassNumber - 1; i >= 0; i--) {
    475561                for (var node in nodes) {
    476                         if (nodes[node]["drawOrder"] == i) drawSceneGraphNode(canvas,nodes[node]);
    477                 }
    478         }
    479 
    480         canvas.drawHandler = window.requestAnimationFrame(function(time) {draw(canvas,options)});
     562                        if (nodes[node].drawOrder == i) { drawSceneGraphNode(canvas,nodes[node]); }
     563                }
     564        }
     565
     566        canvas.drawHandler = window.requestAnimationFrame(function(time) { draw(canvas,options); });
    481567} //}}}
    482568//}}}
Note: See TracChangeset for help on using the changeset viewer.