예제 #1
0
static void ttd_add_item(M_Form *form)
{
	s32 *new_gr;
	gf_sg_vrml_mf_append(&form->groups, GF_SG_VRML_MFINT32, (void **) &new_gr);
	(*new_gr) = gf_node_list_get_count(form->children);
	gf_sg_vrml_mf_append(&form->groups, GF_SG_VRML_MFINT32, (void **) &new_gr);
	(*new_gr) = -1;
	/*store line info*/
	gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &new_gr);
	(*new_gr) = gf_node_list_get_count(form->children);
}
예제 #2
0
static void RenderSwitch(GF_Node *node, void *rs, Bool is_destroy)
{
	GF_ChildNodeItem *l;
	u32 i, count;
	Bool prev_switch;
	GF_ChildNodeItem *children;
	s32 whichChoice;
	GF_Node *child;
	SwitchStack *st = (SwitchStack *)gf_node_get_private(node);
	RenderEffect2D *eff; 
	eff = (RenderEffect2D *)rs;

	if (is_destroy) {
		free(st);
		return;
	}
	

	if (gf_node_get_name(node)) {
		node = node;
	}
	/*WARNING: X3D/MPEG4 NOT COMPATIBLE*/
	if (gf_node_get_tag(node)==TAG_MPEG4_Switch) {
		children = ((M_Switch *)node)->choice;
		whichChoice = ((M_Switch *)node)->whichChoice;
	} else {
		children = ((X_Switch *)node)->children;
		whichChoice = ((X_Switch *)node)->whichChoice;
	}
	count = gf_node_list_get_count(children);

	prev_switch = eff->trav_flags;
	/*check changes in choice field*/
	if ((gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) || (st->last_switch != whichChoice) ) {
		eff->trav_flags |= GF_SR_TRAV_SWITCHED_OFF;
		i=0;
		l = children;
		while (l) {
//			if ((s32) i!=whichChoice) gf_node_render(l->node, eff);
			if ((s32) i == st->last_switch) gf_node_render(l->node, eff);
			l = l->next;
			i++;
		}
		eff->trav_flags &= ~GF_SR_TRAV_SWITCHED_OFF;
		st->last_switch = whichChoice;
	}

	gf_node_dirty_clear(node, 0);

	/*no need to check for sensors since a sensor is active for the whole parent group, that is for switch itself
	CSQ: switch cannot be used to switch sensors, too bad...*/
	eff->trav_flags = prev_switch;

	if (whichChoice>=0) {
		child = (GF_Node*)gf_node_list_get_child(children, whichChoice);
		gf_node_render(child, eff);
	}
}
예제 #3
0
static void TraverseOrderedGroup(GF_Node *node, void *rs, Bool is_destroy)
{
	u32 i, count;
	struct og_pos *priorities;
	Bool invalidate_backup;
	OrderedGroupStack *stack = (OrderedGroupStack *) gf_node_get_private(node);
	M_OrderedGroup *og = (M_OrderedGroup *) node;
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		gf_sc_check_focus_upon_destroy(node);
		group_2d_destroy(node, (GroupingNode2D*)stack);
		if (stack->positions) gf_free(stack->positions);
		gf_free(stack);
		return;
	}

	if (!og->order.count || (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) ) {
		gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);
		group_2d_traverse(node, (GroupingNode2D*)stack, tr_state);
		return;
	}

	invalidate_backup = tr_state->invalidate_all;
	/*check whether the OrderedGroup node has changed*/
	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {
		if (stack->positions) gf_free(stack->positions);
		count = gf_node_list_get_count(og->children);
		priorities = (struct og_pos*)gf_malloc(sizeof(struct og_pos)*count);
		for (i=0; i<count; i++) {
			priorities[i].position = i;
			priorities[i].priority = (i<og->order.count) ? og->order.vals[i] : 0;
		}
		qsort(priorities, count, sizeof(struct og_pos), compare_priority);

		stack->positions = (u32*)gf_malloc(sizeof(u32) * count);
		for (i=0; i<count; i++) stack->positions[i] = priorities[i].position;
		gf_free(priorities);
		
		tr_state->invalidate_all = 1;
		gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);
	}
	group_2d_traverse_with_order(node, (GroupingNode2D*)stack, tr_state, stack->positions);
	tr_state->invalidate_all = invalidate_backup;
}
예제 #4
0
// AddRecursive -- recursively adds items with an ID to the dictionnary
void V4SceneManager::AddRecursive(GF_Node * node, bool parentAdded) {

  // skips empty nodes
  if (!node) return;

  // skips the dictionnary
  const char * c = gf_node_get_name(node);
  if ( (c != NULL) && (!strcmp(c, DICTNAME)) ) return;

  // if node as an id adds it to the dictionnary and the node pool
  u32 id = gf_node_get_id(node);
  if (id) {
    pools.Add(node);
    // children of added node are not added to the dictionnary
    if (!parentAdded) AddEffective(node);
    parentAdded = true;
  }
  
  GF_FieldInfo field;
  GF_ChildNodeItem * list;
  int count = gf_node_get_field_count(node);

  // tests all fields, if a field is a node then adds it and process its children recursively
  for (int i=0; i<count; i++) {

    gf_node_get_field(node, i, &field);

    // single value node field
    if (field.fieldType == GF_SG_VRML_SFNODE)
      AddRecursive( * ((GF_Node **) field.far_ptr), parentAdded );

    // multiple value node field
    if (field.fieldType == GF_SG_VRML_MFNODE) {
      list = *( (GF_ChildNodeItem **) field.far_ptr);
			for (u32 j=0; j<gf_node_list_get_count(list); j++)
				AddRecursive( (GF_Node *) gf_node_list_get_child(list, j), parentAdded );
    }
  }
}
예제 #5
0
static void svg_sani_UpdateGradient(SVG_SANI_GradientStack *st, GF_ChildNodeItem *children)
{
	u32 count;
	Fixed alpha, max_offset;

	if (!gf_node_dirty_get(st->txh.owner)) return;
	gf_node_dirty_clear(st->txh.owner, 0);

	st->txh.needs_refresh = 1;
	st->txh.transparent = 0;
	count = gf_node_list_get_count(children);
	st->nb_col = 0;
	st->cols = (u32*)realloc(st->cols, sizeof(u32)*count);
	st->keys = (Fixed*)realloc(st->keys, sizeof(Fixed)*count);

	max_offset = 0;
	while (children) {
		Fixed key;
		SVG_SANI_stopElement *gstop = (SVG_SANI_stopElement *) children->node;
		children = children->next;
		if (gf_node_get_tag((GF_Node *)gstop) != TAG_SVG_SANI_stop) continue;

		if (gstop->stop_opacity.type==SVG_NUMBER_VALUE) alpha = gstop->stop_opacity.value;
		else alpha = FIX_ONE;
		st->cols[st->nb_col] = GF_COL_ARGB_FIXED(alpha, gstop->stop_color.color.red, gstop->stop_color.color.green, gstop->stop_color.color.blue);
		key = gstop->offset.value;
		if (gstop->offset.value>FIX_ONE) key/=100; 
		if (key>max_offset) max_offset=key;
		else key = max_offset;
		st->keys[st->nb_col] = key;

		st->nb_col++;
		if (alpha!=FIX_ONE) st->txh.transparent = 1;
	}
	st->txh.compositor->r2d->stencil_set_gradient_interpolation(st->txh.hwtx, st->keys, st->cols, st->nb_col);
	st->txh.compositor->r2d->stencil_set_gradient_mode(st->txh.hwtx, /*lg->spreadMethod*/ GF_GRADIENT_MODE_PAD);
}
예제 #6
0
static void TraverseLOD(GF_Node *node, void *rs, Bool is_destroy)
{
	GF_ChildNodeItem *children;
	MFFloat *ranges;
	SFVec3f pos, usr;
	u32 which_child, nb_children;
	Fixed dist;
	Bool do_all;
	GF_Matrix mx;
	SFVec3f center;
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;
	s32 *prev_child = (s32 *)gf_node_get_private(node);

	if (is_destroy) {
		gf_free(prev_child);
		gf_sc_check_focus_upon_destroy(node);
		return;
	}

	/*WARNING: X3D/MPEG4 NOT COMPATIBLE*/
	if (gf_node_get_tag(node) == TAG_MPEG4_LOD) {
		children = ((M_LOD *) node)->level;
		ranges = &((M_LOD *) node)->range;
		center = ((M_LOD *) node)->center;
#ifndef GPAC_DISABLE_X3D
	} else {
		children = ((X_LOD *) node)->children;
		ranges = &((X_LOD *) node)->range;
		center = ((X_LOD *) node)->center;
#endif
	}

	if (!children) return;
	nb_children = gf_node_list_get_count(children);

	if (!tr_state->camera) {
		do_all = 1;
		which_child = 0;
	} else {
		/*can't cache the matrix here*/
		usr = tr_state->camera->position;
		pos = center;
		gf_mx_copy(mx, tr_state->model_matrix);
		gf_mx_inverse(&mx);
		gf_mx_apply_vec(&mx, &usr);
		gf_vec_diff(pos, pos, usr);
		dist = gf_vec_len(pos);
		for (which_child=0; which_child<ranges->count; which_child++) {
			if (dist<ranges->vals[which_child]) break;
		}
		if (which_child>=nb_children) which_child = nb_children-1;

		/*check if we're traversing the same child or not for audio rendering*/
		do_all = 0;
		if (gf_node_dirty_get(node)) {
			gf_node_dirty_clear(node, 0);
			do_all = 1;
		} else if ((s32) which_child != *prev_child) {
			*prev_child = which_child;
			do_all = 1;
		}
	}

	if (do_all) {
		u32 i;
		Bool prev_switch = tr_state->switched_off;
		GF_ChildNodeItem *l = children;
		tr_state->switched_off = 1;
		i=0;
		while (l) {
			if (i!=which_child) gf_node_traverse(l->node, rs);
			l = l->next;
		}
		tr_state->switched_off = prev_switch;
	}
	gf_node_traverse(gf_node_list_get_child(children, which_child), rs);
}
예제 #7
0
GF_Err gf_bifs_enc_mf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
{
	GF_ChildNodeItem *list = NULL;
	GF_Err e;
	u32 nbBits, qp_local;
	Bool use_list, qp_on, initial_qp;
	u32 nbF, i;
	GF_FieldInfo sffield;

	nbF = 0;
	if (field->fieldType != GF_SG_VRML_MFNODE) {
		nbF = field->far_ptr ? ((GenMFField *)field->far_ptr)->count : 0;
		if (!nbF && (field->fieldType == GF_SG_VRML_MFSCRIPT))
			nbF = 1;
	} else if (field->far_ptr) {
		list = *((GF_ChildNodeItem **)field->far_ptr);
		nbF = gf_node_list_get_count(list);
	}
	/*reserved*/
	GF_BIFS_WRITE_INT(codec, bs, 0, 1, "reserved", NULL);
	if (!nbF) {
		/*is list*/
		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL);
		/*end flag*/
		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
		return GF_OK;
	}

	/*do we work in list or vector*/
	use_list = GF_FALSE;
	nbBits = gf_get_bit_size(nbF);
	if (nbBits + 5 > nbF + 1) use_list = GF_TRUE;

	GF_BIFS_WRITE_INT(codec, bs, use_list, 1, "isList", NULL);
	if (!use_list) {
		GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL);
		GF_BIFS_WRITE_INT(codec, bs, nbF, nbBits, "length", NULL);
	}

	memset(&sffield, 0, sizeof(GF_FieldInfo));
	sffield.fieldIndex = field->fieldIndex;
	sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);
	sffield.NDTtype = field->NDTtype;

	initial_qp = qp_on = GF_FALSE;
	qp_local = 0;
	initial_qp = codec->ActiveQP ? GF_TRUE : GF_FALSE;
	for (i=0; i<nbF; i++) {

		if (use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);

		if (field->fieldType != GF_SG_VRML_MFNODE) {
			gf_sg_vrml_mf_get_item(field->far_ptr, field->fieldType, &sffield.far_ptr, i);
			e = gf_bifs_enc_sf_field(codec, bs, node, &sffield);
		} else {
			assert(list);
			e = gf_bifs_enc_node(codec, list->node, field->NDTtype, bs, node);

			/*activate QP*/
			if (list->node->sgprivate->tag == TAG_MPEG4_QuantizationParameter) {
				qp_local = ((M_QuantizationParameter *)list->node)->isLocal;
				if (qp_on) gf_bifs_enc_qp_remove(codec, GF_FALSE);
				e = gf_bifs_enc_qp_set(codec, list->node);
				if (e) return e;
				qp_on = GF_TRUE;
				if (qp_local) qp_local = 2;
			}
			list = list->next;
		}

		if (e) return e;

		if (qp_on && qp_local) {
			if (qp_local == 2) qp_local -= 1;
			else {
				gf_bifs_enc_qp_remove(codec, initial_qp);
				qp_local = qp_on = GF_FALSE;
			}
		}
	}

	if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
	if (qp_on) gf_bifs_enc_qp_remove(codec, initial_qp);
	/*for QP14*/
	gf_bifs_enc_qp14_set_length(codec, nbF);
	return GF_OK;
}
예제 #8
0
static void TraverseSwitch(GF_Node *node, void *rs, Bool is_destroy)
{
	GF_ChildNodeItem *l;
	u32 i;
	Bool prev_switch;
	GF_ChildNodeItem *children;
	s32 whichChoice;
	GF_Node *child;
	SwitchStack *st = (SwitchStack *)gf_node_get_private(node);
	GF_TraverseState *tr_state; 
	tr_state = (GF_TraverseState *)rs;
	children = NULL;
	/* souchay : be sure to be initialized, -1 seems reasonable since we check if (whichChoice>=0)  */
	whichChoice = -1;
	if (is_destroy) {
		gf_sc_check_focus_upon_destroy(node);
		gf_free(st);
		return;
	}
	/*WARNING: X3D/MPEG4 NOT COMPATIBLE*/
	switch (gf_node_get_tag(node)) {
	case TAG_MPEG4_Switch:
		children = ((M_Switch *)node)->choice;
		whichChoice = ((M_Switch *)node)->whichChoice;
		break;
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Switch:
		children = ((X_Switch *)node)->children;
		whichChoice = ((X_Switch *)node)->whichChoice;
		break;
#endif
	}

	if (tr_state->traversing_mode!=TRAVERSE_GET_BOUNDS) {
		prev_switch = tr_state->switched_off;
		/*check changes in choice field*/
		if ((gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) || (st->last_switch != whichChoice) ) {
			tr_state->switched_off = 1;
			i=0;
			l = children;
			while (l) {
	//			if ((s32) i!=whichChoice) gf_node_traverse(l->node, tr_state);
				if ((s32) i == st->last_switch) gf_node_traverse(l->node, tr_state);
				l = l->next;
				i++;
			}
			tr_state->switched_off = 0;
			st->last_switch = whichChoice;
		}

		gf_node_dirty_clear(node, 0);

		/*no need to check for sensors since a sensor is active for the whole parent group, that is for switch itself
		CSQ: switch cannot be used to switch sensors, too bad...*/
		tr_state->switched_off = prev_switch;
	}

	if (!children) return;
	if (whichChoice==-2) {
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->autostereo_type) {
			u32 idx;
			u32 count = gf_node_list_get_count(children);
			/*this should be a bit more subtle (reusing views if missing, ...)...*/
			idx = tr_state->visual->current_view % count;

			child = (GF_Node*)gf_node_list_get_child(children, idx);
			gf_node_traverse(child, tr_state);
			return;
		} else 
#endif //GPAC_DISABLE_3D
		{
			/*fallback to first view*/
			whichChoice=0;
		}
	}
	if (whichChoice>=0) {
		child = (GF_Node*)gf_node_list_get_child(children, whichChoice);
		gf_node_traverse(child, tr_state);
	}
}
예제 #9
0
static void RenderOrderedGroup(GF_Node *node, void *rs, Bool is_destroy)
{
	u32 i, count;
	GF_Node *child;
	Bool split_text_backup, invalidate_backup;
	M_OrderedGroup *og;
	u32 count2;
	GF_List *sensor_backup;
	SensorHandler *hsens;
	OrderedGroupStack *ogs = (OrderedGroupStack *) gf_node_get_private(node);
	RenderEffect2D *eff = (RenderEffect2D *)rs;

	if (is_destroy) {
		DeleteGroupingNode2D((GroupingNode2D *)ogs);
		if (ogs->priorities) free(ogs->priorities);
		free(ogs);
		return;
	}
	og = (M_OrderedGroup *) ogs->owner;

	if (!og->order.count) {
		group2d_traverse((GroupingNode2D*)ogs, og->children, eff);
		return;
	}
	count = gf_node_list_get_count(og->children);
	invalidate_backup = eff->invalidate_all;

	/*check whether the OrderedGroup node has changed*/
	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {

		if (ogs->priorities) free(ogs->priorities);
		ogs->priorities = (struct og_pos*)malloc(sizeof(struct og_pos)*count);
		for (i=0; i<count; i++) {
			ogs->priorities[i].position = i;
			ogs->priorities[i].priority = (i<og->order.count) ? og->order.vals[i] : 0;
		}
		qsort(ogs->priorities, count, sizeof(struct og_pos), compare_priority);
		eff->invalidate_all = 1;
	}

	sensor_backup = NULL;
	if (gf_node_dirty_get(node) & GF_SG_CHILD_DIRTY) {
		/*rebuild sensor list*/
		if (gf_list_count(ogs->sensors)) {
			gf_list_del(ogs->sensors);
			ogs->sensors = gf_list_new();
		}

		for (i=0; i<count; i++) {
			child = (GF_Node*)gf_node_list_get_child(og->children, ogs->priorities[i].position);
			if (!child || !is_sensor_node(child) ) continue;
			hsens = get_sensor_handler(child);
			if (hsens) gf_list_add(ogs->sensors, hsens);
		}
	}

	/*if we have an active sensor at this level discard all sensors in current render context (cf VRML)*/
	count2 = gf_list_count(ogs->sensors);
	if (count2) {
		sensor_backup = eff->sensors;
		eff->sensors = gf_list_new();
		/*add sensor to effects*/	
		for (i=0; i <count2; i++) {
			SensorHandler *hsens = (SensorHandler *)gf_list_get(ogs->sensors, i);
			effect_add_sensor(eff, hsens, &eff->transform);
		}
	}
	gf_node_dirty_clear(node, 0);

	if (eff->parent == (GroupingNode2D *) ogs) {
		for (i=0; i<count; i++) {
			group2d_start_child((GroupingNode2D *) ogs);
			child = (GF_Node*)gf_node_list_get_child(og->children, ogs->priorities[i].position);
			gf_node_render(child, eff);
			group2d_end_child((GroupingNode2D *) ogs);
		}
	} else {
		split_text_backup = eff->text_split_mode;
		if (count>1) eff->text_split_mode = 0;
		for (i=0; i<count; i++) {
			child = (GF_Node*)gf_node_list_get_child(og->children, ogs->priorities[i].position);
			gf_node_render(child, eff);
		}
		eff->text_split_mode = split_text_backup;
	}

	/*restore effect*/
	invalidate_backup = eff->invalidate_all;
	if (count2) {
		/*destroy current effect list and restore previous*/
		effect_reset_sensors(eff);
		gf_list_del(eff->sensors);
		eff->sensors = sensor_backup;
	}
}
예제 #10
0
GF_Node *CloneNodeForEditing(GF_SceneGraph *inScene, GF_Node *orig) //, GF_Node *cloned_parent)
{
	u32 i, j, count;
	GF_Node *node, *child, *tmp;
	GF_ChildNodeItem *list, *list2;
	GF_FieldInfo field_orig, field;

	/*this is not a mistake*/
	if (!orig) return NULL;

	/*check for DEF/USE
	if (orig->sgprivate->NodeID) {
		node = gf_sg_find_node(inScene, orig->sgprivate->NodeID);
		//node already created, USE
		if (node) {
			gf_node_register(node, cloned_parent);
			return node;
		}
	}
	*/
	/*create a node*/
/*
	if (orig->sgprivate->tag == TAG_MPEG4_ProtoNode) {
		proto_node = ((GF_ProtoInstance *)orig)->proto_interface;
		//create the instance but don't load the code -c we MUST wait for ISed routes to be cloned before
		node = gf_sg_proto_create_node(inScene, proto_node, (GF_ProtoInstance *) orig);
	} else {
*/
	node = gf_node_new(inScene, gf_node_get_tag(orig));
//	}

	count = gf_node_get_field_count(orig);

	/*copy each field*/
	for (i=0; i<count; i++) {
		gf_node_get_field(orig, i, &field_orig);

		/*get target ptr*/
		gf_node_get_field(node, i, &field);

		assert(field.eventType==field_orig.eventType);
		assert(field.fieldType==field_orig.fieldType);

		/*duplicate it*/
		switch (field.fieldType) {
		case GF_SG_VRML_SFNODE:
			child = CloneNodeForEditing(inScene, (GF_Node *) (* ((GF_Node **) field_orig.far_ptr)));//, node);
			*((GF_Node **) field.far_ptr) = child;
			break;
		case GF_SG_VRML_MFNODE:
			list = *( (GF_ChildNodeItem **) field_orig.far_ptr);
			list2 = *( (GF_ChildNodeItem **) field.far_ptr);

			for (j=0; j<gf_node_list_get_count(list); j++) {
				tmp = (GF_Node *)gf_node_list_get_child(list, j);
				child = CloneNodeForEditing(inScene, tmp);//, node);
				gf_node_list_add_child(&list2, child);
			}
			break;
		default:
			gf_sg_vrml_field_copy(field.far_ptr, field_orig.far_ptr, field.fieldType);
			break;
		}
	}
	/*register node
	if (orig->sgprivate->NodeID) {
		Node_SetID(node, orig->sgprivate->NodeID);
		gf_node_register(node, cloned_parent);
	}*/

	/*init node before creating ISed routes so the eventIn handler are in place*/
	if (gf_node_get_tag(node) != TAG_ProtoNode) gf_node_init(node);

	return node;
}