Skip to content

Commit

Permalink
Merge pull request #43 from DavidLevinsky/master
Browse files Browse the repository at this point in the history
Advanced hit test for geodata
  • Loading branch information
davidmtech authored May 16, 2017
2 parents 9bb8379 + 7f9e1f6 commit e2b9d72
Show file tree
Hide file tree
Showing 24 changed files with 300 additions and 666 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vts-browser-js",
"version": "2.2.4",
"version": "2.3.0",
"description": "JavaScript WebGL 3D maps rendering engine",
"main": "src/browser/index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/core/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ string getCoreVersion()
*/

function getCoreVersion(full) {
return (full ? 'Core: ' : '') + '2.2.4';
return (full ? 'Core: ' : '') + '2.3.0';
}


Expand Down
11 changes: 8 additions & 3 deletions src/core/map/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -522,17 +522,22 @@ MapDraw.prototype.drawHitmap = function() {
this.map.renderSlots.processRenderSlots();
this.renderer.switchToFramebuffer('base');
this.drawChannel = 0;
this.map.hitMapDirty = false;
};


MapDraw.prototype.drawGeodataHitmap = function() {
this.renderer.gpu.setState(this.drawTileState);
this.renderer.switchToFramebuffer('geo');
//this.renderer.onlyHitLayers = true;
this.renderer.draw.drawGpuJobs();
//this.renderer.onlyHitLayers = false;

if (this.renderer.advancedPassNeeded) {
this.renderer.switchToFramebuffer('geo2');
this.renderer.draw.drawGpuJobs();
}

this.renderer.switchToFramebuffer('base');
this.geoHitMapDirty = false;
this.map.geoHitMapDirty = false;
};


Expand Down
43 changes: 35 additions & 8 deletions src/core/map/geodata-processor/worker-linestring.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var processLineStringPass = function(lineString, lod, style, zIndex, eventInfo)
var drawEvent = getLayerPropertyValue(style, 'draw-event', lineString, lod);
var enterEvent = getLayerPropertyValue(style, 'enter-event', lineString, lod);
var leaveEvent = getLayerPropertyValue(style, 'leave-event', lineString, lod);
var advancedHit = getLayerPropertyValue(style, 'advanced-hit', lineString, lod);

var zbufferOffset = getLayerPropertyValue(style, 'zbuffer-offset', lineString, lod);

Expand All @@ -55,11 +56,10 @@ var processLineStringPass = function(lineString, lod, style, zIndex, eventInfo)
//console.log("lineflat: "+lineFlat);
//var lineWidth = Math.pow(2, 23 - lod) / 32;

var index = 0;
var index2 = 0;
var index = 0, index2 = 0, index3 = 0;
var skipJoins = (!lineFlat && lineWidth < 2.1);

var ii, i, li, p2, v, vv, l, n, nn, p1, p;
var ii, i, li, p2, v, vv, l, n, nn, p1, p, elementIndex, elemetBase = 0;

//console.log("lod: " + lod + " width: " + lineWidth);

Expand Down Expand Up @@ -93,6 +93,9 @@ var processLineStringPass = function(lineString, lod, style, zIndex, eventInfo)
var joinVertices = skipJoins ? 0 : (circleSides * (texturedLine || !lineFlat? 4 : 3) * 3);
var vertexBuffer = new Float32Array(totalPoints * lineVertices + totalPoints * joinVertices);

if (advancedHit) {
var elementBuffer = new Float32Array(totalPoints * (3 * 2) + totalPoints * (skipJoins ? 0 : circleSides) * 3);
}

if (!lineFlat || texturedLine) {
var lineNormals = 3 * 4 * 2;
Expand Down Expand Up @@ -174,7 +177,21 @@ var processLineStringPass = function(lineString, lod, style, zIndex, eventInfo)
}
}

if (advancedHit) {
elementIndex = elemetBase + i;

elementBuffer[index3] = elementIndex;
elementBuffer[index3+1] = elementIndex;
elementBuffer[index3+2] = elementIndex;

//add polygon
elementBuffer[index3+3] = elementIndex;
elementBuffer[index3+4] = elementIndex;
elementBuffer[index3+5] = elementIndex;

index3 += 6;
}

if (lineFlat && !texturedLine) {

//normalize vector to line width and rotate 90 degrees
Expand Down Expand Up @@ -236,7 +253,7 @@ var processLineStringPass = function(lineString, lod, style, zIndex, eventInfo)
vertexBuffer[index+17] = p2[2] + n[2];

index += 18;

} else {

//direction vector
Expand Down Expand Up @@ -414,7 +431,15 @@ var processLineStringPass = function(lineString, lod, style, zIndex, eventInfo)
}

