Отслеживание родительских и дочерних целей three.js

Итак, вот вопрос вектора, матрицы, вращения, кватерниона для мастеров three.js!

У меня есть родительский объект в position(0,0,275) с direction(0,0,-1), + y вверх и rotation(0,0,0).

К родительскому объекту прикреплен дочерний объект с отношением:

 rel_position(.5, 0, 0)
 rel_rotation(0, 0, 0)

У меня также есть цель в сцене:

 position(0, 100, 0)

Рассмотрим корабль (родительский) с тангажом, рысканием и креном. Имеет башню (дочернюю) с угловой скоростью и рысканием. Турель должна сопровождать цель с заданной скоростью вращения (рад / с).

Я потратил 5 дней, пытаясь найти правильный алгоритм отслеживания. Лучшее, что я могу сделать, это удалить функцию matrixAutoUpdate для родительского и дочернего элементов, обновляя матрицу вручную. Затем используйте child.matrixWorld для создания матриц или кватернионов вращения для текущего дочернего вращения. Затем я могу создать вторичный Object3D, который смотрит на цель из дочерней позиции. Я могу понять разницу между дочерним и второстепенным Object3D и измерить кватернион на основе рад / с. Однако, когда я добавляю рулон к родительскому элементу или цель поворачивается за пределами октанта (+, +, +), происходит сбой вычислений дочернего вращения (или кватерниона), вызывая дикие повороты.

Любое направление в алгоритме отслеживания дочернего Object3D было бы безмерно оценено. Ваши усилия будут указаны в моем следующем проекте.

Спасибо за уделенное время!


person Jacob Kizzee    schedule 27.03.2013    source источник


Ответы (2)


Вот и ответ! @Stemkoski, спасибо за направление. Я применил аналогичный подход к окончательному решению, которое обнаружилось вчера. Это немного требует вычислительной мощности из-за инвертирования матрицы, но работает хорошо. Сначала создайте новую матрицу следующим образом:

var m = new THREE.Matrix4().getInverse(parent.matrix).multiply(target.matrix);  

Это поворачивает опорный кадр оси XYZ к новым координатам X'Y'Z 'на основе поворота родительского объекта. Результатом является матрица Object3D цели в опорном кадре X'Y'Z '. Теперь, создав новый Vector3 из матрицы m, мы можем получить относительное положение, используя:

var rel_pos = new THREE.Vector3().getPositionFromMatrix(m, 'XYZ');

Теперь создайте объект Faux, чтобы смотреть прямо на цель с позиции ребенка (турели).

var child_faux = new THREE.Object3D();  //can be created outside the loop
child_faux.position.copy(child.position);   //copy the child local position
child_faux.lookAt(rel_pos);     //look at the target 
child_faux.updateMatrix();     //Update the Matrix4 element for use in a second

Наконец, установив child_fuax для просмотра объекта, мы автоматически установили child_faux.rotation. Мы можем получить относительное вращение между текущим child.rotation и child_faux.rotation, используя следующее:

var diff = turret_target.rotation.sub(turret.rotation);

Отсюда мы можем установить простой алгоритм для поворота турели (+ или -) (x и y) до тех пор, пока разница (x и y) не станет равной 0.

var trackrate = .2 * delta;
var diff = turret_target.rotation.sub(turret.rotation);
turret.rotation.x += diff.x/Math.abs(diff.x) * trackrate;
turret.rotation.y += diff.y / Math.abs(diff.y) * trackrate;
turret.updateMatrix();

Вот и все ... Алгоритм отслеживания цели для дочернего объекта, повернутого в родительской группе! Спасибо за прочтение!

person Jacob Kizzee    schedule 28.03.2013

Возможно, сработает какая-то комбинация методов lookAt и worldToLocal? Поскольку вам нужно преобразовать положение целевого объекта в локальные координаты турели, а затем соответствующим образом изменить поворот турели, как насчет этого:

turret.lookAt(  turret.worldToLocal( target.position.clone() )  )
person Lee Stemkoski    schedule 28.03.2013
comment
Получите предложение! Я применил аналогичный подход к окончательному решению, которое обнаружилось вчера. Я попробую ваш код и посмотрю, смогу ли я реализовать вариант, потому что он более элегантен, чем мое решение. См. ниже! - person Jacob Kizzee; 28.03.2013