Changeset 21641


Ignore:
Timestamp:
03/24/17 15:25:15 (8 years ago)
Author:
dlcheng
Message:

CHG: Updating javascript plot files for mesh modification by brush. Adding debug comment for saving buffers to files in generic.js.

Location:
issm/trunk-jpl/src/m
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/m/classes/clusters/generic.js

    r21437 r21641  
    9696                        var returnBuffer_size = returnBuffer.byteLength;
    9797                        try {
     98                                //Write result buffer to file for debugging. Filename and MIME type are optional.
     99                                //writetofile(returnBuffer, "resultBuffer", "application/octet-stream");
    98100                                md.results = parseresultsfrombuffer(md,returnBuffer,returnBuffer_size);
    99101                                $(callbackid).html(sprintf("%-16s", "RUN")).prop("disabled", false);
  • issm/trunk-jpl/src/m/plot/applyoptions.js

    r21300 r21641  
    356356                        node.shader = gl.shaders[node.shaderName];
    357357                        node.drawOrder = 1;
     358                        node.cullFace = gl.FRONT;
    358359                        node.enableCullFace = true;
    359360                        node.mesh = GL.Mesh.icosahedron({size:6371000*atmosphereScale,subdivisions:6});
     
    372373                        node.shader = gl.shaders[node.shaderName];
    373374                        node.drawOrder = 2;
     375                        node.cullFace = gl.FRONT;
    374376                        node.enableCullFace = true;
    375                         node.mesh = GL.Mesh.sphere({size:6371000*10});
     377                        node.mesh = GL.Mesh.sphere({size:6371000*20});
    376378                        node.texture = initTexture(gl,canvas.rootPath+'textures/TychoSkymapII_t4_2k.jpg');
    377379                        node.useIndexBuffer = false;
  • issm/trunk-jpl/src/m/plot/plot_unit.js

    r21437 r21641  
    1 function plot_unit(md,data,datatype,options,canvas) { //{{{
     1function plot_unit(md,data,datatype,options,canvas) {
    22        //PLOT_UNIT - unit plot, display data
    33        //
     
    6363        canvas.nodes[canvas.nodes.length] = node;
    6464        canvas.unitNode = node;
     65        canvas.unitData = data;
    6566        node.name = "unit";
    6667        node.shaderName = "Textured";
     
    219220                                        indices[iindex++] = element[2];
    220221                                }
    221                                 var frame =
     222                       
    222223                                //Initialize movie loop
    223224                                node.movieLoop = canvas.movieOptions.loop;
     
    226227                                node.movieLength = timestamps.length;
    227228                                node.movieFrame = 0;
    228 
     229                                canvas.dataArray = [];
    229230                                var quiverVelFrames = {};
    230231                                for(var i=0; i < md.results.length; i++){
     
    273274                                                buffer.upload(canvas.gl.DYNAMIC_DRAW);
    274275                                                node.mesh.octree = new GL.Octree(node.mesh);
    275                                        
    276                                                 if(options.getfieldvalue('quiver') == 'data'){
     276                                                node.texcoords = texcoords;
     277                                                if(options.getfieldvalue('quiver') == 'on'){
    277278                                                        plot_quiver(md,options,canvas, {vel:quiverVelFrames[node.movieFrame].Vel, vx:quiverVelFrames[node.movieFrame].Vx, vy:quiverVelFrames[node.movieFrame].Vy});
    278279
    279280                                                }
    280281                                                canvas.movieFrame = node.movieFrame;
     282
     283                                                if (canvas.moviePlay || canvas.lastMovieFrame != canvas.movieFrame) {
     284                                                        updatePlot(true);
     285                                                }
     286
    281287                                        }, node.movieInterval);
    282288                                if (canvas.progressBar) {
     
    295301                        throw Error(sprintf("%s%i%s\n",'case ',datatype,' not supported'));
    296302        }
    297 } //}}}
     303}
  • issm/trunk-jpl/src/m/plot/plotdoc.js

    r21300 r21641  
    1818        console.log('       "2d": renders orthographic camera with view set to [0, 90] (default "off", ex: "on", "off")');
    1919        console.log('       "backgroundcolor": plot background color. (default "lightcyan", ex: "green","blue")');
     20        console.log('       "brush": specify brush options (default {"strength":0.075,"falloff":0.5})');
    2021        console.log('       "caxis": modify  colorbar range. (array of type [a, b] where b>=a)');
    2122        console.log('       "colorbar": add colorbar (default "off", ex: "on", "off")');
     
    4748        console.log('       "overlay": overlay a radar amplitude image behind (default "off", ex: "on", "off")');
    4849        console.log('       "overlay_image": path to overlay image (default "", ex: "./images/radar.png")');
     50        console.log('       "quiver": add quiver plot overlay for velocities. (default "off", ex: "on", "off")');
    4951        console.log('       "scaling": scaling factor used by quiver plots. Default is 0.4');
    5052        console.log('       "alpha": transparency coefficient 0.0 to 1.0, the lower, the more transparent. (default 1.0, ex: 0.5, 0.25)');
  • issm/trunk-jpl/src/m/plot/webgl.js

    r21437 r21641  
    6464        canvas.gl = gl;
    6565        canvas.rootPath = options.getfieldvalue('rootpath','../../../js/');
     66        canvas.brush = options.getfieldvalue('brush',{'enabled':'off','strength':0.075,'falloff':0.5});
    6667        canvas.cameraPosition = vec3.create();
    6768        canvas.cameraMatrix = mat4.create();
    6869        canvas.controlSensitivity = options.getfieldvalue('controlsensitivity',1);
     70        canvas.dataArray = [];
    6971        canvas.dataMarkersAllowed = options.getfieldvalue('datamarkers','off') == 'on';
    7072        canvas.dataMarkersEnabled = true; //if data marker feature is on, user can toggle feature on and off
    7173        canvas.dataMarkerImage = options.getfieldvalue('datamarkers_image',canvas.rootPath+'textures/data_marker.svg');
    7274        canvas.dataMarkerSize = options.getfieldvalue('datamarkerssize',[32,32]);
    73         canvas.dataMarkerOptions = options.getfieldvalue('datamarkersoptions',{'enabled':'on','image':canvas.rootPath+'textures/data_marker.svg','size':[32,32],'format':['X: %.2e<br>Y: %.2e<br>Z: %.2e]<br>Value: %0.1f','x','y','z','value']});
     75        canvas.dataMarkerOptions = options.getfieldvalue('datamarkersoptions',{'enabled':'on','image':canvas.rootPath+'textures/data_marker.svg','size':[32,32],'format':['X: %.2e<br>Y: %.2e<br>Z: %.2e]<br>Value: %0.1f','x','y','z','value'],'animated':false});
    7476        canvas.inverseCameraMatrix = mat4.create();
    7577        canvas.id = options.getfieldvalue('canvasid','.sim-canvas');
     
    154156                alpha:1.0,
    155157                buffers:[],
    156                 cullFace:gl.FRONT,
     158                cullFace:gl.BACK,
    157159                disableDepthTest:false,
    158160                drawMode:gl.TRIANGLES,
    159161                drawOrder:0,
    160162                enabled:true,
    161                 enableCullFace:false,
     163                enableCullFace:true,
    162164                hideOcean:false,
    163165                lineWidth:1.0,
     
    277279        }
    278280} //}}}
    279 function raycast(canvas, origin, ray) { //{{{
     281function raycast(canvas, x, y) { //{{{
     282        var inverseMVPMatrix = mat4.invert(mat4.create(), mat4.multiply(mat4.create(), canvas.cameraMatrix, canvas.unitNode.modelMatrix));
     283        var origin = origin || vec3.transformMat4(vec3.create(), [(x - canvas.width / 2) / (canvas.width / 2), (canvas.height / 2 - y) / (canvas.height / 2), 0], inverseMVPMatrix);
     284        var far = far || vec3.transformMat4(vec3.create(), [(x - canvas.width / 2) / (canvas.width / 2), (canvas.height / 2 - y) / (canvas.height / 2), 1.0], inverseMVPMatrix);
     285        var ray = vec3.subtract(vec3.create(), far, origin);
     286
    280287        var mesh = canvas.unitNode.mesh;
    281288        if (!mesh || mesh.ready == false) { return; }
     
    298305        ev.preventDefault();
    299306        if (!(canvas.dataMarkersAllowed && canvas.dataMarkersEnabled)) { return; }
    300         updateMarker(canvas, ev.srcEvent.layerX, ev.srcEvent.layerY, true);
    301 } //}}}
    302 function updateMarker(canvas, x, y, reset, origin, far) { //{{{
     307        initializeMarker(canvas, ev.srcEvent.layerX, ev.srcEvent.layerY, true);
     308        brushModify(canvas, ev.srcEvent.layerX, ev.srcEvent.layerY);
     309} //}}}
     310function brushModify(canvas, x, y) { //{{{
     311        //This function takes in the canvas and x/y coordinates, performing a raycast against the mesh, and modifies the mesh using a the canvas.brush.strength and canvas.brush.falloff properties.
     312        //Currently the brush extends to the raycasted element and its immediate neighbors.
     313        //TODO: Allow variable brush size/additional neighbors. Allow the function to work on multiple models (currently hardcoded to md model).
     314        if (!canvas.unitNode || canvas.brush.enabled != 'on') { return; }
     315       
     316        var hit = raycast(canvas, x, y);
     317
     318        if (hit) {
     319                var bufferVertices = canvas.unitNode.mesh.getBuffer("vertices");
     320                var vertices = bufferVertices.data;
     321                var bufferCoords = canvas.unitNode.mesh.getBuffer("coords");
     322                var coords = bufferCoords.data;
     323
     324                //Query nearby elements and store indicies of affected vertices using pregenerated vertexconnectivity list (from NodeConnectivity)
     325                var baseIndices = new Set(hit.indices);
     326                var connectedIndices = new Set(hit.indices);
     327                var connectedElement;
     328                var indices;
     329                var lengthIndex = md.mesh.vertexconnectivity[0].length - 1;
     330                var length;
     331                for (var i = 0; i < 3; i++) {
     332                        length = md.mesh.vertexconnectivity[hit.indices[i]][lengthIndex];
     333                        for (var j = 0; j < length; j++) {
     334                                //Shift elements down by one (matlab 1-based index to 0-based index)
     335                                connectedElement = md.mesh.vertexconnectivity[hit.indices[i]][j] - 1;
     336                                indices = md.mesh.elements[connectedElement];
     337                                connectedIndices.add(indices[0] - 1);
     338                                connectedIndices.add(indices[1] - 1);
     339                                connectedIndices.add(indices[2] - 1);
     340                        }
     341                }
     342
     343                //Apply modifications to included vertices in mesh using brush strength and falloff.
     344                var strength;
     345                for (var index of connectedIndices) {
     346                        if (!baseIndices.has(index)) {
     347                                strength = canvas.brush.strength * canvas.brush.falloff;
     348                        }
     349                        else {
     350                                strength = canvas.brush.strength;
     351                        }
     352                        vertices[index*3+2] += strength * 100;
     353                        md.geometry.surface[index] += strength;
     354                        md.geometry.thickness[index] += strength;
     355                        coords[index*2+1] += strength;
     356                        canvas.unitData[index] += strength;
     357                }
     358               
     359                //Update mesh on GPU
     360                bufferVertices.upload(canvas.gl.DYNAMIC_DRAW);
     361                bufferCoords.upload(canvas.gl.DYNAMIC_DRAW);
     362                canvas.unitNode.mesh.octree = new GL.Octree(canvas.unitNode.mesh);     
     363        }
     364}
     365function initializeMarker(canvas, x, y, reset, origin, far) { //{{{
    303366        //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.
    304367        if (!canvas.unitNode) { return; }
    305        
    306         var inverseMVPMatrix = mat4.invert(mat4.create(), mat4.multiply(mat4.create(), canvas.cameraMatrix, canvas.unitNode.modelMatrix));
    307         var origin = origin || vec3.transformMat4(vec3.create(), [(x - canvas.width / 2) / (canvas.width / 2), (canvas.height / 2 - y) / (canvas.height / 2), 0], inverseMVPMatrix);
    308         var far = far || vec3.transformMat4(vec3.create(), [(x - canvas.width / 2) / (canvas.width / 2), (canvas.height / 2 - y) / (canvas.height / 2), 1.0], inverseMVPMatrix);
    309         var ray = vec3.subtract(vec3.create(), far, origin);
    310         var hit = raycast(canvas, origin, ray);
    311        
     368
     369        var hit = raycast(canvas, x, y);
     370
    312371        if (hit) {
    313                 var coords = canvas.unitNode.mesh.vertexBuffers.coords.data;
    314                 var latitude = md.mesh.lat;
    315                 var longitude = md.mesh.long;
    316                 var thickness;
    317                 var velocity;
    318                 if (md.results[0]) {
    319                         thickness = md.results[canvas.movieFrame].Thickness;
    320                         velocity = md.results[canvas.movieFrame].Vel;
    321                 }
    322                 else {
    323                         thickness = md.geometry.thickness;
    324                         velocity = md.initialization.vel;
    325                 }
    326                
    327                 var hitCoords = [coords[hit.indices[0]*2], coords[hit.indices[0]*2+1],coords[hit.indices[1]*2], coords[hit.indices[1]*2+1],coords[hit.indices[2]*2], coords[hit.indices[2]*2+1]];
    328                 var hitLatitude = [latitude[hit.indices[0]], latitude[hit.indices[1]], latitude[hit.indices[2]]];
    329                 var hitLongitude = [longitude[hit.indices[0]], longitude[hit.indices[1]], longitude[hit.indices[2]]];
    330                 var hitThickness = [thickness[hit.indices[0]], thickness[hit.indices[1]], thickness[hit.indices[2]]];
    331                 var hitVelocity = [velocity[hit.indices[0]], velocity[hit.indices[1]], velocity[hit.indices[2]]];
    332                 var u = hitCoords[0] * hit.uvw[0] + hitCoords[2] * hit.uvw[1] + hitCoords[4] * hit.uvw[2];
    333                 var v = hitCoords[1] * hit.uvw[0] + hitCoords[3] * hit.uvw[1] + hitCoords[5] * hit.uvw[2];
    334                 var value = canvas.unitNode.caxis[0] * (1.0 - v) + canvas.unitNode.caxis[1] * v;
    335                 var valueLatitude = Math.abs(hitLatitude[0] * hit.uvw[0] + hitLatitude[1] * hit.uvw[1] + hitLatitude[2] * hit.uvw[2]);
    336                 var valueLongitude = Math.abs(hitLongitude[0] * hit.uvw[0] + hitLongitude[1] * hit.uvw[1] + hitLongitude[2] * hit.uvw[2]);
    337                 var valueThickness = hitThickness[0] * hit.uvw[0] + hitThickness[1] * hit.uvw[1] + hitThickness[2] * hit.uvw[2];
    338                 var valueVelocity = hitVelocity[0] * hit.uvw[0] + hitVelocity[1] * hit.uvw[1] + hitVelocity[2] * hit.uvw[2];
    339                
     372                canvas.lastHit = hit;
    340373                var dataMarkerSize = canvas.dataMarkerSize;
    341374                if (!canvas.marker) {
     
    349382                                'pointer-events': 'all',
    350383                                'cursor': 'pointer',
    351                                 'display': 'none'               
     384                                'display': 'none'
    352385                        });
    353386                        $('#sim-data-marker-' + canvas.id).tooltipster({
     387                                contentAsHTML: 'true',
     388                                animation: 'grow',
    354389                                maxWidth: 320,
    355                                 zIndex: 2200,
     390                                maxHeight: 320,
     391                                zIndex: 1000,
    356392                                trigger: 'custom',
    357393                                triggerOpen: {
     
    364400                                        originClick: true,
    365401                                        touchleave: false
    366                                 }
     402                                },
    367403                        });
    368404                        canvas.marker = $('#sim-data-marker-' + canvas.id);
     
    374410                }
    375411               
    376                
    377412                canvas.marker.hit = hit;
    378                 canvas.marker.update = function() {
    379                         if (!canvas.unitNode) { return; }
    380                         var screenPoint = vec3.transformMat4(vec3.create(), canvas.marker.hit.pos, canvas.cameraMatrix);
    381                         var x = screenPoint[0] * (canvas.width / 2) + canvas.width / 2;
    382                         var y = -screenPoint[1] * (canvas.height / 2) + canvas.height / 2;
    383                         updateMarker(canvas, Math.round(x), Math.round(y), false, origin, far);
    384                         canvas.marker.css({
    385                                 'left': (Math.round(x) - dataMarkerSize[0] / 2) + 'px',
    386                                 'top': (Math.round(y) - dataMarkerSize[1]) + 'px'
    387                         });
    388                         if (canvas.dataMarkerDisplay.tooltipster('status').state != 'closed') { canvas.dataMarkerDisplay.tooltipster('reposition'); }
    389                 };
    390                
     413
    391414                if (!canvas.dataMarkerDisplay) {
    392415                        canvas.dataMarkerDisplay = $('#sim-data-marker-' + canvas.id);
    393416                        canvas.dataMarkerDisplay.tooltipster('open');
    394417                }
    395                 if (canvas.dataMarkerOptions) {
    396                         var format = [canvas.dataMarkerOptions.format[0]];     
    397                         for (var i = 1; i < canvas.dataMarkerOptions.format.length; i++) {
    398                                 var formatString = canvas.dataMarkerOptions.format[i];
    399                                 if (formatString.toLowerCase() == 'x') { format.push(hit.modelPos[0]); }
    400                                 else if (formatString.toLowerCase() == 'y') { format.push(hit.modelPos[1]); }
    401                                 else if (formatString.toLowerCase() == 'z') { format.push(hit.modelPos[2]); }
    402                                 else if (formatString.toLowerCase() == 'lat') { format.push(valueLatitude); }
    403                                 else if (formatString.toLowerCase() == 'long') { format.push(valueLongitude); }
    404                                 else if (formatString.toLowerCase() == 'thickness') { format.push(valueThickness); }
    405                                 else if (formatString.toLowerCase() == 'vel') { format.push(valueVelocity); }
    406                                 else if (formatString.toLowerCase() == 'value') { format.push(value); }
    407                                 else {format.push(formatString); }
     418
     419                updatePlot(true);
     420                repositionMarker();
     421                if (reset) { modifyDataMarkersEnabled(true,canvas); }
     422        }
     423} //}}}
     424function updatePlot(reset) {
     425        if (!canvas.lastHit) { return; }
     426        var hit = canvas.lastHit;
     427        var coords = canvas.unitNode.mesh.vertexBuffers.coords.data;
     428        var latitude = md.mesh.lat;
     429        var longitude = md.mesh.long;
     430        var thickness;
     431        var velocity;
     432        if (md.results[0]) {
     433                thickness = md.results[canvas.movieFrame].Thickness;
     434                velocity = md.results[canvas.movieFrame].Vel;
     435        }
     436        else {
     437                thickness = md.geometry.thickness;
     438                velocity = md.initialization.vel;
     439        }
     440       
     441        var hitCoords = [coords[hit.indices[0]*2], coords[hit.indices[0]*2+1],coords[hit.indices[1]*2], coords[hit.indices[1]*2+1],coords[hit.indices[2]*2], coords[hit.indices[2]*2+1]];
     442        var hitLatitude = [latitude[hit.indices[0]], latitude[hit.indices[1]], latitude[hit.indices[2]]];
     443        var hitLongitude = [longitude[hit.indices[0]], longitude[hit.indices[1]], longitude[hit.indices[2]]];
     444        var hitThickness = [thickness[hit.indices[0]], thickness[hit.indices[1]], thickness[hit.indices[2]]];
     445        var hitVelocity = [velocity[hit.indices[0]], velocity[hit.indices[1]], velocity[hit.indices[2]]];
     446        var u = hitCoords[0] * hit.uvw[0] + hitCoords[2] * hit.uvw[1] + hitCoords[4] * hit.uvw[2];
     447        var v = hitCoords[1] * hit.uvw[0] + hitCoords[3] * hit.uvw[1] + hitCoords[5] * hit.uvw[2];
     448        var value = canvas.unitNode.caxis[0] * (1.0 - v) + canvas.unitNode.caxis[1] * v;
     449        var valueLatitude = Math.abs(hitLatitude[0] * hit.uvw[0] + hitLatitude[1] * hit.uvw[1] + hitLatitude[2] * hit.uvw[2]);
     450        var valueLongitude = Math.abs(hitLongitude[0] * hit.uvw[0] + hitLongitude[1] * hit.uvw[1] + hitLongitude[2] * hit.uvw[2]);
     451        var valueThickness = hitThickness[0] * hit.uvw[0] + hitThickness[1] * hit.uvw[1] + hitThickness[2] * hit.uvw[2];
     452        var valueVelocity = hitVelocity[0] * hit.uvw[0] + hitVelocity[1] * hit.uvw[1] + hitVelocity[2] * hit.uvw[2];   
     453        if (canvas.dataMarkerOptions) {
     454                var format = [canvas.dataMarkerOptions.format[0]];     
     455                for (var i = 1; i < canvas.dataMarkerOptions.format.length; i++) {
     456                        var formatString = canvas.dataMarkerOptions.format[i];
     457                        if (formatString.toLowerCase() == 'x') { format.push(hit.modelPos[0]); }
     458                        else if (formatString.toLowerCase() == 'y') { format.push(hit.modelPos[1]); }
     459                        else if (formatString.toLowerCase() == 'z') { format.push(hit.modelPos[2]); }
     460                        else if (formatString.toLowerCase() == 'lat') { format.push(valueLatitude); }
     461                        else if (formatString.toLowerCase() == 'long') { format.push(valueLongitude); }
     462                        else if (formatString.toLowerCase() == 'thickness') { format.push(valueThickness); }
     463                        else if (formatString.toLowerCase() == 'vel') { format.push(valueVelocity); }
     464                        else if (formatString.toLowerCase() == 'value') { format.push(value); }
     465                        else {format.push(formatString); }
     466                }
     467                if (canvas.dataMarkerOptions.animated) {
     468                        var isEmpty = (canvas.dataArray.length == 0);
     469                        var lastUpdatedIndex = (canvas.dataArray.length-1);
     470                        var newMovieFrame = (!isEmpty && canvas.dataArray[lastUpdatedIndex][0] != canvas.movieFrame);
     471                        if (reset) {
     472                                canvas.dataArray = [];
     473                                newMovieFrame = true;
     474                                for (var currentFrame = 0; currentFrame < (canvas.unitNode.movieLength); currentFrame++) {
     475                                        coords = canvas.unitNode.texcoords[currentFrame];
     476                                        var hitCoords = [coords[hit.indices[0]*2], coords[hit.indices[0]*2+1],coords[hit.indices[1]*2], coords[hit.indices[1]*2+1],coords[hit.indices[2]*2], coords[hit.indices[2]*2+1]];
     477                                        var u = hitCoords[0] * hit.uvw[0] + hitCoords[2] * hit.uvw[1] + hitCoords[4] * hit.uvw[2];
     478                                        var v = hitCoords[1] * hit.uvw[0] + hitCoords[3] * hit.uvw[1] + hitCoords[5] * hit.uvw[2];
     479                                        var value = canvas.unitNode.caxis[0] * (1.0 - v) + canvas.unitNode.caxis[1] * v;
     480                                        canvas.dataArray.push([currentFrame, value]);
     481                                }
    408482                        }
    409                        
    410                         $('#tooltip-content-data-marker-' + canvas.id).html(sprintf.apply(null, format));
    411                         $('#tooltip-content-data-marker-' + canvas.id).css({
    412                                 'font': canvas.dataMarkerOptions.font
    413                         });
    414                 }
    415 
    416                 if (reset) { modifyDataMarkersEnabled(true,canvas); }
    417         }
    418 } //}}}
     483                        else {
     484                                if (isEmpty || newMovieFrame) {
     485                                        canvas.dataArray.push([canvas.movieFrame,value]);
     486                                }
     487                        }
     488                        if (isEmpty || newMovieFrame) {
     489                                $('#tooltip-content-data-marker-' + canvas.id).html(sprintf.apply(null, format));
     490                                $('#tooltip-content-data-marker-' + canvas.id).css({
     491                                        'font': canvas.dataMarkerOptions.font
     492                                });                             
     493                                var dataLabels = {'latitude':valueLatitude,'longitude':valueLongitude,'thickness':valueThickness,'velocity':valueVelocity,'value':value};
     494                                var dataDisplay = canvas.dataArray.slice(0,canvas.movieFrame+1);                                       
     495                                plot('id','#sim-plot','type','bar','width',400,'height',300,'nticks',25,'xlabel','Time','ylabel',
     496                                        'Value','title','Changes Over Time','datalabels',canvas.dataMarkerOptions.labels,'labelvalues',dataLabels,'data',dataDisplay);
     497                        }
     498                }
     499        }
     500}
     501
     502function repositionMarker() {
     503        if (!canvas.unitNode) { return; }
     504        if (!canvas.dataMarkerDisplay) { return; }
     505        var dataMarkerSize = canvas.dataMarkerSize;
     506        var screenPoint = vec3.transformMat4(vec3.create(), canvas.marker.hit.pos, canvas.cameraMatrix);
     507        var x = screenPoint[0] * (canvas.width / 2) + canvas.width / 2;
     508        var y = -screenPoint[1] * (canvas.height / 2) + canvas.height / 2;
     509        canvas.marker.css({
     510                'left': (Math.round(x) - dataMarkerSize[0] / 2) + 'px',
     511                'top': (Math.round(y) - dataMarkerSize[1]) + 'px'
     512        });
     513        if (canvas.dataMarkerDisplay.tooltipster('status').state != 'closed') { canvas.dataMarkerDisplay.tooltipster('reposition'); }
     514}
     515
    419516function onPan(ev,canvas,displaylog) { //{{{
    420517        ev.preventDefault();
     518        repositionMarker();
     519        brushModify(canvas, ev.srcEvent.layerX, ev.srcEvent.layerY);
    421520        if (ev.type == 'panstart') {
    422521                canvas.lastDeltaX = 0;
     
    456555function onPinch(ev,canvas,displaylog) { //{{{
    457556        ev.preventDefault();
     557        repositionMarker();
    458558        if (ev.type == 'pinchstart') { canvas.zoomLast = canvas.zoom; }
    459559        else { modifyZoom(ev.scale * canvas.zoomLast, canvas, displaylog); }
     
    461561function onZoom(ev,canvas,displaylog) { //{{{
    462562        ev.preventDefault();
     563        repositionMarker();
    463564        var delta = clamp(ev.scale || ev.wheelDelta || -ev.detail, -1, 1) * canvas.controlSensitivity * canvas.zoom / 20;
    464565        modifyZoom(canvas.zoom + delta, canvas, displaylog);
     
    654755        updateCameraMatrix(canvas);
    655756       
    656         if (canvas.marker) { canvas.marker.update(); }
     757        //if (canvas.marker) { canvas.marker.update(); }
    657758       
    658759        var drawPassNumber = 3;
Note: See TracChangeset for help on using the changeset viewer.