Задача состоит в том, чтобы добавить инструмент выбора диапазона в приложение Dart WebGL. Инструмент будет использоваться для рисования прямоугольника над несколькими объектами путем перетаскивания мышью. Таким образом, несколько объектов могут быть выбраны/выделены одним действием пользователя. В настоящее время я использую gl.readPixels() для чтения цветов из внеэкранного буфера рендеринга. Проблема в том, что при полосовом выделении большой области gl.readPixels() выдает миллионы пикселей. Сканирование такого большого количества цветов тратит драгоценные секунды только на то, чтобы найти несколько объектов.
Пожалуйста, укажите, возможно, более быстрые методы для выбора нескольких объектов с помощью Dart + WebGL.
Для справки ниже я показываю текущую основную часть инструмента выбора полосы.
Uint8List _color = new Uint8List(4);
void bandSelection(int x, y, width, height, PickerShader picker, RenderingContext gl, bool shift) {
if (picker == null) {
err("bandSelection: picker not available");
return;
}
int size = 4 * width * height;
if (size > _color.length) {
_color = new Uint8List(size);
}
gl.bindFramebuffer(RenderingContext.FRAMEBUFFER, picker.framebuffer);
gl.readPixels(x, y, width, height, RenderingContext.RGBA, RenderingContext.UNSIGNED_BYTE, _color);
if (!shift) {
// shift is released
_selection.clear();
}
for (int i = 0; i < size; i += 4) {
if (_selection.length >= picker.numberOfInstances) {
// selected all available objects, no need to keep searching
break;
}
PickerInstance pi = picker.findInstanceByColor(_color[i], _color[i+1], _color[i+2]);
if (pi == null) {
continue;
}
_selection.add(pi);
}
debug("bandSelection: $_selection");
}
// findInstanceByColor is method from PickerShader
PickerInstance findInstanceByColor(int r, g, b) {
return colorHit(_instanceList, r, g, b);
}
PickerInstance colorHit(Iterable<Instance> list, int r,g,b) {
bool match(Instance i) {
Float32List f = i.pickColor;
return (255.0*f[0] - r.toDouble()).abs() < 1.0 &&
(255.0*f[1] - g.toDouble()).abs() < 1.0 &&
(255.0*f[2] - b.toDouble()).abs() < 1.0;
}
Instance pi;
try {
pi = list.firstWhere(match);
} catch (e) {
return null;
}
return pi as PickerInstance;
}