diff --git a/package.json b/package.json index c12f586d..97b7ffb5 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vts-browser-js", - "version": "2.15.8", + "version": "2.15.10", "description": "JavaScript WebGL 3D maps rendering engine", "main": "src/browser/index.js", "scripts": { diff --git a/src/browser/interface.js b/src/browser/interface.js index 516266fe..cc57a856 100755 --- a/src/browser/interface.js +++ b/src/browser/interface.js @@ -94,25 +94,29 @@ BrowserInterface.prototype.destroyMap = function() { BrowserInterface.prototype.on = function(eventName, call) { + if (this.killed) return; this.core.on(eventName, call); return this; }; BrowserInterface.prototype.setParams = function(params) { - this.setConfigParams(params); + if (this.killed) return; + this.setConfigParams(params,true); return this; }; BrowserInterface.prototype.setParam = function(key, value) { - this.setConfigParam(key, value); + if (this.killed) return; + this.browser.setConfigParam(key, value, true); return this; }; BrowserInterface.prototype.getParam = function(key) { - return this.getConfigParam(key); + if (this.killed) return; + return this.browser.getConfigParam(key); }; diff --git a/src/core/core.js b/src/core/core.js index 317cb0bf..b2d1b878 100755 --- a/src/core/core.js +++ b/src/core/core.js @@ -62,6 +62,9 @@ var Core = function(element, config, coreInterface) { mapXhrImageLoad : true, mapStoreLoadStats : false, mapRefreshCycles : 3, + mapFeatureGridCells : 31, + mapFeaturesPerSquareInch : 0.25, //0.6614, + mapFeaturesSortByTop : false, mapDegradeHorizon : false, mapDegradeHorizonParams : [1, 1500, 97500, 3500], //[1, 3000, 15000, 7000], mapDefaultFont : '//cdn.melown.com/libs/vtsjs/fonts/noto-basic/1.0.0/noto.fnt', @@ -69,6 +72,8 @@ var Core = function(element, config, coreInterface) { mapFog : true, mapNoTextures: false, mapMetricUnits : !(lang == 'en' || lang.indexOf('en-') == 0), + mapForceFrameTime: 0, + mapForcePipeline: 0, rendererAnisotropic : 0, rendererAntialiasing : true, rendererAllowScreenshots : false, @@ -188,6 +193,13 @@ Core.prototype.loadMap = function(path) { //this.tokenLoaded = true; var onAutorizationLoaded = (function(data) { + if (!data || (data && data['status'])) { + if (this.tokenCanBeSkiped) { + onLoadMapconfig(path); + } + return; + } + this.tokenLoaded = true; this.xhrParams['token'] = data['token']; this.xhrParams['tokenHeader'] = data['header']; @@ -427,6 +439,8 @@ Core.prototype.setConfigParam = function(key, value) { this.config.map = utils.validateString(value, null); } else if (key == 'mapVirtualSurfaces') { this.config.mapVirtualSurfaces = utils.validateBool(value, true); + } else if (key == 'mapForcePipeline') { + this.config.mapForcePipeline = utils.validateNumber(value, -1, Number.MAXINTEGER, 0); } else if (key == 'inspector') { this.config.inspector = utils.validateBool(value, true); } else if (key == 'authorization') { @@ -494,7 +508,7 @@ string getCoreVersion() */ function getCoreVersion(full) { - return (full ? 'Core: ' : '') + '2.15.8'; + return (full ? 'Core: ' : '') + '2.15.10'; } diff --git a/src/core/inspector/input.js b/src/core/inspector/input.js index e64359cd..a433fd57 100755 --- a/src/core/inspector/input.js +++ b/src/core/inspector/input.js @@ -253,6 +253,21 @@ InspectorInput.prototype.onKeyUp = function(event, press) { } } + if (this.diagnosticMode && debug.drawWireframe && !press) { + if (keyCode >= 96 && keyCode <= 105) { + if (this.altDown) { + debug.drawTestData = keyCode - 96; + if (this.ctrlDown) { + debug.drawTestData += 10; + } + } else { + debug.drawTestMode = keyCode - 96; + } + + hit = true; + } + } + if (this.diagnosticMode && inspector.drawRadar && !this.shiftDown && !press) { blockHit = true; diff --git a/src/core/map/body.js b/src/core/map/body.js new file mode 100644 index 00000000..64a7b7cb --- /dev/null +++ b/src/core/map/body.js @@ -0,0 +1,34 @@ + +var MapBody = function(map, json) { + //this.map = map; + //this.id = json["id"] || null; + this.parse(json); +}; + + +MapBody.prototype.parse = function(json) { + this.class = json['class'] || ''; + this.comment = json['comment'] || ''; + this.parent = json['parent'] || ''; + this.atmosphere = json['atmosphere'] || null; + + if (this.atmosphere) { + if (!this.atmosphere['colorHorizon']) this.atmosphere['colorHorizon'] = [0,0,0,0]; + if (!this.atmosphere['colorZenith']) this.atmosphere['colorZenith'] = [0,0,0,0]; + if (!this.atmosphere['thickness']) this.atmosphere['thickness'] = 100000; + if (!this.atmosphere['visibility']) this.atmosphere['visibility'] = 100000; + } +}; + + +MapBody.prototype.getInfo = function() { + return { + 'class' : this.class, + 'comment' : this.comment, + 'parent' : this.parent, + 'atmosphere' : JSON.parse(JSON.stringify(this.atmosphere)), + }; +}; + + +export default MapBody; \ No newline at end of file diff --git a/src/core/map/bound-layer.js b/src/core/map/bound-layer.js index 669a501d..64cb2e8a 100755 --- a/src/core/map/bound-layer.js +++ b/src/core/map/bound-layer.js @@ -23,6 +23,7 @@ var MapBoundLayer = function(map, json, id) { this.baseUrlSchema = this.map.url.baseUrlSchema; this.baseUrlOrigin = this.map.url.baseUrlOrigin; this.ready = false; + this.dataType = VTS_TEXTURETYPE_COLOR; //hack if (id == 'esri-world-imagery') { @@ -73,6 +74,13 @@ MapBoundLayer.prototype.parseJson = function(json) { this.credits = json['credits'] || []; this.creditsUrl = null; + switch(json['dataType']) { + default: + case 'color': this.dataType = VTS_TEXTURETYPE_COLOR; break; + case 'height': this.dataType = VTS_TEXTURETYPE_HEIGHT; break; + case 'classification': this.dataType = VTS_TEXTURETYPE_CLASS; break; + } + this.specificity = Math.pow(2,this.lodRange[0]) / ((this.tileRange[1][0] - this.tileRange[1][0]+1)*(this.tileRange[1][1] - this.tileRange[1][1]+1)); this.availability = json['availability'] ? {} : null; diff --git a/src/core/map/config.js b/src/core/map/config.js index 6831db6e..13877744 100755 --- a/src/core/map/config.js +++ b/src/core/map/config.js @@ -4,6 +4,7 @@ import MapCredit_ from './credit'; import MapRefFrame_ from './refframe'; import MapView_ from './view'; import MapSrs_ from './srs'; +import MapBody_ from './body'; import MapSurface_ from './surface'; import MapVirtualSurface_ from './virtual-surface'; import MapStylesheet_ from './stylesheet'; @@ -14,6 +15,7 @@ var MapBoundLayer = MapBoundLayer_; var MapRefFrame = MapRefFrame_; var MapView = MapView_; var MapSrs = MapSrs_; +var MapBody = MapBody_; var MapSurface = MapSurface_; var MapVirtualSurface = MapVirtualSurface_; var MapStylesheet = MapStylesheet_; @@ -27,7 +29,7 @@ var MapConfig = function(map, config) { MapConfig.prototype.parseConfig = function() { - if (!(this.parseSrses() && this.parseReferenceFrame() && + if (!(this.parseSrses() && this.parseBodies() && this.parseReferenceFrame() && this.parseCredits() && this.parseStylesheets() && this.parseSurfaces() && this.parseGlues() && this.parseVirtualSurfaces() && this.parseBoundLayers() && @@ -69,6 +71,22 @@ MapConfig.prototype.parseSrses = function() { }; +MapConfig.prototype.parseBodies = function() { + var bodies = this.mapConfig['bodies']; + this.map.bodies = {}; + + if (bodies == null) { + return true;//false; + } + + for (var key in bodies) { + this.map.addBody(key, new MapBody(this.map, bodies[key])); + } + + return true; +}; + + MapConfig.prototype.parseReferenceFrame = function() { var rf = this.mapConfig['referenceFrame']; diff --git a/src/core/map/draw-tiles.js b/src/core/map/draw-tiles.js index 7c5e156d..2b6b13e5 100755 --- a/src/core/map/draw-tiles.js +++ b/src/core/map/draw-tiles.js @@ -261,7 +261,7 @@ MapDrawTiles.prototype.drawMeshTile = function(tile, node, cameraPos, pixelSize, if (submesh.internalUVs) { //draw surface if (tile.surfaceTextures[i] == null) { path = tile.resourceSurface.getTextureUrl(tile.id, i); - tile.surfaceTextures[i] = tile.resources.getTexture(path, null, null, null, tile, true); + tile.surfaceTextures[i] = tile.resources.getTexture(path, VTS_TEXTURETYPE_COLOR, null, null, tile, true); } tile.drawCommands[0].push({ @@ -301,8 +301,8 @@ MapDrawTiles.prototype.drawMeshTile = function(tile, node, cameraPos, pixelSize, mesh : tile.surfaceMesh, submesh : i, texture : texture, - material : VTS_MATERIAL_EXTERNAL_NOFOG, - alpha : bounds.alpha[layers[j]][1] + alpha : bounds.alpha[layers[j]][1], + material : VTS_MATERIAL_EXTERNAL_NOFOG }); } } @@ -386,7 +386,7 @@ MapDrawTiles.prototype.drawMeshTile = function(tile, node, cameraPos, pixelSize, if (submesh.internalUVs) { //draw surface if (tile.surfaceTextures[i] == null) { path = tile.resourceSurface.getTextureUrl(tile.id, i); - tile.surfaceTextures[i] = tile.resources.getTexture(path, null, null, null, tile, true); + tile.surfaceTextures[i] = tile.resources.getTexture(path, VTS_TEXTURETYPE_COLOR, null, null, tile, true); } //draw mesh @@ -414,7 +414,7 @@ MapDrawTiles.prototype.drawMeshTile = function(tile, node, cameraPos, pixelSize, if (tile.surfaceTextures[i] == null) { path = tile.resourceSurface.getTextureUrl(tile.id, i); - tile.surfaceTextures[i] = tile.resources.getTexture(path, null, null, null, tile, true); + tile.surfaceTextures[i] = tile.resources.getTexture(path, VTS_TEXTURETYPE_COLOR, null, null, tile, true); } //else { tile.drawCommands[0].push({ type : VTS_DRAWCOMMAND_SUBMESH, @@ -431,7 +431,7 @@ MapDrawTiles.prototype.drawMeshTile = function(tile, node, cameraPos, pixelSize, if (tile.surfaceTextures[i] == null) { path = tile.resourceSurface.getTextureUrl(tile.id, i); - tile.surfaceTextures[i] = tile.resources.getTexture(path, null, null, null, tile, true); + tile.surfaceTextures[i] = tile.resources.getTexture(path, VTS_TEXTURETYPE_COLOR, null, null, tile, true); } //else { tile.drawCommands[0].push({ type : VTS_DRAWCOMMAND_SUBMESH, @@ -616,11 +616,53 @@ MapDrawTiles.prototype.drawGeodataTile = function(tile, node, cameraPos, pixelSi MapDrawTiles.prototype.updateTileHmap = function(tile, node) { - if (node && node.hasNavtile() && tile.surface) { - var path = tile.surface.getNavUrl(tile.id); - this.hmap = tile.resources.getTexture(path, null, null, null, tile, true); + if (node && node.hasNavtile() && tile.surface) { + + if (!tile.surface || !tile.resourceSurface) { //surface.virtual) { + return false; //is it best way how to do it? + } + + if (!tile.resourceSurface.getHMapUrl) { //virtual surface is as resource surface. Is it bug??!! + return false; //is it best way how to do it? + } + + var path = tile.resourceSurface.getHMapUrl(tile.id, true); + tile.hmap = tile.resources.getTexture(path); + + //var path = tile.surface.getNavUrl(tile.id); + //tile.hmap = tile.resources.getTexture(path, null, null, null, tile, true); } else { - this.hmap = this.renderer.blackTexture; + + //get parent with nav tile + var parent = tile.parent; + var extraBound = null; + + while(parent && parent.id[0] > 0) { + if (parent.metanode && parent.metanode.hasNavtile()) { + extraBound = { + sourceTile : parent, + sourceTexture : null, + hmap : true, + tile : tile + }; + + break; + } + + parent = parent.parent; + } + + //does parent with navtile exist + if (extraBound) { + var path = tile.resourceSurface.getHMapUrl(tile.id, true); + tile.hmap = tile.resources.getTexture(path, null, extraBound, {tile: tile, hmap: true}, tile, false); + + if (tile.hmap.neverReady) { + tile.hmap = null; + } + } else { + tile.hmap = null; + } } }; @@ -721,7 +763,7 @@ MapDrawTiles.prototype.updateTileSurfaceBounds = function(tile, submesh, surface if (!texture) { //TODO: make sure that we load only textures which we need path = layer.getUrl(tile.id); - texture = tile.resources.getTexture(path, null, extraBound, {tile: tile, layer: layer}, tile, false); + texture = tile.resources.getTexture(path, layer.dataType, extraBound, {tile: tile, layer: layer}, tile, false); if (texture.checkType == VTS_TEXTURECHECK_MEATATILE) { texture.checkMask = true; @@ -818,7 +860,7 @@ MapDrawTiles.prototype.updateTileSurfaceBounds = function(tile, submesh, surface tile.boundLayers[layer.id] = layer; if (!tile.boundTextures[layer.id]) { path = layer.getUrl(tile.id); - tile.boundTextures[layer.id] = tile.resources.getTexture(path, null, extraBound, {tile: tile, layer: layer}, tile, false); + tile.boundTextures[layer.id] = tile.resources.getTexture(path, layer.dataType, extraBound, {tile: tile, layer: layer}, tile, false); } } } @@ -842,7 +884,7 @@ MapDrawTiles.prototype.updateTileSurfaceBounds = function(tile, submesh, surface tile.boundLayers[layer.id] = layer; if (!tile.boundTextures[layer.id]) { path = layer.getUrl(tile.id); - tile.boundTextures[layer.id] = tile.resources.getTexture(path, null, extraBound, {tile: tile, layer: layer}, tile, false); + tile.boundTextures[layer.id] = tile.resources.getTexture(path, layer.dataType, extraBound, {tile: tile, layer: layer}, tile, false); } } } diff --git a/src/core/map/draw.js b/src/core/map/draw.js index ad1af338..67a8e1ef 100755 --- a/src/core/map/draw.js +++ b/src/core/map/draw.js @@ -34,6 +34,8 @@ var MapDraw = function(map) { drawPositions : false, drawTexelSize : false, drawWireframe : 0, + drawTestMode : 0, + drawTestData : 0, drawFaceCount : false, drawDistance : false, drawMaxLod : false, @@ -163,21 +165,32 @@ MapDraw.prototype.drawMap = function(skipFreeLayers) { var drawTiles = this.drawTiles; var camInfo = camera.update(); - this.renderer.dirty = true; - this.renderer.drawFog = this.debug.drawFog; - this.renderer.frameTime = this.stats.frameTime; - - this.renderer.hoverFeatureCounter = 0; - this.renderer.hoverFeatureList = map.hoverFeatureList; - this.renderer.hoverFeature = map.hoverFeature; - - this.renderer.cameraPosition = camera.position; - this.renderer.cameraOrientation = map.position.getOrientation(); - this.renderer.cameraTiltFator = Math.cos(math.radians(renderer.cameraOrientation[1])); - this.renderer.cameraVector = camera.vector; - this.renderer.cameraViewExtent = map.position.getViewExtent(); - this.renderer.cameraViewExtent2 = Math.pow(2.0, Math.max(1.0, Math.floor(Math.log(map.position.getViewExtent()) / Math.log(2)))); - this.renderer.drawLabelBoxes = this.debug.drawLabelBoxes; + var renderer = this.renderer; + + renderer.dirty = true; + renderer.drawFog = this.debug.drawFog; + + if (this.config.mapForceFrameTime) { + if (this.config.mapForceFrameTime != -1) { + renderer.frameTime = this.config.mapForceFrameTime; + } else { + renderer.frameTime = 0; + } + } else { + renderer.frameTime = this.stats.frameTime; + } + + renderer.hoverFeatureCounter = 0; + renderer.hoverFeatureList = map.hoverFeatureList; + renderer.hoverFeature = map.hoverFeature; + + renderer.cameraPosition = camera.position; + renderer.cameraOrientation = map.position.getOrientation(); + renderer.cameraTiltFator = Math.cos(math.radians(renderer.cameraOrientation[1])); + renderer.cameraVector = camera.vector; + renderer.cameraViewExtent = map.position.getViewExtent(); + renderer.cameraViewExtent2 = Math.pow(2.0, Math.max(1.0, Math.floor(Math.log(map.position.getViewExtent()) / Math.log(2)))); + renderer.drawLabelBoxes = this.debug.drawLabelBoxes; if (projected) { var yaw = math.radians(renderer.cameraOrientation[0]); @@ -219,7 +232,7 @@ MapDraw.prototype.drawMap = function(skipFreeLayers) { map.loader.setChannel(0); //0 = hires channel this.zFactor = 0; - this.ndcToScreenPixel = this.renderer.curSize[0] * 0.5; + this.ndcToScreenPixel = renderer.curSize[0] * 0.5; this.updateFogDensity(); this.updateGridFactors(); this.maxGpuUsed = Math.max(32*102*1204, map.gpuCache.getMaxCost() - 32*102*1204); @@ -330,9 +343,9 @@ MapDraw.prototype.drawMap = function(skipFreeLayers) { (replay.drawLoaded && replay.loaded)) { if (this.freeLayersHaveGeodata && this.drawChannel == 0) { - this.renderer.drawnGeodataTiles = this.stats.drawnGeodataTilesPerLayer; //drawnGeodataTiles; - this.renderer.drawnGeodataTilesFactor = this.stats.drawnGeodataTilesFactor; - this.renderer.draw.drawGpuJobs(); + renderer.drawnGeodataTiles = this.stats.drawnGeodataTilesPerLayer; //drawnGeodataTiles; + renderer.drawnGeodataTilesFactor = this.stats.drawnGeodataTilesFactor; + renderer.draw.drawGpuJobs(); } } @@ -494,12 +507,19 @@ MapDraw.prototype.drawMap = function(skipFreeLayers) { if (debug.drawEarth) { if (!skipFreeLayers) { if (map.freeLayersHaveGeodata && this.drawChannel == 0) { - this.renderer.drawnGeodataTiles = this.stats.drawnGeodataTilesPerLayer; //drawnGeodataTiles; - this.renderer.drawnGeodataTilesFactor = this.stats.drawnGeodataTilesFactor; + renderer.drawnGeodataTiles = this.stats.drawnGeodataTilesPerLayer; //drawnGeodataTiles; + renderer.drawnGeodataTilesFactor = this.stats.drawnGeodataTilesFactor; renderer.draw.drawGpuJobs(); } } } + + if (this.config.mapForceFrameTime) { + if (this.config.mapForceFrameTime != -1) { + renderer.frameTime = 0; + this.config.mapForceFrameTime = -1; + } + } }; MapDraw.prototype.drawToTexture = function(texture) { @@ -581,6 +601,26 @@ MapDraw.prototype.areDrawCommandsReady = function(commands, priority, doNotLoad, switch (command.type) { case VTS_DRAWCOMMAND_SUBMESH: + + var pipeline = command.pipeline; + if (pipeline) { + var hmap = command.hmap; + + if (!(hmap && hmap.isReady(doNotLoad, priority))) { + ready = false; + } + + if (this.debug.drawTestMode == 9) { + var texture = command.texture; + var textureReady = this.config.mapNoTextures ? true : (!texture || (texture && texture.isReady(doNotLoad, priority, checkGpu))); + + if (!textureReady) { + ready = false; + } + } + + break; + } var mesh = command.mesh; var texture = command.texture; @@ -591,7 +631,8 @@ MapDraw.prototype.areDrawCommandsReady = function(commands, priority, doNotLoad, if (!(meshReady && textureReady) ) { ready = false; } - + + break; case VTS_DRAWCOMMAND_GEODATA: @@ -624,8 +665,31 @@ MapDraw.prototype.processDrawCommands = function(cameraPos, commands, priority, break; case VTS_DRAWCOMMAND_SUBMESH: + + var pipeline = command.pipeline; + if (pipeline) { + var hmap = command.hmap; + + if (this.debug.drawTestMode == 9) { + var texture = command.texture; + var textureReady = this.config.mapNoTextures ? true : (!texture || (texture && texture.isReady(doNotLoad, priority))); + + if (textureReady) { + if (hmap && hmap.isReady(doNotLoad, priority)) { + tile.drawHmapTile(cameraPos, null, null, pipeline, texture); + } + } + } else { + if (hmap && hmap.isReady(doNotLoad, priority)) { + tile.drawHmapTile(cameraPos, null, null, pipeline); + } + } + + return; + } + var mesh = command.mesh; - var texture = command.texture, hmap; + var texture = command.texture; var meshReady = (mesh && mesh.isReady(doNotLoad, priority)), textureReady; @@ -635,16 +699,6 @@ MapDraw.prototype.processDrawCommands = function(cameraPos, commands, priority, } else { textureReady = (!texture || (texture && texture.isReady(doNotLoad, priority))); } - - var pipeline = command.pipeline; - - if (pipeline) { - //hmap = command.hmap; - //textureReady = (textureReady && (hmap && hmap.isReady(doNotLoad, priority))); - - tile.drawHmapTile(cameraPos, null, null, pipeline); - return; - } if (meshReady && textureReady) { //debug bbox diff --git a/src/core/map/geodata-processor/processor.js b/src/core/map/geodata-processor/processor.js index aee6ef6c..acbf2bd1 100755 --- a/src/core/map/geodata-processor/processor.js +++ b/src/core/map/geodata-processor/processor.js @@ -78,7 +78,7 @@ MapGeodataProcessor.prototype.setListener = function(listener) { }; -MapGeodataProcessor.prototype.sendCommand = function(command, data, tile) { +MapGeodataProcessor.prototype.sendCommand = function(command, data, tile, dpr) { if (this.killed) { return; } @@ -95,6 +95,10 @@ MapGeodataProcessor.prototype.sendCommand = function(command, data, tile) { } } + if (dpr) { + message['dpr'] = dpr; + } + this.processWorker.postMessage(message); }; diff --git a/src/core/map/geodata-processor/worker-globals.js b/src/core/map/geodata-processor/worker-globals.js index 946776f7..f6d3302b 100755 --- a/src/core/map/geodata-processor/worker-globals.js +++ b/src/core/map/geodata-processor/worker-globals.js @@ -19,6 +19,7 @@ var globals = { tileLod : 0, tileSize : 1, hitState : 0, + pixelFactor : 1, metricUnits : true, groupOptimize : true, groupOrigin : [0,0,0], diff --git a/src/core/map/geodata-processor/worker-linestring.js b/src/core/map/geodata-processor/worker-linestring.js index 56be51f5..63157afd 100755 --- a/src/core/map/geodata-processor/worker-linestring.js +++ b/src/core/map/geodata-processor/worker-linestring.js @@ -56,23 +56,21 @@ var processLineStringPass = function(lineString, lod, style, featureIndex, zInde var texturedLine = (lineStyle != 'solid'); var widthByRatio = (lineWidthUnits == 'ratio'); - //console.log("lineflat: "+lineFlat); - //var lineWidth = Math.pow(2, 23 - lod) / 32; + if (lineWidthUnits == 'points') { + lineWidth *= globals.pixelFactor / ((1 / 72) * (96)); + } var index = 0, index2 = 0, index3 = 0; var skipJoins = false; if (widthByRatio) { - skipJoins = (!lineFlat && (lineWidth*1080) < 2.1); + skipJoins = (!lineFlat && ((lineWidth/* *globals.invPixelFactor*/)*1080) < 2.1); } else { - skipJoins = (!lineFlat && lineWidth < 2.1); + skipJoins = (!lineFlat && (lineWidth/* *globals.invPixelFactor*/) < 2.1); } var ii, i, li, p2, v, vv, l, n, nn, p1, p, elementIndex, elemetBase = 1; - //console.log("lod: " + lod + " width: " + lineWidth); - //skipJoins = true; - if (!skipJoins) { var circleBuffer = []; var circleBuffer2 = []; diff --git a/src/core/map/geodata-processor/worker-main.js b/src/core/map/geodata-processor/worker-main.js index a2814443..27710b53 100755 --- a/src/core/map/geodata-processor/worker-main.js +++ b/src/core/map/geodata-processor/worker-main.js @@ -415,6 +415,8 @@ self.onmessage = function (e) { case 'processGeodata': globals.tileLod = message['lod'] || 0; globals.tileSize = message['tileSize'] || 1; + globals.pixelFactor = message['dpr'] || 1; + globals.invPixelFactor = 1.0 / globals.pixelFactor; data = JSON.parse(data); exportedGeometries = []; processGeodata(data, globals.tileLod); diff --git a/src/core/map/geodata-processor/worker-pointarray.js b/src/core/map/geodata-processor/worker-pointarray.js index b48ccacb..f1cfa7c1 100755 --- a/src/core/map/geodata-processor/worker-pointarray.js +++ b/src/core/map/geodata-processor/worker-pointarray.js @@ -115,12 +115,17 @@ var processPointArrayPass = function(pointArray, lod, style, featureIndex, zInde bufferSize = getCharVerticesCount() * text.length * totalPoints; bufferSize2 = getCharVerticesCount(true) * text.length * totalPoints; + var factor = 1; + if (getLayerPropertyValue(style, 'label-size-units', pointArray, lod) == 'points') { + factor = globals.pixelFactor / ((1 / 72) * (96)); + } + var labelData = { color : getLayerPropertyValue(style, 'label-color', pointArray, lod), color2 : getLayerPropertyValue(style, 'label-color2', pointArray, lod), outline : getLayerPropertyValue(style, 'label-outline', pointArray, lod), reduce : getLayerPropertyValue(style, 'dynamic-reduce', pointArray, lod), - size : size, + size : size * factor, offset : getLayerPropertyValue(style, 'label-offset', pointArray, lod), stick : getLayerPropertyValue(style, 'label-stick', pointArray, lod), origin : getLayerPropertyValue(style, 'label-origin', pointArray, lod), @@ -129,7 +134,7 @@ var processPointArrayPass = function(pointArray, lod, style, featureIndex, zInde fontsStorage : getFontsStorage(fontNames), text : text, hysteresis : getLayerPropertyValue(style, 'hysteresis', pointArray, lod), - width : getLayerPropertyValue(style, 'label-width', pointArray, lod), + width : factor * getLayerPropertyValue(style, 'label-width', pointArray, lod), noOverlap : getLayerPropertyValue(style, 'label-no-overlap', pointArray, lod), noOverlapMargin : getLayerPropertyValue(style, 'label-no-overlap-margin', pointArray, lod), noOverlapFactor : getLayerPropertyValue(style, 'label-no-overlap-factor', pointArray, lod), @@ -140,6 +145,11 @@ var processPointArrayPass = function(pointArray, lod, style, featureIndex, zInde index2 : 0, glyphsRes : glyphsRes }; + + if (labelData.stick) { + labelData.stick = labelData.stick.slice(); + labelData.stick[2] *= factor; + } } else { label = false; } diff --git a/src/core/map/geodata-processor/worker-style.js b/src/core/map/geodata-processor/worker-style.js index 87d8e8fb..147c9c41 100755 --- a/src/core/map/geodata-processor/worker-style.js +++ b/src/core/map/geodata-processor/worker-style.js @@ -38,6 +38,7 @@ var getLayerExpresionValue = function(layer, value, feature, lod, key) { case '#lod': return globals.tileLod; case '#tileSize': return globals.tileSize; case '#metric': return globals.metricUnits; + case '#dpr': return globals.pixelFactor; } return finalValue; @@ -72,6 +73,7 @@ var getLayerExpresionValue = function(layer, value, feature, lod, key) { case '#lod': return globals.tileLod; case '#tileSize': return globals.tileSize; case '#metric': return globals.metricUnits; + case '#dpr': return globals.pixelFactor; } case '$': @@ -173,6 +175,7 @@ var getLayerPropertyValueInner = function(layer, key, feature, lod, value, depth case '#lod': return globals.tileLod; case '#tileSize': return globals.tileSize; case '#metric': return globals.metricUnits; + case '#dpr': return globals.pixelFactor; } break; } @@ -653,8 +656,9 @@ var validateValue = function(layerId, key, value, type, arrayLength, min, max) { if (Array.isArray(value) && value.length > 0 && (typeof value[0] === 'string')) { if (key == 'dynamic-reduce') { - if (!((value[0] == 'tilt' || value[0] == 'tilt-cos' || value[0] == 'tilt-cos2' || value[0] == 'scr-count' || value[0] == 'scr-count2' || value[0] == 'scr-count3') && - (typeof value[1] === 'number') && (typeof value[2] === 'number'))) { + if (!((value[0] == 'tilt' || value[0] == 'tilt-cos' || value[0] == 'tilt-cos2' || value[0] == 'scr-count' || value[0] == 'scr-count2' || + value[0] == 'scr-count3' || value[0] == 'scr-count4') && + (typeof value[1] === 'number') && ((typeof value[2] === 'number') || value[0] == 'scr-count4'))) { logError('wrong-property-value', layerId, key, value); return getDefaultLayerPropertyValue(key); } @@ -769,9 +773,20 @@ var validateValue = function(layerId, key, value, type, arrayLength, min, max) { } } + if (key == 'label-size-units') { + switch(value) { + case 'pixels': + case 'points': return value; + default: + logError('wrong-property-value', layerId, key, value); + return getDefaultLayerPropertyValue(key); + } + } + if (key == 'line-width-units') { switch(value) { case 'pixels': + case 'points': case 'meters': case 'ratio': return value; default: @@ -871,6 +886,7 @@ var validateLayerPropertyValue = function(layerId, key, value) { case 'label-color2': return validateValue(layerId, key, value, 'object', 4, 0, 255); case 'label-source': return validateValue(layerId, key, value, 'string'); case 'label-size': return validateValue(layerId, key, value, 'number', null, 0.0001, Number.MAX_VALUE); + case 'label-size-units': return validateValue(layerId, key, value, 'string'); case 'label-offset': return validateValue(layerId, key, value, 'object', 2, -Number.MAX_VALUE, Number.MAX_VALUE); case 'label-origin': return validateValue(layerId, key, value, 'string'); case 'label-align': return validateValue(layerId, key, value, 'string'); @@ -958,6 +974,7 @@ var getDefaultLayerPropertyValue = function(key) { case 'label-outline': return [0.27,0.75,2.2,2.2]; case 'label-source': return '$name'; case 'label-size': return 10; + case 'label-size-units': return 'pixels'; case 'label-offset': return [0,0]; case 'label-origin': return 'bottom-center'; case 'label-align': return 'center'; diff --git a/src/core/map/geodata-view.js b/src/core/map/geodata-view.js index ccc7239d..b612fa45 100755 --- a/src/core/map/geodata-view.js +++ b/src/core/map/geodata-view.js @@ -167,7 +167,7 @@ MapGeodataView.prototype.isReady = function(doNotLoad, priority, doNotCheckGpu) if (this.geodata.isReady(doNotLoad, priority, doNotCheckGpu) && this.geodataProcessor.isReady()) { this.killedByCache = false; this.geodataProcessor.setListener(this.onGeodataProcessorMessage.bind(this)); - this.geodataProcessor.sendCommand('processGeodata', this.geodata.geodata, this.tile); + this.geodataProcessor.sendCommand('processGeodata', this.geodata.geodata, this.tile, (window.devicePixelRatio || 1)); this.geodataProcessor.busy = true; } } diff --git a/src/core/map/map.js b/src/core/map/map.js index d024e8b5..5ca1615c 100755 --- a/src/core/map/map.js +++ b/src/core/map/map.js @@ -59,6 +59,7 @@ var Map = function(core, mapConfig, path, config) { this.lastPosition = this.position.clone(); this.srses = {}; + this.bodies = {}; this.referenceFrame = {}; this.credits = {}; this.creditsByNumber = {}; @@ -137,30 +138,34 @@ var Map = function(core, mapConfig, path, config) { this.draw = new MapDraw(this); this.draw.setupDetailDegradation(); - switch(this.referenceFrame.id) { - case 'melown2015': - case 'earth-qsc': - this.draw.atmoColor = [216.0/255.0, 232.0/255.0, 243.0/255.0, 1.0]; - this.draw.atmoColor2 = [72.0/255.0, 154.0/255.0, 255.0/255.0, 1.0]; - this.draw.atmoColor3 = [216.0/255.0, 232.0/255.0, 243.0/255.0, 1.0]; - this.draw.atmoHeight = 50000; - break; - - case 'mars-qsc': - this.draw.atmoColor = [255.0/255.0, 187.0/255.0, 157.0/255.0, 1.0]; - this.draw.atmoColor2 = [255.0/255.0, 155.0/255.0, 113.0/255.0, 1.0]; - this.draw.atmoColor3 = [255.0/255.0, 187.0/255.0, 157.0/255.0, 0.5]; - this.draw.atmoHeight = 25000; - this.draw.atmoDensity = 1.0 / 0.25; - - // this.draw.atmoColor = [223.0/255.0, 200.0/255.0, 190.0/255.0, 1.0]; - // this.draw.atmoColor2 = [255.0/255.0, 155.0/255.0, 113.0/255.0, 1.0]; - - // this.draw.atmoColor = [201.0/255.0, 149.0/255.0, 65.0/255.0, 1.0]; - // this.draw.atmoColor2 = [201.0/255.0, 149.0/255.0, 65.0/255.0, 0.1]; - break; - } + var body = this.referenceFrame.body, c; + if (body && body.atmosphere) { + c = body.atmosphere.colorHorizon; + this.draw.atmoColor = [c[0]/255.0, c[1]/255.0, c[2]/255.0, c[3]/255.0]; + c = body.atmosphere.colorZenith; + this.draw.atmoColor2 = [c[0]/255.0, c[1]/255.0, c[2]/255.0, c[3]/255.0]; + this.draw.atmoHeight = 50000 * (body.atmosphere.thickness / 100000); + this.draw.atmoDensity = (body.atmosphere.visibility / 100000) * (100000 / body.atmosphere.thickness); + } else { + switch(this.referenceFrame.id) { + case 'melown2015': + case 'earth-qsc': + this.draw.atmoColor = [216.0/255.0, 232.0/255.0, 243.0/255.0, 1.0]; + this.draw.atmoColor2 = [72.0/255.0, 154.0/255.0, 255.0/255.0, 1.0]; + //this.draw.atmoColor3 = [216.0/255.0, 232.0/255.0, 243.0/255.0, 1.0]; + this.draw.atmoHeight = 50000; + break; + + case 'mars-qsc': + this.draw.atmoColor = [255.0/255.0, 187.0/255.0, 157.0/255.0, 1.0]; + this.draw.atmoColor2 = [255.0/255.0, 155.0/255.0, 113.0/255.0, 1.0]; + //this.draw.atmoColor3 = [255.0/255.0, 187.0/255.0, 157.0/255.0, 0.5]; + this.draw.atmoHeight = 25000; + this.draw.atmoDensity = 1.0 / 0.25; + break; + } + } this.draw.atmoHeightFactor = this.draw.atmoHeight / 50000; @@ -252,6 +257,21 @@ Map.prototype.getSrses = function() { }; +Map.prototype.addBody = function(id, body) { + this.bodies[id] = body; +}; + + +Map.prototype.getBody = function(id) { + return this.bodies[id]; +}; + + +Map.prototype.getBodies = function() { + return this.getMapKeys(this.bodies); +}; + + Map.prototype.setReferenceFrame = function(referenceFrame) { this.referenceFrame = referenceFrame; }; @@ -794,6 +814,11 @@ Map.prototype.setConfigParam = function(key, value) { case 'mapDefaultFont': this.config.mapDefaultFont = utils.validateString(value, ''); break; case 'mapMetricUnits': this.config.mapMetricUnits = utils.validateBool(value, true); break; case 'mapNoTextures': this.config.mapNoTextures = this.config.mapDisableCulling = utils.validateBool(value, false); break; + case 'mapForceFrameTime': this.config.mapForceFrameTime = utils.validateNumber(value, -1, Number.MAXINTEGER, 0); break; + case 'mapForcePipeline': this.config.mapForcePipeline = utils.validateNumber(value, 0, Number.MAXINTEGER, 0); break; + case 'mapFeatureGridCells': this.config.mapFeatureGridCells = utils.validateNumber(value, 1, Number.MAXINTEGER, 0); break; + case 'mapFeaturesPerSquareInch': this.config.mapFeaturesPerSquareInch = utils.validateNumber(value, 0.000001, Number.MAXINTEGER, 0); break; + case 'mapFeaturesSortByTop': this.config.mapFeaturesSortByTop = utils.validateBool(value, false); break; case 'mario': this.config.mario = utils.validateBool(value, true); break; } }; @@ -842,6 +867,11 @@ Map.prototype.getConfigParam = function(key) { case 'mapDefaultFont': return this.config.mapDefaultFont; case 'mapMetricUnits': return this.config.mapMetricUnits; case 'mapNoTextures': return this.config.mapNoTextures; + case 'mapForceFrameTime': return this.config.mapForceFrameTime; + case 'mapForcePipeline': return this.config.mapForcePipeline; + case 'mapFeatureGridCells': return this.config.mapFeatureGridCells; + case 'mapFeaturesPerSquareInch': return this.config.mapFeaturesPerSquareInch; + case 'mapFeaturesSortByTop': return this.config.mapFeaturesSortByTop; case 'mario': return this.config.mario; } }; diff --git a/src/core/map/refframe.js b/src/core/map/refframe.js index 2aa59db9..6ddc3e1f 100755 --- a/src/core/map/refframe.js +++ b/src/core/map/refframe.js @@ -25,6 +25,8 @@ var MapRefFrame = function(map, json) { publicSrs : map.getMapsSrs(model['publicSrs']) }; + this.body = json['body'] ? map.getBody(json['body']) : null; + this.params = {}; if (json['parameters'] != null) { diff --git a/src/core/map/resource-node.js b/src/core/map/resource-node.js index 7a0ae0e3..523e8b41 100755 --- a/src/core/map/resource-node.js +++ b/src/core/map/resource-node.js @@ -116,21 +116,21 @@ MapResourceNode.prototype.getGeodata = function(path, extraInfo) { // Textures --------------------------------- -MapResourceNode.prototype.getTexture = function(path, heightMap, extraBound, extraInfo, tile, internal) { +MapResourceNode.prototype.getTexture = function(path, type, extraBound, extraInfo, tile, internal) { var texture; - if (extraInfo && extraInfo.layer) { - var id = path + extraInfo.layer.id; + if (extraInfo && (extraInfo.layer || extraInfo.hmap)) { + var id = path + (extraInfo.hmap ? '' : extraInfo.layer.id); texture = this.textures[id]; if (!texture) { - texture = new MapTexture(this.map, path, heightMap, extraBound, extraInfo, tile, internal); + texture = new MapTexture(this.map, path, type, extraBound, extraInfo, tile, internal); this.textures[id] = texture; } } else { texture = this.textures[path]; if (!texture) { - texture = new MapTexture(this.map, path, heightMap, extraBound, extraInfo, tile, internal); + texture = new MapTexture(this.map, path, type, extraBound, extraInfo, tile, internal); this.textures[path] = texture; } } @@ -141,11 +141,11 @@ MapResourceNode.prototype.getTexture = function(path, heightMap, extraBound, ext // SubTextures --------------------------------- -MapResourceNode.prototype.getSubtexture = function(texture, path, heightMap, extraBound, extraInfo, tile, internal) { +MapResourceNode.prototype.getSubtexture = function(texture, path, type, extraBound, extraInfo, tile, internal) { texture = this.subtextures[path]; if (!texture) { - texture = new MapSubtexture(this.map, path, heightMap, extraBound, extraInfo, tile, internal); + texture = new MapSubtexture(this.map, path, type, extraBound, extraInfo, tile, internal); this.subtextures[path] = texture; } diff --git a/src/core/map/subtexture.js b/src/core/map/subtexture.js index 9a67c6dd..33b3acd9 100755 --- a/src/core/map/subtexture.js +++ b/src/core/map/subtexture.js @@ -7,7 +7,7 @@ var utils = utils_; var GpuTexture = GpuTexture_; -var MapSubtexture = function(map, path, heightMap, tile, internal) { +var MapSubtexture = function(map, path, type, tile, internal) { this.map = map; this.stats = map.stats; this.tile = tile; // used only for stats @@ -21,7 +21,7 @@ var MapSubtexture = function(map, path, heightMap, tile, internal) { this.loadErrorCounter = 0; this.neverReady = false; this.mapLoaderUrl = path; - this.heightMap = heightMap || false; + this.type = type || false; this.statsCounter = 0; this.checkStatus = 0; this.checkType = null; @@ -166,7 +166,7 @@ MapSubtexture.prototype.isReady = function(doNotLoad, priority, doNotCheckGpu, t this.map.resourcesCache.updateItem(this.cacheItem); } - if (((this.heightMap && !this.imageData) || (!this.heightMap && !this.gpuTexture)) && + if (((this.type == VTS_TEXTURETYPE_HEIGHT && !this.imageData) || (this.type != VTS_TEXTURETYPE_HEIGHT && !this.gpuTexture)) && this.stats.renderBuild > this.map.config.mapMaxProcessingTime) { //console.log("testure resource build overflow"); this.map.markDirty(); @@ -174,7 +174,7 @@ MapSubtexture.prototype.isReady = function(doNotLoad, priority, doNotCheckGpu, t } if (doNotCheckGpu) { - if (this.heightMap) { + if (this.type == VTS_TEXTURETYPE_HEIGHT) { if (!this.imageData) { t = performance.now(); this.buildHeightMap(); @@ -185,7 +185,7 @@ MapSubtexture.prototype.isReady = function(doNotLoad, priority, doNotCheckGpu, t return true; } - if (this.heightMap) { + if (this.type == VTS_TEXTURETYPE_HEIGHT) { if (!this.imageData) { t = performance.now(); this.buildHeightMap(); @@ -458,7 +458,7 @@ MapSubtexture.prototype.onHeadLoaded = function(downloadAll, data, status) { MapSubtexture.prototype.buildGpuTexture = function () { this.gpuTexture = new GpuTexture(this.map.renderer.gpu, null, this.map.core); - this.gpuTexture.createFromImage(this.image, 'linear', false); + this.gpuTexture.createFromImage(this.image, (this.type == VTS_TEXTURETYPE_CLASS) ? 'nearest' : 'linear', false); this.stats.gpuTextures += this.gpuTexture.size; this.stats.graphsFluxTexture[0][0]++; diff --git a/src/core/map/surface-tile.js b/src/core/map/surface-tile.js index 29dd8fa2..089501af 100755 --- a/src/core/map/surface-tile.js +++ b/src/core/map/surface-tile.js @@ -1,8 +1,10 @@ import {vec3 as vec3_} from '../utils/matrix'; +import GpuTexture_ from '../renderer/gpu/texture'; //get rid of compiler mess var vec3 = vec3_; +var GpuTexture = GpuTexture_; var tileBorderTable = [ [-1, -1, 0, 0], @@ -1352,16 +1354,21 @@ MapSurfaceTile.prototype.drawGrid = function(cameraPos, divNode, angle) { }; -MapSurfaceTile.prototype.drawHmapTile = function(cameraPos, divNode, angle, pipeline) { - if ((this.texelSize == Number.POSITIVE_INFINITY || this.texelSize > 4.4) && this.metanode && this.metanode.hasChildren()) { - return; - } +MapSurfaceTile.prototype.drawHmapTile = function(cameraPos, divNode, angle, pipeline, texture) { + //if ((this.texelSize == Number.POSITIVE_INFINITY || this.texelSize > 4.4) && this.metanode && this.metanode.hasChildren()) { + // return; + //} if (!this.metanode) { return; } var map = this.map, node, ll, ur, res; + var renderer = map.renderer; + + if (!renderer.progHmapPlane) { + renderer.initProceduralShaders(); + } if (divNode) { node = divNode[0]; @@ -1408,7 +1415,8 @@ MapSurfaceTile.prototype.drawHmapTile = function(cameraPos, divNode, angle, pipe if (!gridPoints) { - h = this.metanode.minZ; +// h = this.metanode.minZ; + h = 0;//this.metanode.minHeight; var n1 = node.getPhysicalCoords([ur[0], ur[1], h], true); var n2 = node.getPhysicalCoords([ur[0], ll[1], h], true); var n3 = node.getPhysicalCoords([ll[0], ll[1], h], true); @@ -1478,7 +1486,6 @@ MapSurfaceTile.prototype.drawHmapTile = function(cameraPos, divNode, angle, pipe } } - var renderer = map.renderer; var mv = renderer.camera.getModelviewMatrix(); var proj = renderer.camera.getProjectionMatrix(); @@ -1526,6 +1533,9 @@ MapSurfaceTile.prototype.drawHmapTile = function(cameraPos, divNode, angle, pipe map.poleRadiusFactor = 8 * Math.pow(2.0, 552058 / map.poleRadius); } + var mnode = this.metanode; + var testMode = draw.debug.drawTestMode; + factor = 1; if (hasPoles && node.isPole) { @@ -1534,54 +1544,178 @@ MapSurfaceTile.prototype.drawHmapTile = function(cameraPos, divNode, angle, pipe renderer.gpu.useProgram(prog, ['aPosition', 'aTexCoord']); prog.setVec4('uParams4', [-sx, -sy, map.poleRadius, 0]); } else { - prog = renderer.progHmapPlane; - renderer.gpu.useProgram(prog, ['aPosition', 'aTexCoord']); + + switch(testMode) { + default: + case 0: prog = renderer.progHmapPlane; break; + case 1: prog = renderer.progHmapPlane2; break; + case 2: prog = renderer.progHmapPlane5; break; + case 3: prog = renderer.progHmapPlane6; break; + case 4: prog = renderer.progHmapPlane7; break; + + case 8: prog = renderer.progHmapPlane4; break; + case 9: prog = pipeline == 1 ? renderer.progHmapPlane3 : renderer.progHmapPlane8; break; + } + + + if (testMode == 3 || testMode == 4) { + if (!renderer.ntextures) { + renderer.ntextures = [ + new GpuTexture(renderer.gpu, './textures/test/test001.png', renderer.core, null), //0 + new GpuTexture(renderer.gpu, './textures/test/test002.png', renderer.core, null), //1 + new GpuTexture(renderer.gpu, './textures/test003.jpg', renderer.core, null), //2 + new GpuTexture(renderer.gpu, './textures/download.png', renderer.core, null), //3 + new GpuTexture(renderer.gpu, './textures/test009.jpg', renderer.core, null), //4 + new GpuTexture(renderer.gpu, './textures/test004.jpg', renderer.core, null), //5 + new GpuTexture(renderer.gpu, './textures/test005.jpg', renderer.core, null), //6 + new GpuTexture(renderer.gpu, './textures/nor_sand.jpg', renderer.core, null), //7 + new GpuTexture(renderer.gpu, './textures/test007.jpg', renderer.core, null), //8 + new GpuTexture(renderer.gpu, './textures/test008.jpg', renderer.core, null), //9 + + new GpuTexture(renderer.gpu, './textures/download (1).png', renderer.core, null), //10 + new GpuTexture(renderer.gpu, './textures/test010.jpg', renderer.core, null), //11 + new GpuTexture(renderer.gpu, './textures/test011.jpg', renderer.core, null), //12 + new GpuTexture(renderer.gpu, './textures/test012.jpg', renderer.core, null), //13 + new GpuTexture(renderer.gpu, './textures/test013.jpg', renderer.core, null), //14 + new GpuTexture(renderer.gpu, './textures/test014.jpg', renderer.core, null), //15 + new GpuTexture(renderer.gpu, './textures/test015.jpg', renderer.core, null), //16 + new GpuTexture(renderer.gpu, './textures/test016.jpg', renderer.core, null), //17 + new GpuTexture(renderer.gpu, './textures/test017.jpg', renderer.core, null), //18 + new GpuTexture(renderer.gpu, './textures/test018.jpg', renderer.core, null) //18 + + ]; + } + } + +// renderer.gpu.useProgram(prog, ['aPosition', 'aTexCoord', 'aBarycentric']); + //renderer.gpu.useProgram(prog, ['aPosition', 'aTexCoord']); + renderer.gpu.useProgram(prog, ['aPosition']); + prog.setVec3('uVector', mnode.diskNormal); + + //prog.setVec3('uRight', mnode.diskNormal); + + if (gridPoints) { + var vecRight = [gridPoints[15] - gridPoints[12], gridPoints[16] - gridPoints[13], gridPoints[17] - gridPoints[14]]; + var vecTop = [gridPoints[21] - gridPoints[12], gridPoints[22] - gridPoints[13], gridPoints[23] - gridPoints[14]]; + + vec3.normalize(vecRight); + vec3.normalize(vecTop); + + var vecDir = mnode.diskNormal.slice(); + //vecDir = [-vecDir[0], -vecDir[1], -vecDir[2]]; + + //prog.setVec3('uRight', vecRight); + //prog.setVec3('uTop', vecTop); + + + var mv = map.camera.camera.modelview; + var mv2 = vts.mat3.create(); + + vts.mat4.toInverseMat3(mv, mv2); + + //vts.mat4.toMat3(mv, mv2); + vts.mat3.transpose(mv2); + + vts.mat3.multiplyVec3(mv2, vecTop); + vts.mat3.multiplyVec3(mv2, vecDir); + vts.mat3.multiplyVec3(mv2, vecRight); + + var space = [ + vecRight[0], vecRight[1], vecRight[2], + vecTop[0], vecTop[1], vecTop[2], + vecDir[0], vecDir[1], vecDir[2], + ]; + + /* + var mv3 = vts.mat3.toMat4(mv2); + vts.mat4.multiply(mv3, vts.mat3.toMat4(space), mv3); + prog.setMat3('uSpace', vts.mat4.toMat3(mv3)); + */ + + prog.setMat3('uSpace', space); + } } prog.setMat4('uMV', mv); prog.setMat4('uProj', proj); prog.setFloatArray('uPoints', buffer); - /* - var lx = (ur[0] - ll[0]); - var ly = (ll[1] - ur[1]); - var px = (ll[0] - node.extents.ll[0]) / lx; - var py = (ur[1] - node.extents.ll[1]) / ly; - - var llx = (node.extents.ur[0] - node.extents.ll[0]) / lx; - var lly = (node.extents.ur[1] - node.extents.ll[1]) / ly; - - px = px / llx; - py = py / lly; - llx = 1.0/llx; - lly = 1.0/lly; - - llx *= step1; - lly *= step1; - px *= step1; - py *= step1; - */ var step1 = node.gridStep1 * factor; + prog.setVec4('uParams', [step1 * factor, draw.fogDensity, 1/127, node.gridStep2 * factor]); - var lx = 1.0 / (ur[0] - ll[0]); - var ly = 1.0 / (ll[1] - ur[1]); - var llx = step1 / ((node.extents.ur[0] - node.extents.ll[0]) * lx); - var lly = step1 / ((node.extents.ur[1] - node.extents.ll[1]) * ly); - var px = (ll[0] - node.extents.ll[0]) * lx * llx; - var py = (ur[1] - node.extents.ll[1]) * ly * lly; + if (testMode >= 3 && testMode <= 4) { + prog.setVec4('uParams3', [1,1,0,0]); + } else { + if (texture) { + prog.setVec4('uParams3', texture.getTransform()); + } else { + var lx = 1.0 / (ur[0] - ll[0]); + var ly = 1.0 / (ll[1] - ur[1]); + var llx = step1 / ((node.extents.ur[0] - node.extents.ll[0]) * lx); + var lly = step1 / ((node.extents.ur[1] - node.extents.ll[1]) * ly); + var px = (ll[0] - node.extents.ll[0]) * lx * llx; + var py = (ur[1] - node.extents.ll[1]) * ly * lly; + + prog.setVec4('uParams3', [lly, llx, (py - Math.floor(py)), (px - Math.floor(px))]); + } + } - prog.setVec4('uParams', [step1 * factor, draw.fogDensity, 1/15, node.gridStep2 * factor]); - prog.setVec4('uParams3', [(py - Math.floor(py)), (px - Math.floor(px)), lly, llx]); prog.setVec4('uParams2', [0, 0, node.gridBlend, 0]); prog.setVec4('uFogColor', draw.atmoColor); - renderer.gpu.bindTexture(renderer.heightmapTexture); - + + if (this.hmap.extraBound) { + //get height form parent + mnode = this.hmap.extraBound.sourceTile.metanode; + prog.setVec3('uHeights', [mnode.minHeight, mnode.maxHeight, (1.0/mnode.pixelSize)]); + prog.setVec4('uTransform', this.hmap.getTransform()); + } else { + prog.setVec3('uHeights', [mnode.minHeight, mnode.maxHeight, (1.0/mnode.pixelSize)]); + prog.setVec4('uTransform', [1,1,0,0]); + } + + if (testMode >= 3 && testMode <= 4) { + if (!renderer.ntextures[draw.debug.drawTestData].loaded) { + return; + } + renderer.gpu.bindTexture(renderer.ntextures[draw.debug.drawTestData]); + } else { + if (texture) { + renderer.gpu.bindTexture(texture.getGpuTexture()); + } else { + renderer.gpu.bindTexture(renderer.heightmapTexture); + } + } + + prog.setSampler('uSampler', 0); + +// if(this.hmap) { + renderer.gpu.bindTexture(this.hmap.getGpuTexture(), 1); + // } else { + //renderer.gpu.bindTexture(renderer.blackTexture, 1); + // renderer.gpu.bindTexture(renderer.blackTexture2, 1); + // } + + prog.setSampler('uSampler2', 1); + //draw bbox - renderer.planeMesh.draw(prog, 'aPosition', 'aTexCoord'); + //renderer.planeMesh2.draw(prog, 'aPosition', 'aTexCoord'); + renderer.planeMesh2.draw(prog, 'aPosition'); - this.map.stats.drawnFaces += renderer.planeMesh.polygons; + /* + if (vecRight && gridPoints) { + //renderer.draw.drawLineString(points, screenSpace, size, color, depthOffset, depthTest, transparent, writeDepth, useState); + renderer.draw.drawLineString([[gridPoints[12], gridPoints[13], gridPoints[14]], [gridPoints[15], gridPoints[16], gridPoints[17]]], false, 4, [1,0,0,1], null, false, false, false, false); + renderer.draw.drawLineString([[gridPoints[12], gridPoints[13], gridPoints[14]], [gridPoints[21], gridPoints[22], gridPoints[23]]], false, 4, [0,0,1,1], null, false, false, false, false); + + renderer.draw.drawLineString([[0, 0, 0], [9000000, 0, 0]], false, 4, [1,0,0,1], null, false, false, false, false); + renderer.draw.drawLineString([[0, 0, 0], [0, 9000000, 0, 0]], false, 4, [0,1,0,1], null, false, false, false, false); + renderer.draw.drawLineString([[0, 0, 0], [0, 0, 9000000]], false, 4, [0,0,1,1], null, false, false, false, false); + }*/ + + + this.map.stats.drawnFaces += renderer.planeMesh2.polygons; }; diff --git a/src/core/map/surface.js b/src/core/map/surface.js index d24acd8e..641aa28b 100755 --- a/src/core/map/surface.js +++ b/src/core/map/surface.js @@ -85,10 +85,10 @@ MapSurface.prototype.parseJson = function(json) { this.metaBinaryOrder = json['metaBinaryOrder'] || 1; this.metaUrl = this.processUrl(json['metaUrl'], ''); this.navUrl = this.processUrl(json['navUrl'], ''); - this.hmapUrl = this.processUrl(json['hmapUrl'], json['navUrl']); + this.hmapUrl = this.processUrl(json['hmapUrl'], json['navUrl'] + '00'); //this.cmapUrl = this.processUrl(json['cmapUrl'], ''); - //this.pipeline = json['pipeline'] || VTS_PIPELINE_HMAP;//VTS_PIPELINE_BASIC; - this.pipeline = json['pipeline'] || VTS_PIPELINE_BASIC; + this.pipeline = this.map.config.mapForcePipeline ? this.map.config.mapForcePipeline : (json['pipeline']); // || VTS_PIPELINE_HMAP);//VTS_PIPELINE_BASIC); + //this.pipeline = json['pipeline'] || VTS_PIPELINE_BASIC; this.navDelta = json['navDelta'] || 1; this.meshUrl = this.processUrl(json['meshUrl'], ''); this.textureUrl = this.processUrl(json['textureUrl'], ''); @@ -363,6 +363,10 @@ MapSurface.prototype.getNavUrl = function(id, skipBaseUrl) { }; +MapSurface.prototype.getHMapUrl = function(id, skipBaseUrl) { + return this.map.url.makeUrl(this.hmapUrl, {lod:id[0], ix:id[1], iy:id[2] }, null, skipBaseUrl); +}; + MapSurface.prototype.getMeshUrl = function(id, skipBaseUrl) { return this.map.url.makeUrl(this.meshUrl, {lod:id[0], ix:id[1], iy:id[2] }, null, skipBaseUrl); }; diff --git a/src/core/map/texture.js b/src/core/map/texture.js index 6a897b04..47915b65 100755 --- a/src/core/map/texture.js +++ b/src/core/map/texture.js @@ -5,16 +5,16 @@ import MapSubtexture_ from './subtexture'; var MapSubtexture = MapSubtexture_; -var MapTexture = function(map, path, heightMap, extraBound, extraInfo, tile, internal) { +var MapTexture = function(map, path, type, extraBound, extraInfo, tile, internal) { this.map = map; this.stats = map.stats; this.tile = tile; // used only for stats this.internal = internal; // used only for stats if (tile) { - this.mainTexture = tile.resources.getSubtexture(this, path, heightMap, tile, internal); + this.mainTexture = tile.resources.getSubtexture(this, path, type, tile, internal); } else { - this.mainTexture = new MapSubtexture(map, path, heightMap, tile, internal); + this.mainTexture = new MapSubtexture(map, path, type, tile, internal); } this.maskTexture = null; @@ -25,7 +25,7 @@ var MapTexture = function(map, path, heightMap, extraBound, extraInfo, tile, int this.neverReady = false; this.maskTexture = null; this.mapLoaderUrl = path; - this.heightMap = heightMap || false; + this.type = type || VTS_TEXTURETYPE_COLOR; this.extraBound = extraBound; this.extraInfo = extraInfo; this.statsCounter = 0; @@ -80,20 +80,33 @@ MapTexture.prototype.killGpuTexture = function() { }; -MapTexture.prototype.setBoundTexture = function(tile, layer) { - if (tile && layer) { - this.extraBound.sourceTile = tile; - this.extraBound.layer = layer; - - if (!tile.boundTextures[layer.id]) { - tile.boundLayers[layer.id] = layer; - var path = layer.getUrl(tile.id); - tile.boundTextures[layer.id] = tile.resources.getTexture(path, null, null, {tile: tile, layer: layer}, this.tile, this.internal); - } +MapTexture.prototype.setBoundTexture = function(tile, layer, hmap) { + if (tile) { + if (hmap) { + this.extraBound.sourceTile = tile; + this.extraBound.hmap = hmap; - this.extraBound.texture = tile.boundTextures[layer.id]; - this.extraBound.transform = this.map.draw.drawTiles.getTileTextureTransform(tile, this.extraBound.tile); + if (!tile.hmap) { + var path = tile.resourceSurface.getHMapUrl(tile.id, true); + tile.hmap = tile.resources.getTexture(path, null, null, {tile: tile, hmap: hmap}, this.tile, this.internal); + } + + this.extraBound.texture = tile.hmap; + + } else if (layer) { + this.extraBound.sourceTile = tile; + this.extraBound.layer = layer; + + if (!tile.boundTextures[layer.id]) { + tile.boundLayers[layer.id] = layer; + var path = layer.getUrl(tile.id); + tile.boundTextures[layer.id] = tile.resources.getTexture(path, null, null, {tile: tile, layer: layer}, this.tile, this.internal); + } + + this.extraBound.texture = tile.boundTextures[layer.id]; + } + this.extraBound.transform = this.map.draw.drawTiles.getTileTextureTransform(tile, this.extraBound.tile); this.map.markDirty(); } }; @@ -118,11 +131,21 @@ MapTexture.prototype.isReady = function(doNotLoad, priority, doNotCheckGpu) { while (this.extraBound.texture.extraBound || this.extraBound.texture.checkStatus == -1) { // while (this.extraBound.texture.checkStatus == -1) { parent = this.extraBound.sourceTile.parent; - if (parent.id[0] < this.extraBound.layer.lodRange[0]) { - this.neverReady = true; - this.extraBound.tile.resetDrawCommands = true; - this.map.markDirty(); - return false; + + if (this.extraBound.hmap) { + if (!parent || parent.id[0] < 1) { + this.neverReady = true; + this.extraBound.tile.resetDrawCommands = true; + this.map.markDirty(); + return false; + } + } else if (this.extraBound.layer) { + if (parent.id[0] < this.extraBound.layer.lodRange[0]) { + this.neverReady = true; + this.extraBound.tile.resetDrawCommands = true; + this.map.markDirty(); + return false; + } } this.setBoundTexture(parent, this.extraBound.layer); @@ -138,7 +161,7 @@ MapTexture.prototype.isReady = function(doNotLoad, priority, doNotCheckGpu) { return ready; } else { - this.setBoundTexture(this.extraBound.sourceTile, this.extraBound.layer); + this.setBoundTexture(this.extraBound.sourceTile, this.extraBound.layer, this.extraBound.hmap); } return false; diff --git a/src/core/renderer/draw.js b/src/core/renderer/draw.js index 3ba3f391..e222c019 100755 --- a/src/core/renderer/draw.js +++ b/src/core/renderer/draw.js @@ -1,10 +1,13 @@ import {vec3 as vec3_, mat3 as mat3_, mat4 as mat4_} from '../utils/matrix'; import {math as math_} from '../utils/math'; +import {processGMap as processGMap_} from './gmap'; //get rid of compiler mess var vec3 = vec3_, mat3 = mat3_, mat4 = mat4_; var math = math_; +var processGMap = processGMap_; + var RendererDraw = function(renderer) { this.renderer = renderer; @@ -237,7 +240,7 @@ RendererDraw.prototype.drawLineString = function(points, screenSpace, size, colo for (i = 0; i < totalPoints; i++) { p = points[i]; - p = mat4.multiplyVec4(mvp, [point[0] - cameraPos[0], point[1] - cameraPos[1], point[2] - cameraPos[2], 1 ]); + p = mat4.multiplyVec4(mvp, [p[0] - cameraPos[0], p[1] - cameraPos[1], p[2] - cameraPos[2], 1 ]); //project point coords to screen if (p[3] != 0) { @@ -661,6 +664,8 @@ RendererDraw.prototype.drawGpuJobs = function() { this.rmap.clear(); } + renderer.gmapIndex = 0; + var forceUpdate = false; renderer.jobHBuffer = {}; @@ -724,10 +729,19 @@ RendererDraw.prototype.drawGpuJobs = function() { } else { if (job.tile && job2.tile && job.tile.id[0] != job2.tile.id[0]) { //if (job != job2) { + buffer2[job.id] = job; job.timerShow = job2.timerShow; job.timerHide = job2.timerHide; job.draw = job2.draw; + //job.mv = job2.mv; + //job.mvp = job2.mvp; + job.renderCounter[0][0] = 0; + + if (job2.lastSubJob) { + job.lastSubJob = job2.lastSubJob.slice(); + job.lastSubJob[0] = job; + } job2.timerShow = 0; job2.timerHide = 0; @@ -742,6 +756,11 @@ RendererDraw.prototype.drawGpuJobs = function() { } } + if (renderer.gmapIndex > 0) { + processGMap(gpu, gl, renderer, screenPixelSize); + renderer.gmapIndex = 0; + } + if (rmap.rectanglesCount > 0) { rmap.processRectangles(gpu, gl, renderer, screenPixelSize); } @@ -756,7 +775,7 @@ RendererDraw.prototype.drawGpuJobs = function() { if (!hitmapRender) { if (job) { - + if (!job.draw) { job.timerShow += frameTime; @@ -766,6 +785,9 @@ RendererDraw.prototype.drawGpuJobs = function() { } else { forceUpdate = true; } + } else if (job.timerHide) { + job.draw = false; + job.timerShow = (job.hysteresis[0]) * (1.0-(job.timerHide / (job.hysteresis[1]))); } job.timerHide = 0; @@ -784,6 +806,9 @@ RendererDraw.prototype.drawGpuJobs = function() { } else { forceUpdate = true; } + } else if (job.timerShow) { + job.draw = true; + job.timerHide = (job.hysteresis[1]) * (1.0-(job.timerShow / (job.hysteresis[0]))); } job.timerShow = 0; @@ -1198,7 +1223,7 @@ RendererDraw.prototype.drawGpuJob = function(gpu, gl, renderer, job, screenPixel case VTS_JOB_LABEL: - if (job.reduce) { + if (job.reduce && job.reduce[0] != 7) { var a; if (job.reduce[0] > 4) { @@ -1383,7 +1408,13 @@ RendererDraw.prototype.drawGpuJob = function(gpu, gl, renderer, job, screenPixel } } - job.lastSubJob = [job, stickShift, texture, files, color, pp]; + job.lastSubJob = [job, stickShift, texture, files, color, pp, true, depth, o]; + + if (job.reduce && job.reduce[0] == 7) { + renderer.gmap[renderer.gmapIndex] = job.lastSubJob; + renderer.gmapIndex++; + return; + } if (!renderer.rmap.addRectangle(pp[0]+o[0], pp[1]+o[1], pp[0]+o[2], pp[1]+o[3], depth, job.lastSubJob)) { renderer.rmap.storeRemovedRectangle(pp[0]+o[0], pp[1]+o[1], pp[0]+o[2], pp[1]+o[3], depth, job.lastSubJob); @@ -1391,6 +1422,18 @@ RendererDraw.prototype.drawGpuJob = function(gpu, gl, renderer, job, screenPixel } return; //draw all labe from same z-index together + } else { + if (job.reduce && job.reduce[0] == 7) { + if (!pp) { + pp = renderer.project2(job.center, renderer.camera.mvp, renderer.cameraPosition); + } + + job.lastSubJob = [job, stickShift, texture, files, color, pp, false]; + + renderer.gmap[renderer.gmapIndex] = job.lastSubJob; + renderer.gmapIndex++; + return; + } } if (job.hysteresis && job.id) { @@ -1404,15 +1447,17 @@ RendererDraw.prototype.drawGpuJob = function(gpu, gl, renderer, job, screenPixel } if (renderer.drawLabelBoxes) { - if (!pp) { - pp = renderer.project2(job.center, renderer.camera.mvp, renderer.cameraPosition); - } - o = job.noOverlap; - gpu.setState(hitmapRender ? renderer.lineLabelHitState : renderer.lineLabelState); - this.drawLineString([[pp[0]+o[0], pp[1]+o[1], 0.5], [pp[0]+o[2], pp[1]+o[1], 0.5], - [pp[0]+o[2], pp[1]+o[3], 0.5], [pp[0]+o[0], pp[1]+o[3], 0.5], [pp[0]+o[0], pp[1]+o[1], 0.5]], true, 1, [255, 0, 0, 255], null, true, null, null, null); + if (o) { + if (!pp) { + pp = renderer.project2(job.center, renderer.camera.mvp, renderer.cameraPosition); + } + + gpu.setState(hitmapRender ? renderer.lineLabelHitState : renderer.lineLabelState); + this.drawLineString([[pp[0]+o[0], pp[1]+o[1], 0.5], [pp[0]+o[2], pp[1]+o[1], 0.5], + [pp[0]+o[2], pp[1]+o[3], 0.5], [pp[0]+o[0], pp[1]+o[3], 0.5], [pp[0]+o[0], pp[1]+o[1], 0.5]], true, 1, [255, 0, 0, 255], null, true, null, null, null); + } } gpu.setState(hitmapRender ? renderer.lineLabelHitState : renderer.labelState); @@ -1537,6 +1582,7 @@ RendererDraw.prototype.drawGpuSubJob = function(gpu, gl, renderer, screenPixelSi } } + /* var rmap = renderer.rmap; //screen including credits @@ -1552,7 +1598,7 @@ RendererDraw.prototype.drawGpuSubJob = function(gpu, gl, renderer, screenPixelSi //serach bar if (x1 < rmap.blx && x2 > 0 && y1 <= rmap.bly && y2 > 0) { return false; - } + }*/ } if (s[0] != 0) { @@ -1571,7 +1617,7 @@ RendererDraw.prototype.drawGpuSubJob = function(gpu, gl, renderer, screenPixelSi var hitmapRender = job.hitable && renderer.onlyHitLayers; - if (renderer.drawLabelBoxes) { + if (renderer.drawLabelBoxes && o) { gpu.setState(hitmapRender ? renderer.lineLabelHitState : renderer.lineLabelState); this.drawLineString([[pp[0]+o[0], pp[1]+o[1], 0.5], [pp[0]+o[2], pp[1]+o[1], 0.5], [pp[0]+o[2], pp[1]+o[3], 0.5], [pp[0]+o[0], pp[1]+o[3], 0.5], [pp[0]+o[0], pp[1]+o[1], 0.5]], true, 1, [255, 0, 0, 255], null, true, null, null, null); diff --git a/src/core/renderer/gmap.js b/src/core/renderer/gmap.js new file mode 100644 index 00000000..6dbcb2dc --- /dev/null +++ b/src/core/renderer/gmap.js @@ -0,0 +1,187 @@ + + +function processGMap(gpu, gl, renderer, screenPixelSize) { + var tileCount = renderer.config.mapFeatureGridCells; //31; //labelGridCells + var featuresPerSquareInch = renderer.config.mapFeaturesPerSquareInch; //0.6614; //labelsPerSquareInch + var ppi = 96 * (window.devicePixelRatio || 1); + var screenLX = renderer.curSize[0]; + var screenLY = renderer.curSize[1]; + var featureCount = (screenLX/ppi)*(screenLY/ppi)*featuresPerSquareInch; + var i, li, top = renderer.config.mapFeaturesSortByTop; + + //get top features + var featureCache = renderer.gmap; + var featureCacheSize = renderer.gmapIndex; + var topFeatures = renderer.gmapTop; + var featureCount2 = featureCount; + + if (featureCount > featureCacheSize) { + featureCount2 = featureCacheSize; + } + + //distribute top features + var tileSize = Math.floor(Math.sqrt((screenLX*screenLY) / tileCount)); + var hitMap = renderer.gmapHit, usedFeatures = 0; + var tileFeatures, count, feature; + + do { + var a,b,c,d,ix,iy,is,pp,tx,ty,mx,my,v,index,o,j; + + ix = screenLX / tileSize; + iy = screenLY / tileSize; + is = ix * iy; + mx = Math.floor(ix); + my = Math.floor(iy); + ix = ix - mx; + iy = iy - my; + + a = 1 / is; + b = ix / is; + c = iy / is; + d = (ix*iy) / is; + + a = Math.floor(a * featureCount); + b = Math.floor(b * featureCount); + c = Math.floor(c * featureCount); + d = Math.floor(d * featureCount); + + var hitMap = renderer.gmapStore; + var hitMapCount = renderer.gmapHit; + + //clear hit-map + for (i = 0, li = (mx+1) * (my+1); i < li; i++) { + hitMap[i] = null; + } + + for (i = 0, li = featureCacheSize; i < li; i++) { + feature = featureCache[i]; + if (!feature) { + continue; + } + + pp = feature[5]; + + if (pp[0] < 0 || pp[0] >= screenLX || pp[1] < 0 || pp[1] >= screenLY) { + featureCache[i] = null; + continue; + } + + tx = pp[0] / tileSize; + ty = pp[1] / tileSize; + + if (tx > mx) { + if (ty > my) { + v = d; + } else { + v = b; + } + } else if (ty > my) { + v = c; + } else { + v = a; + } + + if (v > 0) { + index = Math.floor(tx) + Math.floor(ty) * (mx + 1); + + tileFeatures = hitMap[index]; + + if (tileFeatures) { + hitMap[index].push(i); + } else { + hitMap[index] = [i]; + hitMapCount[index] = v; + } + } + } + + for (i = 0, li = (mx+1) * (my+1); i < li; i++) { + tileFeatures = hitMap[i]; + + if (tileFeatures && tileFeatures.length) { + count = hitMapCount[i]; + + if (count > tileFeatures.length) { + count = tileFeatures.length; + } + + sortFeatures(tileFeatures, top, count, renderer); + + for (j = 0; j < count; j++){ + index = topFeatures[j] + feature = featureCache[index]; + topFeatures[j] = null; + featureCache[index] = null; + + //render job + if (feature[6]) { //no-overlap + pp = feature[5]; + o = feature[8]; + if (!renderer.rmap.addRectangle(pp[0]+o[0], pp[1]+o[1], pp[0]+o[2], pp[1]+o[3], feature[7], feature[0].lastSubJob)) { + renderer.rmap.storeRemovedRectangle(pp[0]+o[0], pp[1]+o[1], pp[0]+o[2], pp[1]+o[3], feature[7], feature[0].lastSubJob); + } + } else { + if (feature[0].hysteresis) { + renderer.jobHBuffer[feature[0].id] = feature[0]; + } else { + draw.drawGpuSubJob(gpu, gl, renderer, screenPixelSize, subjob, null); + } + } + } + + } + } + + a *= mx * my; + b *= mx; + c *= my; + + usedFeatures += a + b + c + d; + tileSize *= 2; + + } while(usedFeatures < featureCount2); + +} + + +function sortFeatures(features, top, count, renderer) { + var value, feature; + var currentIndex = 0; + var currentValue2 = top ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; + var topFeatures = renderer.gmapTop; + var topFeaturesIndex = 0; + var topFeaturesIndex2 = 0; + + //remove feature from cache + var featureCache = renderer.gmap, index; + + + do { + var currentValue = top ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY; + topFeaturesIndex2 = topFeaturesIndex; + + for (var i = 0, li = features.length; i < li; i++) { + index = features[i]; + feature = featureCache[index]; + value = feature[0].reduce[1]; + + if (((top && value >= currentValue && value < currentValue2) || (value <= currentValue && value > currentValue2)) ) { + if (currentValue != value) { + topFeaturesIndex = topFeaturesIndex2; + } + + topFeatures[topFeaturesIndex] = index; + topFeaturesIndex++; + currentValue = value; + } + } + + currentValue2 = currentValue; + currentIndex++; + + } while(currentIndex < count); + +} + +export {processGMap}; + diff --git a/src/core/renderer/gpu/group.js b/src/core/renderer/gpu/group.js index 0665fff9..b4d8a708 100755 --- a/src/core/renderer/gpu/group.js +++ b/src/core/renderer/gpu/group.js @@ -372,6 +372,7 @@ GpuGroup.prototype.addIconJob = function(data, label, tile) { case 'scr-count': job.reduce[0] = 4; break; case 'scr-count2': job.reduce[0] = 5; break; case 'scr-count3': job.reduce[0] = 6; break; + case 'scr-count4': job.reduce[0] = 7; break; } } diff --git a/src/core/renderer/gpu/shaders.js b/src/core/renderer/gpu/shaders.js index ce59d975..36fed307 100755 --- a/src/core/renderer/gpu/shaders.js +++ b/src/core/renderer/gpu/shaders.js @@ -711,7 +711,6 @@ GpuShaders.planeFragmentShader = 'precision mediump float;\n'+ 'gl_FragColor = mix(uFogColor, c, vFogFactor);\n'+ '}'; - GpuShaders.planeVertex2Shader = 'attribute vec3 aPosition;\n'+ 'attribute vec2 aTexCoord;\n'+ @@ -810,19 +809,51 @@ GpuShaders.planeVertex3Shader = 'vTexCoord = uv;\n'+ '}'; +GpuShaders.getHFNormal = + 'vec3 getHFNormal(vec2 uv, float texelSize, float heightDelta) {\n'+ + 'vec4 h;\n'+ + 'h[0] = texture2D(uSampler2, uv + (texelSize * vec2( 0.0,-1.0))).r * heightDelta;\n'+ + 'h[1] = texture2D(uSampler2, uv + (texelSize * vec2(-1.0, 0.0))).r * heightDelta;\n'+ + 'h[2] = texture2D(uSampler2, uv + (texelSize * vec2( 1.0, 0.0))).r * heightDelta;\n'+ + 'h[3] = texture2D(uSampler2, uv + (texelSize * vec2( 0.0, 1.0))).r * heightDelta;\n'+ + 'return normalize(vec3(h[1] - h[2], h[3] - h[0], 2.0));}\n'; + +GpuShaders.getHFNormal2 = + 'vec2 getHFNormal2(vec2 uv, float texelSize, float heightDelta) {\n'+ + 'vec4 h;\n'+ + 'h[0] = texture2D(uSampler2, uv + (texelSize * vec2( 0.0,-1.0))).r * heightDelta;\n'+ + 'h[1] = texture2D(uSampler2, uv + (texelSize * vec2(-1.0, 0.0))).r * heightDelta;\n'+ + 'h[2] = texture2D(uSampler2, uv + (texelSize * vec2( 1.0, 0.0))).r * heightDelta;\n'+ + 'h[3] = texture2D(uSampler2, uv + (texelSize * vec2( 0.0, 1.0))).r * heightDelta;\n'+ + 'return vec2(h[1] - h[2], h[3] - h[0]);}\n'; + GpuShaders.planeVertex4Shader = + '#define newspace\n'+ 'uniform sampler2D uSampler2;\n'+ 'attribute vec3 aPosition;\n'+ - 'attribute vec2 aTexCoord;\n'+ + //'attribute vec2 aTexCoord;\n'+ + //'attribute vec3 aBarycentric;\n'+ 'uniform mat4 uMV, uProj;\n'+ 'uniform vec4 uParams;\n'+ //[uGridStep1, fogDensity, indexFactor, uGridStep2] 'uniform vec4 uParams3;\n'+ //[px, py, sx, sy] 'uniform float uPoints[9*3];\n'+ 'uniform vec3 uVector;\n'+ - 'uniform vec2 uHeights;\n'+ //[hmin, hmax] + 'uniform vec3 uHeights;\n'+ //[hmin, hmax] + 'uniform vec4 uTransform;\n'+ + //'uniform vec4 uTransform2;\n'+ 'varying vec2 vTexCoord;\n'+ 'varying vec2 vTexCoord2;\n'+ - 'varying float vFogFactor;\n'+ GpuShaders.quadPoint + + 'varying vec3 vBarycentric;\n'+ + + '#ifdef newspace\n'+ + 'varying mat3 vTBN;\n'+ + '#else\n'+ + 'varying vec3 vNormal;\n'+ + '#endif\n'+ + + 'varying float vFogFactor;\n'+ GpuShaders.quadPoint + GpuShaders.getHFNormal + GpuShaders.getHFNormal2 + + //'float random(vec2 p) { return fract(cos(dot(p,vec2( 23.14069263277926, 2.665144142690225)))*12345.6789);}\n'+ + 'void main() {\n'+ 'vec3 indices = aPosition;\n'+ 'float t = aPosition.y * uParams[2];\n'+ //vertical index @@ -838,17 +869,154 @@ GpuShaders.planeVertex4Shader = 'float p2y = 2.0*p2.y-p1.y*0.5-p3.y*0.5;\n'+ 'float p2z = 2.0*p2.z-p1.z*0.5-p3.z*0.5;\n'+ 'vec4 p = vec4(t2*t2*p1.x+2.0*t2*t*p2x+t*t*p3.x, t2*t2*p1.y+2.0*t2*t*p2y+t*t*p3.y, t2*t2*p1.z+2.0*t2*t*p2z+t*t*p3.z, 1);\n'+ - 'p.xyz += uVector * (uHeights[0] + (uHeights[1]-uHeights[0])*texture2D(uSampler2, vec2(tt, tt2)).x);\n'+ + 'vec2 uv2 = vec2(tt, 1.0-tt2);\n'+ + 'uv2 = vec2(uTransform[0] * uv2[0] + uTransform[2], uTransform[1] * uv2[1] + uTransform[3]);\n'+ + + 'p.xyz += uVector * (uHeights[0] + (uHeights[1]-uHeights[0])*texture2D(uSampler2, uv2).x);\n'+ + 'vec4 camSpacePos = uMV * p;\n'+ 'gl_Position = uProj * camSpacePos;\n'+ 'float camDist = length(camSpacePos.xyz);\n'+ 'vFogFactor = exp(uParams[1] * camDist);\n'+ - 'vec2 uv = aTexCoord;\n'+ - 'uv.x = uv.x * uParams3[2] + uParams3[0];\n'+ - 'uv.y = uv.y * uParams3[3] + uParams3[1];\n'+ + + 'vec2 uv = vec2(tt, 1.0-tt2);\n'+ + 'uv.x = uv.x * uParams3[0] + uParams3[2];\n'+ + 'uv.y = uv.y * uParams3[1] + uParams3[3];\n'+ 'vTexCoord = uv;\n'+ + + 'vBarycentric = camSpacePos.xyz;\n'+ + + '#ifdef newspace\n'+ + 'vec2 d = getHFNormal2(uv2, 1.0/(128.0), (uHeights[1]-uHeights[0]) * uHeights[2]);\n'+ + 'vec3 T = vec3(2.0,0.0,-d.x); vec3 B = vec3(0.0,2.0,-d.y);\n'+ + 'vTBN = mat3(normalize(T), normalize(B), cross(T,B));\n'+ + '#else\n'+ + 'vec3 n = getHFNormal(uv2, 1.0/(128.0), (uHeights[1]-uHeights[0]) * uHeights[2]);\n'+ + 'vNormal = normalize(n);\n'+ + '#endif\n'+ + '}'; +GpuShaders.planeFragmentShader2 = 'precision mediump float;\n'+ + '#extension GL_OES_standard_derivatives : enable\n'+ + '#define newspace\n'+ + 'uniform sampler2D uSampler;\n'+ + 'uniform vec4 uParams2;\n'+ //[uGridStep1, uGridStep2, uGridBlend, 0] + 'uniform mat3 uSpace;\n'+ + 'varying vec2 vTexCoord;\n'+ + 'varying float vFogFactor;\n'+ + 'varying vec3 vBarycentric;\n'+ + + '#ifdef newspace\n'+ + 'varying mat3 vTBN;\n'+ + '#else\n'+ + 'varying vec3 vNormal;\n'+ + '#endif\n'+ + + 'uniform vec4 uFogColor;\n'+ // = vec4(216.0/255.0, 232.0/255.0, 243.0/255.0, 1.0);\n'+ + 'void main() {\n'+ + 'vec3 ldir = normalize(-vBarycentric);\n'+ + + '#ifdef flat\n'+ + 'vec3 nx = dFdx(vBarycentric);\n'+ + 'vec3 ny = dFdy(vBarycentric);\n'+ + 'vec3 normal2 = normalize(cross(nx,ny));\n'+ + 'vec4 c2 = vec4(vec3(max(0.0,normal2.z*(204.0/255.0))+(32.0/255.0)),1.0);\n'+ + '#else\n'+ + + '#ifdef newspace\n'+ + //'vec3 normal = cross(normalize(vTangent), normalize(vBitangent));\n'+ + + '#ifdef nmix\n'+ + 'vec3 normal = vTBN * normalize((texture2D(uSampler, vTexCoord).xyz-0.5)*2.0);\n'+ + '#else\n'+ + 'vec3 normal = vTBN * vec3(0.0,0.0,1.0);\n'+ + '#endif\n'+ + + '#else\n'+ + 'vec3 normal = vNormal;\n'+ + '#endif\n'+ + + 'normal = normalize(uSpace * normal);\n'+ + + 'vec3 eyeDir = ldir;\n'+ + 'vec3 refDir = reflect(-ldir, normal);\n'+ + 'float specW = min(1.0, pow(max(dot(refDir, eyeDir), 0.0), 90.0));\n'+ + 'float diffW = min(1.0, max(dot(normal, ldir), 0.0));\n'+ + 'float lcolor = (dot(normal, ldir) + 1.0) * 0.5;\n'+ + //'float lcolor = 0.25+(0.5*diffW)+(0.25*specW);\n'+ + //'float lcolor = 0.25+(0.75*diffW);\n'+ + + '#ifdef normals\n'+ + 'vec4 c2 = vec4(normal*0.5+0.5,1.0);\n'+ + '#else\n'+ + 'vec4 c2 = vec4(vec3(dot(vec3(0.0,0.0,1.0), normal)),1.0);\n'+ + '#endif\n'+ + //'vec4 c2 = vec4(normalize(ldir)*0.5+0.5,1.0);\n'+ + //'vec4 c2 = vec4(vec3(lcolor),1.0);\n'+ + '#endif\n'+ + + '#ifdef grid\n'+ + 'vec4 c = mix(texture2D(uSampler, vTexCoord), texture2D(uSampler, vTexCoord*8.0), uParams2[2]);\n'+ + 'c = mix(c, c2, 0.5);\n'+ + '#else\n'+ + '#ifdef exmap\n'+ + + 'vec4 c = texture2D(uSampler, vTexCoord);\n'+ + + '#ifdef classmap\n'+ + 'int i = int(c.x*255.0);\n'+ + + /* + 'if (i == 0) c = vec4(0.3, 0.44, 0.64, 1.0);\n'+ + 'if (i == 1) c = vec4(0.0, 0.24, 0.0, 1.0);\n'+ + 'if (i == 2) c = vec4(0.58, 0.61, 0.44, 1.0);\n'+ + 'if (i == 3) c = vec4(0.0, 0.39, 0.0, 1.0);\n'+ + 'if (i == 4) c = vec4(0.12, 0.67, 0.02, 1.0);\n'+ + 'if (i == 5) c = vec4(0.08, 0.55, 0.24, 1.0);\n'+ + 'if (i == 6) c = vec4(0.36, 0.46, 0.17, 1.0);\n'+ + 'if (i == 7) c = vec4(0.7, 0.62, 0.18, 1.0);\n'+ + 'if (i == 8) c = vec4(0.7, 0.54, 0.2, 1.0);\n'+ + 'if (i == 9) c = vec4(0.91, 0.86, 0.37, 1.0);\n'+ + 'if (i == 10) c = vec4(0.88, 0.81, 0.54, 1.0);\n'+ + 'if (i == 11) c = vec4(0.61, 0.46, 0.33, 1.0);\n'+ + 'if (i == 12) c = vec4(0.73, 0.83, 0.56, 1.0);\n'+ + 'if (i == 13) c = vec4(0.25, 0.54, 0.45, 1.0);\n'+ + 'if (i == 14) c = vec4(0.42, 0.64, 0.54, 1.0);\n'+ + 'if (i == 15) c = vec4(0.9, 0.68, 0.4, 1.0);\n'+ + 'if (i == 16) c = vec4(0.66, 0.67, 0.68, 1.0);\n'+ + 'if (i == 17) c = vec4(0.86, 0.13, 0.15, 1.0);\n'+ + 'if (i == 18) c = vec4(0.3, 0.44, 0.64, 1.0);\n'+ + 'if (i == 19) c = vec4(1.0, 0.98, 1.0, 1.0);\n'+ + 'c = c * c2;\n'+ + */ + + 'if (i == 1 || i == 2 || i == 5 || i == 6) c = vec4(146.0, 178.0, 144.0, 255.0);\n'+ + 'if (i == 3 || i == 4) c = vec4(94.0, 169.0, 133.0, 255.0);\n'+ + 'if (i == 8 || i == 11) c = vec4(238.0, 221.0, 185.0, 255.0);\n'+ + 'if (i == 7) c = vec4(226.0, 192.0, 154.0, 255.0);\n'+ + 'if (i == 9 || i == 10 || i == 12) c = vec4(250.0, 246.0, 167.0, 255.0);\n'+ + 'if (i == 13 || i == 16) c = vec4(245.0, 236.0, 211.0, 255.0);\n'+ + 'if (i == 14) c = vec4(139.0, 185.0, 166.0, 255.0);\n'+ + 'if (i == 15) c = vec4(199.0, 219.0, 155.0, 255.0);\n'+ + 'if (i == 17) c = vec4(149.0, 132.0, 162.0, 255.0);\n'+ + 'if (i == 18 || i == 0) c = vec4(188.0, 221.0, 255.0, 255.0);\n'+ + 'if (i == 19) c = vec4(255.0, 255.0, 255.0, 255.0);\n'+ + 'c = (c*(1.0/255.0)) * c2;\n'+ + '#endif\n'+ + + '#else\n'+ + 'vec4 c = c2;\n'+ + '#endif\n'+ + '#endif\n'+ + + '#ifdef fog\n'+ + 'gl_FragColor = mix(uFogColor, c, vFogFactor);\n'+ + '#else\n'+ + 'gl_FragColor = c;\n'+ + '#endif\n'+ + '}'; + //textured tile mesh GpuShaders.tileVertexShader = 'attribute vec3 aPosition;\n'+ diff --git a/src/core/renderer/init.js b/src/core/renderer/init.js index 1f4ccf55..0d0da0a9 100755 --- a/src/core/renderer/init.js +++ b/src/core/renderer/init.js @@ -26,8 +26,6 @@ var RendererInit = function(renderer) { //renderer.font = new GpuFont(this.gpu, this.core); //renderer.fonts['#default'] = renderer.font; - //renderer.font = new GpuFont(this.gpu, this.core, null, null, './font.png'); - //renderer.font = new GpuFont(this.gpu, this.core, null, null, './font22.png'); //renderer.font = new GpuFont(this.gpu, this.core, null, null, './allinone.fnt'); this.initShaders(); @@ -62,9 +60,6 @@ RendererInit.prototype.initShaders = function() { renderer.progPlane2 = new GpuProgram(gpu, shaders.planeVertex2Shader, shaders.planeFragment2Shader); //poles renderer.progPlane3 = new GpuProgram(gpu, shaders.planeVertex3Shader, shaders.planeFragmentShader); // grid - renderer.progHmapPlane = new GpuProgram(gpu, shaders.planeVertex4Shader, shaders.planeFragmentShader); - - renderer.progSkydome = new GpuProgram(gpu, shaders.skydomeVertexShader, shaders.skydomeFragmentShader); renderer.progStardome = new GpuProgram(gpu, shaders.skydomeVertexShader, shaders.stardomeFragmentShader); @@ -100,6 +95,19 @@ RendererInit.prototype.initShaders = function() { renderer.progIcon2 = new GpuProgram(gpu, shaders.icon2VertexShader, shaders.text2FragmentShader); //label }; +RendererInit.prototype.initProceduralShaders = function() { + var shaders = GpuShaders; + var renderer = this.renderer; + var gpu = this.gpu; + renderer.progHmapPlane = new GpuProgram(gpu, shaders.planeVertex4Shader, shaders.planeFragmentShader2); + renderer.progHmapPlane2 = new GpuProgram(gpu, shaders.planeVertex4Shader, '#define grid\n' + shaders.planeFragmentShader2); + renderer.progHmapPlane3 = new GpuProgram(gpu, shaders.planeVertex4Shader, '#define exmap\n' + shaders.planeFragmentShader2); + renderer.progHmapPlane4 = new GpuProgram(gpu, shaders.planeVertex4Shader, '#define flat\n' + shaders.planeFragmentShader2); + renderer.progHmapPlane5 = new GpuProgram(gpu, shaders.planeVertex4Shader, '#define normals\n' + shaders.planeFragmentShader2); + renderer.progHmapPlane6 = new GpuProgram(gpu, shaders.planeVertex4Shader, '#define nmix\n#define normals\n' + shaders.planeFragmentShader2); + renderer.progHmapPlane7 = new GpuProgram(gpu, shaders.planeVertex4Shader, '#define nmix\n' + shaders.planeFragmentShader2); + renderer.progHmapPlane8 = new GpuProgram(gpu, shaders.planeVertex4Shader, '#define exmap\n#define classmap\n' + shaders.planeFragmentShader2); +} RendererInit.prototype.initHeightmap = function() { var renderer = this.renderer; @@ -112,6 +120,9 @@ RendererInit.prototype.initHeightmap = function() { meshData = RendererGeometry.buildPlane(16); renderer.planeMesh = new GpuMesh(gpu, meshData, null, this.core); + meshData = RendererGeometry.buildPlane(128); + renderer.planeMesh2 = new GpuMesh(gpu, meshData, null, this.core); + // create heightmap texture var size = 64; var halfLineWidth = 1; diff --git a/src/core/renderer/renderer.js b/src/core/renderer/renderer.js index 0febc515..416ddf63 100755 --- a/src/core/renderer/renderer.js +++ b/src/core/renderer/renderer.js @@ -94,6 +94,12 @@ var Renderer = function(core, div, onUpdate, onResize, config) { this.fonts = {}; this.fogDensity = 0; + this.gmap = new Array(2048); + this.gmapIndex = 0; + this.gmapTop = new Array(512); + this.gmapHit = new Array(512); + this.gmapStore = new Array(512); + this.jobZBuffer = new Array(512); this.jobZBufferSize = new Array(512); @@ -150,6 +156,10 @@ var Renderer = function(core, div, onUpdate, onResize, config) { this.resizeGL(Math.floor(this.curSize[0]*factor), Math.floor(this.curSize[1]*factor)); }; +Renderer.prototype.initProceduralShaders = function() { + this.init.initProceduralShaders(); +}; + Renderer.prototype.onResize = function() { if (this.killed){ diff --git a/src/core/utils/matrix.js b/src/core/utils/matrix.js index fa4d7382..c0b29dc0 100755 --- a/src/core/utils/matrix.js +++ b/src/core/utils/matrix.js @@ -397,6 +397,17 @@ mat3.toMat4 = function (a, b) { return b; }; +mat3.multiplyVec3 = function (a, b, c) { + c || (c = b); + var d = b[0], + e = b[1]; + b = b[2]; + c[0] = a[0] * d + a[3] * e + a[6] * b; + c[1] = a[1] * d + a[4] * e + a[7] * b; + c[2] = a[2] * d + a[5] * e + a[8] * b; + return c; +}; + mat3.str = function (a) { return '[' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + a[8] + ']'; diff --git a/webpack.config.js b/webpack.config.js index d0324bb1..5eae8c2f 100755 --- a/webpack.config.js +++ b/webpack.config.js @@ -58,6 +58,10 @@ plugins.push( 'VTS_TEXTURECHECK_CODE' : 3, 'VTS_TEXTURECHECK_SIZE' : 4, + 'VTS_TEXTURETYPE_COLOR' : 0, + 'VTS_TEXTURETYPE_HEIGHT' : 1, + 'VTS_TEXTURETYPE_CLASS' : 2, + 'VTS_JOB_FLAT_LINE' : 1, 'VTS_JOB_FLAT_RLINE' : 2, 'VTS_JOB_FLAT_TLINE' : 3,