Управление несколькими камерами с одинаковыми элементами управления
У меня есть две разные сцены из трех сцен, каждая из которых имеет свою собственную камеру. Я могу управлять каждой камерой индивидуально с помощью соответствующего экземпляра TrackballControls
.
Есть ли надежный способ "блокировать" или "связывать" эти элементы управления вместе, так что манипулирование ими приводит к тому, что одна и та же камера перемещается в другую? Мой текущий подход состоит в том, чтобы добавить слушателей change
к элементам управления и обновить обе камеры, чтобы либо сменить, но это не очень аккуратно, так как, как один, оба элемента управления могут меняться сразу (из-за увлажнения).
Ответы
Ответ 1
Я считаю, что он должен работать, если вы установите матрицы второй камеры в значения первых и отключите автоматическую матрицу-обновления обеих камер:
camera2.matrix = camera1.matrix;
camera2.projectionMatrix = camera1.projectionMatrix;
camera1.matrixAutoUpdate = false;
camera2.matrixAutoUpdate = false;
Но теперь вам нужно обновить матрицу вручную в своем рендере:
camera1.updateMatrix();
Этот вызов будет принимать значения для position
, rotation
и scale
(которые были обновлены элементами управления) и скомпоновать их в camera1.matrix
, которые для каждого присваивания ранее также используются в качестве матрицы для вторая камера.
Тем не менее, это немного взломанно и может привести к разным проблемам. Я лично предпочел бы более явный подход, который вы уже реализовали.
Вопрос: почему вы даже используете два экземпляра камеры и управления? Пока камера не добавляется в сцену, вы можете просто отображать обе сцены с использованием одной и той же камеры.
Ответ 2
Можно ли использовать шаблоны проектирования Observer или Publisher для управления этими объектами?
Кажется, что вы управляете камерами с помощью элемента управления. Вы можете создать объект с одним и тем же интерфейсом управления, но когда вы передаете команду объекту, он повторяет ту же самую команду для каждой из подписанных или зарегистрированных камер.
/* код psuedo: es6 */
class MasterControl {
constructor(){
this.camera_bindings = [];
}
control_action1(){
for( var camera of this.camera_bindings ){
camera.control_action1();
}
}
control_action2( arg1, arg2 ){
for( var camera of this.camera_bindings ){
camera.control_action2( arg1, arg2 );
}
}
bindCamera( camera ){
if( this.camera_bindings.indexOf( camera ) === -1 ){
this.camera_bindings.push( camera );
}
}
}
var master = new MasterControl();
master.bindCamera( camera1 );
master.bindCamera( camera2 );
master.bindCamera( camera3 );
let STEP_X = -5;
let STEP_Y = 10;
//the following command will send the command to all three cameras
master.control_action2( STEP_X, STEP_Y );
Эта привязка создается самостоятельно, а не использует собственные функции three.js, но ее легко реализовать и быстро заставить вас функционировать.
Примечание. Я написал свой psuedocode в es6, потому что он проще и удобнее в общении. Вы можете записать его в es5 или старше, но вы должны изменить определение класса на ряд определений функциональных объектов, которые создают главный объект и его функциональные возможности.