LCOV - code coverage report
Current view: top level - compositor - mpeg4_geometry_ifs2d.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 75 125 60.0 %
Date: 2021-04-29 23:48:07 Functions: 4 6 66.7 %

          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             : #include "visual_manager.h"
      30             : 
      31             : #ifndef GPAC_DISABLE_VRML
      32             : 
      33        7558 : static void ifs2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
      34             : {
      35             :         u32 i;
      36             :         SFVec2f *pts;
      37             :         u32 ci_count, c_count;
      38             :         Bool started;
      39             :         M_IndexedFaceSet2D *ifs2D;
      40             :         M_Coordinate2D *coord;
      41             : 
      42        7558 :         if (! gf_node_dirty_get(node)) return;
      43             : 
      44             :         ifs2D = (M_IndexedFaceSet2D *)node;
      45         243 :         coord = (M_Coordinate2D *)ifs2D->coord;
      46         243 :         drawable_reset_path(stack);
      47         243 :         gf_node_dirty_clear(node, 0);
      48         243 :         drawable_mark_modified(stack, tr_state);
      49             : 
      50             : 
      51         243 :         c_count = coord->point.count;
      52         243 :         ci_count = ifs2D->coordIndex.count;
      53         243 :         pts = coord->point.vals;
      54             : 
      55         243 :         if (ci_count > 0) {
      56             :                 started = 0;
      57         201 :                 for (i=0; i < ci_count; i++) {
      58         201 :                         if (ifs2D->coordIndex.vals[i] == -1) {
      59          25 :                                 gf_path_close(stack->path);
      60             :                                 started = 0;
      61         176 :                         } else if (!started) {
      62             :                                 started = 1;
      63          36 :                                 gf_path_add_move_to_vec(stack->path, &pts[ifs2D->coordIndex.vals[i]]);
      64             :                         } else {
      65         140 :                                 gf_path_add_line_to_vec(stack->path, &pts[ifs2D->coordIndex.vals[i]]);
      66             :                         }
      67             :                 }
      68          26 :                 if (started) gf_path_close(stack->path);
      69         217 :         } else if (c_count) {
      70         217 :                 gf_path_add_move_to_vec(stack->path, &pts[0]);
      71        1227 :                 for (i=1; i < c_count; i++) {
      72        1010 :                         gf_path_add_line_to_vec(stack->path, &pts[i]);
      73             :                 }
      74         217 :                 gf_path_close(stack->path);
      75             :         }
      76             : }
      77             : 
      78             : 
      79        2419 : static void IFS2D_Draw(GF_Node *node, GF_TraverseState *tr_state)
      80             : {
      81             :         u32 i, count, ci_count;
      82             : #if 0 //unused
      83             :         u32 j, ind_col, num_col;
      84             :         SFVec2f center, end;
      85             :         SFColor col_cen;
      86             :         GF_EVGStencil *grad;
      87             :         u32 *colors;
      88             : #endif
      89             :         SFVec2f start;
      90             :         SFVec2f *pts;
      91             :         SFColor col;
      92             :         Fixed alpha;
      93        2419 :         DrawableContext *ctx = tr_state->ctx;
      94             :         M_IndexedFaceSet2D *ifs2D = (M_IndexedFaceSet2D *)node;
      95        2419 :         M_Coordinate2D *coord = (M_Coordinate2D*) ifs2D->coord;
      96        2419 :         M_Color *color = (M_Color *) ifs2D->color;
      97             : 
      98             :         col.red = col.green = col.blue = 0;
      99             :         /*simple case, no color specified*/
     100        2419 :         if (!ifs2D->color) {
     101        2409 :                 visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state);
     102        2409 :                 visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state);
     103        2409 :                 return;
     104             :         }
     105             : 
     106             :         /*if default face use first color*/
     107          10 :         ci_count = ifs2D->coordIndex.count;
     108          10 :         pts = coord->point.vals;
     109             : 
     110          10 :         if (ci_count == 0) {
     111           0 :                 col = (ifs2D->colorIndex.count > 0) ? color->color.vals[ifs2D->colorIndex.vals[0]] : color->color.vals[0];
     112             : 
     113           0 :                 alpha = INT2FIX(GF_COL_A(ctx->aspect.fill_color)) / 255;
     114           0 :                 if (!alpha || !ctx->aspect.pen_props.width) {
     115           0 :                         alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255;
     116           0 :                         ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     117             :                 } else {
     118           0 :                         ctx->aspect.fill_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     119             :                 }
     120           0 :                 visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state);
     121           0 :                 visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state);
     122           0 :                 return;
     123             :         }
     124             : 
     125             :         /*we have color per faces so we need N path :(*/
     126          10 :         if (! ifs2D->colorPerVertex) {
     127           0 :                 GF_Path *path = gf_path_new();
     128             : 
     129             :                 count = 0;
     130             :                 i = 0;
     131             :                 while (1) {
     132           0 :                         gf_path_reset(path);
     133           0 :                         start = pts[ifs2D->coordIndex.vals[i]];
     134           0 :                         gf_path_add_move_to(path, start.x, start.y);
     135           0 :                         i++;
     136             : 
     137           0 :                         while (ifs2D->coordIndex.vals[i] != -1) {
     138           0 :                                 start = pts[ifs2D->coordIndex.vals[i]];
     139           0 :                                 gf_path_add_line_to(path, start.x, start.y);
     140           0 :                                 i++;
     141           0 :                                 if (i >= ci_count) break;
     142             :                         }
     143             :                         /*close in ALL cases because even if the start/end points are the same the line join needs to be present*/
     144           0 :                         gf_path_close(path);
     145             : 
     146           0 :                         col = (ifs2D->colorIndex.count > 0) ? color->color.vals[ifs2D->colorIndex.vals[count]] : color->color.vals[count];
     147             : 
     148           0 :                         alpha = INT2FIX(GF_COL_A(ctx->aspect.fill_color)) / 255;
     149           0 :                         if (!alpha) {
     150           0 :                                 alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255;
     151           0 :                                 ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     152             :                         } else {
     153           0 :                                 ctx->aspect.fill_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     154             :                         }
     155             : 
     156           0 :                         visual_2d_texture_path(tr_state->visual, path, ctx, tr_state);
     157           0 :                         visual_2d_draw_path(tr_state->visual, path, ctx, NULL, NULL, tr_state);
     158           0 :                         count++;
     159           0 :                         i++;
     160           0 :                         if (i >= ci_count) break;
     161           0 :                         ctx->flags &= ~CTX_PATH_FILLED;
     162           0 :                         ctx->flags &= ~CTX_PATH_STROKE;
     163             :                 }
     164           0 :                 gf_path_del(path);
     165           0 :                 return;
     166             :         }
     167             : 
     168             :         /*final case, color per vertex means gradient fill/strike*/
     169             :         /*not supported, fill default*/
     170          10 :         visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state);
     171          10 :         visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state);
     172          10 :         return;
     173             : 
     174             : 
     175             : #if 0 //deprecated
     176             :         path = gf_path_new();
     177             : 
     178             :         ind_col = 0;
     179             :         i = 0;
     180             :         while (1) {
     181             :                 gf_path_reset(path);
     182             :                 start = pts[ifs2D->coordIndex.vals[i]];
     183             :                 center = start;
     184             :                 gf_path_add_move_to(path, start.x, start.y);
     185             :                 num_col = 1;
     186             :                 i+=1;
     187             :                 while (ifs2D->coordIndex.vals[i] != -1) {
     188             :                         end = pts[ifs2D->coordIndex.vals[i]];
     189             :                         gf_path_add_line_to(path, end.x, end.y);
     190             :                         i++;
     191             :                         center.x += end.x;
     192             :                         center.y += end.y;
     193             :                         num_col ++;
     194             :                         if (i >= ci_count) break;
     195             :                 }
     196             :                 gf_path_close(path);
     197             :                 num_col++;
     198             : 
     199             :                 alpha = INT2FIX(GF_COL_A(ctx->aspect.fill_color) ) / 255;
     200             : 
     201             :                 colors = (u32*)gf_malloc(sizeof(u32) * num_col);
     202             :                 col_cen.blue = col_cen.red = col_cen.green = 0;
     203             :                 for (j=0; j<num_col-1; j++) {
     204             :                         if (ifs2D->colorIndex.count > ind_col + j) {
     205             :                                 col = color->color.vals[ifs2D->colorIndex.vals[ind_col + j]];
     206             :                         } else if (ci_count > ind_col + j) {
     207             :                                 col = color->color.vals[ifs2D->coordIndex.vals[ind_col + j]];
     208             :                         }
     209             :                         colors[j] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     210             :                         col_cen.blue += col.blue;
     211             :                         col_cen.green += col.green;
     212             :                         col_cen.red += col.red;
     213             :                 }
     214             :                 colors[num_col-1] = colors[0];
     215             : 
     216             :                 if (ifs2D->colorIndex.count > ind_col) {
     217             :                         col = color->color.vals[ifs2D->colorIndex.vals[ind_col]];
     218             :                 } else if (ci_count > ind_col) {
     219             :                         col = color->color.vals[ifs2D->coordIndex.vals[ind_col]];
     220             :                 }
     221             :                 col_cen.blue += col.blue;
     222             :                 col_cen.green += col.green;
     223             :                 col_cen.red += col.red;
     224             : 
     225             :                 gf_evg_stencil_set_vertex_path(grad, path);
     226             :                 gf_evg_stencil_set_vertex_colors(grad, colors, num_col);
     227             : 
     228             :                 gf_free(colors);
     229             : 
     230             :                 col_cen.blue /= num_col;
     231             :                 col_cen.green /= num_col;
     232             :                 col_cen.red /= num_col;
     233             :                 center.x /= num_col;
     234             :                 center.y /= num_col;
     235             :                 gf_evg_stencil_set_vertex_center(grad, center.x, center.y, GF_COL_ARGB_FIXED(alpha, col_cen.red, col_cen.green, col_cen.blue) );
     236             : 
     237             :                 gf_evg_stencil_set_matrix(grad, &ctx->transform);
     238             : 
     239             :                 /*draw*/
     240             :                 visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, grad, grad, tr_state);
     241             : 
     242             :                 gf_evg_stencil_delete(grad);
     243             : 
     244             :                 //goto next point
     245             :                 i++;
     246             :                 ind_col += num_col + 1;
     247             :                 if (i >= ci_count) break;
     248             :                 grad = gf_evg_stencil_new(GF_STENCIL_VERTEX_GRADIENT);
     249             :                 ctx->flags &= ~CTX_PATH_FILLED;
     250             :                 ctx->flags &= ~CTX_PATH_STROKE;
     251             :         }
     252             :         gf_path_del(path);
     253             : #endif
     254             : 
     255             : 
     256             : }
     257             : 
     258        7651 : static void TraverseIFS2D(GF_Node *node, void *rs, Bool is_destroy)
     259             : {
     260             :         DrawableContext *ctx;
     261             :         M_IndexedFaceSet2D *ifs2D = (M_IndexedFaceSet2D *)node;
     262        7651 :         Drawable *stack = (Drawable *)gf_node_get_private(node);
     263             :         GF_TraverseState *tr_state = (GF_TraverseState *)rs;
     264             : 
     265        7651 :         if (is_destroy) {
     266          93 :                 drawable_node_del(node);
     267          93 :                 return;
     268             :         }
     269        7558 :         if (!ifs2D->coord) return;
     270             : 
     271        7558 :         ifs2d_check_changes(node, stack, tr_state);
     272             : 
     273        7558 :         switch (tr_state->traversing_mode) {
     274        2419 :         case TRAVERSE_DRAW_2D:
     275        2419 :                 IFS2D_Draw(node, tr_state);
     276        2419 :                 return;
     277             : #ifndef GPAC_DISABLE_3D
     278         211 :         case TRAVERSE_DRAW_3D:
     279             :         {
     280             :                 DrawAspect2D asp;
     281             : 
     282         211 :                 if (!stack->mesh) {
     283          32 :                         stack->mesh = new_mesh();
     284          32 :                         mesh_new_ifs2d(stack->mesh, node);
     285             :                 }
     286             : 
     287             :                 memset(&asp, 0, sizeof(DrawAspect2D));
     288         211 :                 drawable_get_aspect_2d_mpeg4(node, &asp, tr_state);
     289         211 :                 if (ifs2D->color && !GF_COL_A(asp.fill_color) ) {
     290             :                         /*use special func to disable outline recompute and handle recompute ourselves*/
     291           0 :                         StrikeInfo2D *si = drawable_get_strikeinfo(tr_state->visual->compositor, stack, &asp, tr_state->appear, NULL, 0, tr_state);
     292           0 :                         if (!si->mesh_outline) {
     293           0 :                                 si->mesh_outline = new_mesh();
     294           0 :                                 mesh_new_ils(si->mesh_outline, ifs2D->coord, &ifs2D->coordIndex, ifs2D->color, &ifs2D->colorIndex, ifs2D->colorPerVertex, 1);
     295             :                         }
     296           0 :                         visual_3d_mesh_strike(tr_state, si->mesh_outline, asp.pen_props.width, asp.line_scale, asp.pen_props.dash);
     297             :                 } else {
     298         211 :                         visual_3d_draw_2d_with_aspect(stack, tr_state, &asp);
     299             :                 }
     300             :                 return;
     301             :         }
     302             : #endif
     303         674 :         case TRAVERSE_PICK:
     304         674 :                 vrml_drawable_pick(stack, tr_state);
     305         674 :                 return;
     306           6 :         case TRAVERSE_GET_BOUNDS:
     307           6 :                 gf_path_get_bounds(stack->path, &tr_state->bounds);
     308           6 :                 return;
     309        4248 :         case TRAVERSE_SORT:
     310             : #ifndef GPAC_DISABLE_3D
     311        4248 :                 if (tr_state->visual->type_3d) return;
     312             : #endif
     313             : 
     314        4248 :                 ctx = drawable_init_context_mpeg4(stack, tr_state);
     315        4248 :                 if (!ctx) return;
     316        4243 :                 drawable_finalize_sort(ctx, tr_state, NULL);
     317        4243 :                 return;
     318             :         }
     319             : }
     320             : 
     321           0 : static void IFS2D_SetColorIndex(GF_Node *node, GF_Route *route)
     322             : {
     323             :         M_IndexedFaceSet2D *ifs2D = (M_IndexedFaceSet2D *)node;
     324           0 :         if (node) {
     325           0 :                 gf_sg_vrml_field_copy(&ifs2D->colorIndex, &ifs2D->set_colorIndex, GF_SG_VRML_MFINT32);
     326           0 :                 gf_sg_vrml_mf_reset(&ifs2D->set_colorIndex, GF_SG_VRML_MFINT32);
     327             :         }
     328           0 : }
     329             : 
     330           0 : static void IFS2D_SetCoordIndex(GF_Node *node, GF_Route *route)
     331             : {
     332             :         M_IndexedFaceSet2D *ifs2D = (M_IndexedFaceSet2D *)node;
     333           0 :         if (node) {
     334           0 :                 gf_sg_vrml_field_copy(&ifs2D->coordIndex, &ifs2D->set_coordIndex, GF_SG_VRML_MFINT32);
     335           0 :                 gf_sg_vrml_mf_reset(&ifs2D->set_coordIndex, GF_SG_VRML_MFINT32);
     336             :         }
     337           0 : }
     338             : 
     339          93 : void compositor_init_indexed_face_set2d(GF_Compositor *compositor, GF_Node *node)
     340             : {
     341             :         M_IndexedFaceSet2D *ifs2D = (M_IndexedFaceSet2D *)node;
     342          93 :         Drawable *stack = drawable_stack_new(compositor, node);
     343          93 :         stack->flags = DRAWABLE_USE_TRAVERSE_DRAW;
     344          93 :         gf_node_set_callback_function(node, TraverseIFS2D);
     345          93 :         ifs2D->on_set_colorIndex = IFS2D_SetColorIndex;
     346          93 :         ifs2D->on_set_coordIndex = IFS2D_SetCoordIndex;
     347             : 
     348             : #ifdef GPAC_ENABLE_COVERAGE
     349          93 :         if (gf_sys_is_cov_mode()) {
     350             :                 IFS2D_SetCoordIndex(NULL, NULL);
     351             :                 IFS2D_SetColorIndex(NULL, NULL);
     352             :         }
     353             : #endif
     354             : 
     355          93 : }
     356             : 
     357             : #endif /*GPAC_DISABLE_VRML*/

Generated by: LCOV version 1.13