Форум

Детекция движения камеры (изменения вьюпорта)

02 ноября 2016 16:29
Вроде бы и просто, не не выходит каменный цветок.
Задача в том, чтобы вызывать определенную функцию при изменении вида 3Dканваса.
Справедливо предположил, что при статичной сцене такое может происходить только в случае движения камеры. У меня Target камера.
Подсоединил
var m_cam = b4w.require("camera_anim");

запускаю вращение камеры
 m_cam.auto_rotate(0.1);

Камера вращается вокруг бокса (канвас меняется)
Пишу консольный вывод
console.log(m_cam.is_moving(),m_cam.is_rotating());


Консоль выводит (false, false). Двигаю\ротирую камеру мышкой - по прежнему false.

Как правильно детектить изменение канваса (может не через эти переменные), и почему в моём случае не работают детекции перемещения камеры?
(ну, как бы можно приравнять камеру к объекту и мониторить её углы и позицию, но почему не работает стандартная конструкция?)

Upd:
Засунул считывание углов камеры в
set_render_callback
, однако не уверен, что это оптимальный по производительности подход. Если экран статичен, то функция считывания углов всё равно вызывается.
03 ноября 2016 10:32
Справедливо предположил, что при статичной сцене такое может происходить только в случае движения камеры. У меня Target камера.
можно использовать спец. сенсор на движение объекта, подробности здесь: ссылка

console.log(m_cam.is_moving(),m_cam.is_rotating());
это не очень хорошие очень специфические функции, которые детектят, работают ли на данный момент методы move_camera_to_point и rotate_camera из того же модуля; обновим описание в документации, чтобы было понятнее

P.S. вы правы, set_render_callback менее оптимальный
03 ноября 2016 11:39
можно использовать спец. сенсор на движение объекта, подробности здесь: ссылка
Разобрался, спасибо!
Из особенностей отмечу параметр чувствительности сенсора. Если поставить его слишком маленький (0.1-0.001) то после остановки камеры он срабатывает еще около секунды-двух ( Видимо, детектится внутренняя интерполяция камеры возле точки остановки. ) , а если ставить там дефолтную величину (1) то не срабатывает на мелкий драг (медленное перемещение).Но всё ж лучше, чем сетрендерколбек. Продолжу ковыряться.
03 ноября 2016 11:56
Видимо, детектится внутренняя интерполяция камеры возле точки остановки.
Можно уменьшить коэффициент сглаживания, но тогда движения станут более резкими. Впрочем, если камеру будет двигать не юзер, а, например, скриптом через API или анимацией, то так заметно не будет.

set_camera_smooth_factor, get_camera_smooth_factor
03 ноября 2016 12:02
Можно уменьшить коэффициент сглаживания, но тогда движения станут более резкими. Впрочем, если камеру будет двигать не юзер, а, например, скриптом через API или анимацией, то так заметно не будет.
Понятно. Но, думаю 20-30 лишних вызовов колбека не создадут сильной нагрузки. Если речь зайдет о хардкорной оптимизации, тогда уже посмотрим.
04 ноября 2016 21:01
Так, а еще один вопрос по сенсорам.
Благополучно сделал и эксплуатирую сенсор движения камеры.
var move_sensor = m_controls.create_motion_sensor(camobj, 0.2, 0.2);
.....
function my_function() {
       var cam_move_cb = function () {
       //тело функции
       }
m_controls.create_sensor_manifold(camobj, "CAM_MOVE", m_controls.CT_POSITIVE, [move_sensor], function (s) {return s[0]}, cam_move_cb);
}
....
my_function();


Теперь появилась задача "выполнить другую функцию, если камера не двигается 10 секунд". Как обычно 2 варианта
1. Сетрендер колбек, проверяем координаты камеры, если в течении 10 секунд ничего не происходит (get_timeline()) - запускаем функцию.
2. Сенсоры.
Думал использовать тот же сенсор, т.к в руководстве написано
"Create a motion sensor. The sensor's value is 1 if the object is in motion. "
Ага, думаю буду проверять свою переменную move_sensor, ан нет, она не 0 и не 1 ,а целый набор параметров.

Нашел сенсор create_timeline_sensor()
Вроде тоже подходит.

Вопрос собственно в том, как оптимальней справиться с задачей?
07 ноября 2016 10:57
"Create a motion sensor. The sensor's value is 1 if the object is in motion. "
Ага, думаю буду проверять свою переменную move_sensor, ан нет, она не 0 и не 1 ,а целый набор параметров.
это сам объект-сенсор, а надо использовать метод get_sensor_value

Вопрос собственно в том, как оптимальней справиться с задачей?
лучше, думаю, использовать таймер-сенсор: create_timer_sensor
07 ноября 2016 11:40
это сам объект-сенсор, а надо использовать метод get_sensor_value
Виноват, протупил.

лучше, думаю, использовать таймер-сенсор: create_timer_sensor
Смогу попробовать протестировать вечером, но сразу замечание (ну или мысли вслух).
А я правильно понимаю, что рекомендовав create_timer_sensor вы подразумевали их (сенсор движения камеры и сенсор таймера) завязку в одну систему? Ну, т.е. стартовать сенсор таймера после того как сенсор камеры не детектит движение? Просто выполнять сенсор таймера каждые например 10 секунд идеологически неправильно, его должна побуждать камера.

Получается в этом случае (связка) он нужен просто для отсчета времени внутри приложения? Я к тому, что а не из пушки ли по воробьям мы стреляем ,используя сенсор для отсчета времени?
07 ноября 2016 12:09
А, ну да, тут же главная проблема отследить момент, когда камера перестанет двигаться. А так-то можно и обычный setTimeout использовать.

Надо поменять тип с m_controls.CT_POSITIVE на m_controls.CT_CONTINUOUS. Принцип здесь хорошо описан: ссылка.
В cam_move_cb 3-им параметром придет пульс, если он станет -1, то камера остановилась и можно запускать setTimeout, если 1 - то clearTimeout.
 
Пожалуйста, зарегистрируйтесь или войдите под своей учетной записью , чтобы оставлять сообщения.