Beispiel #1
0
static void DestroyBackground(GF_Node *node)
{
	BackgroundStack *ptr = (BackgroundStack *) gf_node_get_private(node);
	PreDestroyBindable(node, ptr->reg_stacks);
	gf_list_del(ptr->reg_stacks);

	if (ptr->sky_mesh) mesh_free(ptr->sky_mesh);
	if (ptr->ground_mesh) mesh_free(ptr->ground_mesh);

	gf_sg_vrml_mf_reset(&ptr->ground_ang, GF_SG_VRML_MFFLOAT);
	gf_sg_vrml_mf_reset(&ptr->sky_ang, GF_SG_VRML_MFFLOAT);
	gf_sg_vrml_mf_reset(&ptr->ground_col, GF_SG_VRML_MFCOLOR);
	gf_sg_vrml_mf_reset(&ptr->sky_col, GF_SG_VRML_MFCOLOR);

	mesh_free(ptr->front_mesh);
	mesh_free(ptr->back_mesh);
	mesh_free(ptr->top_mesh);
	mesh_free(ptr->bottom_mesh);
	mesh_free(ptr->left_mesh);
	mesh_free(ptr->right_mesh);


	gf_sc_texture_destroy(&ptr->txh_front);
	gf_sc_texture_destroy(&ptr->txh_back);
	gf_sc_texture_destroy(&ptr->txh_top);
	gf_sc_texture_destroy(&ptr->txh_bottom);
	gf_sc_texture_destroy(&ptr->txh_left);
	gf_sc_texture_destroy(&ptr->txh_right);

	gf_free(ptr);
}
Beispiel #2
0
static void animationstream_check_url(AnimationStreamStack *stack, M_AnimationStream *as)
{
    if (!stack->stream) {
        gf_sg_vrml_mf_reset(&stack->current_url, GF_SG_VRML_MFURL);
        gf_sg_vrml_field_copy(&stack->current_url, &as->url, GF_SG_VRML_MFURL);
        stack->stream = gf_mo_register((GF_Node *)as, &as->url, 0, 0);
        gf_sc_invalidate(stack->compositor, NULL);

        /*if changed while playing trigger*/
        if (as->isActive) {
            gf_mo_play(stack->stream, 0, -1, 0);
            gf_mo_set_speed(stack->stream, as->speed);
        }
        return;
    }
    /*check change*/
    if (gf_mo_url_changed(stack->stream, &as->url)) {
        gf_sg_vrml_mf_reset(&stack->current_url, GF_SG_VRML_MFURL);
        gf_sg_vrml_field_copy(&stack->current_url, &as->url, GF_SG_VRML_MFURL);
        /*if changed while playing stop old source*/
        if (as->isActive) {
            gf_mo_set_flag(stack->stream, GF_MO_DISPLAY_REMOVE, 1);
            gf_mo_stop(stack->stream);
        }
        gf_mo_unregister((GF_Node *)as, stack->stream);

        stack->stream = gf_mo_register((GF_Node *)as, &as->url, 0, 0);
        /*if changed while playing play new source*/
        if (as->isActive) {
            gf_mo_play(stack->stream, 0, -1, 0);
            gf_mo_set_speed(stack->stream, as->speed);
        }
        gf_sc_invalidate(stack->compositor, NULL);
    }
}
Beispiel #3
0
GF_Err gf_bifs_dec_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field, Bool is_mem_com)
{
	GF_Err e;
	u8 flag;

//	if (codec->LastError) return codec->LastError;

	assert(node);
//	if (field->fieldType == GF_SG_VRML_UNKNOWN) return GF_NON_COMPLIANT_BITSTREAM;

	if (gf_sg_vrml_is_sf_field(field->fieldType)) {
		e = gf_bifs_dec_sf_field(codec, bs, node, field, is_mem_com);
		if (e) return e;
	} else {
		/*clean up the eventIn field if not done*/
		if (field->eventType == GF_SG_EVENT_IN) {
			if (field->fieldType == GF_SG_VRML_MFNODE) {
				gf_node_unregister_children(node, * (GF_ChildNodeItem **)field->far_ptr);
				* (GF_ChildNodeItem **)field->far_ptr = NULL;
			} else {
				//remove all items of the MFField
				gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType);
			}
		}

		/*predictiveMFField*/
		if (codec->info->config.UsePredictiveMFField) {
			flag = gf_bs_read_int(bs, 1);
			if (flag) {
				GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] Stream uses Predictive Field Coding!\n"));
#ifdef GPAC_ENABLE_BIFS_PMF
				return gf_bifs_dec_pred_mf_field(codec, bs, node, field);
#else
				return GF_NOT_SUPPORTED;
#endif
			}
		}

		/*reserved*/
		flag = gf_bs_read_int(bs, 1);
		if (!flag) {
			/*destroy the field content...*/
			if (field->fieldType != GF_SG_VRML_MFNODE) {
				e = gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType);
				if (e) return e;
			}
			/*List description - alloc is dynamic*/
			flag = gf_bs_read_int(bs, 1);
			if (flag) {
				e = BD_DecMFFieldList(codec, bs, node, field, is_mem_com);
			} else {
				e = BD_DecMFFieldVec(codec, bs, node, field, is_mem_com);
			}
			if (e) return e;
		}
	}
	return GF_OK;
}
Beispiel #4
0
static void build_indexed_triangle_strip_set(GF_Node *node, Drawable3D *stack, GF_TraverseState *tr_state)
{
	MFInt32 stripList;
	u32 i, nb_strips;
	X_IndexedTriangleStripSet *itss = (X_IndexedTriangleStripSet *)node;

	if (!itss->coord) return;

	stripList.count = 0;
	stripList.vals = NULL;
	nb_strips = 0;
	for (i=0; i<itss->index.count; i++) {
		if (itss->index.vals[i]==-1) {
			if (nb_strips>=3) {
				u32 *out_nb;
				gf_sg_vrml_mf_append(&stripList, GF_SG_VRML_MFINT32, (void **) &out_nb);
				*out_nb = nb_strips;
			}
			nb_strips = 0;
		} else {
			nb_strips++;
		}
	}
	if (nb_strips>=3) {
		u32 *out_nb;
		gf_sg_vrml_mf_append(&stripList, GF_SG_VRML_MFINT32, (void **) &out_nb);
		*out_nb = nb_strips;
	}
	BuildTriangleStripSet(stack->mesh, itss->coord, itss->color, itss->texCoord, itss->normal, &stripList, &itss->index, itss->normalPerVertex, itss->ccw, itss->solid);
	gf_sg_vrml_mf_reset(&stripList, GF_SG_VRML_MFINT32);
}
Beispiel #5
0
void gf_sg_vrml_copy_mfurl(MFURL *dst, MFURL *src)
{
	u32 i;
	gf_sg_vrml_mf_reset(dst, GF_SG_VRML_MFURL);
	dst->count = src->count;
	dst->vals = gf_malloc(sizeof(SFURL)*src->count);
	for (i=0; i<src->count; i++) {
		dst->vals[i].OD_ID = src->vals[i].OD_ID;
		dst->vals[i].url = src->vals[i].url ? gf_strdup(src->vals[i].url) : NULL;
	}
}
Beispiel #6
0
/* Creates a subscene from the xlink:href */
static GF_Scene *gf_svg_get_subscene(GF_Node *elt, XLinkAttributesPointers *xlinkp, SMILSyncAttributesPointers *syncp, Bool use_sync, Bool primary_resource)
{
	MFURL url;
	Bool lock_timelines = 0;
	GF_MediaObject *mo;
	GF_SceneGraph *graph = gf_node_get_graph(elt);
	GF_Scene *scene = (GF_Scene *)gf_sg_get_private(graph);
	if (!scene) return NULL;

	if (use_sync && syncp) {
		switch ((syncp->syncBehavior?*syncp->syncBehavior:SMIL_SYNCBEHAVIOR_DEFAULT)) {
		case SMIL_SYNCBEHAVIOR_LOCKED:
		case SMIL_SYNCBEHAVIOR_CANSLIP:
			lock_timelines = 1;
			break;
		case SMIL_SYNCBEHAVIOR_DEFAULT:
		{
#if 0
			if (svg && syncp) {
				switch ((syncp->syncBehaviorDefault ? *syncp->syncBehaviorDefault : SMIL_SYNCBEHAVIOR_LOCKED)) {
				case SMIL_SYNCBEHAVIOR_LOCKED:
				case SMIL_SYNCBEHAVIOR_CANSLIP:
					lock_timelines = 1;
					break;
				default:
					break;
				}
			}
#endif
		}
		default:
			break;
		}
	}
	memset(&url, 0, sizeof(MFURL));
	if (!xlinkp->href) return NULL;

	gf_term_get_mfurl_from_xlink(elt, &url);

	while (scene->secondary_resource && scene->root_od->parentscene)
		scene = scene->root_od->parentscene;

	mo = gf_scene_get_media_object_ex(scene, &url, GF_MEDIA_OBJECT_SCENE, lock_timelines, NULL, primary_resource, elt);
	gf_sg_vrml_mf_reset(&url, GF_SG_VRML_MFURL);

	if (!mo || !mo->odm) return NULL;
	mo->odm->subscene->secondary_resource = primary_resource ? 0 : 1;
	return mo->odm->subscene;
}
Beispiel #7
0
static void media_sensor_activate(MediaSensorStack *media_sens, GF_Segment *desc)
{
	media_sens->sensor->isActive = 1;
	gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
	/*set info*/
	gf_sg_vrml_mf_reset(& media_sens->sensor->info, GF_SG_VRML_MFSTRING);
	gf_sg_vrml_mf_alloc(& media_sens->sensor->info, GF_SG_VRML_MFSTRING, 1);
	media_sens->sensor->info.vals[0] = desc->SegmentName ? gf_strdup(desc->SegmentName) : NULL;
	gf_node_event_out((GF_Node *) media_sens->sensor, 5/*"info"*/);
	/*set duration*/
	media_sens->sensor->mediaDuration = desc->Duration;
	gf_node_event_out((GF_Node *) media_sens->sensor, 3/*"mediaDuration"*/);
	/*set seg start time*/
	media_sens->sensor->streamObjectStartTime = desc->startTime;
	gf_node_event_out((GF_Node *) media_sens->sensor, 2/*"streamObjectStartTime"*/);
}
Beispiel #8
0
static void animationstream_destroy(GF_Node *node, void *rs, Bool is_destroy)
{
    if (is_destroy) {
        M_AnimationStream *as = (M_AnimationStream *)node;
        AnimationStreamStack *st = (AnimationStreamStack *) gf_node_get_private(node);

        if (st->time_handle.is_registered) {
            gf_sc_unregister_time_node(st->compositor, &st->time_handle);
        }
        if (st->stream && as->isActive) {
            gf_mo_set_flag(st->stream, GF_MO_DISPLAY_REMOVE, 1);
            gf_mo_stop(st->stream);
        }
        gf_sg_vrml_mf_reset(&st->current_url, GF_SG_VRML_MFURL);
        gf_free(st);
    }
}
Beispiel #9
0
void compositor_svg_video_modified(GF_Compositor *compositor, GF_Node *node)
{
	/*if href has been modified, stop the video (and associated audio if any) right away - we cannot wait for next traversal to
	process this as the video could be in a hidden subtree not traversed*/
	if (gf_node_dirty_get(node) & GF_SG_SVG_XLINK_HREF_DIRTY) {
		SVG_video_stack *st = (SVG_video_stack *)gf_node_get_private(node);
		/*WARNING - stack may be NULL at this point when inserting the video from script*/
		if (st && st->txh.is_open) {
			if (st->audio) {
				svg_audio_smil_evaluate_ex(NULL, 0, SMIL_TIMING_EVAL_REMOVE, st->audio, st->txh.owner);
				gf_node_unregister(st->audio, NULL);
				st->audio = NULL;
			}
			/*reset cached URL to avoid reopening the resource in the smil timing callback*/
			gf_sg_vrml_mf_reset(&st->txurl, GF_SG_VRML_MFURL);
			gf_sc_texture_stop(&st->txh);
		}
	}
	gf_node_dirty_set(node, 0, GF_FALSE);
	/*and force a redraw of next frame*/
	gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME);
}
Beispiel #10
0
GF_EXPORT
GF_Err gf_term_get_mfurl_from_xlink(GF_Node *node, MFURL *mfurl)
{
	u32 stream_id = 0;
	GF_Err e = GF_OK;
	SFURL *sfurl = NULL;
	GF_FieldInfo info;
	XMLRI *iri;
	GF_Scene *scene = gf_sg_get_private(gf_node_get_graph(node));
	if (!scene) return GF_BAD_PARAM;

	gf_sg_vrml_mf_reset(mfurl, GF_SG_VRML_MFURL);

	e = gf_node_get_attribute_by_tag(node, TAG_XLINK_ATT_href, 0, 0, &info);
	if (e) return e;

	iri = (XMLRI*)info.far_ptr;

	if (iri->type==XMLRI_STREAMID) {
		stream_id = iri->lsr_stream_id;
	} else if (!iri->string) return GF_OK;

	mfurl->count = 1;
	GF_SAFEALLOC(mfurl->vals, SFURL)
	sfurl = mfurl->vals;
	sfurl->OD_ID = stream_id;
	if (stream_id) return GF_OK;

	if (!strncmp(iri->string, "data:", 5)) {
		const char *cache_dir = gf_cfg_get_key(scene->root_od->term->user->config, "General", "CacheDirectory");
		e = gf_node_store_embedded_data(iri, cache_dir, "embedded_");
		if (e) return e;
		sfurl->url = gf_strdup(iri->string);
		return GF_OK;
	}
	sfurl->url = gf_term_resolve_xlink(node, iri->string);
	return e;
}
Beispiel #11
0
GF_EXPORT
GF_Err gf_sg_vrml_mf_alloc(void *mf, u32 FieldType, u32 NbItems)
{
	u32 FieldSize;
	GenMFField *mffield = (GenMFField *)mf;

	if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM;
	if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM;

	FieldSize = gf_sg_vrml_get_sf_size(FieldType);

	//field we can't copy
	if (!FieldSize) return GF_BAD_PARAM;
	if (NbItems>MAX_MFFIELD_ALLOC) return GF_IO_ERR;

	if (mffield->count==NbItems) return GF_OK;
	gf_sg_vrml_mf_reset(mf, FieldType);
	if (NbItems) {
		mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize*NbItems);
		memset(mffield->array, 0, sizeof(char)*FieldSize*NbItems);
	}
	mffield->count = NbItems;
	return GF_OK;
}
Beispiel #12
0
static void ILS2D_SetColorIndex(GF_Node *node, GF_Route *route)
{
	M_IndexedLineSet2D *ils2D = (M_IndexedLineSet2D *)node;
	gf_sg_vrml_field_copy(&ils2D->colorIndex, &ils2D->set_colorIndex, GF_SG_VRML_MFINT32);
	gf_sg_vrml_mf_reset(&ils2D->set_colorIndex, GF_SG_VRML_MFINT32);
}
Beispiel #13
0
GF_EXPORT
void gf_sg_vrml_field_clone(void *dest, void *orig, u32 field_type, GF_SceneGraph *inScene)
{
	u32 size, i, sf_type;
	void *dst_field, *orig_field;

	if (!dest || !orig) return;

	switch (field_type) {
	case GF_SG_VRML_SFBOOL:
		memcpy(dest, orig, sizeof(SFBool));
		break;
	case GF_SG_VRML_SFCOLOR:
		memcpy(dest, orig, sizeof(SFColor));
		break;
	case GF_SG_VRML_SFFLOAT:
		memcpy(dest, orig, sizeof(SFFloat));
		break;
	case GF_SG_VRML_SFINT32:
		memcpy(dest, orig, sizeof(SFInt32));
		break;
	case GF_SG_VRML_SFROTATION:
		memcpy(dest, orig, sizeof(SFRotation));
		break;
	case GF_SG_VRML_SFTIME:
		memcpy(dest, orig, sizeof(SFTime));
		break;
	case GF_SG_VRML_SFVEC2F:
		memcpy(dest, orig, sizeof(SFVec2f));
		break;
	case GF_SG_VRML_SFVEC3F:
		memcpy(dest, orig, sizeof(SFVec3f));
		break;
	case GF_SG_VRML_SFATTRREF:
		memcpy(dest, orig, sizeof(SFAttrRef));
		break;
	case GF_SG_VRML_SFSTRING:
		if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
		if ( ((SFString*)orig)->buffer )
			((SFString*)dest)->buffer = gf_strdup(((SFString*)orig)->buffer);
		else
			((SFString*)dest)->buffer = NULL;
		break;
	case GF_SG_VRML_SFURL:
		if ( ((SFURL *)dest)->url ) gf_free( ((SFURL *)dest)->url );
		((SFURL *)dest)->OD_ID = ((SFURL *)orig)->OD_ID;
		if (((SFURL *)orig)->url)
			((SFURL *)dest)->url = gf_strdup(((SFURL *)orig)->url);
		else
			((SFURL *)dest)->url = NULL;
		break;
	case GF_SG_VRML_SFIMAGE:
		if (((SFImage *)dest)->pixels) gf_free(((SFImage *)dest)->pixels);
		((SFImage *)dest)->width = ((SFImage *)orig)->width;
		((SFImage *)dest)->height = ((SFImage *)orig)->height;
		((SFImage *)dest)->numComponents  = ((SFImage *)orig)->numComponents;
		size = ((SFImage *)dest)->width * ((SFImage *)dest)->height * ((SFImage *)dest)->numComponents;
		((SFImage *)dest)->pixels = (u8*)gf_malloc(sizeof(char)*size);
		memcpy(((SFImage *)dest)->pixels, ((SFImage *)orig)->pixels, sizeof(char)*size);
		break;
	case GF_SG_VRML_SFCOMMANDBUFFER:
	{
		SFCommandBuffer *cb_dst = (SFCommandBuffer *)dest;
		SFCommandBuffer *cb_src = (SFCommandBuffer *)orig;

		cb_dst->bufferSize = cb_src->bufferSize;
		if (cb_dst->bufferSize && !gf_list_count(cb_src->commandList) ) {
			cb_dst->buffer = (u8*)gf_realloc(cb_dst->buffer, sizeof(char)*cb_dst->bufferSize);
			memcpy(cb_dst->buffer, cb_src->buffer, sizeof(char)*cb_src->bufferSize);
		} else {
			u32 j, c2;
			if (cb_dst->buffer) gf_free(cb_dst->buffer);
			cb_dst->buffer = NULL;
			/*clone command list*/
			c2 = gf_list_count(cb_src->commandList);
			for (j=0; j<c2;j++) {
				GF_Command *sub_com = (GF_Command *)gf_list_get(cb_src->commandList, j);
				GF_Command *new_com = gf_sg_vrml_command_clone(sub_com, inScene, 0);
				gf_list_add(cb_dst->commandList, new_com);
			}
		}
	}
		break;

	/*simply copy text string*/
	case GF_SG_VRML_SFSCRIPT:
		if (((SFScript*)dest)->script_text) gf_free(((SFScript*)dest)->script_text);
		((SFScript*)dest)->script_text = NULL;
		if ( ((SFScript*)orig)->script_text)
			((SFScript *)dest)->script_text = (char *)gf_strdup( (char*) ((SFScript*)orig)->script_text );
		break;


	//simple MFFields, do a memcpy
	case GF_SG_VRML_MFBOOL:
	case GF_SG_VRML_MFFLOAT:
	case GF_SG_VRML_MFTIME:
	case GF_SG_VRML_MFINT32:
	case GF_SG_VRML_MFVEC3F:
	case GF_SG_VRML_MFVEC2F:
	case GF_SG_VRML_MFCOLOR:
	case GF_SG_VRML_MFROTATION:
	case GF_SG_VRML_MFATTRREF:
		size = gf_sg_vrml_get_sf_size(field_type) * ((GenMFField *)orig)->count;
		if (((GenMFField *)orig)->count != ((GenMFField *)dest)->count) {
			((GenMFField *)dest)->array = gf_realloc(((GenMFField *)dest)->array, size);
			((GenMFField *)dest)->count = ((GenMFField *)orig)->count;
		}
		memcpy(((GenMFField *)dest)->array, ((GenMFField *)orig)->array, size);
		break;
	//complex MFFields
	case GF_SG_VRML_MFSTRING:
	case GF_SG_VRML_MFIMAGE:
	case GF_SG_VRML_MFURL:
	case GF_SG_VRML_MFSCRIPT:
		size = ((GenMFField *)orig)->count;
		gf_sg_vrml_mf_reset(dest, field_type);
		gf_sg_vrml_mf_alloc(dest, field_type, size);
		sf_type = gf_sg_vrml_get_sf_type(field_type);
		//duplicate all items
		for (i=0; i<size; i++) {
			gf_sg_vrml_mf_get_item(dest, field_type, &dst_field, i);
			gf_sg_vrml_mf_get_item(orig, field_type, &orig_field, i);
			gf_sg_vrml_field_copy(dst_field, orig_field, sf_type);
		}
		break;
	}
}
Beispiel #14
0
GF_EXPORT
void gf_sg_vrml_field_copy(void *dest, void *orig, u32 field_type)
{
	u32 size, i, sf_type;
	void *dst_field, *orig_field;

	if (!dest || !orig) return;

	switch (field_type) {
	case GF_SG_VRML_SFBOOL:
		memcpy(dest, orig, sizeof(SFBool));
		break;
	case GF_SG_VRML_SFCOLOR:
		memcpy(dest, orig, sizeof(SFColor));
		break;
	case GF_SG_VRML_SFFLOAT:
		memcpy(dest, orig, sizeof(SFFloat));
		break;
	case GF_SG_VRML_SFINT32:
		memcpy(dest, orig, sizeof(SFInt32));
		break;
	case GF_SG_VRML_SFROTATION:
		memcpy(dest, orig, sizeof(SFRotation));
		break;
	case GF_SG_VRML_SFTIME:
		memcpy(dest, orig, sizeof(SFTime));
		break;
	case GF_SG_VRML_SFVEC2F:
		memcpy(dest, orig, sizeof(SFVec2f));
		break;
	case GF_SG_VRML_SFVEC3F:
		memcpy(dest, orig, sizeof(SFVec3f));
		break;
	case GF_SG_VRML_SFSTRING:
		if ( ((SFString*)dest)->buffer) free(((SFString*)dest)->buffer);
		if ( ((SFString*)orig)->buffer )
			((SFString*)dest)->buffer = strdup(((SFString*)orig)->buffer);
		else
			((SFString*)dest)->buffer = NULL;
		break;
	case GF_SG_VRML_SFURL:
		if ( ((SFURL *)dest)->url ) free( ((SFURL *)dest)->url );
		((SFURL *)dest)->OD_ID = ((SFURL *)orig)->OD_ID;
		if (((SFURL *)orig)->url) 
			((SFURL *)dest)->url = strdup(((SFURL *)orig)->url);
		else
			((SFURL *)dest)->url = NULL;
		break;
	case GF_SG_VRML_SFIMAGE:
		if (((SFImage *)dest)->pixels) free(((SFImage *)dest)->pixels);
		((SFImage *)dest)->width = ((SFImage *)orig)->width;
		((SFImage *)dest)->height = ((SFImage *)orig)->height;
		((SFImage *)dest)->numComponents  = ((SFImage *)orig)->numComponents;
		size = ((SFImage *)dest)->width * ((SFImage *)dest)->height * ((SFImage *)dest)->numComponents;
		((SFImage *)dest)->pixels = (u8*)malloc(sizeof(char)*size);
		memcpy(((SFImage *)dest)->pixels, ((SFImage *)orig)->pixels, sizeof(char)*size);
		break;
	case GF_SG_VRML_SFCOMMANDBUFFER:
		gf_sg_sfcommand_del( *(SFCommandBuffer *)dest);
		((SFCommandBuffer *)dest)->commandList = gf_list_new();
		((SFCommandBuffer *)dest)->bufferSize = ((SFCommandBuffer *)orig)->bufferSize;
		if (((SFCommandBuffer *)dest)->bufferSize) {
			((SFCommandBuffer *)dest)->buffer = (u8*)malloc(sizeof(char)*((SFCommandBuffer *)orig)->bufferSize);
			memcpy(((SFCommandBuffer *)dest)->buffer, 
				((SFCommandBuffer *)orig)->buffer,
				sizeof(char)*((SFCommandBuffer *)orig)->bufferSize);
		} else {
			((SFCommandBuffer *)dest)->buffer = NULL;
		}
		break;

	/*simply copy text string*/
	case GF_SG_VRML_SFSCRIPT:
		if (((SFScript*)dest)->script_text) free(((SFScript*)dest)->script_text);		
		((SFScript*)dest)->script_text = NULL;
		if ( ((SFScript*)orig)->script_text)
			((SFScript *)dest)->script_text = (u8*)strdup( (char*) ((SFScript*)orig)->script_text );
		break;


	//MFFields
	case GF_SG_VRML_MFBOOL:
	case GF_SG_VRML_MFFLOAT:
	case GF_SG_VRML_MFTIME:
	case GF_SG_VRML_MFINT32:
	case GF_SG_VRML_MFSTRING:
	case GF_SG_VRML_MFVEC3F:
	case GF_SG_VRML_MFVEC2F:
	case GF_SG_VRML_MFCOLOR:
	case GF_SG_VRML_MFROTATION:
	case GF_SG_VRML_MFIMAGE:
	case GF_SG_VRML_MFURL:
	case GF_SG_VRML_MFSCRIPT:
		size = ((GenMFField *)orig)->count;
		gf_sg_vrml_mf_reset(dest, field_type);
		gf_sg_vrml_mf_alloc(dest, field_type, size);
		sf_type = gf_sg_vrml_get_sf_type(field_type);
		//duplicate all items
		for (i=0; i<size; i++) {
			gf_sg_vrml_mf_get_item(dest, field_type, &dst_field, i);
			gf_sg_vrml_mf_get_item(orig, field_type, &orig_field, i);
			gf_sg_vrml_field_copy(dst_field, orig_field, sf_type);
		}
		break;
	}
}
Beispiel #15
0
void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos)
{
	GF_Segment *desc;
	u32 i, count, j, ms_count;
	Double time;
	ms_count = gf_list_count(odm->ms_stack);
	if (!ms_count) return;
	
	time = odm->current_time / 1000.0;

	for (j=0; j<ms_count; j++) {
		MediaSensorStack *media_sens = (MediaSensorStack *)gf_list_get(odm->ms_stack, j);
		if (!media_sens->is_init) continue;
		count = gf_list_count(media_sens->seg);
		
		/*full object controled*/
		if (!media_sens->active_seg && !count) {
			/*check for end of scene (MediaSensor on inline)*/
			if (odm->subscene && odm->subscene->duration) {
				GF_Clock *ck = gf_odm_get_media_clock(odm);
				if (ck->has_seen_eos && (1000*time>=(Double) (s64)odm->subscene->duration)) {
					if (media_sens->sensor->isActive) {
						/*force notification of time (ntify the scene duration rather than the current clock*/
						media_sens->sensor->mediaCurrentTime = (Double) odm->subscene->duration;
						media_sens->sensor->mediaCurrentTime /= 1000;
						gf_node_event_out((GF_Node *) media_sens->sensor, 1/*"mediaCurrentTime"*/);
						media_sens->sensor->isActive = 0;
						gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);

						GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Deactivating media sensor\n", odm->OD->objectDescriptorID));
					}
					continue;
				}
			}

			if (!is_eos && !media_sens->sensor->isActive) {
				media_sens->sensor->isActive = 1;
				gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
				if (odm->subscene) {
					media_sens->sensor->mediaDuration = (Double) (s64)odm->subscene->duration;
				} else {
					media_sens->sensor->mediaDuration = (Double) (s64)odm->duration;
				}
				if (media_sens->sensor->mediaDuration)
					media_sens->sensor->mediaDuration /= 1000;
				else
					media_sens->sensor->mediaDuration = -FIX_ONE;

				gf_node_event_out((GF_Node *) media_sens->sensor, 3/*"mediaDuration"*/);
			}

			if (is_eos && media_sens->sensor->isActive) {
				if (media_sens->sensor->mediaDuration>=0) {
					media_sens->sensor->mediaCurrentTime = media_sens->sensor->mediaDuration;
				} else {
					media_sens->sensor->mediaCurrentTime = time;
				}
				gf_node_event_out((GF_Node *) media_sens->sensor, 1/*"mediaCurrentTime"*/);
				media_sens->sensor->isActive = 0;
				gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
			} else {
				if (media_sens->sensor->isActive && (media_sens->sensor->mediaCurrentTime != time)) {
					media_sens->sensor->mediaCurrentTime = time;
					gf_node_event_out((GF_Node *) media_sens->sensor, 1/*"mediaCurrentTime"*/);
				}
			}
			continue;
		}

		/*locate segment*/
		for (i=media_sens->active_seg; i<count; i++) {
			desc = (GF_Segment*)gf_list_get(media_sens->seg, i);
			/*not controled*/
			if (desc->startTime > time) {
				if (media_sens->sensor->isActive) {
					media_sens->sensor->isActive = 0;
					gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);

					GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Deactivating media sensor at time %g - segment %s\n", odm->OD->objectDescriptorID, time, desc->SegmentName));
				}
				break;
			}
			if (desc->startTime + desc->Duration < time) continue;
			if (desc->startTime + desc->Duration == time) {
				continue;
			}
			/*segment switch, force activation (isActive TRUE send at each seg)*/
			if (media_sens->active_seg != i) {
				media_sens->active_seg = i;
				media_sens->sensor->isActive = 0;
			}

			if (!media_sens->sensor->isActive) {
				media_sens->sensor->isActive = 1;
				gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
				/*set info*/
				gf_sg_vrml_mf_reset(& media_sens->sensor->info, GF_SG_VRML_MFSTRING);
				gf_sg_vrml_mf_alloc(& media_sens->sensor->info, GF_SG_VRML_MFSTRING, 1);
				media_sens->sensor->info.vals[0] = desc->SegmentName ? gf_strdup(desc->SegmentName) : NULL;
				gf_node_event_out((GF_Node *) media_sens->sensor, 5/*"info"*/);
				/*set duration*/
				media_sens->sensor->mediaDuration = desc->Duration;
				gf_node_event_out((GF_Node *) media_sens->sensor, 3/*"mediaDuration"*/);
				/*set seg start time*/
				media_sens->sensor->streamObjectStartTime = desc->startTime;
				gf_node_event_out((GF_Node *) media_sens->sensor, 2/*"streamObjectStartTime"*/);

				GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Activating media sensor time %g - segment %s\n", odm->OD->objectDescriptorID, time, desc->SegmentName));
			}
			/*set media time - relative to segment start time*/
			time -= desc->startTime;
			if (media_sens->sensor->mediaCurrentTime != time) {
				media_sens->sensor->mediaCurrentTime = time;
				gf_node_event_out((GF_Node *) media_sens->sensor, 1/*"mediaCurrentTime"*/);
			}
			break;
		}
		if (i==count) {
			/*we're after last segment, deactivate*/
			if (media_sens->sensor->isActive) {
				media_sens->sensor->isActive = 0;
				gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
				media_sens->active_seg = count;
				GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Deactivating media sensor at time %g: no more segments\n", odm->OD->objectDescriptorID, time));
			}
		}
	}
}
Beispiel #16
0
static void Extrusion_SetOrientation(GF_Node *node, GF_Route *route)
{
	M_Extrusion *eg = (M_Extrusion *)node;
	gf_sg_vrml_field_copy(&eg->orientation, &eg->set_orientation, GF_SG_VRML_MFROTATION);
	gf_sg_vrml_mf_reset(&eg->set_orientation, GF_SG_VRML_MFROTATION);
}
Beispiel #17
0
static void ElevationGrid_SetHeight(GF_Node *node, GF_Route *route)
{
	M_ElevationGrid *eg = (M_ElevationGrid *)node;
	gf_sg_vrml_field_copy(&eg->height, &eg->set_height, GF_SG_VRML_MFFLOAT);
	gf_sg_vrml_mf_reset(&eg->set_height, GF_SG_VRML_MFFLOAT);
}
Beispiel #18
0
static void TTD_NewTextChunk(TTDPriv *priv, GF_TextSampleDescriptor *tsd, M_Form *form, u16 *utf16_txt, TTDTextChunk *tc)
{
	GF_Node *txt_model, *n2, *txt_material;
	M_Text *text;
	M_FontStyle *fs;
	char *fontName;
	char szStyle[1024];
	u32 fontSize, styleFlags, color, i, start_char;

	if (!tc->srec) {
		fontName = TTD_FindFont(tsd, tsd->default_style.fontID);
		fontSize = tsd->default_style.font_size;
		styleFlags = tsd->default_style.style_flags;
		color = tsd->default_style.text_color;
	} else {
		fontName = TTD_FindFont(tsd, tc->srec->fontID);
		fontSize = tc->srec->font_size;
		styleFlags = tc->srec->style_flags;
		color = tc->srec->text_color;
	}

	/*create base model for text node. It will then be cloned for each text item*/
	txt_model = ttd_create_node(priv, TAG_MPEG4_Shape, NULL);
	gf_node_register(txt_model, NULL);
	n2 = ttd_create_node(priv, TAG_MPEG4_Appearance, NULL);
	((M_Shape *)txt_model)->appearance = n2;
	gf_node_register(n2, txt_model);
	txt_material = ttd_create_node(priv, TAG_MPEG4_Material2D, NULL);
	((M_Appearance *)n2)->material = txt_material;
	gf_node_register(txt_material, n2);

	((M_Material2D *)txt_material)->filled = 1;
	((M_Material2D *)txt_material)->transparency = FIX_ONE - INT2FIX((color>>24) & 0xFF) / 255;
	((M_Material2D *)txt_material)->emissiveColor.red = INT2FIX((color>>16) & 0xFF) / 255;
	((M_Material2D *)txt_material)->emissiveColor.green = INT2FIX((color>>8) & 0xFF) / 255;
	((M_Material2D *)txt_material)->emissiveColor.blue = INT2FIX((color) & 0xFF) / 255;
	/*force 0 lineWidth if blinking (the stupid MPEG-4 default values once again..)*/
	if (tc->has_blink) {
		((M_Material2D *)txt_material)->lineProps = ttd_create_node(priv, TAG_MPEG4_LineProperties, NULL);
		((M_LineProperties *)((M_Material2D *)txt_material)->lineProps)->width = 0;
		gf_node_register(((M_Material2D *)txt_material)->lineProps, txt_material);
	}

	n2 = ttd_create_node(priv, TAG_MPEG4_Text, NULL);
	((M_Shape *)txt_model)->geometry = n2;
	gf_node_register(n2, txt_model);
	text = (M_Text *) n2;
	fs = (M_FontStyle *) ttd_create_node(priv, TAG_MPEG4_FontStyle, NULL);
	gf_free(fs->family.vals[0]);

	/*translate default fonts to MPEG-4/VRML names*/
	if (!stricmp(fontName, "Serif")) fs->family.vals[0] = gf_strdup("SERIF");
	else if (!stricmp(fontName, "Sans-Serif")) fs->family.vals[0] = gf_strdup("SANS");
	else if (!stricmp(fontName, "Monospace")) fs->family.vals[0] = gf_strdup("TYPEWRITER");
	else fs->family.vals[0] = gf_strdup(fontName);

	fs->size = INT2FIX(fontSize);
	gf_free(fs->style.buffer);
	strcpy(szStyle, "");
	if (styleFlags & GF_TXT_STYLE_BOLD) {
		if (styleFlags & GF_TXT_STYLE_ITALIC) strcpy(szStyle, "BOLDITALIC");
		else strcpy(szStyle, "BOLD");
	} else if (styleFlags & GF_TXT_STYLE_ITALIC) strcat(szStyle, "ITALIC");
	if (!strlen(szStyle)) strcpy(szStyle, "PLAIN");
	/*also underline for URLs*/
	if ((styleFlags & GF_TXT_STYLE_UNDERLINED) || (tc->hlink && tc->hlink->URL)) strcat(szStyle, " UNDERLINED");

	if (tc->is_hilight) {
		if (tc->hilight_col) {
			char szTxt[50];
			sprintf(szTxt, " HIGHLIGHT#%x", tc->hilight_col);
			strcat(szStyle, szTxt);
		} else {
			strcat(szStyle, " HIGHLIGHT#RV");
		}
	}
	/*a better way would be to draw the entire text box in a composite texture & bitmap but we can't really rely
	on text box size (in MP4Box, it actually defaults to the entire video area) and drawing a too large texture
	& bitmap could slow down rendering*/
	if (priv->use_texture) strcat(szStyle, " TEXTURED");
	if (priv->outline) strcat(szStyle, " OUTLINED");

	fs->style.buffer = gf_strdup(szStyle);
	fs->horizontal = (tsd->displayFlags & GF_TXT_VERTICAL) ? 0 : 1;
	text->fontStyle = (GF_Node *) fs;
	gf_node_register((GF_Node *)fs, (GF_Node *)text);
	gf_sg_vrml_mf_reset(&text->string, GF_SG_VRML_MFSTRING);

	if (tc->hlink && tc->hlink->URL) {
		SFURL *s;
		M_Anchor *anc = (M_Anchor *) ttd_create_node(priv, TAG_MPEG4_Anchor, NULL);
		gf_sg_vrml_mf_append(&anc->url, GF_SG_VRML_MFURL, (void **) &s);
		s->OD_ID = 0;
		s->url = gf_strdup(tc->hlink->URL);
		if (tc->hlink->URL_hint) anc->description.buffer = gf_strdup(tc->hlink->URL_hint);
		gf_node_list_add_child(& anc->children, txt_model);
		gf_node_register(txt_model, (GF_Node *)anc);
		txt_model = (GF_Node *)anc;
		gf_node_register((GF_Node *)anc, NULL);
	}

	start_char = tc->start_char;
	for (i=tc->start_char; i<tc->end_char; i++) {
		Bool new_line = 0;
		if ((utf16_txt[i] == '\n') || (utf16_txt[i] == '\r') || (utf16_txt[i] == 0x85) || (utf16_txt[i] == 0x2028) || (utf16_txt[i] == 0x2029)) new_line = 1;

		if (new_line || (i+1==tc->end_char) ) {
			SFString *st;

			if (i+1==tc->end_char) i++;

			if (i!=start_char) {
				char szLine[5000];
				u32 len;
				s16 wsChunk[5000], *sp;

				/*spliting lines, duplicate node*/

				n2 = gf_node_clone(priv->sg, txt_model, NULL, "", 1);
				if (tc->hlink && tc->hlink->URL) {
					GF_Node *t = ((M_Anchor *)n2)->children->node;
					text = (M_Text *) ((M_Shape *)t)->geometry;
					txt_material = ((M_Appearance *) ((M_Shape *)t)->appearance)->material;
				} else {
					text = (M_Text *) ((M_Shape *)n2)->geometry;
					txt_material = ((M_Appearance *) ((M_Shape *)n2)->appearance)->material;
				}
				gf_sg_vrml_mf_reset(&text->string, GF_SG_VRML_MFSTRING);
				gf_node_list_add_child( &form->children, n2);
				gf_node_register(n2, (GF_Node *) form);
				ttd_add_item(form);
				/*clone node always register by default*/
				gf_node_unregister(n2, NULL);

				if (tc->has_blink && txt_material) gf_list_add(priv->blink_nodes, txt_material);


				memcpy(wsChunk, &utf16_txt[start_char], sizeof(s16)*(i-start_char));
				wsChunk[i-start_char] = 0;
				sp = &wsChunk[0];
				len = gf_utf8_wcstombs(szLine, 5000, (const unsigned short **) &sp);
				szLine[len] = 0;

				gf_sg_vrml_mf_append(&text->string, GF_SG_VRML_MFSTRING, (void **) &st);
				st->buffer = gf_strdup(szLine);
			}
			start_char = i+1;
			if (new_line) {
				ttd_add_line(form);
				if ((utf16_txt[i]=='\r') && (utf16_txt[i+1]=='\n')) i++;
			}
		}
	}
	gf_node_unregister(txt_model, NULL);
	return;
}
Beispiel #19
0
void gf_inline_on_modified(GF_Node *node)
{
	u32 ODID;
	GF_MediaObject *mo;
	M_Inline *pInline = (M_Inline *) node;
	GF_Scene *scene = (GF_Scene *)gf_node_get_private(node);

	ODID = gf_mo_get_od_id(&pInline->url);
	if (scene) {
		mo = (scene->root_od) ? scene->root_od->mo : NULL;

		/*disconnect current inline if we're the last one using it (same as regular OD session leave/join)*/
		if (mo) {
			Bool changed = 1;
			if (ODID != GF_MEDIA_EXTERNAL_ID) {
				if (ODID && (ODID==scene->root_od->OD->objectDescriptorID)) changed = 0;
			} else {
				if (gf_mo_is_same_url(mo, &pInline->url, NULL, 0) ) changed = 0;
			}
			if (mo->num_open) {
				if (!changed) return;

				gf_scene_notify_event(scene, GF_EVENT_UNLOAD, node, NULL, GF_OK);
				gf_node_dirty_parents(node);
				gf_list_del_item(mo->nodes, node);

				/*reset the scene pointer as it may get destroyed*/
				switch (gf_node_get_tag(node)) {
				case TAG_MPEG4_Inline:
#ifndef GPAC_DISABLE_X3D
				case TAG_X3D_Inline:
#endif
					gf_node_set_private(node, NULL);
					break;
				}

				mo->num_open --;
				if (!mo->num_open) {
					if (ODID == GF_MEDIA_EXTERNAL_ID) {
						GF_Scene *parent = scene->root_od->parentscene;
						/*!!! THIS WILL DESTROY THE INLINE SCENE OBJECT !!!*/
						gf_odm_disconnect(scene->root_od, 1);
						/*and force removal of the media object*/
						if (parent) {
							if (gf_list_del_item(parent->scene_objects, mo)>=0) {
								gf_sg_vrml_mf_reset(&mo->URLs, GF_SG_VRML_MFURL);
								gf_list_del(mo->nodes);
								gf_free(mo);
							}
						}
					} else {
						gf_term_lock_media_queue(scene->root_od->term, 1);
						
						/*external media are completely unloaded*/
						if (scene->root_od->OD->objectDescriptorID==GF_MEDIA_EXTERNAL_ID) {
							scene->root_od->action_type = GF_ODM_ACTION_DELETE;
						} else {
							scene->root_od->action_type = GF_ODM_ACTION_STOP;
						}
						if (gf_list_find(scene->root_od->term->media_queue, scene->root_od)<0)
							gf_list_add(scene->root_od->term->media_queue, scene->root_od);

						gf_term_lock_media_queue(scene->root_od->term, 0);
					}
				}
			}
		}
	} else {
		gf_node_dirty_parents(node);
	}
	if (ODID) gf_inline_set_scene(pInline);
}
Beispiel #20
0
static void gf_storage_load(M_Storage *storage)
{
	const char *opt;
	char szID[20];
	u32 i, count;
	u32 sec, exp, frac;
	GF_Config *cfg = storage_get_cfg(storage);
	char *section = storage_get_section(storage);
	if (!cfg || !section) return;

	if (!gf_cfg_get_key_count(cfg, section)) {
		gf_free(section);
		return;
	}
	opt = gf_cfg_get_key(cfg, section, "expireAfterNTP");
	gf_net_get_ntp(&sec, &frac);
	sscanf(opt, "%u", &exp);
	if (exp && (exp<=sec)) {
		gf_cfg_del_section(cfg, section);
		gf_free(section);
		return;
	}

	count = gf_cfg_get_key_count(cfg, section)-1;
	if (!count || (count!=storage->storageList.count)) {
		gf_cfg_del_section(cfg, section);
		gf_free(section);
		return;
	}

	for (i=0; i<count; i++) {
		GF_FieldInfo info;
		sprintf(szID, "%d", i);
		opt = gf_cfg_get_key(cfg, section, szID);
		if (!opt) break;
		if (!storage->storageList.vals[i].node) break;
		if (gf_node_get_field(storage->storageList.vals[i].node, storage->storageList.vals[i].fieldIndex, &info) != GF_OK) break;

		if (gf_sg_vrml_is_sf_field(info.fieldType)) {
			storage_parse_sf(info.far_ptr, info.fieldType, (char *) opt);
		} else {
			u32 sftype = gf_sg_vrml_get_sf_type(info.fieldType);
			char *sep, *val;
			void *slot;
			gf_sg_vrml_mf_reset(info.far_ptr, info.fieldType);
			while (1) {
				val = strchr(opt, '\'');
				sep = val ? strchr(val+1, '\'') : NULL;
				if (!val || !sep) break;

				sep[0] = 0;
				gf_sg_vrml_mf_append(info.far_ptr, info.fieldType, &slot);
				storage_parse_sf(slot, sftype, val+1);
				sep[0] = '\'';
				opt = sep+1;
			}
		}
		gf_node_changed(storage->storageList.vals[i].node, &info);
	}
	gf_free(section);
}
Beispiel #21
0
static void gf_inline_traverse(GF_Node *n, void *rs, Bool is_destroy)
{
	MFURL *current_url;
	GF_Scene *scene = (GF_Scene *)gf_node_get_private(n);

	if (is_destroy) {
		GF_MediaObject *mo;
		if (!scene) return;
		mo = scene->root_od ? scene->root_od->mo : NULL;

		gf_scene_notify_event(scene, GF_EVENT_UNLOAD, n, NULL, GF_OK);
		if (!mo) return;
		gf_list_del_item(mo->nodes, n);

		/*disconnect current inline if we're the last one using it (same as regular OD session leave/join)*/
		if (mo->num_open) {
			mo->num_open --;
			if (!mo->num_open) {
				gf_term_lock_media_queue(scene->root_od->term, 1);

				/*this is unspecified in the spec: whenever an inline not using the 
				OD framework is destroyed, destroy the associated resource*/
				if (mo->OD_ID == GF_MEDIA_EXTERNAL_ID) {
					/*get parent scene and remove MediaObject in case the ressource
					gets re-requested later on*/
					GF_Scene *parent_scene = (GF_Scene *)gf_sg_get_private(gf_node_get_graph((GF_Node *) n) );
					if (gf_list_del_item(parent_scene->scene_objects, mo)>=0) {
						gf_sg_vrml_mf_reset(&mo->URLs, GF_SG_VRML_MFURL);
						gf_list_del(mo->nodes);
						if (mo->odm) mo->odm->mo = NULL;
						gf_free(mo);
					}
					scene->root_od->action_type = GF_ODM_ACTION_DELETE;
					gf_list_add(scene->root_od->term->media_queue, scene->root_od);
				} else {
					scene->root_od->action_type = GF_ODM_ACTION_SCENE_DISCONNECT;
					gf_list_add(scene->root_od->term->media_queue, scene->root_od);
				}
				gf_term_lock_media_queue(scene->root_od->term, 0);
			}
		}
		return;
	}


	//if no private scene is associated	get the node parent graph, retrieve the IS and find the OD
	if (!scene) {
		M_Inline *inl = (M_Inline *)n;
		gf_inline_set_scene(inl);
		scene = (GF_Scene *)gf_node_get_private(n);
		if (!scene) {
			/*just like protos, we must invalidate parent graph until attached*/
			if (inl->url.count) {
				if (!inl->url.vals[0].OD_ID && (!inl->url.vals[0].url || !strlen(inl->url.vals[0].url) ) ) {
					gf_sg_vrml_mf_reset(&inl->url, GF_SG_VRML_MFURL);
				} else {
					gf_node_dirty_set(n, 0, 1);
				}
			}
			return;
		}
	}

	gf_inline_check_restart(scene);

	/*if we need to restart, shutdown graph and do it*/
	if (scene->needs_restart) {
		/*special case: scene change*/
		if (scene->needs_restart==2) {
			scene->needs_restart = 0;
			gf_inline_on_modified(n);
			return;
		}

		scene->needs_restart = 0;
		gf_term_lock_media_queue(scene->root_od->term, 1);
		scene->root_od->action_type = GF_ODM_ACTION_SCENE_INLINE_RESTART;
		gf_list_add(scene->root_od->term->media_queue, scene->root_od);
		gf_term_lock_media_queue(scene->root_od->term, 0);

		gf_node_dirty_set(n, 0, 1);
		return;
	} 
	
	/*if not attached return (attaching the graph cannot be done in render since render is not called while unattached :) */
	if (!scene->graph_attached) {
		/*just like protos, we must invalidate parent graph until attached*/
		gf_node_dirty_set(n, 0, 1);
		return;
	}
	/*clear dirty flags for any sub-inlines, bitmaps or protos*/
	gf_node_dirty_clear(n, 0);

	current_url = scene->current_url;
	scene->current_url = & ((M_Inline*)n)->url;
	gf_sc_traverse_subscene(scene->root_od->term->compositor, n, scene->graph, rs);
	scene->current_url = current_url;
}
Beispiel #22
0
GF_EXPORT
GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_offset)
{
	GF_Err e;
	GF_CommandField *inf;
	GF_FieldInfo field;
	GF_Node *def, *node;
	void *slot_ptr;

	if (!com || !graph) return GF_BAD_PARAM;

	e = GF_OK;
	switch (com->tag) {
	case GF_SG_SCENE_REPLACE:
		/*unregister root*/
		gf_node_unregister(graph->RootNode, NULL);
		/*remove all protos and routes*/
		while (gf_list_count(graph->routes_to_activate)) 
			gf_list_rem(graph->routes_to_activate, 0);
		
		/*destroy all routes*/
		while (gf_list_count(graph->Routes)) {
			GF_Route *r = (GF_Route *)gf_list_get(graph->Routes, 0);
			/*this will unregister the route from the graph, so don't delete the chain entry*/
			gf_sg_route_del(r);
		}
		/*destroy all proto*/
		while (gf_list_count(graph->protos)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(graph->protos, 0);
			/*this will unregister the proto from the graph, so don't delete the chain entry*/
			gf_sg_proto_del(p);
		}
		/*DO NOT TOUCH node registry*/
		/*DO NOT TOUCH UNREGISTERED PROTOS*/

		/*move all protos in graph*/
		while (gf_list_count(com->new_proto_list)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0);
			gf_list_rem(com->new_proto_list, 0);
			gf_list_del_item(graph->unregistered_protos, p);
			gf_list_add(graph->protos, p);
		}
		/*assign new root (no need to register/unregister)*/
		graph->RootNode = com->node;
		com->node = NULL;
		break;

	case GF_SG_NODE_REPLACE:
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		e = gf_node_replace(com->node, inf->new_node, 0);
		if (inf->new_node) gf_node_register(inf->new_node, NULL);
		break;

	case GF_SG_MULTIPLE_REPLACE:
	case GF_SG_FIELD_REPLACE:
	{
		u32 j;
		GF_ChildNodeItem *list, *cur, *prev;
		j=0;
		while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &j))) {
			e = gf_node_get_field(com->node, inf->fieldIndex, &field);
			if (e) return e;

			switch (field.fieldType) {
			case GF_SG_VRML_SFNODE:
			{
				node = *((GF_Node **) field.far_ptr);
				e = gf_node_unregister(node, com->node);
				*((GF_Node **) field.far_ptr) = inf->new_node;
				if (!e) gf_node_register(inf->new_node, com->node);
				break;
			}
			case GF_SG_VRML_MFNODE:
				gf_node_unregister_children(com->node, * ((GF_ChildNodeItem **) field.far_ptr));
				* ((GF_ChildNodeItem **) field.far_ptr) = NULL;

				list = * ((GF_ChildNodeItem **) inf->field_ptr);
				prev=NULL;
				while (list) {
					cur = malloc(sizeof(GF_ChildNodeItem));
					cur->next = NULL;
					cur->node = list->node;
					if (prev) {
						prev->next = cur;
					} else {
						* ((GF_ChildNodeItem **) field.far_ptr) = cur;
					}
					gf_node_register(list->node, com->node);
					prev = cur;
					list = list->next;
				}
				break;
			default:
				/*this is a regular field, reset it and clone - we cannot switch pointers since the
				original fields are NOT pointers*/
				if (!gf_sg_vrml_is_sf_field(field.fieldType)) {
					e = gf_sg_vrml_mf_reset(field.far_ptr, field.fieldType);
				}
				if (e) return e;
				gf_sg_vrml_field_copy(field.far_ptr, inf->field_ptr, field.fieldType);
				if (field.fieldType==GF_SG_VRML_SFTIME) *(SFTime *)field.far_ptr = *(SFTime *)field.far_ptr + time_offset;
				break;
			}
			SG_CheckFieldChange(com->node, &field);
		}
		break;
	}

	case GF_SG_MULTIPLE_INDEXED_REPLACE:
	case GF_SG_INDEXED_REPLACE:
	{
		u32 sftype, i=0;
		while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &i))) {
			e = gf_node_get_field(com->node, inf->fieldIndex, &field);
			if (e) return e;

			/*if MFNode remove the child and set new node*/
			if (field.fieldType == GF_SG_VRML_MFNODE) {
				/*we must remove the node before in case the new node uses the same ID (not forbidden) and this
				command removes the last instance of the node with the same ID*/
				gf_node_replace_child(com->node, (GF_ChildNodeItem**) field.far_ptr, inf->pos, inf->new_node);
				if (inf->new_node) gf_node_register(inf->new_node, NULL);
			}
			/*erase the field item*/
			else {
				if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) {
					inf->pos = ((GenMFField *)field.far_ptr)->count - 1;
					/*may happen with text and default value*/
					if (inf->pos < 0) {
						inf->pos = 0;
						gf_sg_vrml_mf_alloc(field.far_ptr, field.fieldType, 1);
					}
				}
				e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, & slot_ptr, inf->pos);
				if (e) return e;
				sftype = gf_sg_vrml_get_sf_type(field.fieldType);
				gf_sg_vrml_field_copy(slot_ptr, inf->field_ptr, sftype);
				/*note we don't add time offset, since there's no MFTime*/
			}
			SG_CheckFieldChange(com->node, &field);
		}
		break;
	}
	case GF_SG_ROUTE_REPLACE:
	{
		GF_Route *r;
		char *name;
		r = gf_sg_route_find(graph, com->RouteID);
		def = gf_sg_find_node(graph, com->fromNodeID);
		node = gf_sg_find_node(graph, com->toNodeID);
		if (!node || !def) return GF_SG_UNKNOWN_NODE;
		name = NULL;
		if (r) {
			name = r->name;
			r->name = NULL;
			gf_sg_route_del(r);
		}
		r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex);
		gf_sg_route_set_id(r, com->RouteID);
		if (name) {
			gf_sg_route_set_name(r, name);
			free(name);
		}
		break;
	}
	case GF_SG_NODE_DELETE_EX:
	case GF_SG_NODE_DELETE:
	{
		if (com->node) gf_node_replace(com->node, NULL, (com->tag==GF_SG_NODE_DELETE_EX) ? 1 : 0);
		break;
	}
	case GF_SG_ROUTE_DELETE:
	{
		return gf_sg_route_del_by_id(graph, com->RouteID);
	}
	case GF_SG_INDEXED_DELETE:
	{
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);

		e = gf_node_get_field(com->node, inf->fieldIndex, &field);
		if (e) return e;
		if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;

		/*then we need special handling in case of a node*/
		if (gf_sg_vrml_get_sf_type(field.fieldType) == GF_SG_VRML_SFNODE) {
			e = gf_node_replace_child(com->node, (GF_ChildNodeItem **) field.far_ptr, inf->pos, NULL);
		} else {
			if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) {
				inf->pos = ((GenMFField *)field.far_ptr)->count - 1;
			}
			/*this is a regular MFField, just remove the item (realloc)*/
			e = gf_sg_vrml_mf_remove(field.far_ptr, field.fieldType, inf->pos);
		}
		/*deletion -> node has changed*/
		if (!e) SG_CheckFieldChange(com->node, &field);
		break;
	}
	case GF_SG_NODE_INSERT:
	{
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);

		e = gf_node_insert_child(com->node, inf->new_node, inf->pos);
		if (!e) gf_node_register(inf->new_node, com->node);
		if (!e) gf_node_event_out(com->node, inf->fieldIndex);
		if (!e) gf_node_changed(com->node, NULL);
		break;
	}
	case GF_SG_ROUTE_INSERT:
	{
		GF_Route *r;
		def = gf_sg_find_node(graph, com->fromNodeID);
		node = gf_sg_find_node(graph, com->toNodeID);
		if (!node || !def) return GF_SG_UNKNOWN_NODE;
		r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex);
		if (com->RouteID) gf_sg_route_set_id(r, com->RouteID);
		if (com->def_name) {
			gf_sg_route_set_name(r, com->def_name);
			free(com->def_name);
			com->def_name = NULL;
		}
		break;
	}
	case GF_SG_INDEXED_INSERT:
	{
		u32 sftype;
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		e = gf_node_get_field(com->node, inf->fieldIndex, &field);
		if (e) return e;

		/*rescale the MFField and parse the SFField*/
		if (field.fieldType != GF_SG_VRML_MFNODE) {
			if (inf->pos == -1) {
				e = gf_sg_vrml_mf_append(field.far_ptr, field.fieldType, & slot_ptr);
			} else {
				e = gf_sg_vrml_mf_insert(field.far_ptr, field.fieldType, & slot_ptr, inf->pos);
			}
			if (e) return e;
			sftype = gf_sg_vrml_get_sf_type(field.fieldType);
			gf_sg_vrml_field_copy(slot_ptr, inf->field_ptr, sftype);
		} else {
			if (inf->new_node) {
				if (inf->pos == -1) {
					gf_node_list_add_child( (GF_ChildNodeItem **) field.far_ptr, inf->new_node);
				} else {
					gf_node_list_insert_child((GF_ChildNodeItem **) field.far_ptr, inf->new_node, inf->pos);
				}
				gf_node_register(inf->new_node, com->node);
			}
		}
		if (!e) SG_CheckFieldChange(com->node, &field);
		break;
	}
	case GF_SG_PROTO_INSERT:
		/*destroy all proto*/
		while (gf_list_count(com->new_proto_list)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0);
			gf_list_rem(com->new_proto_list, 0);
			gf_list_del_item(graph->unregistered_protos, p);
			gf_list_add(graph->protos, p);
		}
		return GF_OK;
	case GF_SG_PROTO_DELETE:
		{
			u32 i;
			for (i=0; i<com->del_proto_list_size; i++) {
				/*note this will check for unregistered protos, but since IDs are unique we are sure we will 
				not destroy an unregistered one*/
				GF_Proto *proto = gf_sg_find_proto(graph, com->del_proto_list[i], NULL);
				if (proto) gf_sg_proto_del(proto);
			}
		}
		return GF_OK;
	case GF_SG_PROTO_DELETE_ALL:
		/*destroy all proto*/
		while (gf_list_count(graph->protos)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(graph->protos, 0);
			gf_list_rem(graph->protos, 0);
			/*this will unregister the proto from the graph, so don't delete the chain entry*/
			gf_sg_proto_del(p);
		}
		/*DO NOT TOUCH UNREGISTERED PROTOS*/
		return GF_OK;
	/*only used by BIFS*/
	case GF_SG_GLOBAL_QUANTIZER:
		return GF_OK;

