LCOV - code coverage report
Current view: top level - compositor - navigate.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 277 543 51.0 %
Date: 2021-04-29 23:48:07 Functions: 20 21 95.2 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2012
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / Scene Compositor sub-project
       9             :  *
      10             :  *  GPAC is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU Lesser General Public License as published by
      12             :  *  the Free Software Foundation; either version 2, or (at your option)
      13             :  *  any later version.
      14             :  *
      15             :  *  GPAC is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU Lesser General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU Lesser General Public
      21             :  *  License along with this library; see the file COPYING.  If not, write to
      22             :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             :  *
      24             :  */
      25             : 
      26             : #include "nodes_stacks.h"
      27             : #include "visual_manager.h"
      28             : #include <gpac/options.h>
      29             : 
      30             : 
      31             : #ifndef GPAC_DISABLE_3D
      32             : 
      33         100 : static void camera_changed(GF_Compositor *compositor, GF_Camera *cam)
      34             : {
      35         100 :         cam->flags |= CAM_IS_DIRTY;
      36         100 :         gf_sc_invalidate(compositor, NULL);
      37         100 :         if (compositor->active_layer) gf_node_dirty_set(compositor->active_layer, 0, 1);
      38         100 : }
      39             : 
      40             : #endif
      41             : 
      42          11 : static void nav_set_zoom_trans_2d(GF_VisualManager *visual, Fixed zoom, Fixed dx, Fixed dy)
      43             : {
      44          11 :         compositor_2d_set_user_transform(visual->compositor, zoom, visual->compositor->trans_x + dx, visual->compositor->trans_y + dy, 0);
      45             : #ifndef GPAC_DISABLE_3D
      46          11 :         if (visual->type_3d) camera_changed(visual->compositor, &visual->camera);
      47             : #endif
      48          11 : }
      49             : 
      50             : 
      51             : #ifndef GPAC_DISABLE_3D
      52             : 
      53             : /*shortcut*/
      54          18 : static void gf_mx_rotation_matrix(GF_Matrix *mx, SFVec3f axis_pt, SFVec3f axis, Fixed angle)
      55             : {
      56          36 :         gf_mx_init(*mx);
      57          18 :         gf_mx_add_translation(mx, axis_pt.x, axis_pt.y, axis_pt.z);
      58          18 :         gf_mx_add_rotation(mx, angle, axis.x, axis.y, axis.z);
      59          18 :         gf_mx_add_translation(mx, -axis_pt.x, -axis_pt.y, -axis_pt.z);
      60          18 : }
      61             : 
      62           2 : static void view_orbit_x(GF_Compositor *compositor, GF_Camera *cam, Fixed dx)
      63             : {
      64             :         GF_Matrix mx;
      65           3 :         if (!dx) return;
      66           1 :         gf_mx_rotation_matrix(&mx, cam->target, cam->up, dx);
      67           1 :         gf_mx_apply_vec(&mx, &cam->position);
      68           1 :         camera_changed(compositor, cam);
      69             : }
      70           2 : static void view_orbit_y(GF_Compositor *compositor, GF_Camera *cam, Fixed dy)
      71             : {
      72             :         GF_Matrix mx;
      73             :         SFVec3f axis;
      74           3 :         if (!dy) return;
      75           1 :         axis = camera_get_right_dir(cam);
      76           1 :         gf_mx_rotation_matrix(&mx, cam->target, axis, dy);
      77           1 :         gf_mx_apply_vec(&mx, &cam->position);
      78             :         /*update up vector*/
      79           1 :         cam->up = gf_vec_cross(camera_get_pos_dir(cam), axis);
      80           1 :         gf_vec_norm(&cam->up);
      81           1 :         camera_changed(compositor, cam);
      82             : }
      83             : 
      84           1 : static void view_exam_x(GF_Compositor *compositor, GF_Camera *cam, Fixed dx)
      85             : {
      86             :         GF_Matrix mx;
      87           1 :         if (!dx) return;
      88           1 :         gf_mx_rotation_matrix(&mx, cam->examine_center, cam->up, dx);
      89           1 :         gf_mx_apply_vec(&mx, &cam->position);
      90           1 :         gf_mx_apply_vec(&mx, &cam->target);
      91           1 :         camera_changed(compositor, cam);
      92             : }
      93             : 
      94           1 : static void view_exam_y(GF_Compositor *compositor, GF_Camera *cam, Fixed dy)
      95             : {
      96             :         GF_Matrix mx;
      97             :         SFVec3f axis;
      98           1 :         if (!dy) return;
      99           1 :         axis = camera_get_right_dir(cam);
     100           1 :         gf_mx_rotation_matrix(&mx, cam->examine_center, axis, dy);
     101           1 :         gf_mx_apply_vec(&mx, &cam->position);
     102           1 :         gf_mx_apply_vec(&mx, &cam->target);
     103             :         /*update up vector*/
     104           1 :         cam->up = gf_vec_cross(camera_get_pos_dir(cam), axis);
     105           1 :         gf_vec_norm(&cam->up);
     106           1 :         camera_changed(compositor, cam);
     107             : }
     108             : 
     109           1 : static void view_roll(GF_Compositor *compositor, GF_Camera *cam, Fixed dd)
     110             : {
     111             :         GF_Matrix mx;
     112             :         SFVec3f delta;
     113           1 :         if (!dd) return;
     114           1 :         gf_vec_add(delta, cam->target, cam->up);
     115           1 :         gf_mx_rotation_matrix(&mx, cam->target, camera_get_pos_dir(cam), dd);
     116           1 :         gf_mx_apply_vec(&mx, &delta);
     117           1 :         gf_vec_diff(cam->up, delta, cam->target);
     118           1 :         gf_vec_norm(&cam->up);
     119           1 :         camera_changed(compositor, cam);
     120             : }
     121             : 
     122          13 : static void update_pan_up(GF_Compositor *compositor, GF_Camera *cam)
     123             : {
     124             :         SFVec3f axis, dir;
     125             :         /*update up vector so that right is always horizontal (no y component)*/
     126          13 :         dir = camera_get_pos_dir(cam);
     127          13 :         axis = camera_get_right_dir(cam);
     128          13 :         axis.y = 0;
     129          13 :         gf_vec_norm(&axis);
     130          13 :         cam->up = gf_vec_cross(dir, axis);
     131          13 :         gf_vec_norm(&cam->up);
     132             : 
     133          13 :         camera_changed(compositor, cam);
     134          13 : }
     135             : 
     136          15 : static void view_pan_x(GF_Compositor *compositor, GF_Camera *cam, Fixed dx)
     137             : {
     138             :         GF_Matrix mx;
     139          20 :         if (!dx) return;
     140          10 :         gf_mx_rotation_matrix(&mx, cam->position, cam->up, dx);
     141          10 :         gf_mx_apply_vec(&mx, &cam->target);
     142             : 
     143          10 :         update_pan_up(compositor, cam);
     144             : }
     145           9 : static void view_pan_y(GF_Compositor *compositor, GF_Camera *cam, Fixed dy)
     146             : {
     147             :         GF_Matrix mx;
     148           9 :         GF_Vec prev_target = cam->target;
     149          15 :         if (!dy) return;
     150           3 :         gf_mx_rotation_matrix(&mx, cam->position, camera_get_right_dir(cam), dy);
     151           3 :         gf_mx_apply_vec(&mx, &cam->target);
     152           3 :         switch (cam->navigate_mode) {
     153           2 :         case GF_NAVIGATE_WALK:
     154             :         case GF_NAVIGATE_VR:
     155             :         case GF_NAVIGATE_GAME:
     156           2 :                 if (cam->target.z*prev_target.z<0) {
     157           0 :                         cam->target = prev_target;
     158           0 :                         return;
     159             :                 }
     160             :         default:
     161             :                 break;
     162             :         }
     163             : 
     164           3 :         update_pan_up(compositor, cam);
     165             : }
     166             : 
     167             : /*for translation moves when jumping*/
     168             : #define JUMP_SCALE_FACTOR       4
     169             : 
     170           3 : static void view_translate_x(GF_Compositor *compositor, GF_Camera *cam, Fixed dx)
     171             : {
     172             :         SFVec3f v;
     173           3 :         if (!dx) return;
     174           2 :         if (cam->jumping) dx *= JUMP_SCALE_FACTOR;
     175           2 :         v = gf_vec_scale(camera_get_right_dir(cam), dx);
     176           2 :         gf_vec_add(cam->target, cam->target, v);
     177           2 :         gf_vec_add(cam->position, cam->position, v);
     178           2 :         camera_changed(compositor, cam);
     179             : }
     180           2 : static void view_translate_y(GF_Compositor *compositor, GF_Camera *cam, Fixed dy)
     181             : {
     182             :         SFVec3f v;
     183           2 :         if (!dy) return;
     184           1 :         if (cam->jumping) dy *= JUMP_SCALE_FACTOR;
     185           1 :         v = gf_vec_scale(cam->up, dy);
     186           1 :         gf_vec_add(cam->target, cam->target, v);
     187           1 :         gf_vec_add(cam->position, cam->position, v);
     188           1 :         camera_changed(compositor, cam);
     189             : }
     190             : 
     191           8 : static void view_translate_z(GF_Compositor *compositor, GF_Camera *cam, Fixed dz)
     192             : {
     193             :         SFVec3f v;
     194           8 :         if (!dz) return;
     195           2 :         if (cam->jumping) dz *= JUMP_SCALE_FACTOR;
     196           2 :         dz = gf_mulfix(dz, cam->speed);
     197           2 :         v = gf_vec_scale(camera_get_target_dir(cam), dz);
     198           2 :         gf_vec_add(cam->target, cam->target, v);
     199           2 :         gf_vec_add(cam->position, cam->position, v);
     200           2 :         camera_changed(compositor, cam);
     201             : }
     202             : 
     203           1 : static void view_zoom(GF_Compositor *compositor, GF_Camera *cam, Fixed z)
     204             : {
     205             :         Fixed oz;
     206           1 :         if ((z>FIX_ONE) || (z<-FIX_ONE)) return;
     207           1 :         oz = gf_divfix(cam->vp_fov, cam->fieldOfView);
     208           1 :         if (oz<FIX_ONE) z/=4;
     209           1 :         oz += z;
     210           1 :         if (oz<=0) return;
     211             : 
     212           1 :         cam->fieldOfView = gf_divfix(cam->vp_fov, oz);
     213           1 :         if (cam->fieldOfView>GF_PI) cam->fieldOfView=GF_PI;
     214           1 :         camera_changed(compositor, cam);
     215             : }
     216             : 
     217         204 : Bool gf_sc_fit_world_to_screen(GF_Compositor *compositor)
     218             : {
     219             :         GF_TraverseState tr_state;
     220             :         SFVec3f pos, diff;
     221             :         Fixed dist, d;
     222             :         GF_Camera *cam;
     223             :         GF_Node *top;
     224             : 
     225             : #ifndef GPAC_DISABLE_VRML
     226             : //      if (gf_list_count(compositor->visual->back_stack)) return;
     227         204 :         if (gf_list_count(compositor->visual->view_stack)) return 0;
     228             : #endif
     229             : 
     230         204 :         gf_mx_p(compositor->mx);
     231         204 :         top = gf_sg_get_root_node(compositor->scene);
     232         204 :         if (!top) {
     233           0 :                 gf_mx_v(compositor->mx);
     234           0 :                 return 0;
     235             :         }
     236             :         memset(&tr_state, 0, sizeof(GF_TraverseState));
     237         204 :         gf_mx_init(tr_state.model_matrix);
     238         204 :         tr_state.traversing_mode = TRAVERSE_GET_BOUNDS;
     239         204 :         tr_state.visual = compositor->visual;
     240         204 :         gf_node_traverse(top, &tr_state);
     241         204 :         if (gf_node_dirty_get(top)) {
     242         122 :                 tr_state.bbox.is_set = 0;
     243             :         }
     244             : 
     245         204 :         if (!tr_state.bbox.is_set) {
     246         128 :                 gf_mx_v(compositor->mx);
     247             :                 /*empty world ...*/
     248         128 :                 if (tr_state.bbox.radius==-1) return 1;
     249             :                 /*2D world with 3D camera forced*/
     250         126 :                 if (tr_state.bounds.width&&tr_state.bounds.height) return 1;
     251         125 :                 return 0;
     252             :         }
     253             : 
     254          76 :         cam = &compositor->visual->camera;
     255             : 
     256          76 :         cam->world_bbox = tr_state.bbox;
     257             :         /*fit is based on bounding sphere*/
     258          76 :         dist = gf_divfix(tr_state.bbox.radius, gf_sin(cam->fieldOfView/2) );
     259          76 :         gf_vec_diff(diff, cam->center, tr_state.bbox.center);
     260             :         /*do not update if camera is outside the scene bounding sphere and dist is too close*/
     261          76 :         if (gf_vec_len(diff) > tr_state.bbox.radius + cam->radius) {
     262           5 :                 gf_vec_diff(diff, cam->vp_position, tr_state.bbox.center);
     263           5 :                 d = gf_vec_len(diff);
     264           5 :                 if (d<dist) {
     265           0 :                         gf_mx_v(compositor->mx);
     266           0 :                         return 1;
     267             :                 }
     268             :         }
     269             : 
     270          76 :         diff = gf_vec_scale(camera_get_pos_dir(cam), dist);
     271          76 :         gf_vec_add(pos, tr_state.bbox.center, diff);
     272          76 :         diff = cam->position;
     273          76 :         camera_set_vectors(cam, pos, cam->vp_orientation, cam->fieldOfView);
     274          76 :         cam->position = diff;
     275          76 :         camera_move_to(cam, pos, cam->target, cam->up);
     276          76 :         if (!compositor->player) {
     277          73 :                 camera_stop_anim(cam);
     278          73 :                 camera_set_vectors(cam, cam->end_pos, cam->end_ori, cam->end_fov);
     279             :         }
     280             : 
     281          76 :         cam->examine_center = tr_state.bbox.center;
     282          76 :         cam->flags |= CF_STORE_VP;
     283          76 :         if (cam->z_far < dist) cam->z_far = 10*dist;
     284          76 :         camera_changed(compositor, cam);
     285          76 :         gf_mx_v(compositor->mx);
     286          76 :         return 1;
     287             : }
     288             : 
     289          24 : static void handle_mouse_move_3d(GF_Compositor *compositor, GF_Camera *cam, u32 keys, Fixed dx, Fixed dy)
     290             : {
     291          24 :         Fixed trans_scale = cam->width/20;
     292             :         //if default VP is quite far from center use larger dz/dy moves
     293          24 :         if (cam->vp_dist>100) trans_scale *= 10;
     294             : 
     295          24 :         switch (cam->navigate_mode) {
     296             :         /*FIXME- we'll likely need a "step" value for walk at some point*/
     297           6 :         case GF_NAVIGATE_WALK:
     298             :         case GF_NAVIGATE_FLY:
     299           6 :                 view_pan_x(compositor, cam, -dx);
     300           6 :                 if (keys & GF_KEY_MOD_CTRL) view_pan_y(compositor, cam, dy);
     301           4 :                 else view_translate_z(compositor, cam, gf_mulfix(dy, trans_scale));
     302             :                 break;
     303           3 :         case GF_NAVIGATE_VR:
     304           3 :                 view_pan_x(compositor, cam, -dx);
     305           3 :                 if (keys & GF_KEY_MOD_CTRL) view_zoom(compositor, cam, dy);
     306           2 :                 else view_pan_y(compositor, cam, dy);
     307             :                 break;
     308           3 :         case GF_NAVIGATE_PAN:
     309           3 :                 view_pan_x(compositor, cam, -dx);
     310           3 :                 if (keys & GF_KEY_MOD_CTRL) view_translate_z(compositor, cam, gf_mulfix(dy, trans_scale));
     311           2 :                 else view_pan_y(compositor, cam, dy);
     312             :                 break;
     313           3 :         case GF_NAVIGATE_SLIDE:
     314           3 :                 view_translate_x(compositor, cam, gf_mulfix(dx, trans_scale));
     315           3 :                 if (keys & GF_KEY_MOD_CTRL) view_translate_z(compositor, cam, gf_mulfix(dy, trans_scale));
     316           2 :                 else view_translate_y(compositor, cam, gf_mulfix(dy, trans_scale));
     317             :                 break;
     318           3 :         case GF_NAVIGATE_EXAMINE:
     319           3 :                 if (keys & GF_KEY_MOD_CTRL) {
     320           1 :                         view_translate_z(compositor, cam, gf_mulfix(dy, trans_scale));
     321           1 :                         view_roll(compositor, cam, gf_mulfix(dx, trans_scale));
     322             :                 } else {
     323           2 :                         if (ABS(dx) > ABS(dy)) {
     324           1 :                                 view_exam_x(compositor, cam, -gf_mulfix(GF_PI, dx));
     325             :                         } else {
     326           1 :                                 view_exam_y(compositor, cam, gf_mulfix(GF_PI, dy));
     327             :                         }
     328             :                 }
     329             :                 break;
     330           3 :         case GF_NAVIGATE_ORBIT:
     331           3 :                 if (keys & GF_KEY_MOD_CTRL) {
     332           1 :                         view_translate_z(compositor, cam, gf_mulfix(dy, trans_scale));
     333             :                 } else {
     334           2 :                         view_orbit_x(compositor, cam, -gf_mulfix(GF_PI, dx));
     335           2 :                         view_orbit_y(compositor, cam, gf_mulfix(GF_PI, dy));
     336             :                 }
     337             :                 break;
     338           3 :         case GF_NAVIGATE_GAME:
     339           3 :                 view_pan_x(compositor, cam, -dx);
     340           3 :                 view_pan_y(compositor, cam, dy);
     341           3 :                 break;
     342             :         }
     343          24 : }
     344             : 
     345          56 : static Bool compositor_handle_navigation_3d(GF_Compositor *compositor, GF_Event *ev)
     346             : {
     347             :         Fixed x, y, trans_scale;
     348             :         Fixed dx, dy, key_trans, key_pan, key_exam;
     349             :         s32 key_inv;
     350             :         u32 keys;
     351             :         GF_Camera *cam;
     352          56 :         Fixed zoom = compositor->zoom;
     353             : 
     354             :         cam = NULL;
     355             : #ifndef GPAC_DISABLE_VRML
     356          56 :         if (compositor->active_layer) {
     357           0 :                 cam = compositor_layer3d_get_camera(compositor->active_layer);
     358             :         }
     359             : #endif
     360             : 
     361           0 :         if (!cam) {
     362          56 :                 cam = &compositor->visual->camera;
     363             :                 assert(compositor);
     364             :                 assert(compositor->scene);
     365             :         }
     366          56 :         if (!cam || (cam->navigate_mode==GF_NAVIGATE_NONE)) return 0;
     367             : 
     368          56 :         keys = compositor->key_states;
     369             :         if (!cam->navigate_mode && !(keys & GF_KEY_MOD_ALT) ) return 0;
     370             :         x = y = 0;
     371             :         /*renorm between -1, 1*/
     372          56 :         if (ev->type<=GF_EVENT_MOUSEWHEEL) {
     373          32 :                 x = gf_divfix( INT2FIX(ev->mouse.x - (s32) compositor->visual->width/2), INT2FIX(compositor->visual->width));
     374          32 :                 y = gf_divfix( INT2FIX(ev->mouse.y - (s32) compositor->visual->height/2), INT2FIX(compositor->visual->height));
     375             :         }
     376             : 
     377          56 :         dx = (x - compositor->grab_x);
     378          56 :         dy = (compositor->grab_y - y);
     379             : 
     380          56 :         trans_scale = cam->width/20;
     381          56 :         key_trans = cam->avatar_size.x/2;
     382             :         //if default VP is quite far from center use larger dz/dy moves
     383          56 :         if (cam->vp_dist>100) trans_scale *= 10;
     384             : 
     385          56 :         if (cam->world_bbox.is_set && (key_trans*5 > cam->world_bbox.radius)) {
     386           0 :                 key_trans = cam->world_bbox.radius / 100;
     387             :         }
     388             : 
     389             :         key_pan = FIX_ONE/20;
     390             :         key_exam = FIX_ONE/20;
     391             :         key_inv = 1;
     392             : 
     393          56 :         if (keys & GF_KEY_MOD_SHIFT) {
     394           0 :                 dx *= 4;
     395           0 :                 dy *= 4;
     396             :                 key_pan *= 4;
     397             :                 key_exam *= 4;
     398           0 :                 key_trans*=4;
     399             :         }
     400             : 
     401          56 :         if (! compositor->orientation_sensors_active) {
     402             :                 Fixed yaw, pitch, roll;
     403          56 :                 gf_mx_get_yaw_pitch_roll(&compositor->visual->camera.modelview, &yaw, &pitch, &roll);
     404          56 :                 compositor->audio_renderer->yaw = yaw;
     405          56 :                 compositor->audio_renderer->pitch = pitch;
     406          56 :                 compositor->audio_renderer->roll = roll;
     407             :         }
     408             : 
     409          56 :         switch (ev->type) {
     410           8 :         case GF_EVENT_MOUSEDOWN:
     411             :                 /*left*/
     412           8 :                 if (ev->mouse.button==GF_MOUSE_LEFT) {
     413           8 :                         compositor->grab_x = x;
     414           8 :                         compositor->grab_y = y;
     415           8 :                         compositor->navigation_state = 1;
     416             : 
     417             :                         /*change vp and examine center to current location*/
     418           8 :                         if ((keys & GF_KEY_MOD_CTRL) && compositor->hit_square_dist) {
     419           0 :                                 cam->vp_position = cam->position;
     420           0 :                                 cam->vp_orientation = camera_get_orientation(cam->position, cam->target, cam->up);
     421           0 :                                 cam->vp_fov = cam->fieldOfView;
     422           0 :                                 cam->examine_center = compositor->hit_world_point;
     423           0 :                                 camera_changed(compositor, cam);
     424           0 :                                 return 1;
     425             :                         }
     426             :                 }
     427             :                 /*right*/
     428           0 :                 else if (ev->mouse.button==GF_MOUSE_RIGHT) {
     429           0 :                         if (compositor->navigation_state && (cam->navigate_mode==GF_NAVIGATE_WALK)) {
     430           0 :                                 camera_jump(cam);
     431           0 :                                 gf_sc_invalidate(compositor, NULL);
     432           0 :                                 return 1;
     433             :                         }
     434           0 :                         else if (keys & GF_KEY_MOD_CTRL) gf_sc_fit_world_to_screen(compositor);
     435             :                 }
     436             :                 break;
     437             : 
     438          24 :         case GF_EVENT_MOUSEMOVE:
     439          24 :                 if (compositor->orientation_sensors_active) return 0;
     440             : 
     441          24 :                 if (!compositor->navigation_state) {
     442           0 :                         if (cam->navigate_mode==GF_NAVIGATE_GAME) {
     443             :                                 /*init mode*/
     444           0 :                                 compositor->grab_x = x;
     445           0 :                                 compositor->grab_y = y;
     446           0 :                                 compositor->navigation_state = 1;
     447             :                         }
     448           0 :                         compositor->auto_rotate=0;
     449           0 :                         return 0;
     450             :                 }
     451          24 :                 compositor->navigation_state++;
     452             : 
     453          24 :                 if (x <= -0.49) compositor->auto_rotate = 1;
     454          24 :                 else if (x >= 0.49) compositor->auto_rotate = 2;
     455          24 :                 else if (y <= -0.49) compositor->auto_rotate = 3;
     456          24 :                 else if (y >= 0.49) compositor->auto_rotate = 4;
     457          24 :                 else compositor->auto_rotate = 0;
     458             : 
     459          24 :                 handle_mouse_move_3d(compositor, cam, keys, dx, dy);
     460             : 
     461          24 :                 compositor->grab_x = x;
     462          24 :                 compositor->grab_y = y;
     463          24 :                 return 1;
     464             : 
     465           0 :         case GF_EVENT_MOUSEWHEEL:
     466           0 :                 switch (cam->navigate_mode) {
     467             :                 /*FIXME- we'll likely need a "step" value for walk at some point*/
     468           0 :                 case GF_NAVIGATE_WALK:
     469             :                 case GF_NAVIGATE_FLY:
     470           0 :                         view_pan_y(compositor, cam, gf_mulfix(key_pan, ev->mouse.wheel_pos));
     471           0 :                         break;
     472           0 :                 case GF_NAVIGATE_VR:
     473           0 :                         view_zoom(compositor, cam, gf_mulfix(key_pan, ev->mouse.wheel_pos));
     474           0 :                         break;
     475           0 :                 case GF_NAVIGATE_SLIDE:
     476             :                 case GF_NAVIGATE_EXAMINE:
     477             :                 case GF_NAVIGATE_ORBIT:
     478             :                 case GF_NAVIGATE_PAN:
     479           0 :                         if (cam->is_3D) {
     480           0 :                                 view_translate_z(compositor, cam, gf_mulfix(trans_scale, ev->mouse.wheel_pos) * ((keys & GF_KEY_MOD_SHIFT) ? 4 : 1));
     481             :                         } else {
     482           0 :                                 nav_set_zoom_trans_2d(compositor->visual, zoom + INT2FIX(ev->mouse.wheel_pos)/10, 0, 0);
     483             :                         }
     484             :                 }
     485             :                 return 1;
     486             : 
     487           0 :         case GF_EVENT_MULTITOUCH:
     488           0 :                 compositor->auto_rotate=0;
     489           0 :                 compositor->navigation_state = 0;
     490           0 :                 if (ev->mtouch.num_fingers==2) {
     491           0 :                         if( ABS(ev->mtouch.pinch) * 100 > 2 ) {
     492           0 :                                 if (cam->is_3D) {
     493           0 :                                         view_translate_z(compositor, cam, gf_mulfix(cam->width, compositor->visual->width* ev->mtouch.pinch));
     494             :                                 } else {
     495           0 :                                         nav_set_zoom_trans_2d(compositor->visual, zoom + gf_mulfix(trans_scale, ev->mtouch.pinch), 0, 0);
     496             :                                 }
     497             :                                 return 1;
     498             :                         }
     499           0 :                         if( ABS(ev->mtouch.rotation) > GF_PI/40 ) {
     500           0 :                                 view_roll(compositor, cam, gf_mulfix(ev->mtouch.rotation, trans_scale));
     501           0 :                                 return 1;
     502             :                         }
     503           0 :                 } else if (ev->mtouch.num_fingers==3) {
     504           0 :                         compositor->visual->camera.start_zoom = compositor->zoom;
     505           0 :                         compositor->zoom = FIX_ONE;
     506           0 :                         compositor->interoccular_offset = 0;
     507           0 :                         compositor->focdist = 0;
     508             :                         compositor->interoccular_offset = 0;
     509             :                         compositor->focdist = 0;
     510           0 :                         compositor_3d_reset_camera(compositor);
     511           0 :                         return 1;
     512             :                 }
     513             :                 return 0;
     514             : 
     515           0 :         case GF_EVENT_MOUSEUP:
     516           0 :                 compositor->auto_rotate=0;
     517           0 :                 if (ev->mouse.button==GF_MOUSE_LEFT) compositor->navigation_state = 0;
     518             :                 break;
     519             : 
     520          16 :         case GF_EVENT_KEYDOWN:
     521          16 :                 switch (ev->key.key_code) {
     522           0 :                 case GF_KEY_BACKSPACE:
     523           0 :                         gf_sc_reset_graphics(compositor);
     524           0 :                         return 1;
     525           0 :                 case GF_KEY_C:
     526           0 :                         compositor->collide_mode = compositor->collide_mode  ? GF_COLLISION_NONE : GF_COLLISION_DISPLACEMENT;
     527           0 :                         return 1;
     528           8 :                 case GF_KEY_J:
     529           8 :                         if (cam->navigate_mode==GF_NAVIGATE_WALK) {
     530           1 :                                 camera_jump(cam);
     531           1 :                                 gf_sc_invalidate(compositor, NULL);
     532           1 :                                 return 1;
     533             :                         }
     534             :                         break;
     535           0 :                 case GF_KEY_HOME:
     536           0 :                         if (!compositor->navigation_state) {
     537           0 :                                 compositor->visual->camera.start_zoom = compositor->zoom;
     538           0 :                                 compositor->zoom = FIX_ONE;
     539           0 :                                 compositor->interoccular_offset = 0;
     540           0 :                                 compositor->focdist = 0;
     541             :                                 compositor->interoccular_offset = 0;
     542             :                                 compositor->focdist = 0;
     543           0 :                                 compositor_3d_reset_camera(compositor);
     544             :                         }
     545             :                         break;
     546           0 :                 case GF_KEY_END:
     547           0 :                         if (cam->navigate_mode==GF_NAVIGATE_GAME) {
     548           0 :                                 cam->navigate_mode = GF_NAVIGATE_WALK;
     549           0 :                                 compositor->navigation_state = 0;
     550           0 :                                 return 1;
     551             :                         }
     552             :                         break;
     553           0 :                 case GF_KEY_LEFT:
     554             :                         key_inv = -1;
     555           0 :                 case GF_KEY_RIGHT:
     556           0 :                         if (keys & GF_KEY_MOD_ALT) {
     557           0 :                                 if ( (keys & GF_KEY_MOD_SHIFT) && (compositor->visual->nb_views > 1) ) {
     558             :                                         /*+ or - 10 cm*/
     559           0 :                                         compositor->focdist += INT2FIX(key_inv);
     560           0 :                                         cam->flags |= CAM_IS_DIRTY;
     561           0 :                                         GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("AutoStereo view distance %f - focus %f\n", FIX2FLT(compositor->video_out->dispdist)/100, FIX2FLT(compositor->focdist)/100));
     562           0 :                                         gf_sc_invalidate(compositor, NULL);
     563           0 :                                         return 1;
     564             :                                 }
     565             :                                 return 0;
     566             :                         }
     567             : 
     568             : 
     569           0 :                         switch (cam->navigate_mode) {
     570           0 :                         case GF_NAVIGATE_SLIDE:
     571           0 :                                 if (keys & GF_KEY_MOD_CTRL) view_pan_x(compositor, cam, key_inv * key_pan);
     572           0 :                                 else view_translate_x(compositor, cam, key_inv * key_trans);
     573             :                                 break;
     574           0 :                         case GF_NAVIGATE_EXAMINE:
     575           0 :                                 if (keys & GF_KEY_MOD_CTRL) view_roll(compositor, cam, gf_mulfix(dx, trans_scale));
     576           0 :                                 else view_exam_x(compositor, cam, -key_inv * key_exam);
     577             :                                 break;
     578           0 :                         case GF_NAVIGATE_ORBIT:
     579           0 :                                 if (keys & GF_KEY_MOD_CTRL) view_translate_x(compositor, cam, key_inv * key_trans);
     580           0 :                                 else view_orbit_x(compositor, cam, -key_inv * key_exam);
     581             :                                 break;
     582           0 :                         case GF_NAVIGATE_GAME:
     583           0 :                                 view_translate_x(compositor, cam, key_inv * key_trans);
     584           0 :                                 break;
     585           0 :                         case GF_NAVIGATE_VR:
     586           0 :                                 view_pan_x(compositor, cam, -key_inv * key_pan);
     587           0 :                                 break;
     588             :                         /*walk/fly/pan*/
     589           0 :                         default:
     590           0 :                                 if (keys & GF_KEY_MOD_CTRL) view_translate_x(compositor, cam, key_inv * key_trans);
     591           0 :                                 else view_pan_x(compositor, cam, -key_inv * key_pan);
     592             :                                 break;
     593             :                         }
     594             :                         return 1;
     595           0 :                 case GF_KEY_DOWN:
     596             :                         key_inv = -1;
     597           0 :                 case GF_KEY_UP:
     598           0 :                         if (keys & GF_KEY_MOD_ALT) {
     599           0 :                                 if ( (keys & GF_KEY_MOD_SHIFT) && (compositor->visual->nb_views > 1) ) {
     600           0 :                                         compositor->interoccular_offset += FLT2FIX(0.5) * key_inv;
     601           0 :                                         GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("AutoStereo interoccular distance %f\n", FIX2FLT(compositor->iod + compositor->interoccular_offset)));
     602           0 :                                         cam->flags |= CAM_IS_DIRTY;
     603           0 :                                         gf_sc_invalidate(compositor, NULL);
     604           0 :                                         return 1;
     605             :                                 }
     606             :                                 return 0;
     607             :                         }
     608           0 :                         switch (cam->navigate_mode) {
     609           0 :                         case GF_NAVIGATE_SLIDE:
     610           0 :                                 if (keys & GF_KEY_MOD_CTRL) view_translate_z(compositor, cam, key_inv * key_trans);
     611           0 :                                 else view_translate_y(compositor, cam, key_inv * key_trans);
     612             :                                 break;
     613           0 :                         case GF_NAVIGATE_EXAMINE:
     614           0 :                                 if (keys & GF_KEY_MOD_CTRL) view_translate_z(compositor, cam, key_inv * key_trans);
     615           0 :                                 else view_exam_y(compositor, cam, -key_inv * key_exam);
     616             :                                 break;
     617           0 :                         case GF_NAVIGATE_ORBIT:
     618           0 :                                 if (keys & GF_KEY_MOD_CTRL) view_translate_y(compositor, cam, key_inv * key_trans);
     619           0 :                                 else view_orbit_y(compositor, cam, -key_inv * key_exam);
     620             :                                 break;
     621           0 :                         case GF_NAVIGATE_PAN:
     622           0 :                                 if (keys & GF_KEY_MOD_CTRL) view_translate_y(compositor, cam, key_inv * key_trans);
     623           0 :                                 else view_pan_y(compositor, cam, key_inv * key_pan);
     624             :                                 break;
     625           0 :                         case GF_NAVIGATE_GAME:
     626           0 :                                 view_translate_z(compositor, cam, key_inv * key_trans);
     627           0 :                                 break;
     628           0 :                         case GF_NAVIGATE_VR:
     629           0 :                                 if (keys & GF_KEY_MOD_CTRL) view_zoom(compositor, cam, key_inv * key_pan);
     630           0 :                                 else view_pan_y(compositor, cam, key_inv * key_pan);
     631             :                                 break;
     632             :                         /*walk/fly*/
     633           0 :                         default:
     634           0 :                                 if (keys & GF_KEY_MOD_CTRL) view_pan_y(compositor, cam, key_inv * key_pan);
     635           0 :                                 else view_translate_z(compositor, cam, key_inv * key_trans);
     636             :                                 break;
     637             :                         }
     638             :                         return 1;
     639             : 
     640           0 :                 case GF_KEY_PAGEDOWN:
     641           0 :                         if (keys & GF_KEY_MOD_CTRL) {
     642           0 :                                 view_zoom(compositor, cam, FIX_ONE/10);
     643           0 :                                 return 1;
     644             :                         }
     645             :                         break;
     646           0 :                 case GF_KEY_PAGEUP:
     647           0 :                         if (keys & GF_KEY_MOD_CTRL) {
     648           0 :                                 view_zoom(compositor, cam, -FIX_ONE/10);
     649           0 :                                 return 1;
     650             :                         }
     651             :                         break;
     652           0 :                 case GF_KEY_D:
     653           0 :                         if (keys & GF_KEY_MOD_CTRL) {
     654           0 :                                 if (compositor->tvtd==TILE_DEBUG_FULL) compositor->tvtd = 0;
     655           0 :                                 else compositor->tvtd ++;
     656           0 :                                 gf_sc_invalidate(compositor, NULL);
     657           0 :                                 return 1;
     658             :                         }
     659             :                         break;
     660           0 :                 case GF_KEY_G:
     661           0 :                         if (keys & GF_KEY_MOD_CTRL) {
     662           0 :                                 compositor->vrhud_mode++;
     663           0 :                                 if (compositor->vrhud_mode==5) compositor->vrhud_mode=0;
     664           0 :                                 gf_sc_invalidate(compositor, NULL);
     665           0 :                                 return 1;
     666             :                         }
     667             :                         break;
     668           0 :                 case GF_KEY_A:
     669           0 :                         if (keys & GF_KEY_MOD_CTRL) {
     670           0 :                                 compositor->tvtf = !compositor->tvtf;
     671           0 :                                 gf_sc_invalidate(compositor, NULL);
     672           0 :                                 return 1;
     673             :                         }
     674             :                         break;
     675             :                 }
     676             :                 break;
     677           0 :         case GF_EVENT_SENSOR_ORIENTATION:
     678             :         {
     679             :                 Fixed z, w, yaw, /*pitch, */roll;
     680             :                 GF_Vec target;
     681             :                 GF_Matrix mx;
     682             : 
     683             :                 /* In iOS we get x, y, z in quaternions (first measurement is the frame of reference) */
     684           0 :                 if (ev->sensor.w) {
     685           0 :                         x = ev->sensor.x;
     686           0 :                         y = ev->sensor.y;
     687           0 :                         z = ev->sensor.z;
     688             :                         w = ev->sensor.w;
     689             :                 
     690           0 :                         yaw = gf_atan2(2*gf_mulfix(z,w) - 2*gf_mulfix(y,x) , 1 - 2*gf_mulfix(z,z) - 2*gf_mulfix(x,x));
     691             :                         //pitch = asin(2*y*z + 2*x*w);
     692           0 :                         roll = gf_atan2(2*gf_mulfix(y,w) - 2*gf_mulfix(z,x) , 1 - 2*gf_mulfix(y,y) - 2*gf_mulfix(x,x));
     693             :                 } else {
     694             :                         /*
     695             :                          * In Android we get yaw, pitch, roll values (in rad)
     696             :                          * The frame of reference is absolute
     697             :                          */
     698           0 :                         yaw = ev->sensor.x;
     699             :                         //pitch = ev->sensor.y;
     700           0 :                         roll = ev->sensor.z;
     701             :                 }
     702           0 :                 target.x = 0;
     703           0 :                 target.y = -FIX_ONE;
     704           0 :                 target.z = 0;
     705           0 :                 gf_mx_init(mx);
     706           0 :                 gf_mx_add_rotation(&mx, yaw, 0, FIX_ONE, 0);
     707           0 :                 gf_mx_add_rotation(&mx, -roll, FIX_ONE, 0, 0);
     708             :                 
     709           0 :                 gf_mx_apply_vec(&mx, &target);
     710             : 
     711           0 :                 cam->target = target;
     712           0 :                 update_pan_up(compositor, cam);
     713             :         }
     714           0 :                 return 1;
     715             :         }
     716             :         return 0;
     717             : }
     718             : 
     719             : #endif
     720             : 
     721             : 
     722          56 : static Bool compositor_handle_navigation_2d(GF_VisualManager *visual, GF_Event *ev)
     723             : {
     724             :         Fixed x, y, dx, dy, key_trans, key_rot, zoom, new_zoom;
     725             :         u32 navigation_mode;
     726             :         s32 key_inv;
     727          56 :         Bool is_pixel_metrics = visual->compositor->traverse_state->pixel_metrics;
     728          56 :         u32 keys = visual->compositor->key_states;
     729             : 
     730          56 :         zoom = visual->compositor->zoom;
     731          56 :         navigation_mode = visual->compositor->navigate_mode;
     732             : #ifndef GPAC_DISABLE_3D
     733          56 :         if (visual->type_3d) navigation_mode = visual->camera.navigate_mode;
     734             : #endif
     735             : 
     736          56 :         if (navigation_mode==GF_NAVIGATE_NONE) return 0;
     737             :         if (!navigation_mode && !(keys & GF_KEY_MOD_ALT) ) return 0;
     738             : 
     739             : 
     740             :         x = y = 0;
     741             :         /*renorm between -1, 1*/
     742          28 :         if (ev->type<=GF_EVENT_MOUSEWHEEL) {
     743          16 :                 x = INT2FIX(ev->mouse.x);
     744          16 :                 y = INT2FIX(ev->mouse.y);
     745             :         }
     746          28 :         dx = x - visual->compositor->grab_x;
     747          28 :         if (visual->center_coords) {
     748          28 :                 dy = visual->compositor->grab_y - y;
     749             :         } else {
     750           0 :                 dy = y - visual->compositor->grab_y;
     751             :         }
     752          28 :         if (!is_pixel_metrics) {
     753           0 :                 dx /= visual->width;
     754           0 :                 dy /= visual->height;
     755             :         }
     756             : 
     757             :         key_inv = 1;
     758             :         key_trans = INT2FIX(2);
     759             :         key_rot = GF_PI/100;
     760             : 
     761          28 :         if (keys & GF_KEY_MOD_SHIFT) {
     762           0 :                 dx *= 4;
     763           0 :                 dy *= 4;
     764             :                 key_rot *= 4;
     765             :                 key_trans*=4;
     766             :         }
     767             : 
     768          28 :         if (!is_pixel_metrics) {
     769           0 :                 key_trans /= visual->width;
     770             :         }
     771             : 
     772          28 :         switch (ev->type) {
     773           4 :         case GF_EVENT_MOUSEDOWN:
     774             :                 /*left*/
     775           4 :                 if (ev->mouse.button==GF_MOUSE_LEFT) {
     776           4 :                         visual->compositor->grab_x = x;
     777           4 :                         visual->compositor->grab_y = y;
     778           4 :                         visual->compositor->navigation_state = 1;
     779             :                         /*update zoom center*/
     780           4 :                         if (keys & GF_KEY_MOD_CTRL) {
     781           0 :                                 visual->compositor->trans_x -= visual->compositor->grab_x - INT2FIX(visual->width)/2;
     782           0 :                                 visual->compositor->trans_y += INT2FIX(visual->height)/2 - visual->compositor->grab_y;
     783           0 :                                 nav_set_zoom_trans_2d(visual, visual->compositor->zoom, 0, 0);
     784             :                         }
     785             :                         return 0;
     786             :                 }
     787             :                 break;
     788             : 
     789           0 :         case GF_EVENT_MOUSEUP:
     790           0 :                 if (ev->mouse.button==GF_MOUSE_LEFT) {
     791           0 :                         visual->compositor->navigation_state = 0;
     792           0 :                         return 0;
     793             :                 }
     794             :                 break;
     795           0 :         case GF_EVENT_MULTITOUCH:
     796           0 :                 if (ev->mtouch.num_fingers==2) {
     797           0 :                         if( ABS(ev->mtouch.pinch) * 100 > 2 ) {
     798           0 :                                 new_zoom = zoom + ev->mtouch.pinch * MIN(visual->width, visual->height)/100;
     799           0 :                                 nav_set_zoom_trans_2d(visual, new_zoom, 0, 0);
     800           0 :                                 return 1;
     801             :                         }
     802           0 :                         if( ABS(ev->mtouch.rotation) > GF_PI/40 ) {
     803           0 :                                 visual->compositor->rotation -= ev->mtouch.rotation;
     804           0 :                                 nav_set_zoom_trans_2d(visual, zoom, 0, 0);
     805           0 :                                 return 1;
     806             :                         }
     807           0 :                 } else if (ev->mtouch.num_fingers==3) {
     808           0 :                         visual->compositor->trans_x = visual->compositor->trans_y = 0;
     809           0 :                         visual->compositor->rotation = 0;
     810           0 :                         visual->compositor->zoom = FIX_ONE;
     811           0 :                         nav_set_zoom_trans_2d(visual, FIX_ONE, 0, 0);
     812           0 :                         return 1;
     813             :                 }
     814             :                 return 0;
     815             : 
     816           0 :         case GF_EVENT_MOUSEWHEEL:
     817           0 :                 switch (navigation_mode) {
     818           0 :                 case GF_NAVIGATE_SLIDE:
     819           0 :                         new_zoom = zoom + INT2FIX(ev->mouse.wheel_pos)/10;
     820           0 :                         nav_set_zoom_trans_2d(visual, new_zoom, 0, 0);
     821           0 :                         return 1;
     822           0 :                 case GF_NAVIGATE_EXAMINE:
     823           0 :                         if (ev->mouse.wheel_pos>0)
     824           0 :                                 visual->compositor->rotation += gf_asin( GF_PI / 10);
     825             :                         else
     826           0 :                                 visual->compositor->rotation -= gf_asin( GF_PI / 10);
     827           0 :                         nav_set_zoom_trans_2d(visual, zoom, 0, 0);
     828           0 :                         return 1;
     829             :                 }
     830             :                 return 0;
     831             : 
     832          12 :         case GF_EVENT_MOUSEMOVE:
     833          12 :                 if (!visual->compositor->navigation_state) return 0;
     834          12 :                 visual->compositor->navigation_state++;
     835          12 :                 switch (navigation_mode) {
     836           3 :                 case GF_NAVIGATE_SLIDE:
     837           3 :                         if (keys & GF_KEY_MOD_CTRL) {
     838           1 :                                 if (dy) {
     839             :                                         new_zoom = zoom;
     840           0 :                                         if (new_zoom > FIX_ONE) new_zoom += dy/20;
     841           0 :                                         else new_zoom += dy/80;
     842           0 :                                         nav_set_zoom_trans_2d(visual, new_zoom, 0, 0);
     843             :                                 }
     844             :                         } else {
     845           2 :                                 nav_set_zoom_trans_2d(visual, zoom, dx, dy);
     846             :                         }
     847             :                         break;
     848           9 :                 case GF_NAVIGATE_EXAMINE:
     849             :                 {
     850           9 :                         Fixed sin = gf_mulfix(GF_PI, dy) / visual->height;
     851             :                         //truncate in [-1;1] for arcsin()
     852           9 :                         if (sin < -FIX_ONE)
     853             :                                 sin = -FIX_ONE;
     854           9 :                         if (sin >  FIX_ONE)
     855             :                                 sin =  FIX_ONE;
     856           9 :                         visual->compositor->rotation += gf_asin(sin);
     857           9 :                         nav_set_zoom_trans_2d(visual, zoom, 0, 0);
     858             :                 }
     859           9 :                 break;
     860             :                 }
     861          12 :                 visual->compositor->grab_x = x;
     862          12 :                 visual->compositor->grab_y = y;
     863          12 :                 return 1;
     864           8 :         case GF_EVENT_KEYDOWN:
     865           8 :                 switch (ev->key.key_code) {
     866           0 :                 case GF_KEY_BACKSPACE:
     867           0 :                         gf_sc_reset_graphics(visual->compositor);
     868           0 :                         return 1;
     869           0 :                 case GF_KEY_HOME:
     870           0 :                         if (!visual->compositor->navigation_state) {
     871           0 :                                 visual->compositor->trans_x = visual->compositor->trans_y = 0;
     872           0 :                                 visual->compositor->rotation = 0;
     873           0 :                                 visual->compositor->zoom = FIX_ONE;
     874           0 :                                 nav_set_zoom_trans_2d(visual, FIX_ONE, 0, 0);
     875             :                         }
     876             :                         return 1;
     877           0 :                 case GF_KEY_LEFT:
     878             :                         key_inv = -1;
     879           0 :                 case GF_KEY_RIGHT:
     880           0 :                         if (navigation_mode == GF_NAVIGATE_SLIDE) {
     881           0 :                                 nav_set_zoom_trans_2d(visual, zoom, key_inv*key_trans, 0);
     882             :                         }
     883             :                         else {
     884           0 :                                 visual->compositor->rotation -= key_inv * key_rot;
     885           0 :                                 nav_set_zoom_trans_2d(visual, zoom, 0, 0);
     886             :                         }
     887             :                         return 1;
     888           0 :                 case GF_KEY_DOWN:
     889             :                         key_inv = -1;
     890           0 :                 case GF_KEY_UP:
     891           0 :                         if (navigation_mode == GF_NAVIGATE_SLIDE) {
     892           0 :                                 if (keys & GF_KEY_MOD_CTRL) {
     893             :                                         new_zoom = zoom;
     894           0 :                                         if (new_zoom > FIX_ONE) new_zoom += key_inv*FIX_ONE/10;
     895           0 :                                         else new_zoom += key_inv*FIX_ONE/20;
     896           0 :                                         nav_set_zoom_trans_2d(visual, new_zoom, 0, 0);
     897             :                                 } else {
     898           0 :                                         nav_set_zoom_trans_2d(visual, zoom, 0, key_inv*key_trans);
     899             :                                 }
     900             :                         }
     901             :                         else {
     902           0 :                                 visual->compositor->rotation += key_inv*key_rot;
     903           0 :                                 nav_set_zoom_trans_2d(visual, zoom, 0, 0);
     904             :                         }
     905             :                         return 1;
     906             :                 }
     907             :                 break;
     908             :         }
     909             :         return 0;
     910             : }
     911             : 
     912           0 : void compositor_handle_auto_navigation(GF_Compositor *compositor)
     913             : {
     914             : #ifndef GPAC_DISABLE_3D
     915             :         GF_Camera *cam = NULL;
     916             :         Fixed dx, dy;
     917             : #ifndef GPAC_DISABLE_VRML
     918           0 :         if (compositor->active_layer) {
     919           0 :                 cam = compositor_layer3d_get_camera(compositor->active_layer);
     920             :         }
     921           0 :         if (!cam)
     922           0 :                 cam = &compositor->visual->camera;
     923             : #endif
     924             : 
     925             :         dx = dy = 0;
     926           0 :         switch (compositor->auto_rotate) {
     927             :         case 1:
     928             :                 dx = -FIX_ONE/100;
     929             :                 break;
     930           0 :         case 2:
     931             :                 dx = FIX_ONE/100;
     932           0 :                 break;
     933           0 :         case 3:
     934             :                 dy = FIX_ONE/100;
     935           0 :                 break;
     936           0 :         case 4:
     937             :                 dy = -FIX_ONE/100;
     938           0 :                 break;
     939             :         default:
     940             :                 return;
     941             :         }
     942           0 :         handle_mouse_move_3d(compositor, cam, 0, dx, dy);
     943             : #endif
     944             : }
     945             : 
     946         112 : Bool compositor_handle_navigation(GF_Compositor *compositor, GF_Event *ev)
     947             : {
     948         112 :         if (!compositor->scene) return 0;
     949             : #ifndef GPAC_DISABLE_3D
     950         112 :         if ( (compositor->visual->type_3d>0) || compositor->active_layer)
     951          56 :                 return compositor_handle_navigation_3d(compositor, ev);
     952             : #endif
     953          56 :         return compositor_handle_navigation_2d(compositor->visual, ev);
     954             : }

Generated by: LCOV version 1.13