LCOV - code coverage report
Current view: top level - compositor - mpeg4_background.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 294 305 96.4 %
Date: 2021-04-29 23:48:07 Functions: 10 10 100.0 %

          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             : 
      27             : 
      28             : #include "nodes_stacks.h"
      29             : 
      30             : #ifndef GPAC_DISABLE_VRML
      31             : 
      32             : #ifndef GPAC_DISABLE_3D
      33             : 
      34             : #include "texturing.h"
      35             : #include "visual_manager.h"
      36             : 
      37             : /*for background textures - the offset is to prevent lines on cube map edges*/
      38             : #define PLANE_HSIZE             FLT2FIX(0.5025f)
      39             : #define PLANE_HSIZE_LOW         FLT2FIX(0.5f)
      40             : 
      41             : 
      42             : static Bool back_use_texture(MFURL *url)
      43             : {
      44         588 :         if (!url->count) return 0;
      45         137 :         if (url->vals[0].OD_ID > 0) return 1;
      46          77 :         if (url->vals[0].url && strlen(url->vals[0].url)) return 1;
      47             :         return 0;
      48             : }
      49             : 
      50        6366 : static void UpdateBackgroundTexture(GF_TextureHandler *txh)
      51             : {
      52        6366 :         gf_sc_texture_update_frame(txh, 0);
      53             :         /*restart texture if needed (movie background controled by MediaControl)*/
      54        6366 :         if (txh->stream_finished && gf_mo_get_loop(txh->stream, 0)) gf_sc_texture_restart(txh);
      55        6366 : }
      56             : 
      57             : 
      58         528 : static Bool back_gf_sc_texture_enabled(MFURL *url, GF_TextureHandler *txh)
      59             : {
      60         528 :         Bool use_texture = back_use_texture(url);
      61             :         if (use_texture) {
      62             :                 /*texture not ready*/
      63         129 :                 if (!txh->tx_io) {
      64             :                         use_texture = 0;
      65          70 :                         gf_sc_invalidate(txh->compositor, NULL);
      66             :                 }
      67         129 :                 gf_sc_texture_set_blend_mode(txh, gf_sc_texture_is_transparent(txh) ? TX_REPLACE : TX_DECAL);
      68             :         }
      69         528 :         return use_texture;
      70             : }
      71             : 
      72          30 : static void back_check_gf_sc_texture_change(GF_TextureHandler *txh, MFURL *url)
      73             : {
      74             :         /*if open and changed, stop and play*/
      75          30 :         if (txh->is_open) {
      76           4 :                 if (! gf_sc_texture_check_url_change(txh, url)) return;
      77           0 :                 gf_sc_texture_stop(txh);
      78           0 :                 gf_sc_texture_play(txh, url);
      79           0 :                 return;
      80             :         }
      81             :         /*if not open and changed play*/
      82          26 :         if (url->count) gf_sc_texture_play(txh, url);
      83             : }
      84             : 
      85          11 : static void DestroyBackground(GF_Node *node)
      86             : {
      87          11 :         BackgroundStack *ptr = (BackgroundStack *) gf_node_get_private(node);
      88          11 :         PreDestroyBindable(node, ptr->reg_stacks);
      89          11 :         gf_list_del(ptr->reg_stacks);
      90             : 
      91          11 :         if (ptr->sky_mesh) mesh_free(ptr->sky_mesh);
      92          11 :         if (ptr->ground_mesh) mesh_free(ptr->ground_mesh);
      93             : 
      94          11 :         gf_sg_vrml_mf_reset(&ptr->ground_ang, GF_SG_VRML_MFFLOAT);
      95          11 :         gf_sg_vrml_mf_reset(&ptr->sky_ang, GF_SG_VRML_MFFLOAT);
      96          11 :         gf_sg_vrml_mf_reset(&ptr->ground_col, GF_SG_VRML_MFCOLOR);
      97          11 :         gf_sg_vrml_mf_reset(&ptr->sky_col, GF_SG_VRML_MFCOLOR);
      98             : 
      99          11 :         mesh_free(ptr->front_mesh);
     100          11 :         mesh_free(ptr->back_mesh);
     101          11 :         mesh_free(ptr->top_mesh);
     102          11 :         mesh_free(ptr->bottom_mesh);
     103          11 :         mesh_free(ptr->left_mesh);
     104          11 :         mesh_free(ptr->right_mesh);
     105             : 
     106             : 
     107          11 :         gf_sc_texture_destroy(&ptr->txh_front);
     108          11 :         gf_sc_texture_destroy(&ptr->txh_back);
     109          11 :         gf_sc_texture_destroy(&ptr->txh_top);
     110          11 :         gf_sc_texture_destroy(&ptr->txh_bottom);
     111          11 :         gf_sc_texture_destroy(&ptr->txh_left);
     112          11 :         gf_sc_texture_destroy(&ptr->txh_right);
     113             : 
     114          11 :         gf_free(ptr);
     115          11 : }
     116             : 
     117             : #define COL_TO_RGBA(res, col) { res.red = col.red; res.green = col.green; res.blue = col.blue; res.alpha = FIX_ONE; }
     118             : 
     119             : #define DOME_STEP_V     32
     120             : #define DOME_STEP_H     16
     121             : 
     122           4 : static void back_build_dome(GF_Mesh *mesh, MFFloat *angles, MFColor *color, Bool ground_dome)
     123             : {
     124             :         u32 i, j, last_idx, ang_idx, new_idx;
     125             :         Bool pad;
     126             :         u32 step_div_h;
     127             :         GF_Vertex vx;
     128             :         SFColorRGBA start_col, end_col, fcol;
     129             :         Fixed start_angle, next_angle, angle, r, frac, first_angle;
     130             : 
     131             :         start_angle = 0;
     132           4 :         mesh_reset(mesh);
     133             : 
     134             :         start_col.red = start_col.green = start_col.blue = 0;
     135             :         start_col.alpha = FIX_ONE;
     136             :         end_col = start_col;
     137             : 
     138           4 :         if (color->count) {
     139           4 :                 COL_TO_RGBA(start_col, color->vals[0]);
     140             :                 end_col = start_col;
     141           4 :                 if (color->count>1) COL_TO_RGBA(end_col, color->vals[1]);
     142             :         }
     143             : 
     144           4 :         vx.texcoords.x = vx.texcoords.y = 0;
     145           4 :         vx.color = MESH_MAKE_COL(start_col);
     146           4 :         vx.pos.x = vx.pos.z = 0;
     147           4 :         vx.pos.y = FIX_ONE;
     148           4 :         vx.normal.x = vx.normal.z = 0;
     149           4 :         vx.normal.y = -MESH_NORMAL_UNIT;
     150             : 
     151           4 :         mesh_set_vertex_vx(mesh, &vx);
     152             :         last_idx = 0;
     153             :         ang_idx = 0;
     154             : 
     155             :         pad = 1;
     156             :         next_angle = first_angle = 0;
     157           4 :         if (angles->count) {
     158           4 :                 next_angle = angles->vals[0];
     159           4 :                 first_angle = 7*next_angle/8;
     160             :                 pad = 0;
     161             :         }
     162             : 
     163             :         step_div_h = DOME_STEP_H;
     164             :         i=0;
     165           4 :         if (ground_dome) {
     166             :                 step_div_h *= 2;
     167             :                 i=1;
     168             :         }
     169             : 
     170         106 :         for (; i<DOME_STEP_V; i++) {
     171         108 :                 if (ground_dome) {
     172          44 :                         angle = first_angle + (i * (GF_PI2-first_angle) / DOME_STEP_V);
     173             :                 } else {
     174          64 :                         angle = (i * GF_PI / DOME_STEP_V);
     175             :                 }
     176             : 
     177             :                 /*switch cols*/
     178         108 :                 if (angle >= next_angle) {
     179          34 :                         if (ang_idx+1 < angles->count) {
     180             :                                 start_angle = next_angle;
     181           6 :                                 next_angle = angles->vals[ang_idx+1];
     182           6 :                                 if (next_angle>GF_PI) next_angle=GF_PI;
     183             :                                 start_col = end_col;
     184             :                                 ang_idx++;
     185           6 :                                 if (ang_idx+1<color->count) {
     186           6 :                                         COL_TO_RGBA(end_col, color->vals[ang_idx+1]);
     187             :                                 } else {
     188             :                                         pad = 1;
     189             :                                 }
     190             :                         } else {
     191          28 :                                 if (ground_dome) break;
     192             :                                 pad = 1;
     193             :                         }
     194             :                 }
     195             : 
     196         106 :                 if (pad) {
     197             :                         fcol = end_col;
     198             :                 } else {
     199          80 :                         frac = gf_divfix(angle - start_angle, next_angle - start_angle) ;
     200          80 :                         fcol.red = gf_mulfix(end_col.red - start_col.red, frac) + start_col.red;
     201          80 :                         fcol.green = gf_mulfix(end_col.green - start_col.green, frac) + start_col.green;
     202          80 :                         fcol.blue = gf_mulfix(end_col.blue - start_col.blue, frac) + start_col.blue;
     203             :                         fcol.alpha = FIX_ONE;
     204             :                 }
     205         106 :                 vx.color = MESH_MAKE_COL(fcol);
     206             : 
     207         106 :                 vx.pos.y = gf_sin(GF_PI2 - angle);
     208         106 :                 r = gf_sqrt(FIX_ONE - gf_mulfix(vx.pos.y, vx.pos.y));
     209             : 
     210         106 :                 new_idx = mesh->v_count;
     211        2474 :                 for (j = 0; j < step_div_h; j++) {
     212             :                         SFVec3f n;
     213        2368 :                         Fixed lon = 2 * GF_PI * j / step_div_h;
     214        2368 :                         vx.pos.x = gf_mulfix(gf_sin(lon), r);
     215        2368 :                         vx.pos.z = gf_mulfix(gf_cos(lon), r);
     216        2368 :                         n = gf_vec_scale(vx.pos, FIX_ONE /*-FIX_ONE*/);
     217        2368 :                         gf_vec_norm(&n);
     218        2368 :                         MESH_SET_NORMAL(vx, n);
     219        2368 :                         mesh_set_vertex_vx(mesh, &vx);
     220             : 
     221        2368 :                         if (j) {
     222        2262 :                                 if (i>1) {
     223        2140 :                                         mesh_set_triangle(mesh, last_idx+j, new_idx+j, new_idx+j-1);
     224        2140 :                                         mesh_set_triangle(mesh, last_idx+j, new_idx+j-1, last_idx+j-1);
     225             :                                 } else {
     226         122 :                                         mesh_set_triangle(mesh, 0, new_idx+j, new_idx+j-1);
     227             :                                 }
     228             :                         }
     229             :                 }
     230         106 :                 if (i>1) {
     231         100 :                         mesh_set_triangle(mesh, last_idx, new_idx, new_idx+step_div_h-1);
     232         100 :                         mesh_set_triangle(mesh, last_idx, new_idx+step_div_h-1, last_idx+step_div_h-1);
     233             :                 } else {
     234           6 :                         mesh_set_triangle(mesh, 0, new_idx, new_idx+step_div_h-1);
     235             :                 }
     236             :                 last_idx = new_idx;
     237             :         }
     238             : 
     239           4 :         if (!ground_dome) {
     240           2 :                 new_idx = mesh->v_count;
     241           2 :                 vx.pos.x = vx.pos.z = 0;
     242           2 :                 vx.pos.y = -FIX_ONE;
     243           2 :                 vx.normal.x = vx.normal.z = 0;
     244           2 :                 vx.normal.y = MESH_NORMAL_UNIT;
     245           2 :                 mesh_set_vertex_vx(mesh, &vx);
     246             : 
     247          32 :                 for (j=1; j < step_div_h; j++) {
     248          30 :                         mesh_set_triangle(mesh, last_idx+j-1, last_idx+j, new_idx);
     249             :                 }
     250           2 :                 mesh_set_triangle(mesh, last_idx+step_div_h-1, last_idx, new_idx);
     251             :         }
     252             : 
     253           4 :         mesh->flags |= MESH_HAS_COLOR | MESH_NO_TEXTURE;
     254           4 :         mesh_update_bounds(mesh);
     255           4 : }
     256             : 
     257          59 : static void back_draw_texture(GF_TraverseState *tr_state, GF_TextureHandler *txh, GF_Mesh *mesh)
     258             : {
     259          59 :         if (gf_sc_texture_enable(txh, NULL)) {
     260          59 :                 tr_state->mesh_num_textures = 1;
     261          59 :                 visual_3d_mesh_paint(tr_state, mesh);
     262          59 :                 gf_sc_texture_disable(txh);
     263          59 :                 tr_state->mesh_num_textures = 0;
     264             :         }
     265          59 : }
     266             : 
     267         530 : static void TraverseBackground(GF_Node *node, void *rs, Bool is_destroy)
     268             : {
     269             :         M_Background *bck;
     270             :         BackgroundStack *st;
     271             :         SFVec4f res;
     272             :         Fixed scale;
     273             :         Bool has_sky, has_ground, front_tx, back_tx, top_tx, bottom_tx, right_tx, left_tx;
     274             :         GF_Matrix mx;
     275             :         GF_Compositor *compositor;
     276             :         GF_TraverseState *tr_state = (GF_TraverseState *)rs;
     277             : 
     278         530 :         if (is_destroy) {
     279          11 :                 DestroyBackground(node);
     280          11 :                 return;
     281             :         }
     282         519 :         if (tr_state->visual->compositor->noback)
     283             :                 return;
     284             : 
     285         519 :         gf_node_dirty_clear(node, 0);
     286             :         bck = (M_Background *)node;
     287         519 :         st = (BackgroundStack *) gf_node_get_private(node);
     288         519 :         compositor = (GF_Compositor*)st->compositor;
     289             : 
     290             : 
     291             :         /*may happen in get_bounds*/
     292         519 :         if (!tr_state->backgrounds) return;
     293             : 
     294             :         /*first traverse, bound if needed*/
     295         517 :         if (gf_list_find(tr_state->backgrounds, node) < 0) {
     296          10 :                 gf_list_add(tr_state->backgrounds, node);
     297             :                 assert(gf_list_find(st->reg_stacks, tr_state->backgrounds)==-1);
     298          10 :                 gf_list_add(st->reg_stacks, tr_state->backgrounds);
     299             :                 /*only bound if we're on top*/
     300          10 :                 if (gf_list_get(tr_state->backgrounds, 0) == bck) {
     301          10 :                         if (!bck->isBound) Bindable_SetIsBound(node, 1);
     302             :                 }
     303             : 
     304             :                 /*check streams*/
     305          13 :                 if (back_use_texture(&bck->frontUrl) && !st->txh_front.is_open) gf_sc_texture_play(&st->txh_front, &bck->frontUrl);
     306          11 :                 if (back_use_texture(&bck->bottomUrl) && !st->txh_bottom.is_open) gf_sc_texture_play(&st->txh_bottom, &bck->bottomUrl);
     307          11 :                 if (back_use_texture(&bck->backUrl) && !st->txh_back.is_open) gf_sc_texture_play(&st->txh_back, &bck->backUrl);
     308          11 :                 if (back_use_texture(&bck->topUrl) && !st->txh_top.is_open) gf_sc_texture_play(&st->txh_top, &bck->topUrl);
     309          11 :                 if (back_use_texture(&bck->rightUrl) && !st->txh_right.is_open) gf_sc_texture_play(&st->txh_right, &bck->rightUrl);
     310          11 :                 if (back_use_texture(&bck->leftUrl) && !st->txh_left.is_open) gf_sc_texture_play(&st->txh_left, &bck->leftUrl);
     311             : 
     312             :                 /*in any case don't draw the first time (since the background could have been declared last)*/
     313          10 :                 gf_sc_invalidate(st->compositor, NULL);
     314          10 :                 return;
     315             :         }
     316         507 :         if (!bck->isBound) return;
     317             : 
     318         204 :         if (tr_state->traversing_mode != TRAVERSE_BINDABLE) {
     319         116 :                 if (tr_state->traversing_mode == TRAVERSE_SORT) {
     320          50 :                         gf_mx_copy(st->current_mx, tr_state->model_matrix);
     321          50 :                         if (!tr_state->pixel_metrics && tr_state->visual->compositor->inherit_type_3d) {
     322           0 :                                 Fixed pix_scale = gf_divfix(FIX_ONE, tr_state->min_hsize);
     323           0 :                                 gf_mx_add_scale(&st->current_mx, pix_scale, pix_scale, pix_scale);
     324             : 
     325             :                         }
     326             :                 }
     327             :                 return;
     328             :         }
     329             : 
     330          88 :         front_tx = back_gf_sc_texture_enabled(&bck->frontUrl, &st->txh_front);
     331          88 :         back_tx = back_gf_sc_texture_enabled(&bck->backUrl, &st->txh_back);
     332          88 :         top_tx = back_gf_sc_texture_enabled(&bck->topUrl, &st->txh_top);
     333          88 :         bottom_tx = back_gf_sc_texture_enabled(&bck->bottomUrl, &st->txh_bottom);
     334          88 :         right_tx = back_gf_sc_texture_enabled(&bck->rightUrl, &st->txh_right);
     335          88 :         left_tx = back_gf_sc_texture_enabled(&bck->leftUrl, &st->txh_left);
     336             : 
     337          88 :         has_sky = ((bck->skyColor.count>1) && bck->skyAngle.count) ? 1 : 0;
     338          88 :         has_ground = ((bck->groundColor.count>1) && bck->groundAngle.count) ? 1 : 0;
     339             : 
     340             :         /*if we clear the main visual clear it entirely - ONLY IF NOT IN LAYER*/
     341          88 :         if ((tr_state->visual == compositor->visual) && (tr_state->visual->back_stack == tr_state->backgrounds)) {
     342             :                 SFColor bcol;
     343          13 :                 bcol.red = INT2FIX( GF_COL_R(tr_state->visual->compositor->back_color)) / 255;
     344          13 :                 bcol.green = INT2FIX( GF_COL_G(tr_state->visual->compositor->back_color)) / 255;
     345          13 :                 bcol.blue = INT2FIX( GF_COL_B(tr_state->visual->compositor->back_color)) / 255;
     346             : 
     347          13 :                 visual_3d_clear(tr_state->visual, bcol, FIX_ONE);
     348          13 :                 if (!has_sky && !has_ground && !front_tx && !back_tx && !top_tx && !bottom_tx && !left_tx && !right_tx) {
     349           0 :                         return;
     350             :                 }
     351             :         }
     352             : 
     353             :         /*undo translation*/
     354          88 :         res.x = res.y = res.z = 0;
     355          88 :         res.q = FIX_ONE;
     356          88 :         gf_mx_apply_vec_4x4(&tr_state->camera->unprojection, &res);
     357             :         assert(res.q);
     358          88 :         res.x = gf_divfix(res.x, res.q);
     359          88 :         res.y = gf_divfix(res.y, res.q);
     360          88 :         res.z = gf_divfix(res.z, res.q);
     361             :         /*NB: we don't support local rotation of the background ...*/
     362             : 
     363             :         /*enable background state (turn off all quality options)*/
     364          88 :         visual_3d_set_background_state(tr_state->visual, 1);
     365             : 
     366          88 :         if (has_sky) {
     367             :                 GF_Matrix bck_mx;
     368          13 :                 gf_mx_copy(bck_mx, tr_state->model_matrix);
     369          13 :                 gf_mx_copy(tr_state->model_matrix, st->current_mx);
     370             : 
     371          13 :                 if (!st->sky_mesh) {
     372           2 :                         st->sky_mesh = new_mesh();
     373           2 :                         back_build_dome(st->sky_mesh, &bck->skyAngle, &bck->skyColor, 0);
     374             :                 }
     375             : 
     376          13 :                 gf_mx_init(mx);
     377          13 :                 gf_mx_add_translation(&mx, res.x, res.y, res.z);
     378             : 
     379             :                 /*CHECKME - not sure why, we need to scale less in fixed point otherwise z-far clipping occur - probably some
     380             :                 rounding issues...*/
     381             : #ifdef GPAC_FIXED_POINT
     382             :                 scale = (tr_state->camera->z_far/10)*8;
     383             : #else
     384          13 :                 scale = 8*tr_state->camera->z_far/10;
     385             : #endif
     386          13 :                 gf_mx_add_scale(&mx, scale, scale, scale);
     387             : 
     388          13 :                 gf_mx_add_matrix(&tr_state->model_matrix, &mx);
     389             : 
     390          13 :                 visual_3d_mesh_paint(tr_state, st->sky_mesh);
     391             : 
     392             :                 gf_mx_copy(tr_state->model_matrix, bck_mx);
     393             :         }
     394             : 
     395          88 :         if (has_ground) {
     396             :                 GF_Matrix bck_mx;
     397          13 :                 gf_mx_copy(bck_mx, tr_state->model_matrix);
     398          13 :                 gf_mx_copy(tr_state->model_matrix, st->current_mx);
     399             : 
     400          13 :                 if (!st->ground_mesh) {
     401           2 :                         st->ground_mesh = new_mesh();
     402           2 :                         back_build_dome(st->ground_mesh, &bck->groundAngle, &bck->groundColor, 1);
     403             :                 }
     404             : 
     405          13 :                 gf_mx_init(mx);
     406          13 :                 gf_mx_add_translation(&mx, res.x, res.y, res.z);
     407             :                 /*cf above*/
     408             : #ifdef GPAC_FIXED_POINT
     409             :                 scale = (tr_state->camera->z_far/100)*70;
     410             : #else
     411          13 :                 scale = 70*tr_state->camera->z_far/100;
     412             : #endif
     413          13 :                 gf_mx_add_scale(&mx, scale, -scale, scale);
     414             : 
     415          13 :                 gf_mx_add_matrix(&tr_state->model_matrix, &mx);
     416          13 :                 visual_3d_mesh_paint(tr_state, st->ground_mesh);
     417             :                 gf_mx_copy(tr_state->model_matrix, bck_mx);
     418             :         }
     419             : 
     420          88 :         if (front_tx || back_tx || left_tx || right_tx || top_tx || bottom_tx) {
     421             :                 GF_Matrix bck_mx;
     422          54 :                 gf_mx_copy(bck_mx, tr_state->model_matrix);
     423          54 :                 gf_mx_copy(tr_state->model_matrix, st->current_mx);
     424             : 
     425          54 :                 gf_mx_init(mx);
     426          54 :                 gf_mx_add_translation(&mx, res.x, res.y, res.z);
     427             : #ifdef GPAC_FIXED_POINT
     428             :                 scale = (tr_state->camera->z_far/100)*90;
     429             : #else
     430          54 :                 scale = (tr_state->camera->z_far/100)*90;
     431             : #endif
     432          54 :                 gf_mx_add_scale(&mx, scale, scale, scale);
     433             : 
     434          54 :                 visual_3d_enable_antialias(tr_state->visual, 1);
     435             : 
     436          54 :                 gf_mx_add_matrix(&tr_state->model_matrix, &mx);
     437             : 
     438          54 :                 if (front_tx) back_draw_texture(tr_state, &st->txh_front, st->front_mesh);
     439          54 :                 if (back_tx) back_draw_texture(tr_state, &st->txh_back, st->back_mesh);
     440          54 :                 if (top_tx) back_draw_texture(tr_state, &st->txh_top, st->top_mesh);
     441          54 :                 if (bottom_tx) back_draw_texture(tr_state, &st->txh_bottom, st->bottom_mesh);
     442          54 :                 if (left_tx) back_draw_texture(tr_state, &st->txh_left, st->left_mesh);
     443          54 :                 if (right_tx) back_draw_texture(tr_state, &st->txh_right, st->right_mesh);
     444             : 
     445             :                 gf_mx_copy(tr_state->model_matrix, bck_mx);
     446             :         }
     447             : 
     448             :         /*enable background state (turn off all quality options)*/
     449          88 :         visual_3d_set_background_state(tr_state->visual, 0);
     450             : }
     451             : 
     452             : 
     453           5 : static void back_set_bind(GF_Node *node, GF_Route *route)
     454             : {
     455           5 :         BackgroundStack *st = (BackgroundStack *)gf_node_get_private(node);
     456           5 :         Bindable_OnSetBind(node, st->reg_stacks, NULL);
     457             :         /*and redraw scene*/
     458           5 :         gf_sc_invalidate(st->compositor, NULL);
     459           5 : }
     460             : 
     461          11 : void compositor_init_background(GF_Compositor *compositor, GF_Node *node)
     462             : {
     463             :         BackgroundStack *ptr;
     464          11 :         GF_SAFEALLOC(ptr, BackgroundStack);
     465          11 :         if (!ptr) {
     466           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor] Failed to allocate background stack\n"));
     467             :                 return;
     468             :         }
     469             : 
     470          11 :         ptr->compositor = compositor;
     471          11 :         ptr->reg_stacks = gf_list_new();
     472          11 :         ((M_Background *)node)->on_set_bind = back_set_bind;
     473             : 
     474          22 :         gf_mx_init(ptr->current_mx);
     475             : 
     476             :         /*build texture cube*/
     477          11 :         ptr->front_mesh = new_mesh();
     478          11 :         mesh_set_vertex(ptr->front_mesh, -PLANE_HSIZE, -PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, 0, 0);
     479          11 :         mesh_set_vertex(ptr->front_mesh,  PLANE_HSIZE, -PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, FIX_ONE, 0);
     480          11 :         mesh_set_vertex(ptr->front_mesh,  PLANE_HSIZE,  PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, FIX_ONE, FIX_ONE);
     481          11 :         mesh_set_vertex(ptr->front_mesh, -PLANE_HSIZE,  PLANE_HSIZE, -PLANE_HSIZE_LOW,  0,  0,  FIX_ONE, 0, FIX_ONE);
     482          11 :         mesh_set_triangle(ptr->front_mesh, 0, 1, 2);
     483          11 :         mesh_set_triangle(ptr->front_mesh, 0, 2, 3);
     484          11 :         mesh_update_bounds(ptr->front_mesh);
     485             : 
     486          11 :         ptr->back_mesh = new_mesh();
     487          11 :         mesh_set_vertex(ptr->back_mesh, -PLANE_HSIZE, -PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, FIX_ONE, 0);
     488          11 :         mesh_set_vertex(ptr->back_mesh,  PLANE_HSIZE, -PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, 0, 0);
     489          11 :         mesh_set_vertex(ptr->back_mesh,  PLANE_HSIZE,  PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, 0, FIX_ONE);
     490          11 :         mesh_set_vertex(ptr->back_mesh, -PLANE_HSIZE,  PLANE_HSIZE,  PLANE_HSIZE_LOW,  0,  0,  -FIX_ONE, FIX_ONE, FIX_ONE);
     491          11 :         mesh_set_triangle(ptr->back_mesh, 0, 1, 2);
     492          11 :         mesh_set_triangle(ptr->back_mesh, 0, 2, 3);
     493          11 :         mesh_update_bounds(ptr->back_mesh);
     494             : 
     495          11 :         ptr->top_mesh = new_mesh();
     496          11 :         mesh_set_vertex(ptr->top_mesh, -PLANE_HSIZE,  PLANE_HSIZE_LOW,  PLANE_HSIZE,  0,  -FIX_ONE,  0, 0, 0);
     497          11 :         mesh_set_vertex(ptr->top_mesh,  PLANE_HSIZE,  PLANE_HSIZE_LOW,  PLANE_HSIZE,  0,  -FIX_ONE,  0, 0, FIX_ONE);
     498          11 :         mesh_set_vertex(ptr->top_mesh,  PLANE_HSIZE,  PLANE_HSIZE_LOW, -PLANE_HSIZE,  0,  -FIX_ONE,  0, FIX_ONE, FIX_ONE);
     499          11 :         mesh_set_vertex(ptr->top_mesh, -PLANE_HSIZE,  PLANE_HSIZE_LOW, -PLANE_HSIZE,  0,  -FIX_ONE,  0, FIX_ONE, 0);
     500          11 :         mesh_set_triangle(ptr->top_mesh, 0, 1, 2);
     501          11 :         mesh_set_triangle(ptr->top_mesh, 0, 2, 3);
     502          11 :         mesh_update_bounds(ptr->top_mesh);
     503             : 
     504          11 :         ptr->bottom_mesh = new_mesh();
     505          11 :         mesh_set_vertex(ptr->bottom_mesh, -PLANE_HSIZE, -PLANE_HSIZE_LOW, -PLANE_HSIZE,  0, FIX_ONE,  0, FIX_ONE, FIX_ONE);
     506          11 :         mesh_set_vertex(ptr->bottom_mesh,  PLANE_HSIZE, -PLANE_HSIZE_LOW, -PLANE_HSIZE,  0, FIX_ONE,  0, FIX_ONE, 0);
     507          11 :         mesh_set_vertex(ptr->bottom_mesh,  PLANE_HSIZE, -PLANE_HSIZE_LOW,  PLANE_HSIZE,  0, FIX_ONE,  0, 0, 0);
     508          11 :         mesh_set_vertex(ptr->bottom_mesh, -PLANE_HSIZE, -PLANE_HSIZE_LOW,  PLANE_HSIZE,  0, FIX_ONE,  0, 0, FIX_ONE);
     509          11 :         mesh_set_triangle(ptr->bottom_mesh, 0, 1, 2);
     510          11 :         mesh_set_triangle(ptr->bottom_mesh, 0, 2, 3);
     511          11 :         mesh_update_bounds(ptr->bottom_mesh);
     512             : 
     513          11 :         ptr->left_mesh = new_mesh();
     514          11 :         mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW, -PLANE_HSIZE, -PLANE_HSIZE, FIX_ONE,  0,  0, FIX_ONE, 0);
     515          11 :         mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW, -PLANE_HSIZE,  PLANE_HSIZE, FIX_ONE,  0,  0, 0, 0);
     516          11 :         mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW,  PLANE_HSIZE,  PLANE_HSIZE, FIX_ONE,  0,  0, 0, FIX_ONE);
     517          11 :         mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW,  PLANE_HSIZE, -PLANE_HSIZE, FIX_ONE,  0,  0, FIX_ONE, FIX_ONE);
     518          11 :         mesh_set_triangle(ptr->left_mesh, 0, 1, 2);
     519          11 :         mesh_set_triangle(ptr->left_mesh, 0, 2, 3);
     520          11 :         mesh_update_bounds(ptr->left_mesh);
     521             : 
     522          11 :         ptr->right_mesh = new_mesh();
     523          11 :         mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW, -PLANE_HSIZE,  PLANE_HSIZE, -FIX_ONE,  0,  0, FIX_ONE, 0);
     524          11 :         mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW, -PLANE_HSIZE, -PLANE_HSIZE, -FIX_ONE,  0,  0, 0, 0);
     525          11 :         mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW,  PLANE_HSIZE, -PLANE_HSIZE, -FIX_ONE,  0,  0, 0, FIX_ONE);
     526          11 :         mesh_set_vertex(ptr->right_mesh,  PLANE_HSIZE_LOW,  PLANE_HSIZE,  PLANE_HSIZE, -FIX_ONE,  0,  0, FIX_ONE, FIX_ONE);
     527          11 :         mesh_set_triangle(ptr->right_mesh, 0, 1, 2);
     528          11 :         mesh_set_triangle(ptr->right_mesh, 0, 2, 3);
     529          11 :         mesh_update_bounds(ptr->right_mesh);
     530             : 
     531             : 
     532          11 :         gf_sc_texture_setup(&ptr->txh_back, compositor, node);
     533          11 :         ptr->txh_back.update_texture_fcnt = UpdateBackgroundTexture;
     534          11 :         gf_sc_texture_setup(&ptr->txh_front, compositor, node);
     535          11 :         ptr->txh_front.update_texture_fcnt = UpdateBackgroundTexture;
     536          11 :         gf_sc_texture_setup(&ptr->txh_top, compositor, node);
     537          11 :         ptr->txh_top.update_texture_fcnt = UpdateBackgroundTexture;
     538          11 :         gf_sc_texture_setup(&ptr->txh_bottom, compositor, node);
     539          11 :         ptr->txh_bottom.update_texture_fcnt = UpdateBackgroundTexture;
     540          11 :         gf_sc_texture_setup(&ptr->txh_left, compositor, node);
     541          11 :         ptr->txh_left.update_texture_fcnt = UpdateBackgroundTexture;
     542          11 :         gf_sc_texture_setup(&ptr->txh_right, compositor, node);
     543          11 :         ptr->txh_right.update_texture_fcnt = UpdateBackgroundTexture;
     544             : 
     545          11 :         gf_node_set_private(node, ptr);
     546          11 :         gf_node_set_callback_function(node, TraverseBackground);
     547             : 
     548             : }
     549             : 
     550           5 : void compositor_background_modified(GF_Node *node)
     551             : {
     552             :         M_Background *bck = (M_Background *)node;
     553           5 :         BackgroundStack *st = (BackgroundStack *) gf_node_get_private(node);
     554           5 :         if (!st) return;
     555             : 
     556           5 :         if (!gf_sg_vrml_field_equal(&bck->skyColor, &st->sky_col, GF_SG_VRML_MFCOLOR)
     557           2 :                 || !gf_sg_vrml_field_equal(&bck->skyAngle, &st->sky_ang, GF_SG_VRML_MFFLOAT)
     558             :            ) {
     559             : 
     560           3 :                 if (st->sky_mesh) mesh_free(st->sky_mesh);
     561           3 :                 st->sky_mesh = NULL;
     562           3 :                 gf_sg_vrml_field_copy(&st->sky_col, &bck->skyColor, GF_SG_VRML_MFCOLOR);
     563           3 :                 gf_sg_vrml_field_copy(&st->sky_ang, &bck->skyAngle, GF_SG_VRML_MFFLOAT);
     564             :         }
     565           5 :         if (!gf_sg_vrml_field_equal(&bck->groundColor, &st->ground_col, GF_SG_VRML_MFCOLOR)
     566           5 :                 || !gf_sg_vrml_field_equal(&bck->groundAngle, &st->ground_ang, GF_SG_VRML_MFFLOAT)
     567             :            ) {
     568             : 
     569           0 :                 if (st->ground_mesh) mesh_free(st->ground_mesh);
     570           0 :                 st->ground_mesh = NULL;
     571           0 :                 gf_sg_vrml_field_copy(&st->ground_col, &bck->groundColor, GF_SG_VRML_MFCOLOR);
     572           0 :                 gf_sg_vrml_field_copy(&st->ground_ang, &bck->groundAngle, GF_SG_VRML_MFFLOAT);
     573             :         }
     574             : 
     575           5 :         back_check_gf_sc_texture_change(&st->txh_front, &bck->frontUrl);
     576           5 :         back_check_gf_sc_texture_change(&st->txh_back, &bck->backUrl);
     577           5 :         back_check_gf_sc_texture_change(&st->txh_top, &bck->topUrl);
     578           5 :         back_check_gf_sc_texture_change(&st->txh_bottom, &bck->bottomUrl);
     579           5 :         back_check_gf_sc_texture_change(&st->txh_left, &bck->leftUrl);
     580           5 :         back_check_gf_sc_texture_change(&st->txh_right, &bck->rightUrl);
     581             : 
     582             : 
     583           5 :         gf_sc_invalidate(st->compositor, NULL);
     584             : }
     585             : 
     586             : #endif /*GPAC_DISABLE_3D*/
     587             : 
     588             : #endif  /*GPAC_DISABLE_VRML*/

Generated by: LCOV version 1.13