Bool compositor_compositetexture_handle_event(GF_Compositor *compositor, GF_Node *composite_appear, GF_Event *ev, Bool is_flush) { GF_Ray ray; Fixed dist; Bool had_text_sel=0; GF_Matrix mx; GF_TraverseState *tr_state; GF_ChildNodeItem *children, *l; Bool res; SFVec3f txcoord, loc_pt, world_pt; GF_Matrix l2w_mx, w2l_mx; CompositeTextureStack *stack; GF_Node *appear, *prev_appear; M_Appearance *ap = (M_Appearance *)composite_appear; assert(ap && ap->texture); if (ev->type > GF_EVENT_MOUSEMOVE) return 0; stack = gf_node_get_private(ap->texture); if (!stack->txh.tx_io) return 0; tr_state = NULL; children = NULL; if (!is_flush) { txcoord.x = compositor->hit_texcoords.x; txcoord.y = compositor->hit_texcoords.y; txcoord.z = 0; if (gf_sc_texture_get_transform(&stack->txh, ap->textureTransform, &mx, 1)) { /*tx coords are inverted when mapping, thus applying directly the matrix will give us the untransformed coords*/ gf_mx_apply_vec(&mx, &txcoord); while (txcoord.x<0) txcoord.x += FIX_ONE; while (txcoord.x>FIX_ONE) txcoord.x -= FIX_ONE; while (txcoord.y<0) txcoord.y += FIX_ONE; while (txcoord.y>FIX_ONE) txcoord.y -= FIX_ONE; } /*convert to tx space*/ ev->mouse.x = FIX2INT( (txcoord.x - FIX_ONE/2) * stack->visual->width + FIX_ONE/2); ev->mouse.y = FIX2INT( (txcoord.y - FIX_ONE/2) * stack->visual->height + FIX_ONE/2); GF_SAFEALLOC(tr_state, GF_TraverseState); tr_state->vrml_sensors = gf_list_new(); tr_state->visual = stack->visual; tr_state->traversing_mode = TRAVERSE_PICK; tr_state->pixel_metrics = gf_sg_use_pixel_metrics(gf_node_get_graph(ap->texture)); tr_state->vp_size.x = INT2FIX(stack->txh.width); tr_state->vp_size.y = INT2FIX(stack->txh.height); tr_state->color_mat.identity = 1; gf_mx2d_init(tr_state->transform); #ifndef GPAC_DISABLE_3D gf_mx_init(tr_state->model_matrix); #endif /*collect sensors*/ l = children = ((M_CompositeTexture2D*)ap->texture)->children; while (l) { GF_SensorHandler *hsens = compositor_mpeg4_get_sensor_handler(l->node); if (hsens) gf_list_add(tr_state->vrml_sensors, hsens); l = l->next; } } stack->temp_sensors = compositor->sensors; stack->temp_previous_sensors = compositor->previous_sensors; compositor->sensors = stack->sensors; compositor->previous_sensors = stack->previous_sensors; ray = compositor->hit_world_ray; dist = compositor->hit_square_dist; prev_appear = compositor->prev_hit_appear; /*protect against destrucion in case of self-destroy*/ if (prev_appear) { gf_node_register(prev_appear, NULL); } compositor->prev_hit_appear = stack->prev_hit_appear; appear = compositor->hit_appear; compositor->hit_appear = NULL; /*also backup current hit state in case we hit a node in the texture but don't consume the event*/ loc_pt = compositor->hit_local_point; world_pt = compositor->hit_world_point; gf_mx_copy(l2w_mx, compositor->hit_local_to_world); gf_mx_copy(w2l_mx, compositor->hit_world_to_local); if (compositor->text_selection) had_text_sel=1; if (is_flush) { res = 0; gf_list_reset(stack->sensors); gf_sc_exec_event_vrml(compositor, ev); } else { res = visual_execute_event(stack->visual, tr_state, ev, children); } if (!had_text_sel && compositor->edited_text) { stack->visual->has_text_edit = 1; } else if (!compositor->text_selection) { stack->visual->has_text_edit = 0; } if (!res) { compositor->hit_local_point = loc_pt; gf_mx_copy(compositor->hit_local_to_world, l2w_mx); gf_mx_copy(compositor->hit_world_to_local, w2l_mx); } stack->prev_hit_appear = compositor->prev_hit_appear; if (prev_appear) { if (prev_appear->sgprivate->num_instances>1) { compositor->prev_hit_appear = prev_appear; compositor->hit_appear = appear; } else { compositor->prev_hit_appear = NULL; compositor->hit_appear = NULL; } gf_node_unregister(prev_appear, NULL); } else { compositor->prev_hit_appear = prev_appear; compositor->hit_appear = appear; } compositor->hit_world_point = world_pt; compositor->hit_world_ray = ray; compositor->hit_square_dist = dist; stack->sensors = compositor->sensors; stack->previous_sensors = compositor->previous_sensors; compositor->sensors = stack->temp_sensors; stack->temp_sensors = NULL; compositor->previous_sensors = stack->temp_previous_sensors; stack->temp_previous_sensors = NULL; if (!is_flush) { gf_list_del(tr_state->vrml_sensors); #ifndef GPAC_DISABLE_3D if (tr_state->layer3d) compositor->traverse_state->layer3d = tr_state->layer3d; #endif gf_free(tr_state); } return res; }
Bool compositor_mpeg4_is_sensor_node(GF_Node *node) { GF_SensorHandler *sh = compositor_mpeg4_get_sensor_handler(node); if (sh && sh->IsEnabled(node)) return 1; return 0; }