Changeset 21231 for issm/trunk-jpl/src/m/plot/webgl.js
- Timestamp:
- 09/27/16 10:10:21 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/m/plot/webgl.js
r21205 r21231 10 10 canvas.gl = initWebGL(canvas,options); 11 11 canvas.nodes = []; 12 if (canvas.drawHandler) window.cancelAnimationFrame(canvas.drawHandler);12 if (canvas.drawHandler) { window.cancelAnimationFrame(canvas.drawHandler); } 13 13 draw(canvas,options); 14 14 canvas.initialized = true; … … 21 21 if (!canvas.gl) { 22 22 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); 23 50 } 24 51 else { … … 31 58 } 32 59 33 // Enable depth testing34 gl.enable(gl.DEPTH_TEST);35 // Near things obscure far things36 gl.depthFunc(gl.LEQUAL);37 // Enable color blending/overlay38 gl.enable(gl.BLEND);39 // Enable face culling40 gl.enable(gl.CULL_FACE);41 gl.cullFace(gl.FRONT);42 43 // Load shaders and store them in gl object44 gl.shaders = loadShaders(gl);45 46 60 // Add context state variables 47 61 //TODO:Group variables in objects for organization and naming 48 62 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;52 63 canvas.cameraPosition = vec3.create(); 53 64 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 down58 canvas.rotation = canvas.view;59 canvas.rotationAzimuthBounds = options.getfieldvalue('azlim',[0,360]);60 canvas.rotationElevationBounds = options.getfieldvalue('ellim',[-180,180]);61 65 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'); 63 70 canvas.moviePlay = true; 64 71 canvas.movieReverse = false; 65 72 canvas.movieIncrement = true; 66 73 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; 67 85 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)); } 85 88 86 89 return gl; 90 } //}}} 91 function 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; 87 98 } //}}} 88 99 function initTexture(gl,imageSource) { //{{{ … … 106 117 maskColor:vec4.fromValues(0.0, 0.0, 1.0, 1.0), 107 118 mesh:null, 108 name: "node",109 shaderName: "Colored",110 shader:gl.shaders ["Colored"],119 name:'node', 120 shaderName:'Colored', 121 shader:gl.shaders.Colored, 111 122 texture:null, 112 123 useIndexBuffer:true, … … 115 126 rotation:vec3.create(), 116 127 translation:vec3.create(), 117 modelMatrix:mat4.create() 128 modelMatrix:mat4.create(), 129 rotationMatrix:mat4.create(), 130 inverseModelMatrix:mat4.create(), 131 inverseRotationMatrix:mat4.create() 118 132 }; 119 133 } //}}} 120 function debugNodes(canvasid) { 134 function debugNodes(canvasid) { //{{{ 135 var canvasid = canvasid || '.sim-canvas'; 121 136 var nodes = $(canvasid)[0].nodes; 122 console.log(canvasid, "Nodes:");137 console.log(canvasid, 'Nodes:'); 123 138 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); 125 140 } 126 141 return nodes; 127 } 128 function recalculateModelMatrix(node) { //{{{142 } //}}} 143 function updateModelMatrix(node) { //{{{ 129 144 var modelMatrix = mat4.create(); 130 145 131 146 var translationMatrix = mat4.create(); 132 mat4.translate(translationMatrix, translationMatrix, [-node ["center"][0],-node["center"][1],-node["center"][2]]); //scale/rotation centering147 mat4.translate(translationMatrix, translationMatrix, [-node.center[0],-node.center[1],-node.center[2]]); //scale/rotation centering 133 148 mat4.multiply(modelMatrix, translationMatrix, modelMatrix); 134 149 135 150 var scaleMatrix = mat4.create(); 136 mat4.scale(scaleMatrix, scaleMatrix, node ["scale"]);151 mat4.scale(scaleMatrix, scaleMatrix, node.scale); 137 152 mat4.multiply(modelMatrix, scaleMatrix, modelMatrix); 138 153 154 var rotationMatrix = mat4.create(); 139 155 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); 142 158 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); 145 161 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); 148 165 149 166 mat4.identity(translationMatrix); 150 mat4.translate(translationMatrix, translationMatrix, node ["center"]); //relative translation167 mat4.translate(translationMatrix, translationMatrix, node.center); //relative translation 151 168 mat4.multiply(modelMatrix, translationMatrix, modelMatrix); 152 169 153 170 mat4.identity(translationMatrix); 154 mat4.translate(translationMatrix, translationMatrix, node ["translation"]); //absolute translation171 mat4.translate(translationMatrix, translationMatrix, node.translation); //absolute translation 155 172 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);; 174 178 } //}}} 175 179 function clamp(value, min, max) { //{{{ … … 177 181 } //}}} 178 182 function 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]; } 183 185 return defaultvalue; 184 186 } //}}} … … 186 188 //TypedArray compatibility for Safari/IE 187 189 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; } 190 192 } 191 193 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; } 194 196 } 195 197 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; } 198 200 } 199 201 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; } 202 204 } 203 205 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; } 206 208 } 207 209 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; } 210 212 } 211 213 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; } 214 216 } 215 217 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; } 218 220 } 219 221 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; } 222 224 } 223 225 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 } //}}} 230 function 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; 227 244 } //}}} 228 245 //}}} 229 //{{{ Shader Loading230 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 } //}}}238 246 //{{{ Interface Functions 239 function onTap(ev,canvas) { //{{{ 247 function 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. 240 249 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 } //}}} 258 function 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 } //}}} 246 331 function onPan(ev,canvas,displaylog) { //{{{ 247 332 ev.preventDefault(); … … 256 341 257 342 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; 260 345 } 261 346 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; 264 349 } 265 350 } 266 351 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; }; 274 359 275 360 canvas.rotation[0] = clamp(canvas.rotation[0], canvas.rotationAzimuthBounds[0], canvas.rotationAzimuthBounds[1]); … … 279 364 canvas.lastDeltaY = ev.deltaY; 280 365 281 if (displaylog) console.log(canvas.rotation);366 if (displaylog) { console.log(canvas.rotation); } 282 367 } //}}} 283 368 function onPinch(ev,canvas,displaylog) { //{{{ 284 369 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); } 291 372 } //}}} 292 373 function onZoom(ev,canvas,displaylog) { //{{{ … … 297 378 function modifyZoom(value,canvas,displaylog) { //{{{ 298 379 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 } //}}} 382 function 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 } 300 392 } //}}} 301 393 //}}} … … 312 404 var cameraPosition = vec3.create(); 313 405 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); } 320 408 321 409 //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]]); 323 411 mat4.multiply(vMatrix, translateMatrix, vMatrix); 324 412 325 413 //Calculate rotation around camera focal point about worldspace origin 326 414 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]); 329 417 mat4.multiply(rotationMatrix, elevationRotationMatrix, azimuthRotationMatrix); 330 418 } 331 419 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]); 334 422 mat4.multiply(rotationMatrix, elevationRotationMatrix, azimuthRotationMatrix); 335 423 } 336 424 337 //Apply rotation and scalingtransform425 //Apply rotation transform 338 426 mat4.multiply(vMatrix, rotationMatrix, vMatrix); 339 427 … … 345 433 //Calculate fields for lighting and raycasts 346 434 mat4.invert(canvas.vInverseMatrix, vMatrix); 347 vec3.transformMat4(canvas.cameraPosition, cameraPosition, canvas.vInverseMatrix); 348 435 349 436 //Apply projection matrix to get camera matrix 350 437 mat4.multiply(canvas.cameraMatrix, pMatrix, vMatrix); 438 mat4.invert(canvas.inverseCameraMatrix, canvas.cameraMatrix); 439 vec3.transformMat4(canvas.cameraPosition, cameraPosition, canvas.inverseCameraMatrix); 351 440 }//}}} 352 441 function drawSceneGraphNode(canvas,node) { //{{{ 353 if (!node ["enabled"]) return;442 if (!node.enabled) { return; } 354 443 355 444 var gl = canvas.gl; … … 357 446 358 447 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); 367 456 gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 368 457 … … 373 462 vec3.transformMat4(origin, origin, canvas.vInverseMatrix); 374 463 vec3.normalize(lightOrigin, lightOrigin); 375 vec3.sub(cameraPositionRelative, origin, node ["translation"]);464 vec3.sub(cameraPositionRelative, origin, node.translation); 376 465 cameraHeight = vec3.length(cameraPositionRelative); 377 466 … … 401 490 var scaleDepth = atm.scaleDepth; 402 491 403 node ["shader"].uniforms({492 node.shader.uniforms({ 404 493 m4MVP: mvpMatrix, 405 m4Model: node ["modelMatrix"],494 m4Model: node.modelMatrix, 406 495 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, 411 500 v3CameraPosition: origin, 412 v3Translate: node ["translation"],501 v3Translate: node.translation, 413 502 v3LightPos: lightOrigin, 414 503 v3InvWavelength: inv_wavelength4, … … 434 523 e: atm.e, 435 524 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 440 527 gl.enable(gl.DEPTH_TEST); 441 528 gl.disable(gl.CULL_FACE); 442 529 } //}}} 443 530 function 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); } 453 532 454 533 var nodes = canvas.nodes; 455 534 if (nodes.length < 1) { 456 canvas.drawHandler = window.requestAnimationFrame(function(time) { draw(canvas,options)});535 canvas.drawHandler = window.requestAnimationFrame(function(time) { draw(canvas,options); }); 457 536 return; 458 537 } 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); }); 462 541 return; 463 542 } 464 543 } 465 544 545 var rect = canvas.getBoundingClientRect(); 546 canvas.width = rect.width; 547 canvas.height = rect.height; 548 466 549 var gl = canvas.gl; 550 gl.makeCurrent(); //litegl function to handle switching between multiple canvases 551 gl.viewport(0, 0, rect.width, rect.height); 467 552 gl.clearColor(canvas.backgroundcolor[0], canvas.backgroundcolor[1], canvas.backgroundcolor[2], canvas.backgroundcolor[3]); 468 553 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 469 gl.makeCurrent();470 554 471 555 updateCameraMatrix(canvas); 556 557 if (canvas.marker) { canvas.marker.update(); } 472 558 473 559 var drawPassNumber = 3; 474 560 for (var i = drawPassNumber - 1; i >= 0; i--) { 475 561 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); }); 481 567 } //}}} 482 568 //}}}
Note:
See TracChangeset
for help on using the changeset viewer.