Пытаюсь написать систему снарядов используя спецэффекты и новые нативки. SetSpecialEffectOrientation судя по всему использует углы эйлера, причем направлением "верх" для них является вовсе не верх а "лево" (вроде бы) относительно стандартной игровой камеры. Вот сижу и пытаюсь понять каким образом можно заставит эффект "смотреть" в определенную точку пространства. Обычно ориентация dummy юнита задается двумя углами: поворотом (в плоскости земли) и углом атаки, потому что эти параметры легко посчитать. Но я не могу понять как их конвертировать в yaw, pitch и roll. Надеюсь на помощь.
Приложил карту с моими попытками. Изначально модель стрелки направлена вниз чтобы не делать поправок на поворот. В чат вводить угол атаки (наклона к земле) в градусах. От 0 до 45 все более менее (хотя стрелка то обгоняет то отстает от эффекта по контуру), в при угле больше 45 градусов появляются странные движения.
Приложил карту с моими попытками. Изначально модель стрелки направлена вниз чтобы не делать поправок на поворот. В чат вводить угол атаки (наклона к земле) в градусах. От 0 до 45 все более менее (хотя стрелка то обгоняет то отстает от эффекта по контуру), в при угле больше 45 градусов появляются странные движения.
Принятый ответ
Ах, я понял чего ты хочешь конкретно сейчас. Чтобы модель смотрела в камеру, словно на экране выбора персонажа? В таком случае ситуация немного упрощается.
Нам больше не нужно хранить текущую матрицу поворота эффекта, ведь мы не производим ее вращение, вместо этого мы высчитывает всю необходимую ориентацию из положения камеры и самого эффекта. Подход, в целом, остается прежним, но для поиска осей ориентации мы теперь будем использовать некоторый вспомогательный вектор, чье направление совпадает с направлением глобальной оси Z, и путем векторного произведения этого вспомогательного вектора на вектор оси X эффекта (получаемый как и прежде p2 - p1) мы получаем вектор ориентации эффекта Y, а векторное произведение X на Y нам даст ось Z эффекта.
Нам больше не нужно хранить текущую матрицу поворота эффекта, ведь мы не производим ее вращение, вместо этого мы высчитывает всю необходимую ориентацию из положения камеры и самого эффекта. Подход, в целом, остается прежним, но для поиска осей ориентации мы теперь будем использовать некоторый вспомогательный вектор, чье направление совпадает с направлением глобальной оси Z, и путем векторного произведения этого вспомогательного вектора на вектор оси X эффекта (получаемый как и прежде p2 - p1) мы получаем вектор ориентации эффекта Y, а векторное произведение X на Y нам даст ось Z эффекта.
Весь процесс можно разжевать на множество абзацев, но делать этого нет смысла. Я проще скину твою карту с новым вариантом.
Тем не менее, я вижу некоторое непонимание темы и потому считаю должным указать на некоторые ошибки в твоем прошлом коде
Код
private function RotationMatrixToEuler takes MATRIX3 R returns VECTOR3
local real x
local real y
local real z
local real sy = SquareRoot(R.m11 * R.m11 + R.m21 * R.m21)
local boolean singular = sy < .000001 or sy == 0 // If
if not singular then
set x = Atan2(R.m32 , R.m33)
set y = Atan2(-R.m31, sy)
set z = Atan2(R.m21, R.m11)
else
set x = Atan2(-R.m23, R.m22)
set y = Atan2(-R.m31, sy)
set z = 0
endif
return VECTOR3.New_1(x, y, z)
endfunction
Я не понимаю, как работает эта функция. В моем понимании, преобразование матрицы поворота в углы Эйлера происходит за счет обратного преобразования. То есть, чтобы преобразовать матрицу в Эйлер, необходимо знать как преобразуется Эйлер в матрицу, поскольку это обратные друг другу процессы. В новом примере я ее переписал.
Код
set rotation.m11 = X.x
set rotation.m12 = X.y
set rotation.m13 = X.z
set rotation.m21 = Y.x
set rotation.m22 = Y.y
set rotation.m23 = Y.z
set rotation.m31 = Z.x
set rotation.m32 = Z.y
set rotation.m33 = Z.z
Здесь идет неверное назначение параметров матрицы. Дело в том, что матрица записывается следующим образом (из readme библиотеки Math)
m11 m12 m13
m21 m22 m23
m31 m32 m33
При этом, оси записываются слева направо, столбиками, то есть , ось X здесь, это m11, m21 и m31. Следовательно верной записью будет
Код
set rotation.m11 = X.x
set rotation.m21 = X.y
set rotation.m31 = X.z
set rotation.m12 = Y.x
set rotation.m22 = Y.y
set rotation.m32 = Y.z
set rotation.m13 = Z.x
set rotation.m23 = Z.y
set rotation.m33 = Z.z
И самая ложная строка
set rotation = MATRIX3.New_0()
Это создаст нулевую матрицу, то есть матрицу, все значения которой - нули. Базовая же матрица поворота, это единичная матрица, то есть матрица, чья главная диагональ состоит из единиц, а все остальное - нули.
Но это просто заметки, в текущей версии этих участков кода больше нет.
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован ledoed
чтобы вектора в радианы перевести над нормализовать
пример вектор(40,500,12)
длина = квадратный корень из(40^2+500^2+12^2)
нормализованый = вектор/длина - смори чтобы длина не была 0
Отредактирован Drynwhyl
ledoed: я использовал такой способ но в таком случае параметр roll который этот вектор не характеризует принимает странные значения и вращает объект совершенно непредсказуемым образом.
Прикрепил файл карты.
Скажем что p1, это точка положения эффекта, а p2, это точка наблюдения. Операцией (p2 - p1) ты получишь вектор, назовем его v1, направленный из точки p1 к точке p2. Нормализуя полученный вектор v1 ты получишь ось X матрицы поворота искомой ориентации твоего эффекта. Исходя из текущей ориентации объекта, тебе нужно получить вектор оси X текущей матрицы поворта. Векторное произведение вектора v1 и текущей оси X объекта тебе даст вектор v2, перпендикулярный вектору v1. Нормализуя вектор v2 ты получишь ось Z новой матрицы поворта. Векторное произведение векторов v1 и v2 даст вектор v3, перпендикулярный им обоим, а именно - ось Y матрицы поворота искомой ориентации. Таким образом вектора v1, v2 и v3 станут матрицей поворта искомой ориентации.
Остается преобразовать полученную матрицу в углы Эйлера и передать полученные значения эффекту.
Отредактирован ledoed
попробуй потестить углы до 90 градусов
карту проверить не смогу вара последнего нет
а черт не то говорю, 360 градусов в радианах 6,28