Поворот относительно плоскости экрана, кватернионы

13 апреля 2016 14:29
Добрый день!
Решил сделать возможность поворота объекта мышкой.
Никак не могу разобраться до конца в кватернионах
Я хочу, чтобы кубик вращался как бы относительно системы координат параллельных экрану. То есть я потащил мышу вправо - и кубик вправо и крутится, независимо от того как он сейчас повернут. Потянул вверх - крутится вверх. Сейчас пока добился того, что он крутится относительно своих локальных осей. При чем пробовал и кватернионами и "простым"
 m_quat.setAxisAngle(AXIS_Y, delta_x*0.01, quat_tmp);
	   m_quat.setAxisAngle(AXIS_X, -delta_y*0.01, quat_tmp3);
m_transform.get_rotation(_selected_object, quat_tmp2);
m_quat.multiply(quat_tmp, quat_tmp2, quat_tmp);
m_quat.multiply(quat_tmp, quat_tmp3, quat_tmp);
m_transform.set_rotation_v(_selected_object, quat_tmp);
   //m_transform.rotate_x_local(_selected_object, delta_y*0.01);   
   //m_transform.rotate_y_local(_selected_object, delta_x*0.01);


нашел какой то SPACE_WORLD, но не знаю, как применить
Подскажите, пожалуйста
Проект прикрепилproject.zip
Дорогу осилит идущий
13 апреля 2016 15:46
Добрый день!

Навскидку похоже что вам нужно домножить реузльтирующий кватернион слева на кватернион текущего положения камеры


Команда Blend4Web - разработчик
Twitter
LinkedIn
13 апреля 2016 15:47
Как вариант помести объект в пустышку и вращай её в пределах одной оси, а объект в пределах другой оси.
Не, не так, извиняюсь…
Не стой, где попало… Попадет еще раз.
http://naviris.ru/
13 апреля 2016 16:04

Навскидку похоже что вам нужно домножить реузльтирующий кватернион слева на кватернион текущего положения камеры
Если я правильно понял….
 var cam = m_scenes.get_active_camera();
	   m_transform.get_rotation(cam, quat_cam);
	   
	   m_quat.setAxisAngle(AXIS_Y, delta_x*0.01, quat_tmp);
	   m_quat.setAxisAngle(AXIS_X, -delta_y*0.01, quat_tmp3);
m_transform.get_rotation(_selected_object, quat_tmp2);
m_quat.multiply(quat_tmp, quat_tmp2, quat_tmp);
m_quat.multiply(quat_tmp, quat_tmp3, quat_tmp);
m_quat.multiply(quat_tmp, quat_cam, quat_tmp);
m_transform.set_rotation_v(_selected_object, quat_tmp);

но стало еще хуже… теперь его колбасит безбожно….
Дорогу осилит идущий
13 апреля 2016 16:06

Ответ на сообщение пользователя Кирилл
Не, не так, извиняюсь… frowning
а я только начал вникать
Дорогу осилит идущий
13 апреля 2016 16:26
Да, пардон.
Сейчас покопаюсь повнимательнее
Команда Blend4Web - разработчик
Twitter
LinkedIn
13 апреля 2016 17:48
Итак
Наиболее прозрачный вариант решения, на мой взгляд:
var cam = m_scenes.get_active_camera();
       m_transform.get_rotation(cam, quat_cam);

       //получаем глобальные координат для осей X и Y
       //из локального пространства координат камеры  
       //вокруг этих векторов далее и будет происходить вращение 
       m_util.quat_to_dir(quat_cam, AXIS_X, CAM_X);
       m_util.quat_to_dir(quat_cam, AXIS_Y, CAM_Y);
       
       //получаем кватернионы вращения вокруг "глобальных" осей
       m_quat.setAxisAngle(CAM_Y, delta_x*0.01, quat_Y);
       m_quat.setAxisAngle(CAM_X, -delta_y*0.01, quat_X);

m_transform.get_rotation(_selected_object, quat_obj);

//вращаем наш объект в глобальной системе координат
//порядок операндов важен! в противном случае вращение будет происходить в локальной системе объекта
m_quat.multiply(quat_X, quat_obj, quat_obj);
m_quat.multiply(quat_Y, quat_obj, quat_obj);
m_transform.set_rotation_v(_selected_object, quat_obj);


Обновленный архив с проектом прикрепил
Команда Blend4Web - разработчик
Twitter
LinkedIn
13 апреля 2016 18:16
Спасибо. вверх и вниз стало работать лучше, а вот вправо-влево - хуже… он как бы "качается" как на качелях. получается непредсказуемо крутится…
Наверно стоит сказать, что это будет что-то типа этого
То есть игрок должен получить ожидаемое вращение
Дорогу осилит идущий
13 апреля 2016 18:34
Я хочу, чтобы кубик вращался как бы относительно системы координат параллельных экрану.
В данном примере я настроил вращение полностью в системе координат камеры.

Спасибо. вверх и вниз стало работать лучше, а вот вправо-влево - хуже… он как бы "качается" как на качелях. получается непредсказуемо крутится…
Наверно стоит сказать, что это будет что-то типа этого
Вращение по горизонтали можно оставить относительно локальной системы координат кубика, для подобной игры мне такой вариант управления видится весьма интуитивным .

Для этого в вызове функции умножения на quat_Y небходимо поменять операнды местами:
//поворот в локальной системе координат объекта
m_quat.multiply(quat_obj, quat_Y, quat_obj);
Команда Blend4Web - разработчик
Twitter
LinkedIn
13 апреля 2016 19:05
Такой вариант мне нравится больше :)
var cam = m_scenes.get_active_camera();
	   m_transform.get_rotation(cam, quat_cam);
	   //получаем направляющие векторы в глобальной системе координат для осей X и Y из локального пространства координат камеры  
       //вокруг этих векторов далее и будет происходить вращение 
       m_util.quat_to_dir(quat_cam, AXIS_X, CAM_X);
       m_util.quat_to_dir(quat_cam, AXIS_Y, CAM_Y);
	   
	    //получаем кватернионы вращения вокруг "глобальны" осей
       m_quat.setAxisAngle(AXIS_Y, delta_x*0.01, quat_Y);
       m_quat.setAxisAngle(CAM_X, delta_y*0.01, quat_X);

m_transform.get_rotation(_selected_object, quat_obj);

//вращаем наш объект в глобальной системе координат
//порядок операндов важен! в противном случае вращение будет происходить в локальной системе объекта
m_quat.multiply(quat_X, quat_obj, quat_obj);
m_quat.multiply(quat_Y, quat_obj, quat_obj);
m_transform.set_rotation_v(_selected_object, quat_obj);

Я оставил по горизонтали как у меня было
m_quat.setAxisAngle(AXIS_Y, delta_x*0.01, quat_Y);
, а по вертикали - как Вы посоветовали.
Вроде то, что я хотел, не знаю как потом будет по геймплею, но это уже увижу когда будет чем играть
Спасибо еще раз
Дорогу осилит идущий
 
Пожалуйста, зарегистрируйтесь или войдите под своей учетной записью , чтобы оставлять сообщения.