2017-01-20 12 views
1

В моем приложении я пытаюсь сделать поворот группы объектов через Вращения, которые я получаю от API ориентации устройств.«Применение» или «выпекание» вращения в THREE.Group

В какой-то момент я хочу, чтобы калибровал поворот моего объекта, чтобы он выглядел в том же направлении, что и моя камера. (имеющие значения вращения (0,0,0)!)

Но так как я устанавливаю вращение объектов с помощью

var euler = new THREE.Euler(x, y, z, 'ZXY'); // angles come from Device Orientation 
this.object.setRotationFromEuler(euler); 

мой объект всегда принимает абсолютное вращение моего устройства. Для калибровки я хочу установить поворот в своей группе, а затем «применить» матрицу вращения к группе. Эффективно устанавливая значения вращения x, y, z в 0, поэтому я могу установить их снова с абсолютными значениями, но группа должна вращаться относительно калиброванного вращения.

Раньше я пробовал sth как this, но поскольку у меня в группе нет геометрии, это не сработает. Должен ли я проходить через каждый под-объект и применять поворот к каждой геометрии или есть ли способ установить состояние вращения как «базу» для группы?

Единственное другое решение, о котором я могу думать, это сохранить текущие значения вращения при калибровке запроса и всегда вращаться относительно них, но было бы неплохо, если бы был такой метод.

ответ

1

Есть три способа, которые приходят на ум.

Один - как вы уже сказали, вы можете применить калиброванное вращение ко всем геометриям в группе, но в этом случае это не звучит правильно, поскольку вы не калибруете сами модели.

Вы также упоминали следующий, который предназначен для корректировки значений ориентации устройства с некоторыми смещениями калибровки перед их применением к модели. Это может быть самый простой из вариантов и позволит вам добавлять другие вещи, такие как затухание и слияние датчиков (думаю, предсказание движения от ускорения) и тому подобное, прежде чем подавать значения в модель.

Последнее, что я могу придумать, это использовать другую группу, которая будет выполнять функцию калибровки и обновить ее при выполнении калибровки. Это может выглядеть примерно так:

var reference = new THREE.Group(); 
var model = new THREE.Group(); 

// your model goes here 
model.add(new THREE.Mesh(
    new THREE.BoxGeometry(1,1,1), 
    new THREE.MeshStandardMaterial() 
)); 

reference.add(model); 
scene.add(reference); 

// (not shown) model-rotation will always be updated with 
// unmodified device-orientation data. 

// for calibration, set rotation of the reference-group to the 
// inverse of the current global rotation of the model. 
// That way the overall rotation of the model should be zero for the 
// current value from device-orientation (using the world/global rotation 
// makes this repeatable regardless of previous calibration-values) 
function onCalibration() { 
    reference.quaternion 
     .copy(model.getWorldQuaternion()) 
     .inverse(); 
}