📄 vrml_tools.c
字号:
GF_Err gf_sg_vrml_mf_get_item(void *mf, u32 FieldType, void **new_ptr, u32 ItemPos){ u32 FieldSize; GenMFField *mffield = (GenMFField *)mf; *new_ptr = NULL; 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 (ItemPos >= mffield->count) return GF_BAD_PARAM; *new_ptr = mffield->array + ItemPos * FieldSize; return GF_OK;}GF_EXPORTGF_Err gf_sg_vrml_mf_append(void *mf, u32 FieldType, void **new_ptr){ GenMFField *mffield = (GenMFField *)mf; return gf_sg_vrml_mf_insert(mf, FieldType, new_ptr, mffield->count+2);}//remove the specified item (0-based index)GF_Err gf_sg_vrml_mf_remove(void *mf, u32 FieldType, u32 RemoveFrom){ char *buffer; u32 FieldSize, i, k; GenMFField *mffield = (GenMFField *)mf; FieldSize = gf_sg_vrml_get_sf_size(FieldType); //field we can't copy if (!FieldSize) return GF_BAD_PARAM; if (!mffield->count || RemoveFrom >= mffield->count) return GF_BAD_PARAM; if (mffield->count == 1) { free(mffield->array); mffield->array = NULL; mffield->count = 0; return GF_OK; } k=0; buffer = (char*)malloc(sizeof(char)*(mffield->count-1)*FieldSize); for (i=0; i<mffield->count; i++) { if (RemoveFrom == i) { k = 1; } else { memcpy(buffer + (i-k)*FieldSize, mffield->array + i*FieldSize, FieldSize); } } free(mffield->array); mffield->array = buffer; mffield->count -= 1; return GF_OK;}GF_EXPORTGF_Err gf_sg_vrml_mf_reset(void *mf, u32 FieldType){ GenMFField *mffield = (GenMFField *)mf; if (!mffield->array) return GF_OK; //field we can't copy if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; if (!gf_sg_vrml_get_sf_size(FieldType)) return GF_BAD_PARAM; switch (FieldType) { case GF_SG_VRML_MFSTRING: gf_sg_mfstring_del( * ((MFString *) mf)); break; case GF_SG_VRML_MFURL: gf_sg_mfurl_del( * ((MFURL *) mf)); break; case GF_SG_VRML_MFSCRIPT: gf_sg_mfscript_del( * ((MFScript *) mf)); break; default: if (mffield->array) free(mffield->array); break; } mffield->array = NULL; mffield->count = 0; return GF_OK;}/*special cloning with type-casting from SF/MF strings to URL conversion since proto URL doesn't existas a field type (it's just a stupid encoding trick) */void VRML_FieldCopyCast(void *dest, u32 dst_field_type, void *orig, u32 ori_field_type){ SFURL *url; char tmp[50]; u32 size, i, sf_type_ori, sf_type_dst; void *dst_field, *orig_field; if (!dest || !orig) return; switch (dst_field_type) { case GF_SG_VRML_SFSTRING: if (ori_field_type == GF_SG_VRML_SFURL) { url = ((SFURL *)orig); if (url->OD_ID>0) { sprintf(tmp, "%d", url->OD_ID); if ( ((SFString*)dest)->buffer) free(((SFString*)dest)->buffer); ((SFString*)dest)->buffer = strdup(tmp); } else { if ( ((SFString*)dest)->buffer) free(((SFString*)dest)->buffer); ((SFString*)dest)->buffer = strdup(url->url); } } /*for SFString to MFString cast*/ else if (ori_field_type == GF_SG_VRML_SFSTRING) { if ( ((SFString*)dest)->buffer) free(((SFString*)dest)->buffer); ((SFString*)dest)->buffer = strdup(((SFString*)orig)->buffer); } return; case GF_SG_VRML_SFURL: if (ori_field_type != GF_SG_VRML_SFSTRING) return; url = ((SFURL *)dest); url->OD_ID = 0; if (url->url) free(url->url); if ( ((SFString*)orig)->buffer) url->url = strdup(((SFString*)orig)->buffer); else url->url = NULL; return; case GF_SG_VRML_MFSTRING: case GF_SG_VRML_MFURL: break; default: return; } sf_type_dst = gf_sg_vrml_get_sf_type(dst_field_type); if (gf_sg_vrml_is_sf_field(ori_field_type)) { size = 1; gf_sg_vrml_mf_alloc(dest, dst_field_type, size); gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, 0); VRML_FieldCopyCast(dst_field, sf_type_dst, orig, ori_field_type); return; } size = ((GenMFField *)orig)->count; if (size != ((GenMFField *)dest)->count) gf_sg_vrml_mf_alloc(dest, dst_field_type, size); sf_type_ori = gf_sg_vrml_get_sf_type(ori_field_type); //duplicate all items for (i=0; i<size; i++) { gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, i); gf_sg_vrml_mf_get_item(orig, ori_field_type, &orig_field, i); VRML_FieldCopyCast(dst_field, sf_type_dst, orig_field, sf_type_ori); } return;}GF_EXPORTvoid 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; }}GF_EXPORTBool 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_SFSCRIPT: case GF_SG_VRML_SFCOMMANDBUFFER: changed = 1; 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: 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_EXPORTSFColorRGBA gf_sg_sfcolor_to_rgba(SFColor val){ SFColorRGBA res; res.alpha = FIX_ONE; res.red = val.red; res.green = val.green; res.blue = val.blue; return res;}u32 gf_node_get_num_fields_in_mode(GF_Node *Node, u8 IndexMode){ assert(Node);#ifdef GF_NODE_USE_POINTERS return Node->sgprivate->get_field_count(Node, IndexMode);#else if (Node->sgprivate->tag == TAG_ProtoNode) return gf_sg_proto_get_num_fields(Node, IndexMode); else if ((Node->sgprivate->tag == TAG_MPEG4_Script) || (Node->sgprivate->tag == TAG_X3D_Script) ) return gf_sg_script_get_num_fields(Node, IndexMode); else if (Node->sgprivate->tag <= GF_NODE_RANGE_LAST_MPEG4) return gf_sg_mpeg4_node_get_field_count(Node, IndexMode); else if (Node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) return gf_sg_x3d_node_get_field_count(Node); else return 0;#endif}/*all our internally handled nodes*/Bool InitColorInterpolator(M_ColorInterpolator *node);Bool InitCoordinateInterpolator2D(M_CoordinateInterpolator2D *node);Bool InitCoordinateInterpolator(M_CoordinateInterpolator *n);Bool InitNormalInterpolator(M_NormalInterpolator *n);Bool InitPositionInterpolator2D(M_PositionInterpolator2D *node);Bool InitPositionInterpolator(M_PositionInterpolator *node);Bool InitScalarInterpolator(M_ScalarInterpolator *node);Bool InitOrientationInterpolator(M_OrientationInterpolator *node);Bool InitValuator(M_Valuator *node);Bool InitCoordinateInterpolator4D(M_CoordinateInterpolator4D *node);Bool InitPositionInterpolator4D(M_PositionInterpolator4D *node);void PA_Init(GF_Node *n);void PA_Modified(GF_Node *n, GF_FieldInfo *field);void PA2D_Init(GF_Node *n);void PA2D_Modified(GF_Node *n, GF_FieldInfo *field);void SA_Init(GF_Node *n);void SA_Modified(GF_Node *n, GF_FieldInfo *field);/*X3D tools*/void InitBooleanFilter(GF_Node *n);void InitBooleanSequencer(GF_Node *n);void InitBooleanToggle(GF_Node *n);void InitBooleanTrigger(GF_Node *n);void InitIntegerSequencer(GF_Node *n);void InitIntegerTrigger(GF_Node *n);void InitTimeTrigger(GF_Node *n);Bool gf_sg_vrml_node_init(GF_Node *node){ switch (node->sgprivate->tag) { case TAG_MPEG4_ColorInterpolator: case TAG_X3D_ColorInterpolator: return InitColorInterpolator((M_ColorInterpolator *)node); case TAG_MPEG4_CoordinateInterpolator: case TAG_X3D_CoordinateInterpolator: return InitCoordinateInterpolator((M_CoordinateInterpolator *)node); case TAG_MPEG4_CoordinateInterpolator2D: return InitCoordinateInterpolator2D((M_CoordinateInterpolator2D *)node); case TAG_MPEG4_NormalInterpolator: case TAG_X3D_NormalInterpolator: return InitNormalInterpolator((M_NormalInterpolator*)node); case TAG_MPEG4_OrientationInterpolator: case TAG_X3D_OrientationInterpolator: return InitOrientationInterpolator((M_OrientationInterpolator*)node); case TAG_MPEG4_PositionInterpolator: case TAG_X3D_PositionInterpolator: return InitPositionInterpolator((M_PositionInterpolator *)node); case TAG_MPEG4_PositionInterpolator2D: case TAG_X3D_PositionInterpolator2D: return InitPositionInterpolator2D((M_PositionInterpolator2D *)node); case TAG_MPEG4_ScalarInterpolator: case TAG_X3D_ScalarInterpolator: return InitScalarInterpolator((M_ScalarInterpolator *)node); case TAG_MPEG4_Valuator: return InitValuator((M_Valuator *)node); case TAG_MPEG4_PositionAnimator: PA_Init(node); return 1; case TAG_MPEG4_PositionAnimator2D: PA2D_Init(node); return 1; case TAG_MPEG4_ScalarAnimator: SA_Init(node); return 1; case TAG_MPEG4_PositionInterpolator4D: return InitPositionInterpolator4D((M_PositionInterpolator4D *)node); case TAG_MPEG4_CoordinateInterpolator4D: return InitCoordinateInterpolator4D((M_CoordinateInterpolator4D *)node); case TAG_MPEG4_Script: case TAG_X3D_Script: return 1; case TAG_X3D_BooleanFilter: InitBooleanFilter(node); return 1; case TAG_X3D_BooleanSequencer: InitBooleanSequencer(node); return 1; case TAG_X3D_BooleanToggle: InitBooleanToggle(node); return 1; case TAG_X3D_BooleanTrigger: InitBooleanTrigger(node); return 1; case TAG_X3D_IntegerSequencer: InitIntegerSequencer(node); return 1; case TAG_X3D_IntegerTrigger: InitIntegerTrigger(node); return 1; case TAG_X3D_TimeTrigger: InitTimeTrigger(node); return 1; } return 0;}Bool gf_sg_vrml_node_changed(GF_Node *node, GF_FieldInfo *field){ switch (node->sgprivate->tag) { case TAG_ProtoNode: /*hardcoded protos need modification notifs*/ if (node->sgprivate->UserCallback) return 0; case TAG_MPEG4_ColorInterpolator: case TAG_X3D_ColorInterpolator: case TAG_MPEG4_CoordinateInterpolator: case TAG_X3D_CoordinateInterpolator: case TAG_MPEG4_CoordinateInterpolator2D: case TAG_MPEG4_NormalInterpolator: case TAG_X3D_NormalInterpolator: case TAG_MPEG4_OrientationInterpolator: case TAG_X3D_OrientationInterpolator: case TAG_MPEG4_PositionInterpolator: case TAG_X3D_PositionInterpolator: case TAG_MPEG4_PositionInterpolator2D: case TAG_MPEG4_ScalarInterpolator: case TAG_X3D_ScalarInterpolator: case TAG_MPEG4_Valuator: case TAG_MPEG4_PositionInterpolator4D: case TAG_MPEG4_CoordinateInterpolator4D: case TAG_MPEG4_Script: case TAG_X3D_Script: case TAG_X3D_BooleanFilter: case TAG_X3D_BooleanSequencer: case TAG_X3D_BooleanToggle: case TAG_X3D_BooleanTrigger: case TAG_X3D_IntegerSequencer: case TAG_X3D_IntegerTrigger: case TAG_X3D_TimeTrigger: return 1; case TAG_MPEG4_PositionAnimator: PA_Modified(node, field); return 1; case TAG_MPEG4_PositionAnimator2D: PA2D_Modified(node, field); return 1; case TAG_MPEG4_ScalarAnimator: SA_Modified(node, field); return 1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -