Поворот объекта в сторону другого

07 июня 2016 17:12
Подскажите, как реализовать этакий Look At.

Имеется объект A, который движется к объекту B. Нужно развернуть объект A так, чтобы он смотрел в сторону B. Движение и ротация выполняется без физики.

Прикол в том, что я это уже когда-то реализовывал, но хоть убей, не могу вспомнить как
Инди-разработчик игр, фанат Blender
http://prandgames.com
07 июня 2016 17:37
08 июня 2016 12:41
Оно то оно, но в моем случае не прокатывает.

В unity можно было бы так сделать:

var dir = target.position - transform.position;
var angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);

А как в b4w?
Инди-разработчик игр, фанат Blender
http://prandgames.com
08 июня 2016 15:48
Низнаю :) Копаться в примерах?
08 июня 2016 16:22
Хм. И потырить почти неоткуда :) Поиск по SDK дал, что в основном для камеры применяется (что и понятно). А в примерах, как приём не нашёл, только в составе всяких min.js. и в /apps-dev/code_snippets/scripts/gamepad.js Так что учись, как камеру поворачивают, мне кажется, любой объект также.
09 июня 2016 08:55
Выкладываю решение вопроса. Может быть кому-нибудь пригодится. В качестве основы взял исходники AI голема из Пятигора.

Задача. Поворот объекта A в сторону объекта Б в 2D пространстве (вид сверху в Blender).

 var cur_dir = new Float32Array(3);     
                var dir_to_dest =new Float32Array(3); 
                var cur_rot_q = new Float32Array(4);
                var new_rot_q =new Float32Array(4);
                
                var obj = m_scene.get_object_by_name("Player"); //объект А
                var objPos = m_trans.get_translation(obj);
                var destObj = m_scene.get_object_by_name("Target"); //объект Б
                var targetPos = m_trans.get_translation(destObj);

                m_trans.get_rotation(obj, cur_rot_q);
                m_vec3.transformQuat(m_util.AXIS_Z, cur_rot_q, cur_dir);
                m_vec3.subtract(objPos,targetPos, dir_to_dest);
                m_vec3.normalize(dir_to_dest, dir_to_dest);
                m_quat.rotationTo(cur_dir, dir_to_dest, new_rot_q);
                m_quat.multiply(new_rot_q, cur_rot_q, new_rot_q);
                var vec_dot = m_vec3.dot(cur_dir, dir_to_dest);
                vec_dot = vec_dot > 1? 1: vec_dot < -1? -1: vec_dot;
                var angle_to_turn = Math.acos(vec_dot);
                var angle_ratio   = Math.abs(angle_to_turn) / Math.PI;
                var slerp         = elapsed / angle_ratio * 1;//скорость разворота
                m_quat.slerp(cur_rot_q, new_rot_q, Math.min(slerp, 1), new_rot_q);
                m_trans.set_rotation_v(obj, new_rot_q);

Полагаю, что такие громоздкие вычисления лучше спрятать в API движка, а пользователю предоставить готовую функцию. Или это уже есть и я плохо искал?
Инди-разработчик игр, фанат Blender
http://prandgames.com
10 июня 2016 18:51
Или это уже есть и я плохо искал?

Такой функции действительно нет. append_track() поворачивает мгновенно и не подойдет, если нужна плавность. Плавно сработает track_to_target(), но она только для камеры.

Полагаю, что такие громоздкие вычисления лучше спрятать в API движка, а пользователю предоставить готовую функцию.
Этот функционал довольно специфичен, поэтому его место может быть только в каком-нибудь аддоне по аналогии с аддоном camera_anim, возможно, сделаем что-то подобное когда-нибудь - для пользователей было бы неплохо иметь такой модуль базовой процедурной анимации.
 
Пожалуйста, зарегистрируйтесь или войдите под своей учетной записью , чтобы оставлять сообщения.