I need to read a block of pixels from the picking buffer to check the surrounding points for collisions, like in the picture below:
I am clicking on my canvas
at x
, y
- so I define a square region of, let say, 11x11 pixels, centered at cX
, cY
and then I read from the picking buffer just in one shot starting from x1
, y1
:
var w = 11, h = 11, cX = x, cY = cH - y, rc = ~~(0.5*w), x1 = cX - rc, y1 = cY + rc;
gl.readPixels(x1, y1, w, h, gl.RGBA, gl.UNSIGNED_BYTE, pickBuf);
Then, i am looping from the center of my buffer walking to the outside, following the red arrows, while checking for a positive response inside the picking buffer (collision found):
function readAt(i, pickBuf) {
return pickBuf[i] << 16 | pickBuf[i+1] << 8 | pickBuf[i+2];
}
var l = rc;
while(l--) {
/* Top-Left sector */
var r = rc+(rc-l), c = l, p = r*w + c, i = 4*p;
found = readAt(i, pickBuf) > 0;
/* Top-Right sector */
var r = rc+(rc-l), c = rc+(rc-l), p = r*w + c, i = 4*p;
found = readAt(i, pickBuf) > 0;
/* Bottom-Left sector */
var r = l, c = l, p = r*w + c, i = 4*p;
found = readAt(i, pickBuf) > 0;
/* Bottom-Right sector */
var r = l, c = rc+(rc-l), p = r*w + c, i = 4*p;
found = readAt(i, pickBuf) > 0;
}
The piece of code is working and I am able to pick a geometry, but now I believe I haven't understand correctly the whole coordinate system, because the collision result is always above and left of the point where it should be. Why this happens?
It seems to me that readPixels
should read the bytes starting from the bottom-left corner of the canvas
, to the top-right corner. Is that true, or I am missing something?
I am aware that the gl
coordinate system is Y-inverted against my canvas
, so I am defining the center of the picking buffer at cY = cH - y
and the Y starting point for the picking buffer at y1 = cY + rc
, but anyway this is giving me wrong results during my walk from the center to the outside of my picking square box. Where goes my interpretation of the coordinate system wrong?