void compositor_layer3d_bind_camera(GF_Node *node, Bool do_bind, u32 nav_value) { Layer3DStack *st = (Layer3DStack *) gf_node_get_private(node); GF_Node *n = (GF_Node*)gf_list_get(st->visual->navigation_stack, 0); if (n) Bindable_SetSetBind(n, do_bind); else st->visual->camera.navigate_mode = nav_value; }
GF_Err gf_sc_set_viewpoint(GF_Compositor *compositor, u32 viewpoint_idx, const char *viewpoint_name) { #ifndef GPAC_DISABLE_VRML u32 count, i; GF_Node *n; if (!compositor->visual) return GF_BAD_PARAM; count = gf_list_count(compositor->visual->view_stack); if (viewpoint_idx>count) return GF_BAD_PARAM; if (!viewpoint_idx && !viewpoint_name) return GF_BAD_PARAM; if (viewpoint_idx) { Bool bind; n = (GF_Node*)gf_list_get(compositor->visual->view_stack, viewpoint_idx-1); bind = Bindable_GetIsBound(n); Bindable_SetSetBind(n, !bind); return GF_OK; } for (i=0; i<count; i++) { char *name = NULL; n = (GF_Node*)gf_list_get(compositor->visual->view_stack, viewpoint_idx-1); switch (gf_node_get_tag(n)) { case TAG_MPEG4_Viewport: name = ((M_Viewport*)n)->description.buffer; break; case TAG_MPEG4_Viewpoint: name = ((M_Viewpoint*)n)->description.buffer; break; #ifndef GPAC_DISABLE_X3D case TAG_X3D_Viewpoint: name = ((M_Viewpoint*)n)->description.buffer; break; #endif default: break; } if (name && !stricmp(name, viewpoint_name)) { Bool bind = Bindable_GetIsBound(n); Bindable_SetSetBind(n, !bind); return GF_OK; } } return GF_BAD_PARAM; #else return GF_NOT_SUPPORTED; #endif }
static void OnAnchor(SensorHandler *sh, Bool is_over, GF_Event *ev, RayHitInfo *hit_info) { GF_Event evt; MFURL *url; AnchorStack *st = (AnchorStack *) gf_node_get_private(sh->owner); if ((ev->type==GF_EVENT_MOUSEDOWN) && (ev->mouse.button==GF_MOUSE_LEFT)) st->active = 1; else if (st->active && (ev->type==GF_EVENT_MOUSEUP) && (ev->mouse.button==GF_MOUSE_LEFT) ) { u32 i; if (gf_node_get_tag(sh->owner)==TAG_MPEG4_Anchor) { url = & ((M_Anchor *)sh->owner)->url; evt.navigate.param_count = ((M_Anchor *)sh->owner)->parameter.count; evt.navigate.parameters = (const char **) ((M_Anchor *)sh->owner)->parameter.vals; } else { url = & ((X_Anchor *)sh->owner)->url; evt.navigate.param_count = ((X_Anchor *)sh->owner)->parameter.count; evt.navigate.parameters = (const char **) ((X_Anchor *)sh->owner)->parameter.vals; } evt.type = GF_EVENT_NAVIGATE; i=0; while (i<url->count) { evt.navigate.to_url = url->vals[i].url; if (!evt.navigate.to_url) break; /*current scene navigation*/ if (evt.navigate.to_url[0] == '#') { GF_Node *bindable; evt.navigate.to_url++; bindable = gf_sg_find_node_by_name(gf_node_get_graph(sh->owner), (char *) evt.navigate.to_url); if (bindable) { Bindable_SetSetBind(bindable, 1); break; } } else if (st->compositor->term) { if (gf_is_process_anchor(sh->owner, &evt)) break; } else if (st->compositor->user->EventProc) { if (st->compositor->user->EventProc(st->compositor->user->opaque, &evt)) break; } i++; } } else if (ev->type==GF_EVENT_MOUSEMOVE) { if (st->compositor->user->EventProc) { evt.type = GF_EVENT_NAVIGATE_INFO; if (gf_node_get_tag(sh->owner)==TAG_MPEG4_Anchor) { evt.navigate.to_url = ((M_Anchor *)sh->owner)->description.buffer; url = & ((M_Anchor *)sh->owner)->url; } else { evt.navigate.to_url = ((X_Anchor *)sh->owner)->description.buffer; url = & ((X_Anchor *)sh->owner)->url; } if (!evt.navigate.to_url || !strlen(evt.navigate.to_url)) evt.navigate.to_url = url->vals[0].url; st->compositor->user->EventProc(st->compositor->user->opaque, &evt); } } }
static void anchor_activation(GF_Node *node, AnchorStack *st, GF_Compositor *compositor) { GF_Event evt; u32 i; MFURL *url = NULL; switch (gf_node_get_tag(node)) { case TAG_MPEG4_Anchor: url = & ((M_Anchor *)node)->url; evt.navigate.param_count = ((M_Anchor *)node)->parameter.count; evt.navigate.parameters = (const char **) ((M_Anchor *)node)->parameter.vals; break; #ifndef GPAC_DISABLE_X3D case TAG_X3D_Anchor: url = & ((X_Anchor *)node)->url; evt.navigate.param_count = ((X_Anchor *)node)->parameter.count; evt.navigate.parameters = (const char **) ((X_Anchor *)node)->parameter.vals; break; #endif } evt.type = GF_EVENT_NAVIGATE; i=0; while (url && i<url->count) { evt.navigate.to_url = url->vals[i].url; if (!evt.navigate.to_url) break; /*current scene navigation*/ if (evt.navigate.to_url[0] == '#') { GF_Node *bindable; evt.navigate.to_url++; bindable = gf_sg_find_node_by_name(gf_node_get_graph(node), (char *) evt.navigate.to_url); if (bindable) { Bindable_SetSetBind(bindable, 1); break; } } else if (compositor->term) { if (gf_scene_process_anchor(node, &evt)) break; } else if (gf_term_send_event(compositor->term, &evt)) { break; } i++; } }
void PreDestroyBindable(GF_Node *bindable, GF_List *stack_list) { #if REBIND_AT_DESTROY Bool is_bound = Bindable_GetIsBound(bindable); #endif Bindable_SetIsBound(bindable, GF_FALSE); while (gf_list_count(stack_list)) { #if REBIND_AT_DESTROY GF_Node *stack_top; #endif GF_List *stack = (GF_List*)gf_list_get(stack_list, 0); gf_list_rem(stack_list, 0); gf_list_del_item(stack, bindable); #if REBIND_AT_DESTROY if (is_bound) { stack_top = (GF_Node*)gf_list_get(stack, 0); if (stack_top) Bindable_SetSetBind(stack_top, GF_TRUE); } #endif } }
static void TraverseViewpoint(GF_Node *node, void *rs, Bool is_destroy) { SFVec3f pos, v1, v2; SFRotation ori; GF_Matrix mx; GF_TraverseState *tr_state = (GF_TraverseState *)rs; M_Viewpoint *vp = (M_Viewpoint*) node; ViewStack *st = (ViewStack *) gf_node_get_private(node); if (is_destroy) { DestroyViewStack(node); return; } /*may happen in get_bounds*/ if (!tr_state->viewpoints) return; // if (!tr_state->camera->is_3D) return; /*first traverse, bound if needed*/ if (gf_list_find(tr_state->viewpoints, node) < 0) { gf_list_add(tr_state->viewpoints, node); assert(gf_list_find(st->reg_stacks, tr_state->viewpoints)==-1); gf_list_add(st->reg_stacks, tr_state->viewpoints); if (gf_list_get(tr_state->viewpoints, 0) == vp) { if (!vp->isBound) Bindable_SetIsBound(node, 1); } else { if (gf_inline_is_default_viewpoint(node)) Bindable_SetSetBind(node, 1); } VPCHANGED(tr_state->visual->compositor); /*in any case don't draw the first time (since the viewport could have been declared last)*/ if (tr_state->layer3d) gf_node_dirty_set(tr_state->layer3d, GF_SG_VRML_BINDABLE_DIRTY, 0); gf_sc_invalidate(tr_state->visual->compositor, NULL); } /*not evaluating vp, return*/ if (tr_state->traversing_mode != TRAVERSE_BINDABLE) { /*store model matrix if changed - NOTE: we always have a 1-frame delay between VP used and real world... we could remove this by pre-traversing the scene before applying vp, but that would mean 2 scene traversals*/ if ((tr_state->traversing_mode==TRAVERSE_SORT) || (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) ) { if (!gf_mx_equal(&st->world_view_mx, &tr_state->model_matrix)) { gf_mx_copy(st->world_view_mx, tr_state->model_matrix); gf_node_dirty_set(node, 0, 0); } } return; } /*not bound or in 2D visual*/ if (!vp->isBound || !tr_state->navigations) return; if (!gf_node_dirty_get(node)) return; gf_node_dirty_clear(node, 0); /*move to local system*/ gf_mx_copy(mx, st->world_view_mx); gf_mx_add_translation(&mx, vp->position.x, vp->position.y, vp->position.z); gf_mx_add_rotation(&mx, vp->orientation.q, vp->orientation.x, vp->orientation.y, vp->orientation.z); gf_mx_decompose(&mx, &pos, &v1, &ori, &v2); /*get center*/ v1.x = v1.y = v1.z = 0; #ifndef GPAC_DISABLE_X3D /*X3D specifies examine center*/ if (gf_node_get_tag(node)==TAG_X3D_Viewpoint) v1 = ((X_Viewpoint *)node)->centerOfRotation; #endif gf_mx_apply_vec(&st->world_view_mx, &v1); /*set frustrum param - animate only if not bound last frame and jump false*/ visual_3d_viewpoint_change(tr_state, node, (!st->prev_was_bound && !vp->jump) ? 1 : 0, vp->fieldOfView, pos, ori, v1); st->prev_was_bound = 1; }