Форум

Координаты клика по плоскости

30 июля 2015 11:44
Здравствуйте, хотел узнать есть ли функционал позволяющий определить координату плоскости по которой был произведен клик.
Нашел примерный функционал в https://www.blend4web.com/tutorials/examples/cartoon_interior/cartoon_interior.html. Там объект водится за текущей координатой мышки относительно плоскости(mousemove вместо click). Как я понял координаты (spawner_pos) берутся у объекта spawner, но что он из себя предстваляет я не пойму
30 июля 2015 14:45
Здравстуйте, функционал такой есть, их даже два.

1) Как это сделано в приложении cartoon_interior.html:
- по 2d координатам канваса рассчитывается направляющий вектор луча, выходящего из камеры:
var camera_ray = m_cam.calc_ray(cam, x, y, _vec3_tmp);

calc_ray

- затем ищется точка пересечения этого луча с заданной плоскостью (задается через нормаль):
var point = m_util.line_plane_intersect(FLOOR_PLANE_NORMAL, 0, cam_trans, camera_ray, _vec3_tmp2);


Вот выдержка из статьи:
Рассмотрим подробнее функцию line_plane_intersect():

var point = m_util.line_plane_intersect(FLOOR_PLANE_NORMAL, 0,
cam_trans, camera_ray, _vec3_tmp3);

Она служит для определения точки пересечения прямой и плоскости. Первые два параметра задают плоскость, а именно нормаль (использована константа FLOOR_PLANE_NORMAL) и расстояние от плоскости до центра координат (равно нулю). Эти значения были подобраны в соответствии с моделью комнаты. Также подаются координаты камеры в мировом пространстве (cam_trans) и направляющий вектор прямой (camera_ray).


2) С другой стороны можно воспользоваться возможностями физики движка как в демке "Ray Test" приложения Code Snippets:

    var from = new Float32Array(3);
    var to = new Float32Array(3);
    ...
    var ray_test_cb = function(id, hit_fract, obj_hit, hit_time, hit_pos, hit_norm) {...}

    var mouse_cb = function(e) {
        var x = e.clientX;
        var y = e.clientY;
        m_cam.calc_ray(m_scenes.get_active_camera(), x, y, to);

        m_vec3.scale(to, 100, to);
        var obj_src = m_scenes.get_active_camera();
        var id = m_phy.append_ray_test_ext(obj_src, from, to, "ANY",
                ray_test_cb, true, false, true, true);
    }


Здесь также рассчитывается луч, и далее создается тест на пересечение лучом препятствий (функция append_ray_test_ext). В коллбэк ray_test_cb должна прийти позиция в параметре hit_pos. Параметр "ANY" означает пересечение с любым объектом.
31 июля 2015 22:50
Спасибо, попробовал первый способ, все отлично работало пока не уменьшил экран до появления скрола. При скроле некорректно работает первый способ, добавил скрол в демке https://www.blend4web.com/tutorials/examples/cartoon_interior/cartoon_interior.html?v=20150731181610 , возникла аналогичная проблема(
Сделал подобные действия с Ray Test получил тот же результат.

Избавился от проблема переназначив координаты курсора
с
var x = m_mouse.get_coords_x(e);
var y = m_mouse.get_coords_y(e);

на
var x = e.pageX;
var y = e.pageY;
03 августа 2015 18:57
Спасибо, попробовал первый способ, все отлично работало пока не уменьшил экран до появления скрола.
Рад, что заработало, а случай со скроллом мы посмотрим на предмет багов.
17 августа 2015 18:45
В тему:
код целиком был вставлен из примера. Только пришлось заменить нормаль пересечения пола с [0, 1, 0] на [0, 0,1 ] для изменения плоскости пересечения. Объекты изначально уже в сцене. при активации (нажатии мышкой ) и попытке перетащить, объекты дергаются в центр экрана и оттуда начинают перетаскиваться. Даже если позиция объекта была изменена перетаскиванием, при следующей попытке перетащить он снова дергается в центр и оттуда перетаскивается.
А задача: таскать объект по вертикальной плоскости на всю ее ширину. Да еще и по сетке хотелось бы.
Коплю деньги на коммерческий B4W.
18 августа 2015 11:16

Ответ на сообщение пользователя Йеджи Заборовски
В тему:
код целиком был вставлен из примера. Только пришлось заменить нормаль пересечения пола с [0, 1, 0] на [0, 0,1 ] для изменения плоскости пересечения. Объекты изначально уже в сцене. при активации (нажатии мышкой ) и попытке перетащить, объекты дергаются в центр экрана и оттуда начинают перетаскиваться. Даже если позиция объекта была изменена перетаскиванием, при следующей попытке перетащить он снова дергается в центр и оттуда перетаскивается.
А задача: таскать объект по вертикальной плоскости на всю ее ширину. Да еще и по сетке хотелось бы.

Дергаться может, если сильно скачет точка пересечения луча и плоскости. Идеальным будет расположение плоскости перпендикулярно направлению взгляда камеры. Проверьте нормаль: [0,0,1] означает направление по -Y в блендере.
24 августа 2015 11:46

Избавился от проблема переназначив координаты курсора
с
var x = m_mouse.get_coords_x(e);
var y = m_mouse.get_coords_y(e);

на
var x = e.pageX;
var y = e.pageY;

Да, действительно, при получении координат canvas'а нужно учитывать скроллинг. Функции get_coords_x/y возвращают координаты clientX/Y, которые соответствуют текущему вьюпорту браузера и не берут в расчет скроллинг вообще. В вашем случае, как я понял, скроллится только окно браузера - для этого идеально подходят свойства pageX/Y.

Но есть и более сложные варианты расположения canvas'а, например, скроллинг внутри отдельных элементов страницы, смещение canvas'а относительно верхнего левого угла, изменение его позиции javascript'ом и т.д. Для этого в движке есть функционал по пересчету координат, как им пользоваться, описано в соответствующем разделе документации.
 
Пожалуйста, зарегистрируйтесь или войдите под своей учетной записью , чтобы оставлять сообщения.