Inverted eye camera rotation

28 January 2016 17:10
We have not been able to find a way to invert the rotation of the eye camera in order to simulate the classic dragging behaviour of mobile devices (looking at the environment as into a photosphere or similar)
So we came up with this solution by editing the Camera.js code for our needs and by recompiling the engine…
The affected code portion in the B4W 15.11 is as follows:
exports.rotate_eye_camera = rotate_eye_camera;
function rotate_eye_camera(obj, phi, theta, phi_is_abs, theta_is_abs) {
    var render = obj.render;

    // prepare delta angles
    var d_phi = phi;
    var d_theta = theta;
    if (phi_is_abs || theta_is_abs) {
        var curr_angles = get_camera_angles(obj, _vec2_tmp2);
        if (phi_is_abs)
            d_phi = -(phi - curr_angles[0]);
        if (theta_is_abs)
            d_theta = -(theta - curr_angles[1]);

    if (d_phi || d_theta) {
        var rot_quat = m_quat.identity(_quat4_tmp);

        if (d_phi) {
            var quat_phi = m_quat.setAxisAngle(m_util.AXIS_Y, -d_phi/2, _quat4_tmp2);
            m_quat.multiply(rot_quat, quat_phi, rot_quat);

        if (d_theta) {
            var x_world_cam = m_util.quat_to_dir(render.quat, m_util.AXIS_X, _vec3_tmp);
            var quat_theta = m_quat.setAxisAngle(x_world_cam, -d_theta/2, _quat4_tmp2);
            // NOTE: render.quat->x_world_cam->quat_theta->render.quat leads to 
            // error accumulation if quat_theta is not normalized
            m_quat.normalize(quat_theta, quat_theta);
            m_quat.multiply(rot_quat, quat_theta, rot_quat);

        m_quat.multiply(rot_quat, render.quat, render.quat);

It would be nice if you cold implement something similar or better and add a checkbox in the addon to enable this feature

Thanks a lot
Cineca VistLab team
28 January 2016 18:49

I think we will make some additions to the mouse.js addon. To its request_pointerlock method to be precise.

For now, you can use the following construction without modifying engine modules:
    var canvas_elem = m_cont.get_canvas();
    var x_prev = null;
    var y_prev = null;

    function touch_start_cb(e) {
        var touches = e.targetTouches;

        if (touches.length === 0)

        var touch = touches[0];
        var x = touch.clientX;
        var y = touch.clientY;

        x_prev = x;
        y_prev = y;

    function touch_move_cb (e) {
        var touches = e.targetTouches;

        if (touches.length === 0)

        var touch = touches[0];
        var x = touch.clientX;
        var y = touch.clientY;

        var d_x = x - x_prev;
        var d_y = y - y_prev;

        var character = m_scs.get_first_character();
        var camera    = m_scs.get_active_camera();
        m_cam.eye_rotate(camera, d_x / 100, d_y / 100);
        if (character) {
            var angles = m_cam.get_camera_angles_char(camera, _vec2_tmp);
            m_phy.set_character_rotation(character, angles[0], angles[1]);
        x_prev = x;
        y_prev = y;
    canvas_elem.addEventListener("touchmove", touch_move_cb, false);
    canvas_elem.addEventListener("touchstart", touch_start_cb, false);
02 February 2016 13:09
Thanks a lot! that's perfect!
Please register or log in to leave a reply.