#ifndef GPAC_DISABLE_SVG
	/*laser commands*/
	case GF_SG_LSR_NEW_SCENE:
		/*DO NOT TOUCH node registry*/

		/*assign new root (no need to register/unregister)*/
		graph->RootNode = com->node;
		com->node = NULL;
		break;
	case GF_SG_LSR_DELETE:
		if (!com->node) return GF_NON_COMPLIANT_BITSTREAM;
		if (!gf_list_count(com->command_fields)) {
			gf_node_replace(com->node, NULL, 0);
			gf_node_deactivate(com->node);
			return GF_OK;
		}
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		node = gf_node_list_get_child(((SVG_Element *)com->node)->children, inf->pos);
		if (node) {
			e = gf_node_replace_child(com->node, &((SVG_Element *)com->node)->children, inf->pos, NULL);
			gf_node_deactivate(node);
		}
		break;
	case GF_SG_LSR_INSERT:
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		if (!com->node || !inf) return GF_NON_COMPLIANT_BITSTREAM;
		if (inf->new_node) {
			if (inf->pos<0) 
				gf_node_list_add_child(& ((SVG_Element *)com->node)->children, inf->new_node);
			else
				gf_node_list_insert_child(& ((SVG_Element *)com->node)->children, inf->new_node, inf->pos);

			gf_node_register(inf->new_node, com->node);
			gf_node_activate(inf->new_node);
			gf_node_changed(com->node, NULL);
		} else {
			/*NOT SUPPORTED*/
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[LASeR] VALUE INSERTION NOT SUPPORTED\n"));
		}
		break;
	case GF_SG_LSR_ADD:
	case GF_SG_LSR_REPLACE:
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		if (!com->node || !inf) return GF_NON_COMPLIANT_BITSTREAM;
		if (inf->new_node) {
			if (inf->pos<0) {
				/*if fieldIndex (eg attributeName) is set, this is children replacement*/
				if (inf->fieldIndex>0) {
					gf_node_unregister_children_deactivate(com->node, ((SVG_Element *)com->node)->children);
					((SVG_Element *)com->node)->children = NULL;
					gf_node_list_add_child(& ((SVG_Element *)com->node)->children, inf->new_node);
					gf_node_register(inf->new_node, com->node);
					gf_node_activate(inf->new_node);
				} else {
					e = gf_node_replace(com->node, inf->new_node, 0);
					gf_node_activate(inf->new_node);
				}
			} else {
				node = gf_node_list_get_child( ((SVG_Element *)com->node)->children, inf->pos);
				gf_node_replace_child(com->node, & ((SVG_Element *)com->node)->children, inf->pos, inf->new_node);
				gf_node_register(inf->new_node, com->node);
				if (node) gf_node_deactivate(node);
				gf_node_activate(inf->new_node);
			}
			/*signal node modif*/
			gf_node_changed(com->node, NULL);
			return e;
		} else if (inf->node_list) {
			GF_ChildNodeItem *child, *cur, *prev;
			gf_node_unregister_children_deactivate(com->node, ((SVG_Element *)com->node)->children);
			((SVG_Element *)com->node)->children = NULL;

			prev = NULL;
			child = inf->node_list;
			while (child) {
				cur = (GF_ChildNodeItem*)malloc(sizeof(GF_ChildNodeItem));
				cur->next = NULL;
				cur->node = child->node;
				gf_node_register(child->node, com->node);
				gf_node_activate(child->node);
				if (prev) prev->next = cur;
				else ((SVG_Element *)com->node)->children = cur;
				prev = cur;
				child = child->next;
			}
			/*signal node modif*/
			gf_node_changed(com->node, NULL);
			return GF_OK;
		}
		/*attribute modif*/
		else if (inf->field_ptr) {
			GF_FieldInfo a, b;
			if (inf->fieldIndex==(u32) -2) {
				GF_Point2D scale, translate;
				Fixed rotate;
				GF_Matrix2D *dest;
				gf_node_get_field_by_name(com->node, "transform", &a);
				dest = (GF_Matrix2D*)a.far_ptr;
				
				if (com->tag==GF_SG_LSR_REPLACE) {
					if (gf_mx2d_decompose(dest, &scale, &rotate, &translate)) {
						gf_mx2d_init(*dest);
						if (inf->fieldType==SVG_TRANSFORM_SCALE) scale = *(GF_Point2D *)inf->field_ptr;
						else if (inf->fieldType==SVG_TRANSFORM_TRANSLATE) translate = *(GF_Point2D *)inf->field_ptr;
						else if (inf->fieldType==SVG_TRANSFORM_ROTATE) rotate = ((SVG_Point_Angle*)inf->field_ptr)->angle;

						gf_mx2d_add_scale(dest, scale.x, scale.y);
						gf_mx2d_add_rotation(dest, 0, 0, rotate);
						gf_mx2d_add_translation(dest, translate.x, translate.y);
					}
				} else {
					GF_Point2D *pt = (GF_Point2D *)inf->field_ptr;
					if (inf->fieldType==SVG_TRANSFORM_SCALE) gf_mx2d_add_scale(dest, pt->x, pt->y);
					else if (inf->fieldType==SVG_TRANSFORM_TRANSLATE) gf_mx2d_add_translation(dest, pt->x, pt->y);
					else if (inf->fieldType == SVG_TRANSFORM_ROTATE) gf_mx2d_add_rotation(dest, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle);
				}
			} else {
				if ((inf->fieldIndex==(u32) -1) && (inf->fieldType==SVG_String_datatype)) {
					char *str = *(SVG_String*)inf->field_ptr;

					if (com->tag == GF_SG_LSR_REPLACE) {
						GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; 
						if (t && (t->sgprivate->tag==TAG_DOMText)) {
							if (t->textContent) free(t->textContent);
							t->textContent = NULL;
							if (str) t->textContent = strdup(str);
						}
					} else {
						if (str) gf_dom_add_text_node(com->node, strdup(str));
					}
				}
				else if ((inf->fieldIndex==TAG_LSR_ATT_scale) 
					|| (inf->fieldIndex==TAG_LSR_ATT_translation)
					|| (inf->fieldIndex==TAG_LSR_ATT_rotation)
				) {
					SVG_Transform *mx;
					gf_svg_get_attribute_by_tag(com->node, TAG_SVG_ATT_transform, 1, 0, &a);
					mx = a.far_ptr;
					if (com->tag == GF_SG_LSR_REPLACE) {
						GF_Point2D scale, translate;
						SVG_Point_Angle rotate;
						if (gf_mx2d_decompose(&mx->mat, &scale, &rotate.angle, &translate)) {
							gf_mx2d_init(mx->mat);
							if (inf->fieldIndex==TAG_LSR_ATT_scale) scale = *(GF_Point2D *)inf->field_ptr;
							else if (inf->fieldIndex==TAG_LSR_ATT_translation) translate = *(GF_Point2D *)inf->field_ptr;
							else if (inf->fieldIndex==TAG_LSR_ATT_rotation) rotate = *(SVG_Point_Angle*)inf->field_ptr;

							gf_mx2d_add_scale(&mx->mat, scale.x, scale.y);
							gf_mx2d_add_rotation(&mx->mat, 0, 0, rotate.angle);
							gf_mx2d_add_translation(&mx->mat, translate.x, translate.y);
						}
					} else {
						if (inf->fieldIndex==TAG_LSR_ATT_scale) gf_mx2d_add_scale(&mx->mat, ((GF_Point2D*)inf->field_ptr)->x, ((GF_Point2D*)inf->field_ptr)->y);
						if (inf->fieldIndex==TAG_LSR_ATT_translation) gf_mx2d_add_translation(&mx->mat, ((GF_Point2D*)inf->field_ptr)->x, ((GF_Point2D*)inf->field_ptr)->y);
						if (inf->fieldIndex==TAG_LSR_ATT_rotation) gf_mx2d_add_rotation(&mx->mat, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle);
					}
				}
				else if (gf_svg_get_attribute_by_tag(com->node, inf->fieldIndex, 1, 0, &a) == GF_OK) {
					b = a;
					b.far_ptr = inf->field_ptr;
					if (com->tag == GF_SG_LSR_REPLACE) {
						gf_svg_attributes_copy(&a, &b, 0);
					} else {
						gf_svg_attributes_add(&a, &b, &a, 0);
					}
				}
				b = a;
				b.far_ptr = inf->field_ptr;
			}
			/*signal node modif*/
			gf_node_changed(com->node, &a);
		} else if (com->fromNodeID) {
			GF_FieldInfo a, b;
			GF_Node *fromNode = gf_sg_find_node(graph, com->fromNodeID);
			if (!fromNode) return GF_NON_COMPLIANT_BITSTREAM;
			if (gf_node_get_field(fromNode, com->fromFieldIndex, &b) != GF_OK) return GF_NON_COMPLIANT_BITSTREAM;

			if ((inf->fieldIndex==(u32) -1) && (inf->fieldType==SVG_String_datatype)) {
				char *str = *(SVG_String*)inf->field_ptr;

				if (com->tag == GF_SG_LSR_REPLACE) {
					GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; 
					if (t && (t->sgprivate->tag==TAG_DOMText)) {
						if (t->textContent) free(t->textContent);
						t->textContent = NULL;
						if (str) t->textContent = strdup(str);
					}
				} else {
					if (str) gf_dom_add_text_node(com->node, strdup(str));
				}
			} else {
				gf_node_get_field(com->node, inf->fieldIndex, &a);
				if (com->tag == GF_SG_LSR_REPLACE) {
					e = gf_svg_attributes_copy(&a, &b, 0);
				} else {
					e = gf_svg_attributes_add(&a, &b, &a, 0);
				}
			}
			gf_node_changed(com->node, &a);
			return e;
		} else {
			return GF_NON_COMPLIANT_BITSTREAM;
		}
		break;
	case GF_SG_LSR_ACTIVATE:
		gf_node_activate(com->node);
		break;
	case GF_SG_LSR_DEACTIVATE:
		gf_node_deactivate(com->node);
		gf_node_changed(com->node, NULL);
		break;
