Three.js boids - улучшение обнаружения мыши с изменением положения камеры
Некоторое время я работал с примерами boids / flocks three.js, но и у canvas, и у webgl/shaders есть недостаток: событие mouseOver (которое "мешает" птицам и вызывает отталкивание) работает только тогда, когда camera.position = {x: 0, y: 0,: что угодно}.
Я попытался улучшить это в примере холста (проще для меня), отредактировав эту часть:
function onDocumentMouseMove( event ) {
var vector = new THREE.Vector3( event.clientX - SCREEN_WIDTH_HALF, - event.clientY + SCREEN_HEIGHT_HALF, 0 );
for ( var i = 0, il = boids.length; i < il; i++ ) {
boid = boids[ i ];
vector.z = boid.position.z;
boid.repulse( vector );
}
}
И пытается что-то вроде:
function onDocumentMouseMove( event ) {
var vector = new THREE.Vector3();
vector.x = event.clientX;
vector.y = - event.clientY;
vector.unproject(camera);
for ( var i = 0, il = boids.length; i < il; i++ ) {
boid = boids[ i ];
vector.z = boid.position.z;
boid.repulse( vector );
}
}
Но это не может работать, непроецированный вектор может использоваться только с Raycaster, чтобы найти объекты, пересекающие его путь. В нашем случае эффект отталкивания должен работать на расстоянии 150, согласно boid.repulse:
this.repulse = function ( target ) {
var distance = this.position.distanceTo( target );
if ( distance < 150 ) {
var steer = new THREE.Vector3();
steer.subVectors( this.position, target );
steer.multiplyScalar( 0.5 / distance );
_acceleration.add( steer );
}
}
Так что я застрял. Должен ли я найти способ расширить raycaster, чтобы он был похож на цилиндр шириной 150 для выбора мыши? Или есть способ отменить проекцию вектора, а затем повторно спроецировать его на плоскость, ближайшую к птице, чтобы рассчитать расстояние? (а как насчет производительности с 200+ птицами?)
Если решение может прийти только от шейдеров, не стесняйтесь сказать мне, чтобы создать другую тему.
Включено: пример jsfiddle of canvas с немного перемещенной камерой.