Я использую Three.js, и мне интересно, как получить все объекты в данной области?Threejs - Как выбрать все объекты в области?
Например, получить все объекты, которые найдены в зеленом-квадрат:
Решение:
getEntitiesInSelection: function(x, z, width, height, inGroup) {
var self = this,
entitiesMap = [],
color = 0,
colors = [],
ids = [],
pickingGeometry = new THREE.Geometry(),
pickingMaterial = new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors }),
pickingScene = new THREE.Scene(),
pickingTexture = new THREE.WebGLRenderTarget(this._renderer.domElement.width, this._renderer.domElement.height),
cloneMesh,
entities = inGroup ?
engine.getObjectsByGroup(inGroup) : engine.getRegisteredEntities();
pickingTexture.generateMipmaps = false;
//Go over each entity, change its color into its ID
_.forEach(entities, function(entity) {
if(undefined == entity.threeRenderable) {
return ;
}
//Clone entity
cloneMesh = entity.threeRenderable.mesh().clone();
cloneMesh.material = entity.threeRenderable.mesh().material.clone();
cloneMesh.material.map = null;
cloneMesh.material.vertexColors = THREE.VertexColors;
cloneMesh.geometry = entity.threeRenderable.mesh().geometry.clone();
cloneMesh.position.copy(entity.threeRenderable.mesh().position);
cloneMesh.rotation.copy(entity.threeRenderable.mesh().rotation);
cloneMesh.scale.copy(entity.threeRenderable.mesh().scale);
//Cancel shadow
cloneMesh.castShadow = false;
cloneMesh.receiveShadow = false;
//Set color as entity ID
entitiesMap[color] = entity.id();
self._applyVertexColors(cloneMesh.geometry, new THREE.Color(color));
color++;
THREE.GeometryUtils.merge(pickingGeometry, cloneMesh);
});
pickingScene.add(new THREE.Mesh(pickingGeometry, pickingMaterial));
//render the picking scene off-screen
this._renderer.render(pickingScene, this._objs[this._mainCamera], pickingTexture);
var gl = this._renderer.getContext();
//read the pixel under the mouse from the texture
var pixelBuffer = new Uint8Array(4 * width * height);
gl.readPixels(x, this._renderer.domElement.height - z, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelBuffer);
//Convert RGB in the selected area back to color
for(var i=0; i<pixelBuffer.length; i+=4) {
if(0 == pixelBuffer[i] && 0 == pixelBuffer[i+1] && 0 == pixelBuffer[i+2] && 0 == pixelBuffer[i+3]) {
continue;
}
color = (pixelBuffer[i] << 16) | (pixelBuffer[i+1] << 8) | (pixelBuffer[i+2]);
colors.push(color);
}
colors = _.unique(colors);
//Convert colors to ids
_.forEach(colors, function(color) {
ids.push(entitiesMap[color]);
});
return ids;
}
Линия engine.getObjectsByGroup(inGroup) : engine.getRegisteredEntities();
просто возвращает массив сущностей, которые, в свою очередь, I итерации по объектам:
_.forEach(entities, function(entity) { ...
только лица, которые имеют свойство «threeRenderable» (объект) открыты, поэтому я игнорирую те, которые не имеют его:
if(undefined == entity.threeRenderable) {
return ;
}
тогда я сливаю клонированный сетку хозяйствующего субъекта с с pickingGeometry:
THREE.GeometryUtils.merge(pickingGeometry, cloneMesh);
в конце концов, я добавляю pickingGeometry к pickingScene:
pickingScene.add(new THREE.Mesh(pickingGeometry, pickingMaterial));
Затем я прочитал цвета выбранной области, и возвращает массив идентификаторов.
Вы можете проверить Node.js game engine, который я написал тогда.
Какой вид вы используете сейчас? См. Пример GPU-Picking. Вы можете отобразить пропуск с идентификаторами цвета и использовать readPixels для чтения всей информации о цвете в данной области, возвращая все идентификаторы цвета объекта в этом регионе. Это даст вам необходимую вам информацию. Не уверен в других возможностях с raycaster ... btw: выглядит здорово, что вы готовы;) – GuyGood
Я не уверен, как поможет GPU-сбор. в этом примере каждый куб визуализируется с другим цветом - таким образом, используя readPixel (который возвращает все пиксели/цвета в заданной области), вы можете «знать», на каком кубе щелкнул пользователь. WHILE Мне нужно, чтобы вернуть список объектов в данной области. – eldad87
Да, как вы сказали, readPixels возвращает все пиксели/цвета в данной области. Данная область является вашим прямоугольным выбором. Цвета - это ваши идентификаторы объекта.Используя вывод readPixels, вы можете оценить цвета и вернуть список объектов в данной области, что даст именно то, чего вы хотите достичь? Вам нужно всего лишь отобразить все идентификаторы объектов в фреймбуфере/текстуре. – GuyGood