/
Picking.js
114 lines (89 loc) · 2.81 KB
/
Picking.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// TODO: perhaps render only clicked area
render.Picking = {
idMapping: [null],
viewportSize: 512,
init: function() {
this.shader = new GLX.Shader({
vertexShader: Shaders.picking.vertex,
fragmentShader: Shaders.picking.fragment,
shaderName: 'picking shader',
attributes: ['aPosition', 'aId', 'aFilter'],
uniforms: [
'uModelMatrix',
'uMatrix',
'uFogRadius',
'uTime'
]
});
this.framebuffer = new GLX.Framebuffer(this.viewportSize, this.viewportSize);
},
render: function(framebufferSize) {
var
shader = this.shader,
framebuffer = this.framebuffer;
framebuffer.setSize(framebufferSize[0], framebufferSize[1]);
shader.enable();
framebuffer.enable();
GL.viewport(0, 0, framebufferSize[0], framebufferSize[1]);
GL.clearColor(0, 0, 0, 1);
GL.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT);
shader.setUniforms([
['uFogRadius', '1f', render.fogDistance],
['uTime', '1f', Filter.getTime()]
]);
var
dataItems = data.Index.items,
item,
modelMatrix;
for (var i = 0, il = dataItems.length; i<il; i++) {
item = dataItems[i];
if (APP.zoom < item.minZoom || APP.zoom > item.maxZoom) {
continue;
}
if (!(modelMatrix = item.getMatrix())) {
continue;
}
shader.setUniformMatrices([
['uModelMatrix', '4fv', modelMatrix.data],
['uMatrix', '4fv', GLX.Matrix.multiply(modelMatrix, render.viewProjMatrix)]
]);
shader.bindBuffer(item.vertexBuffer, 'aPosition');
shader.bindBuffer(item.idBuffer, 'aId');
shader.bindBuffer(item.filterBuffer, 'aFilter');
GL.drawArrays(GL.TRIANGLES, 0, item.vertexBuffer.numItems);
}
this.shader.disable();
this.framebuffer.disable();
GL.viewport(0, 0, APP.width, APP.height);
},
// TODO: throttle calls
getTarget: function(x, y, callback) {
requestAnimationFrame(function() {
this.render( [this.viewportSize, this.viewportSize] );
x = x/APP.width *this.viewportSize <<0;
y = y/APP.height*this.viewportSize <<0;
this.framebuffer.enable();
var imageData = this.framebuffer.getPixel(x, this.viewportSize - 1 - y);
this.framebuffer.disable();
if (imageData === undefined) {
callback(undefined);
return;
}
var color = imageData[0] | (imageData[1]<<8) | (imageData[2]<<16);
callback(this.idMapping[color]);
}.bind(this));
},
idToColor: function(id) {
var index = this.idMapping.indexOf(id);
if (index === -1) {
this.idMapping.push(id);
index = this.idMapping.length-1;
}
return [
( index & 0xff) / 255,
((index >> 8) & 0xff) / 255,
((index >> 16) & 0xff) / 255
];
},
destroy: function() {}
};