for (var j = 0; j < circleSides; j++) {


if (advancedHit) {
elementIndex = elemetBase + i;
elementBuffer[index3] = elementIndex;
elementBuffer[index3+1] = elementIndex;
elementBuffer[index3+2] = elementIndex;
index3 += 3;
}

if (lineFlat && !texturedLine) {

vertexBuffer[index] = p1[0];
Expand Down Expand Up @@ -513,6 +538,7 @@ var processLineStringPass = function(lineString, lod, style, zIndex, eventInfo)
}
}

elemetBase += points.length;
}

if (totalPoints > 0) {
Expand All @@ -530,8 +556,8 @@ var processLineStringPass = function(lineString, lod, style, zIndex, eventInfo)
if (line) {
var messageData = {'command':'addRenderJob', 'vertexBuffer': vertexBuffer,
'color':lineColor, 'z-index':zIndex, 'center': center, 'normalBuffer': normalBuffer,
'hover-event':hoverEvent, 'click-event':clickEvent, 'draw-event':drawEvent,
'hitable':hitable, 'state':globals.hitState, 'eventInfo':eventInfo,
'elementBuffer': elementBuffer, 'hover-event':hoverEvent, 'click-event':clickEvent, 'draw-event':drawEvent,
'hitable':hitable, 'state':globals.hitState, 'eventInfo':eventInfo, 'advancedHit': advancedHit,
'enter-event':enterEvent, 'leave-event':leaveEvent, 'zbuffer-offset':zbufferOffset,
'line-width':lineWidth*2, 'lod':(globals.autoLod ? null : globals.tileLod) };

Expand Down Expand Up @@ -607,6 +633,7 @@ var processLineLabel = function(lineLabelPoints, lineLabelPoints2, lineString, c
var drawEvent = getLayerPropertyValue(style, 'draw-event', lineString, lod);
var enterEvent = getLayerPropertyValue(style, 'enter-event', lineString, lod);
var leaveEvent = getLayerPropertyValue(style, 'leave-event', lineString, lod);
var advancedHit = getLayerPropertyValue(style, 'advanced-hit', lineString, lod);

var zbufferOffset = getLayerPropertyValue(style, 'zbuffer-offset', lineString, lod);

Expand All @@ -632,7 +659,7 @@ var processLineLabel = function(lineLabelPoints, lineLabelPoints2, lineString, c
'texcoordsBuffer': texcoordsBuffer, 'color':labelColor, 'z-index':zIndex, 'center': center,
'hover-event':hoverEvent, 'click-event':clickEvent, 'draw-event':drawEvent,
'enter-event':enterEvent, 'leave-event':leaveEvent, 'zbuffer-offset':zbufferOffset,
'hitable':hitable, 'state':globals.hitState, 'eventInfo':eventInfo,
'hitable':hitable, 'state':globals.hitState, 'eventInfo':eventInfo, 'advancedHit': advancedHit,
'lod':(globals.autoLod ? null : globals.tileLod) }, [vertexBuffer.buffer, texcoordsBuffer.buffer], signature);
};

Expand Down
4 changes: 1 addition & 3 deletions src/core/map/geodata-processor/worker-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function processLayerFeaturePass(type, feature, lod, layer, zIndex, eventInfo) {
switch(type) {
case 'line-string':
if (getLayerPropertyValue(layer, 'point', feature, lod) ||
getLayerPropertyValue(layer, 'label', feature, lod)) {
getLayerPropertyValue(layer, 'label', feature, lod)) {
processPointArrayPass(feature, lod, layer, zIndex, eventInfo);
}

Expand Down Expand Up @@ -129,9 +129,7 @@ function processLayerFeature(type, feature, lod, layer, featureIndex) {


function processGroup(group, lod) {

var i, li;

var groupId = group['id'] || '';

var bbox = group['bbox'];
Expand Down
9 changes: 5 additions & 4 deletions src/core/map/geodata-processor/worker-pointarray.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var processPointArrayPass = function(pointArray, lod, style, zIndex, eventInfo)
var drawEvent = getLayerPropertyValue(style, 'draw-event', pointArray, lod);
var enterEvent = getLayerPropertyValue(style, 'enter-event', pointArray, lod);
var leaveEvent = getLayerPropertyValue(style, 'leave-event', pointArray, lod);
var advancedHit = getLayerPropertyValue(style, 'advanced-event', pointArray, lod);

var zbufferOffset = getLayerPropertyValue(style, 'zbuffer-offset', pointArray, lod);

Expand Down Expand Up @@ -187,7 +188,7 @@ var processPointArrayPass = function(pointArray, lod, style, zIndex, eventInfo)
for (var j = 0; j < circleSides; j++) {

if (point) {

if (pointFlat) {

//add polygon
Expand Down Expand Up @@ -272,7 +273,7 @@ var processPointArrayPass = function(pointArray, lod, style, zIndex, eventInfo)
'color':pointColor, 'z-index':zIndex, 'visibility': visibility, 'center': center,
'hover-event':hoverEvent, 'click-event':clickEvent, 'draw-event':drawEvent,
'enter-event':enterEvent, 'leave-event':leaveEvent, 'zbuffer-offset':zbufferOffset,
'hitable':hitable, 'state':globals.hitState, 'eventInfo':eventInfo,
'hitable':hitable, 'state':globals.hitState, 'eventInfo':eventInfo, 'advancedHit': advancedHit,
'lod':(globals.autoLod ? null : globals.tileLod) }, [vertexBuffer.buffer]);
} else {
postGroupMessage({'command':'addRenderJob', 'type': 'pixel-line', 'vertexBuffer': vertexBuffer,
Expand All @@ -290,7 +291,7 @@ var processPointArrayPass = function(pointArray, lod, style, zIndex, eventInfo)
'originBuffer': iconData.originBuffer, 'texcoordsBuffer': iconData.texcoordsBuffer,
'icon':globals.stylesheetBitmaps[iconData.source[0]], 'color':iconData.color, 'z-index':zIndex,
'visibility': visibility, 'culling': culling, 'center': center, 'stick': iconData.stick,
'hover-event':hoverEvent, 'click-event':clickEvent, 'draw-event':drawEvent,
'hover-event':hoverEvent, 'click-event':clickEvent, 'draw-event':drawEvent, 'advancedHit': advancedHit,
'enter-event':enterEvent, 'leave-event':leaveEvent, 'zbuffer-offset':zbufferOffset,
'hitable':hitable, 'state':globals.hitState, 'eventInfo':eventInfo,
'lod':(globals.autoLod ? null : globals.tileLod) }, [iconData.vertexBuffer.buffer, iconData.originBuffer.buffer, iconData.texcoordsBuffer.buffer]);
Expand All @@ -303,7 +304,7 @@ var processPointArrayPass = function(pointArray, lod, style, zIndex, eventInfo)
'center': center, 'stick': labelData.stick,
'hover-event':hoverEvent, 'click-event':clickEvent, 'draw-event':drawEvent,
'enter-event':enterEvent, 'leave-event':leaveEvent, 'zbuffer-offset':zbufferOffset,
'hitable':hitable, 'state':globals.hitState, 'eventInfo':eventInfo,
'hitable':hitable, 'state':globals.hitState, 'eventInfo':eventInfo, 'advancedHit': advancedHit,
'lod':(globals.autoLod ? null : globals.tileLod) }, [labelData.vertexBuffer.buffer, labelData.originBuffer.buffer, labelData.texcoordsBuffer.buffer]);
}

Expand Down
3 changes: 2 additions & 1 deletion src/core/map/geodata-processor/worker-polygon.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ var processPolygonPass = function(polygon, lod, style, zIndex, eventInfo) {
var drawEvent = getLayerPropertyValue(style, 'draw-event', polygon, lod);
var enterEvent = getLayerPropertyValue(style, 'enter-event', polygon, lod);
var leaveEvent = getLayerPropertyValue(style, 'leave-event', polygon, lod);
var advancedHit = getLayerPropertyValue(style, 'advanced-hit', polygon, lod);

var zbufferOffset = getLayerPropertyValue(style, 'zbuffer-offset', polygon, lod);

Expand Down Expand Up @@ -110,7 +111,7 @@ var processPolygonPass = function(polygon, lod, style, zIndex, eventInfo) {
var messageData = {'command':'addRenderJob', 'type': 'flat-line', 'vertexBuffer': vertexBuffer,
'color':polygonColor, 'z-index':zIndex, 'center': center,
'hover-event':hoverEvent, 'click-event':clickEvent, 'draw-event':drawEvent,
'hitable':hitable, 'state':globals.hitState, 'eventInfo':eventInfo,
'hitable':hitable, 'state':globals.hitState, 'eventInfo':eventInfo, 'advancedHit': advancedHit,
'enter-event':enterEvent, 'leave-event':leaveEvent, 'zbuffer-offset':zbufferOffset,
'lod':(globals.autoLod ? null : globals.tileLod) };

Expand Down
14 changes: 8 additions & 6 deletions src/core/map/geodata-processor/worker-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ var validateLayerPropertyValue = function(layerId, key, value) {
case 'leave-event': return validateValue(layerId, key, value, 'boolean');
case 'click-event': return validateValue(layerId, key, value, 'boolean');
case 'draw-event': return validateValue(layerId, key, value, 'boolean');
case 'advanced-hit': return validateValue(layerId, key, value, 'boolean');

case 'visible': return validateValue(layerId, key, value, 'boolean');
case 'visibility': return validateValue(layerId, key, value, 'number', null, 0.0001, Number.MAXVALUE);
Expand Down Expand Up @@ -622,12 +623,13 @@ var getDefaultLayerPropertyValue = function(key) {
case 'z-index': return 0;
case 'zbuffer-offset': return [0,0,0];

case 'hover-event': return false;
case 'hover-layer': return '';
case 'enter-event': return false;
case 'leave-event': return false;
case 'click-event': return false;
case 'draw-event': return false;
case 'hover-event': return false;
case 'hover-layer': return '';
case 'enter-event': return false;
case 'leave-event': return false;
case 'click-event': return false;
case 'draw-event': return false;
case 'advanced-hit': return false;

case 'visible': return true;
case 'visibility': return 0;
Expand Down
35 changes: 20 additions & 15 deletions src/core/map/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -902,17 +902,24 @@ Map.prototype.hitTestGeoLayers = function(screenX, screenY, mode) {
return [null, false, []];
}

var res = this.renderer.hitTestGeoLayers(screenX, screenY, mode);
var relatedEvents;
var res = this.renderer.hitTestGeoLayers(screenX, screenY);
var relatedEvents, elementIndex;

if (res[0]) { //do we hit something?
//console.log(JSON.stringify([id, JSON.stringify(this.hoverFeatureList[id])]));

var id = (res[1]) + (res[2]<<8);
//var elementId = (res[3]) + (res[4]<<8);

var feature = this.hoverFeatureList[id];

if (feature[6]) { //advanced hit feature?
res = this.renderer.hitTestGeoLayers(screenX, screenY, true);

if (res[0]) { //do we hit something?
elementIndex = (res[1]) + (res[2]<<8);
}
}

if (mode == 'hover') {
this.lastHoverFeature = this.hoverFeature;
this.lastHoverFeatureId = this.hoverFeatureId;
Expand Down Expand Up @@ -940,19 +947,17 @@ Map.prototype.hitTestGeoLayers = function(screenX, screenY, mode) {
}

if (this.hoverFeature != null && this.hoverFeature[3]) {
return [this.hoverFeature, true, relatedEvents];
return [this.hoverFeature, true, relatedEvents, elementIndex];
} else {
return [null, false, relatedEvents];
return [null, false, relatedEvents, elementIndex];
}
}

if (mode == 'click') {
//this.hoverFeatureId = (this.hoverFeature != null) ? this.hoverFeature["id"] : null;

if (feature != null && feature[2]) {
return [feature, true, []];
return [feature, true, [], elementIndex];
} else {
return [null, false, []];
return [null, false, [], elementIndex];
}
}
} else {
Expand All @@ -973,7 +978,7 @@ Map.prototype.hitTestGeoLayers = function(screenX, screenY, mode) {
}
}

return [null, false, relatedEvents];
return [null, false, relatedEvents, elementIndex];
}
};

Expand Down Expand Up @@ -1111,7 +1116,7 @@ Map.prototype.update = function() {

if (result[1] && result[0] != null) {
this.core.callListener('geo-feature-hover', {'feature': result[0][0], 'canvas-coords':this.renderer.project2(result[0][1], this.camera.getMvpMatrix()),
'camera-coords':result[0][1], 'state': this.hoverEvent[3] }, true);
'camera-coords':result[0][1], 'state': this.hoverEvent[3], 'element': result[3]}, true);
}

var relatedEvents = result[2];
Expand All @@ -1123,12 +1128,12 @@ Map.prototype.update = function() {
switch(event[0]) {
case 'enter':
this.core.callListener('geo-feature-enter', {'feature': event[1][0], 'canvas-coords':this.renderer.project2(event[1][1], this.camera.getMvpMatrix()),
'camera-coords':event[1][1], 'state': this.hoverEvent[3] }, true);
'camera-coords':event[1][1], 'state': this.hoverEvent[3], 'element': result[3] }, true);
break;

case 'leave':
this.core.callListener('geo-feature-leave', {'feature':event[1][0], 'canvas-coords':this.renderer.project2(event[1][1], this.camera.getMvpMatrix()),
'camera-coords':event[1][1], 'state': this.hoverEvent[3] }, true);
'camera-coords':event[1][1], 'state': this.hoverEvent[3], 'element': result[3] }, true);
break;
}
}
Expand All @@ -1145,7 +1150,7 @@ Map.prototype.update = function() {

if (result[1] && result[0] != null) {
this.core.callListener('geo-feature-click', {'feature': result[0][0], 'canvas-coords':this.renderer.project2(result[0][1], this.camera.getMvpMatrix()),
'camera-coords':result[0][1], 'state': this.clickEvent[2] }, true);
'camera-coords':result[0][1], 'state': this.clickEvent[2], 'element': result[3] }, true);
}

this.clickEvent = null;
Expand Down
Loading

0 comments on commit e2b9d72

Please sign in to comment.