void compositor_background_modified(GF_Node *node) { M_Background *bck = (M_Background *)node; BackgroundStack *st = (BackgroundStack *) gf_node_get_private(node); if (!st) return; if (!gf_sg_vrml_field_equal(&bck->skyColor, &st->sky_col, GF_SG_VRML_MFCOLOR) || !gf_sg_vrml_field_equal(&bck->skyAngle, &st->sky_ang, GF_SG_VRML_MFFLOAT) ) { if (st->sky_mesh) mesh_free(st->sky_mesh); st->sky_mesh = NULL; gf_sg_vrml_field_copy(&st->sky_col, &bck->skyColor, GF_SG_VRML_MFCOLOR); gf_sg_vrml_field_copy(&st->sky_ang, &bck->skyAngle, GF_SG_VRML_MFFLOAT); } if (!gf_sg_vrml_field_equal(&bck->groundColor, &st->ground_col, GF_SG_VRML_MFCOLOR) || !gf_sg_vrml_field_equal(&bck->groundAngle, &st->ground_ang, GF_SG_VRML_MFFLOAT) ) { if (st->ground_mesh) mesh_free(st->ground_mesh); st->ground_mesh = NULL; gf_sg_vrml_field_copy(&st->ground_col, &bck->groundColor, GF_SG_VRML_MFCOLOR); gf_sg_vrml_field_copy(&st->ground_ang, &bck->groundAngle, GF_SG_VRML_MFFLOAT); } back_check_gf_sc_texture_change(&st->txh_front, &bck->frontUrl); back_check_gf_sc_texture_change(&st->txh_back, &bck->backUrl); back_check_gf_sc_texture_change(&st->txh_top, &bck->topUrl); back_check_gf_sc_texture_change(&st->txh_bottom, &bck->bottomUrl); back_check_gf_sc_texture_change(&st->txh_left, &bck->leftUrl); back_check_gf_sc_texture_change(&st->txh_right, &bck->rightUrl); gf_sc_invalidate(st->compositor, NULL); }
GF_EXPORT Bool gf_sg_vrml_field_equal(void *dest, void *orig, u32 field_type) { u32 size, i, sf_type; void *dst_field, *orig_field; Bool changed = 0; if (!dest || !orig) return 0; switch (field_type) { case GF_SG_VRML_SFBOOL: changed = memcmp(dest, orig, sizeof(SFBool)); break; case GF_SG_VRML_SFCOLOR: if (((SFColor *)dest)->red != ((SFColor *)orig)->red) changed = 1; else if (((SFColor *)dest)->green != ((SFColor *)orig)->green) changed = 1; else if (((SFColor *)dest)->blue != ((SFColor *)orig)->blue) changed = 1; break; case GF_SG_VRML_SFFLOAT: if ( (*(SFFloat *)dest) != (*(SFFloat *)orig) ) changed = 1; break; case GF_SG_VRML_SFINT32: changed = memcmp(dest, orig, sizeof(SFInt32)); break; case GF_SG_VRML_SFROTATION: if (((SFRotation *)dest)->x != ((SFRotation *)orig)->x) changed = 1; else if (((SFRotation *)dest)->y != ((SFRotation *)orig)->y) changed = 1; else if (((SFRotation *)dest)->z != ((SFRotation *)orig)->z) changed = 1; else if (((SFRotation *)dest)->q != ((SFRotation *)orig)->q) changed = 1; break; case GF_SG_VRML_SFTIME: if ( (*(SFTime *)dest) != (*(SFTime*)orig) ) changed = 1; break; case GF_SG_VRML_SFVEC2F: if (((SFVec2f *)dest)->x != ((SFVec2f *)orig)->x) changed = 1; else if (((SFVec2f *)dest)->y != ((SFVec2f *)orig)->y) changed = 1; break; case GF_SG_VRML_SFVEC3F: if (((SFVec3f *)dest)->x != ((SFVec3f *)orig)->x) changed = 1; else if (((SFVec3f *)dest)->y != ((SFVec3f *)orig)->y) changed = 1; else if (((SFVec3f *)dest)->z != ((SFVec3f *)orig)->z) changed = 1; break; case GF_SG_VRML_SFSTRING: if ( ((SFString*)dest)->buffer && ((SFString*)orig)->buffer) { changed = strcmp(((SFString*)dest)->buffer, ((SFString*)orig)->buffer); } else { changed = ( !((SFString*)dest)->buffer && !((SFString*)orig)->buffer) ? 0 : 1; } break; case GF_SG_VRML_SFURL: if (((SFURL *)dest)->OD_ID > 0 || ((SFURL *)orig)->OD_ID > 0) { if ( ((SFURL *)orig)->OD_ID != ((SFURL *)dest)->OD_ID) changed = 1; } else { if ( ((SFURL *)orig)->url && ! ((SFURL *)dest)->url) changed = 1; else if ( ! ((SFURL *)orig)->url && ((SFURL *)dest)->url) changed = 1; else if ( strcmp( ((SFURL *)orig)->url , ((SFURL *)dest)->url) ) changed = 1; } break; case GF_SG_VRML_SFIMAGE: case GF_SG_VRML_SFATTRREF: case GF_SG_VRML_SFSCRIPT: case GF_SG_VRML_SFCOMMANDBUFFER: changed = 1; break; //MFFields case GF_SG_VRML_MFATTRREF: changed = 1; break; 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: if ( ((GenMFField *)orig)->count != ((GenMFField *)dest)->count) changed = 1; else { size = ((GenMFField *)orig)->count; sf_type = gf_sg_vrml_get_sf_type(field_type); 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); if (! gf_sg_vrml_field_equal(dst_field, orig_field, sf_type) ) { changed = 1; break; } } } break; } return changed ? 0 : 1; }
GF_Err EncNodeFields(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node) { u8 mode; GF_Route *isedField; GF_Node *clone; GF_Err e; s32 *enc_fields; u32 numBitsALL, numBitsDEF, allInd, count, i, nbBitsProto, nbFinal; Bool use_list, nodeIsFDP = GF_FALSE; GF_FieldInfo field, clone_field; e = GF_OK; if (codec->encoding_proto) { mode = GF_SG_FIELD_CODING_ALL; nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(codec->encoding_proto) - 1); numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL) - 1); } else { mode = GF_SG_FIELD_CODING_DEF; nbBitsProto = 0; numBitsALL = 0; } count = gf_node_get_num_fields_in_mode(node, mode); if (node->sgprivate->tag==TAG_MPEG4_Script) count = 3; if (!count) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isMask", NULL); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); return GF_OK; } if (node->sgprivate->tag == TAG_ProtoNode) { clone = gf_sg_proto_create_instance(node->sgprivate->scenegraph, ((GF_ProtoInstance *)node)->proto_interface);; } else { clone = gf_node_new(node->sgprivate->scenegraph, node->sgprivate->tag); } if (clone) gf_node_register(clone, NULL); numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF) - 1); enc_fields = (s32*)gf_malloc(sizeof(s32) * count); nbFinal = 0; for (i=0; i<count; i++) { enc_fields[i] = -1; /*get field in ALL mode*/ if (mode == GF_SG_FIELD_CODING_ALL) { allInd = i; } else { gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &allInd); } /*encode proto code*/ if (codec->encoding_proto) { isedField = gf_bifs_enc_is_field_ised(codec, node, allInd); if (isedField) { enc_fields[i] = allInd; nbFinal ++; continue; } } /*common case*/ gf_node_get_field(node, allInd, &field); /*if event don't encode (happens when encoding protos)*/ if ((field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_OUT)) continue; /*if field is default skip*/ switch (field.fieldType) { case GF_SG_VRML_SFNODE: if (* (GF_Node **) field.far_ptr) { enc_fields[i] = allInd; nbFinal++; } break; case GF_SG_VRML_MFNODE: if (* (GF_ChildNodeItem **) field.far_ptr) { enc_fields[i] = allInd; nbFinal++; } break; case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *cb = (SFCommandBuffer *)field.far_ptr; if (gf_list_count(cb->commandList)) { enc_fields[i] = allInd; nbFinal++; } } break; case GF_SG_VRML_MFSCRIPT: enc_fields[i] = allInd; nbFinal++; break; default: gf_node_get_field(clone, allInd, &clone_field); if (!gf_sg_vrml_field_equal(clone_field.far_ptr, field.far_ptr, field.fieldType)) { enc_fields[i] = allInd; nbFinal++; } break; } } if (clone) gf_node_unregister(clone, NULL); use_list = GF_TRUE; /* patch for FDP node : */ /* cannot use default field sorting due to spec "mistake", so use list to imply inversion between field 2 and field 3 of FDP*/ if (node->sgprivate->tag == TAG_MPEG4_FDP) { s32 s4SwapValue = enc_fields[2]; enc_fields[2] = enc_fields[3]; enc_fields[3] = s4SwapValue; nodeIsFDP = GF_TRUE; use_list = GF_TRUE; } /*number of bits in mask node is count*1, in list node is 1+nbFinal*(1+numBitsDEF) */ else if (count < 1+nbFinal*(1+numBitsDEF)) use_list = GF_FALSE; GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL); for (i=0; i<count; i++) { if (enc_fields[i] == -1) { if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL); continue; } allInd = (u32) enc_fields[i]; /*encode proto code*/ if (codec->encoding_proto) { isedField = gf_bifs_enc_is_field_ised(codec, node, allInd); if (isedField) { if (use_list) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); } GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isedField", NULL); if (use_list) GF_BIFS_WRITE_INT(codec, bs, allInd, numBitsALL, "nodeField", NULL); if (isedField->ToNode == node) { GF_BIFS_WRITE_INT(codec, bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL); } continue; } } /*common case*/ gf_node_get_field(node, allInd, &field); if (use_list) { /*not end flag*/ GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); } else { /*mask flag*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); } /*not ISed field*/ if (codec->encoding_proto) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isedField", NULL); if (use_list) { if (codec->encoding_proto || nodeIsFDP) { u32 ind=0; /*for proto, we're in ALL mode and we need DEF mode*/ /*for FDP, encoding requires to get def id from all id as fields 2 and 3 are reversed*/ gf_bifs_field_index_by_mode(node, allInd, GF_SG_FIELD_CODING_DEF, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, numBitsDEF, "field", (char*)field.name); } else { GF_BIFS_WRITE_INT(codec, bs, i, numBitsDEF, "field", (char*)field.name); } } e = gf_bifs_enc_field(codec, bs, node, &field); if (e) goto exit; } /*end flag*/ if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); exit: gf_free(enc_fields); return e; }
static GF_Err StatNodeGraph(GF_StatManager *st, GF_Node *n) { GF_Node *clone; GF_FieldInfo field; if (!n) return GF_OK; StatNode(st->stats, n, StatIsUSE(st, n), 0, NULL); if (n->sgprivate->tag != TAG_ProtoNode) { clone = gf_node_new(n->sgprivate->scenegraph, n->sgprivate->tag); } else { #ifndef GPAC_DISABLE_VRML clone = gf_sg_proto_create_node(n->sgprivate->scenegraph, ((GF_ProtoInstance *)n)->proto_interface, NULL); #else clone = NULL; #endif } if (!clone) return GF_OK; gf_node_register(clone, NULL); #ifndef GPAC_DISABLE_SVG if ((n->sgprivate->tag>= GF_NODE_RANGE_FIRST_SVG) && (n->sgprivate->tag<= GF_NODE_RANGE_LAST_SVG)) { GF_ChildNodeItem *list = ((SVG_Element *)n)->children; GF_DOMAttribute *atts = ((GF_DOMNode*)n)->attributes; while (atts) { field.far_ptr = atts->data; field.fieldType = atts->data_type; field.fieldIndex = atts->tag; field.name = NULL; StatSVGAttribute(st->stats, &field); atts = atts->next; } while (list) { StatNodeGraph(st, list->node); list = list->next; } } else #endif if (n->sgprivate->tag == TAG_DOMText) { } else if (n->sgprivate->tag == TAG_DOMFullNode) { } #ifndef GPAC_DISABLE_VRML else if (n->sgprivate->tag<= GF_NODE_RANGE_LAST_X3D) { GF_Node *child; GF_ChildNodeItem *list; u32 i, count; GF_FieldInfo clone_field; count = gf_node_get_field_count(n); for (i=0; i<count; i++) { gf_node_get_field(n, i, &field); if (field.eventType==GF_SG_EVENT_IN) continue; if (field.eventType==GF_SG_EVENT_OUT) continue; switch (field.fieldType) { case GF_SG_VRML_SFNODE: child = *((GF_Node **)field.far_ptr); StatNodeGraph(st, child); break; case GF_SG_VRML_MFNODE: list = *((GF_ChildNodeItem **)field.far_ptr); while (list) { StatNodeGraph(st, list->node); list = list->next; } break; default: gf_node_get_field(clone, i, &clone_field); if (!gf_sg_vrml_field_equal(clone_field.far_ptr, field.far_ptr, field.fieldType)) { StatField(st->stats, &field); } break; } } } #endif gf_node_unregister(clone, NULL); return GF_OK; }