#endif

	default:
		return GF_NOT_SUPPORTED;
	}
	if (e) return e;

	if (com->scripts_to_load) {
		while (gf_list_count(com->scripts_to_load)) {
			GF_Node *script = (GF_Node *)gf_list_get(com->scripts_to_load, 0);
			gf_list_rem(com->scripts_to_load, 0);
			gf_sg_script_load(script);
		}
		gf_list_del(com->scripts_to_load);
		com->scripts_to_load = NULL;
	}
	return GF_OK;
}
Beispiel #23
0
static void ITSS_SetIndex(GF_Node *node, GF_Route *route)
{
	X_IndexedTriangleStripSet *itss = (X_IndexedTriangleStripSet*)node;
	gf_sg_vrml_field_copy(&itss->index, &itss->set_index, GF_SG_VRML_MFINT32);
	gf_sg_vrml_mf_reset(&itss->set_index, GF_SG_VRML_MFINT32);
}
Beispiel #24
0
static void IFS_SetTexCoordIndex(GF_Node *node, GF_Route *route)
{
	M_IndexedFaceSet *ifs = (M_IndexedFaceSet *)node;
	gf_sg_vrml_field_copy(&ifs->texCoordIndex, &ifs->set_texCoordIndex, GF_SG_VRML_MFINT32);
	gf_sg_vrml_mf_reset(&ifs->set_texCoordIndex, GF_SG_VRML_MFINT32);
}
Beispiel #25
0
static void ILS_SetCoordIndex(GF_Node *node, GF_Route *route)
{
	M_IndexedLineSet *ils = (M_IndexedLineSet *)node;
	gf_sg_vrml_field_copy(&ils->coordIndex, &ils->set_coordIndex, GF_SG_VRML_MFINT32);
	gf_sg_vrml_mf_reset(&ils->set_coordIndex, GF_SG_VRML_MFINT32);
}
Beispiel #26
0
static void TraversePlanarExtrusion(GF_Node *node, void *rs, Bool is_destroy)
{
    PlanarExtrusion plane_ext;
    Drawable *stack_2d;
    u32 i, j, k;
    MFVec3f spine_vec;
    SFVec3f d;
    Fixed spine_len;
    GF_Rect bounds;
    GF_Path *geo, *spine;
    GF_TraverseState *tr_state = (GF_TraverseState *)rs;
    Drawable3D *stack = (Drawable3D *)gf_node_get_private(node);

    if (is_destroy) {
        drawable_3d_del(node);
        return;
    }

    if (!PlanarExtrusion_GetNode(node, &plane_ext)) return;
    if (!plane_ext.geometry || !plane_ext.spine) return;


    if (gf_node_dirty_get(node)) {
        u32 cur, nb_pts;
        u32 mode = tr_state->traversing_mode;
        geo = spine = NULL;

        tr_state->traversing_mode = TRAVERSE_GET_BOUNDS;
        gf_node_traverse(plane_ext.geometry, tr_state);
        gf_node_traverse(plane_ext.spine, tr_state);
        tr_state->traversing_mode = mode;

        switch (gf_node_get_tag(plane_ext.geometry) ) {
        case TAG_MPEG4_Circle:
        case TAG_MPEG4_Ellipse:
        case TAG_MPEG4_Rectangle:
        case TAG_MPEG4_Curve2D:
        case TAG_MPEG4_XCurve2D:
        case TAG_MPEG4_IndexedFaceSet2D:
        case TAG_MPEG4_IndexedLineSet2D:
            stack_2d = (Drawable*)gf_node_get_private(plane_ext.geometry);
            if (stack_2d) geo = stack_2d->path;
            break;
        default:
            return;
        }
        switch (gf_node_get_tag(plane_ext.spine) ) {
        case TAG_MPEG4_Circle:
        case TAG_MPEG4_Ellipse:
        case TAG_MPEG4_Rectangle:
        case TAG_MPEG4_Curve2D:
        case TAG_MPEG4_XCurve2D:
        case TAG_MPEG4_IndexedFaceSet2D:
        case TAG_MPEG4_IndexedLineSet2D:
            stack_2d = (Drawable*)gf_node_get_private(plane_ext.spine);
            if (stack_2d) spine = stack_2d->path;
            break;
        default:
            return;
        }
        if (!geo || !spine) return;

        mesh_reset(stack->mesh);
        gf_path_flatten(spine);
        gf_path_get_bounds(spine, &bounds);
        gf_path_flatten(geo);
        gf_path_get_bounds(geo, &bounds);

        cur = 0;
        for (i=0; i<spine->n_contours; i++) {
            nb_pts = 1 + spine->contours[i] - cur;
            spine_vec.vals = NULL;
            gf_sg_vrml_mf_alloc(&spine_vec, GF_SG_VRML_MFVEC3F, nb_pts);
            spine_len = 0;
            for (j=cur; j<nb_pts; j++) {
                spine_vec.vals[j].x = spine->points[j].x;
                spine_vec.vals[j].y = spine->points[j].y;
                spine_vec.vals[j].z = 0;
                if (j) {
                    gf_vec_diff(d, spine_vec.vals[j], spine_vec.vals[j-1]);
                    spine_len += gf_vec_len(d);
                }
            }
            cur += nb_pts;
            if (!plane_ext.orientation->count && !plane_ext.scale->count) {
                mesh_extrude_path_ext(stack->mesh, geo, &spine_vec, plane_ext.creaseAngle,
                                      bounds.x, bounds.y-bounds.height, bounds.width, bounds.height,
                                      plane_ext.beginCap, plane_ext.endCap, NULL, NULL, plane_ext.txAlongSpine);
            }
            /*interpolate orientation and scale along subpath line*/
            else {
                MFRotation ori;
                MFVec2f scale;
                Fixed cur_len, frac;

                ori.vals = NULL;
                gf_sg_vrml_mf_alloc(&ori, GF_SG_VRML_MFROTATION, nb_pts);
                scale.vals = NULL;
                gf_sg_vrml_mf_alloc(&scale, GF_SG_VRML_MFVEC2F, nb_pts);
                cur_len = 0;
                if (!plane_ext.orientation->count) ori.vals[0].y = FIX_ONE;
                if (!plane_ext.scale->count) scale.vals[0].x = scale.vals[0].y = FIX_ONE;
                for (j=0; j<nb_pts; j++) {
                    if (j) {
                        gf_vec_diff(d, spine_vec.vals[j], spine_vec.vals[j-1]);
                        cur_len += gf_vec_len(d);
                        ori.vals[j] = ori.vals[j-1];
                        scale.vals[j] = scale.vals[j-1];
                    }

                    if (plane_ext.orientation->count && (plane_ext.orientation->count == plane_ext.orientationKeys->count)) {

                        frac = gf_divfix(cur_len , spine_len);
                        if (frac < plane_ext.orientationKeys->vals[0]) ori.vals[j] = plane_ext.orientation->vals[0];
                        else if (frac >= plane_ext.orientationKeys->vals[plane_ext.orientationKeys->count-1]) ori.vals[j] = plane_ext.orientation->vals[plane_ext.orientationKeys->count-1];
                        else {
                            for (k=1; k<plane_ext.orientationKeys->count; k++) {
                                Fixed kDiff = plane_ext.orientationKeys->vals[k] - plane_ext.orientationKeys->vals[k-1];
                                if (!kDiff) continue;
                                if (frac < plane_ext.orientationKeys->vals[k-1]) continue;
                                if (frac > plane_ext.orientationKeys->vals[k]) continue;
                                frac = gf_divfix(frac - plane_ext.orientationKeys->vals[k-1], kDiff);
                                break;
                            }
                            ori.vals[j] = gf_sg_sfrotation_interpolate(plane_ext.orientation->vals[k-1], plane_ext.orientation->vals[k], frac);
                        }
                    }

                    if (plane_ext.scale->count == plane_ext.scaleKeys->count) {
                        frac = gf_divfix(cur_len , spine_len);
                        if (frac <= plane_ext.scaleKeys->vals[0]) scale.vals[j] = plane_ext.scale->vals[0];
                        else if (frac >= plane_ext.scaleKeys->vals[plane_ext.scaleKeys->count-1]) scale.vals[j] = plane_ext.scale->vals[plane_ext.scale->count-1];
                        else {
                            for (k=1; k<plane_ext.scaleKeys->count; k++) {
                                Fixed kDiff = plane_ext.scaleKeys->vals[k] - plane_ext.scaleKeys->vals[k-1];
                                if (!kDiff) continue;
                                if (frac < plane_ext.scaleKeys->vals[k-1]) continue;
                                if (frac > plane_ext.scaleKeys->vals[k]) continue;
                                frac = gf_divfix(frac - plane_ext.scaleKeys->vals[k-1], kDiff);
                                break;
                            }
                            scale.vals[j].x = gf_mulfix(plane_ext.scale->vals[k].x - plane_ext.scale->vals[k-1].x, frac) + plane_ext.scale->vals[k-1].x;
                            scale.vals[j].y = gf_mulfix(plane_ext.scale->vals[k].y - plane_ext.scale->vals[k-1].y, frac) + plane_ext.scale->vals[k-1].y;
                        }
                    }
                }

                mesh_extrude_path_ext(stack->mesh, geo, &spine_vec, plane_ext.creaseAngle,
                                      bounds.x, bounds.y-bounds.height, bounds.width, bounds.height,
                                      plane_ext.beginCap, plane_ext.endCap, &ori, &scale, plane_ext.txAlongSpine);

                gf_sg_vrml_mf_reset(&ori, GF_SG_VRML_MFROTATION);
                gf_sg_vrml_mf_reset(&scale, GF_SG_VRML_MFVEC2F);
            }

            gf_sg_vrml_mf_reset(&spine_vec, GF_SG_VRML_MFVEC3F);
        }
        mesh_update_bounds(stack->mesh);
        gf_mesh_build_aabbtree(stack->mesh);
    }

    if (tr_state->traversing_mode==TRAVERSE_DRAW_3D) {
        visual_3d_draw(tr_state, stack->mesh);
    } else if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) {
        tr_state->bbox = stack->mesh->bounds;
    }
}
Beispiel #27
0
static void Extrusion_SetCrossSection(GF_Node *node, GF_Route *route)
{
	M_Extrusion *eg = (M_Extrusion *)node;
	gf_sg_vrml_field_copy(&eg->crossSection, &eg->set_crossSection, GF_SG_VRML_MFVEC2F);
	gf_sg_vrml_mf_reset(&eg->set_crossSection, GF_SG_VRML_MFVEC2F);
}
Beispiel #28
0
/*import cubic QTVR to mp4*/
GF_Err gf_sm_load_init_qt(GF_SceneLoader *load)
{
	u32 i, di, w, h, tk, nb_samp;
	Bool has_qtvr;
	GF_ISOSample *samp;
	GF_ISOFile *src;
	GF_StreamContext *st;
	GF_AUContext *au;
	GF_Command *com;
	M_Background *back;
	M_NavigationInfo *ni;
	M_Group *gr;
	GF_ODUpdate *odU;
	GF_SceneGraph *sg;
	GF_ObjectDescriptor *od;
	GF_ESD *esd;

	if (!load->ctx) return GF_NOT_SUPPORTED;

	src = gf_isom_open(load->fileName, GF_ISOM_OPEN_READ, NULL);
	if (!src) return gf_qt_report(load, GF_URL_ERROR, "Opening file %s failed", load->fileName);

	w = h = tk = 0;
	nb_samp = 0;

	has_qtvr = 0;
	for (i=0; i<gf_isom_get_track_count(src); i++) {
		switch (gf_isom_get_media_type(src, i+1)) {
		case GF_ISOM_MEDIA_VISUAL:
			if (gf_isom_get_media_subtype(src, i+1, 1) == GF_4CC('j', 'p', 'e', 'g')) {
				GF_GenericSampleDescription *udesc = gf_isom_get_generic_sample_description(src, i+1, 1);
				if ((udesc->width>w) || (udesc->height>h)) {
					w = udesc->width;
					h = udesc->height;
					tk = i+1;
					nb_samp = gf_isom_get_sample_count(src, i+1);
				}
				if (udesc->extension_buf) gf_free(udesc->extension_buf);
				gf_free(udesc);
			}
			break;
		case GF_4CC('q','t','v','r'):
			has_qtvr = 1;
			break;
		}
	}
	if (!has_qtvr) {
		gf_isom_delete(src);
		return gf_qt_report(load, GF_NOT_SUPPORTED, "QTVR not found - no conversion available for this QuickTime movie");
	}
	if (!tk) {
		gf_isom_delete(src);
		return gf_qt_report(load, GF_NON_COMPLIANT_BITSTREAM, "No associated visual track with QTVR movie");
	}
	if (nb_samp!=6) {
		gf_isom_delete(src);
		return gf_qt_report(load, GF_NOT_SUPPORTED, "Movie %s doesn't look a Cubic QTVR - sorry...", load->fileName);
	}

	GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("QT: Importing Cubic QTVR Movie"));

	/*create scene*/
	sg = load->ctx->scene_graph;
	gr = (M_Group *) gf_node_new(sg, TAG_MPEG4_Group);
	gf_node_register((GF_Node *)gr, NULL);
	st = gf_sm_stream_new(load->ctx, 1, GF_STREAM_SCENE, 1);
	au = gf_sm_stream_au_new(st, 0, 0, 1);
	com = gf_sg_command_new(load->ctx->scene_graph, GF_SG_SCENE_REPLACE);
	gf_list_add(au->commands, com);
	com->node = (GF_Node *)gr;

	back = (M_Background *) gf_node_new(sg, TAG_MPEG4_Background);
	gf_node_list_add_child( &gr->children, (GF_Node*)back);
	gf_node_register((GF_Node *)back, (GF_Node *)gr);

	gf_sg_vrml_mf_alloc(&back->leftUrl, GF_SG_VRML_MFURL, 1);
	back->leftUrl.vals[0].OD_ID = 2;
	gf_sg_vrml_mf_alloc(&back->frontUrl, GF_SG_VRML_MFURL, 1);
	back->frontUrl.vals[0].OD_ID = 3;
	gf_sg_vrml_mf_alloc(&back->rightUrl, GF_SG_VRML_MFURL, 1);
	back->rightUrl.vals[0].OD_ID = 4;
	gf_sg_vrml_mf_alloc(&back->backUrl, GF_SG_VRML_MFURL, 1);
	back->backUrl.vals[0].OD_ID = 5;
	gf_sg_vrml_mf_alloc(&back->topUrl, GF_SG_VRML_MFURL, 1);
	back->topUrl.vals[0].OD_ID = 6;
	gf_sg_vrml_mf_alloc(&back->bottomUrl, GF_SG_VRML_MFURL, 1);
	back->bottomUrl.vals[0].OD_ID = 7;

	ni = (M_NavigationInfo *) gf_node_new(sg, TAG_MPEG4_NavigationInfo);
	gf_node_list_add_child(&gr->children, (GF_Node*)ni);
	gf_node_register((GF_Node *)ni, (GF_Node *)gr);
	gf_sg_vrml_mf_reset(&ni->type, GF_SG_VRML_MFSTRING);
	gf_sg_vrml_mf_alloc(&ni->type, GF_SG_VRML_MFSTRING, 1);
	ni->type.vals[0] = gf_strdup("QTVR");

	/*create ODs*/
	st = gf_sm_stream_new(load->ctx, 2, GF_STREAM_OD, 1);
	au = gf_sm_stream_au_new(st, 0, 0, 1);
	odU = (GF_ODUpdate*) gf_odf_com_new(GF_ODF_OD_UPDATE_TAG);
	gf_list_add(au->commands, odU);
	for (i=0; i<6; i++) {
		GF_MuxInfo *mi;
		FILE *img;
		char szName[1024];
		od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
		od->objectDescriptorID = 2+i;
		esd = gf_odf_desc_esd_new(2);
		esd->decoderConfig->streamType = GF_STREAM_VISUAL;
		esd->decoderConfig->objectTypeIndication = GPAC_OTI_IMAGE_JPEG;
		esd->ESID = 3+i;
		/*extract image and remember it*/
		mi = (GF_MuxInfo *) gf_odf_desc_new(GF_ODF_MUXINFO_TAG);
		gf_list_add(esd->extensionDescriptors, mi);
		mi->delete_file = 1;
		sprintf(szName, "%s_img%d.jpg", load->fileName, esd->ESID);
		mi->file_name = gf_strdup(szName);
		
		gf_list_add(od->ESDescriptors, esd);
		gf_list_add(odU->objectDescriptors, od);

		samp = gf_isom_get_sample(src, tk, i+1, &di);
		img = gf_f64_open(mi->file_name, "wb");
		fwrite(samp->data, samp->dataLength, 1, img);
		fclose(img);
		gf_isom_sample_del(&samp);
	}
	gf_isom_delete(src);
	return GF_OK;
}
Beispiel #29
0
static void Extrusion_SetSpine(GF_Node *node, GF_Route *route)
{
	M_Extrusion *eg = (M_Extrusion *)node;
	gf_sg_vrml_field_copy(&eg->spine, &eg->set_spine, GF_SG_VRML_MFVEC3F);
	gf_sg_vrml_mf_reset(&eg->set_spine, GF_SG_VRML_MFVEC3F);
}
Beispiel #30
0
void gf_inline_on_modified(GF_Node *node)
{
	u32 ODID;
	GF_MediaObject *mo;
	M_Inline *pInline = (M_Inline *) node;
	GF_Scene *scene = (GF_Scene *)gf_node_get_private(node);

	ODID = gf_mo_get_od_id(&pInline->url);
	if (scene) {
		mo = (scene->root_od) ? scene->root_od->mo : NULL;

		/*disconnect current inline if we're the last one using it (same as regular OD session leave/join)*/
		if (mo) {
			Bool changed = GF_TRUE;
			if (ODID != GF_MEDIA_EXTERNAL_ID) {
				if (ODID && (ODID==scene->root_od->OD->objectDescriptorID)) changed = GF_FALSE;
			} else {
				if (gf_mo_is_same_url(mo, &pInline->url, NULL, 0) ) changed = GF_FALSE;
			}
			if (mo->num_open) {
				if (!changed) return;

				gf_scene_notify_event(scene, GF_EVENT_UNLOAD, node, NULL, GF_OK, GF_TRUE);
				gf_node_dirty_parents(node);
				gf_mo_event_target_remove_by_node(mo, node);

				/*reset the scene pointer as it may get destroyed*/
				switch (gf_node_get_tag(node)) {
				case TAG_MPEG4_Inline:
#ifndef GPAC_DISABLE_X3D
				case TAG_X3D_Inline:
#endif
					gf_node_set_private(node, NULL);
					break;
				}

				mo->num_open --;
				if (!mo->num_open) {
					if (ODID == GF_MEDIA_EXTERNAL_ID) {
						GF_Scene *parent = scene->root_od->parentscene;
						/*!!! THIS WILL DESTROY THE INLINE SCENE OBJECT !!!*/
						gf_odm_disconnect(scene->root_od, GF_TRUE);
						/*and force removal of the media object*/
						if (parent) {
							if (gf_list_del_item(parent->scene_objects, mo)>=0) {
								gf_sg_vrml_mf_reset(&mo->URLs, GF_SG_VRML_MFURL);
								gf_mo_del(mo);
							}
						}
					} else {
						gf_term_lock_media_queue(scene->root_od->term, GF_TRUE);

						/*external media are completely unloaded, except addons which are only declared once */
						if (!scene->root_od->addon && (scene->root_od->OD->objectDescriptorID==GF_MEDIA_EXTERNAL_ID)) {
							scene->root_od->action_type = GF_ODM_ACTION_DELETE;
						} else {
							scene->root_od->action_type = GF_ODM_ACTION_STOP;
						}
						if (gf_list_find(scene->root_od->term->media_queue, scene->root_od)<0)
							gf_list_add(scene->root_od->term->media_queue, scene->root_od);

						gf_term_lock_media_queue(scene->root_od->term, GF_FALSE);
					}
				}
			}
		}
	}
	/*force a redraw and load scene at next pass - we cannot load the scene now because
		- we can be in a JS call (eg JS mutex blocked)
		- locating scene objects matching the new url needs exclusive access to the MediaObject list, achieved with the term net mutex
		- another service may already be setting up objects (eg exclusive access to the net mutex grabbed), which can trigger event forwarding
		- some event forwarders may request JS context (eg access to JS mutex)

		In such a case we would end up in a deadlock - this needs urgent fixing ...
	*/
	if (ODID) {
		/*if no parent we must process the url change as we may not be traversed later on (not in the scene tree)*/
		if (gf_node_get_parent(node, 0)==NULL) {
			gf_inline_set_scene(pInline);
		} else {
			gf_node_dirty_parents(node);
		}
	}
}