📄 v4scenegraph.cpp
字号:
}// GetBifsStream -- gets the first stream with id = 3GF_StreamContext * V4SceneGraph::GetBifsStream() { GF_StreamContext * ctx = NULL; u32 count = gf_list_count(m_pSm->streams); // cycle trough each stream while (count--) { ctx = (GF_StreamContext *) gf_list_get(m_pSm->streams, count); if (ctx->streamType == 3) break; } if (ctx == NULL) return NULL; // if we went through the loop without finding any BIFS stream return null if (ctx->streamType != 3) return NULL; return ctx;}// CreateDictionnary -- Create the root node of the dictionnary and populates itvoid V4SceneGraph::CreateDictionnary() { GF_Node * root = gf_sg_get_root_node(m_pSg); dictionnary = NewNode(TAG_MPEG4_Switch); // Insert the dictionnary in the scene and gives it a name gf_node_insert_child(root, dictionnary, 0); gf_node_register(dictionnary, root); gf_node_set_id(dictionnary, gf_sg_get_next_available_node_id(m_pSg), DICTNAME); // makes the dictionnary invisible // the number 1 field is the "whichChoice", setting it to -1 makes it display nothing GF_FieldInfo field; gf_node_get_field(dictionnary, 1, &field); frame->GetFieldView()->SetFieldValue(field, &wxString("-1"), -1); // TODO : maybe put the method SetFieldValue somewhere more accessible // populates dictionnary with the root node of the scene AddToDictionnary(root);}// AddToDictionnary -- adds a node to the dictionnary, increases its reference count, the node must already have an ID// WARNING : does not add the node to the pool if it has a parent in the dictionnaryvoid V4SceneGraph::AddToDictionnary(GF_Node * node) { // checks if nodes has a parent with an id // if true then there is already a reference to this node if (HasDefParent(node)) return; AddRecursive(node);}// AddRecursive -- recursively adds items with an ID to the dictionnaryvoid V4SceneGraph::AddRecursive(GF_Node * node, bool parentAdded) { // skips empty nodes if (!node) return; // skips the dictionnary const char * c = gf_node_get_name(node); if ( (c != NULL) && (!strcmp(c, DICTNAME)) ) return; // if node as an id adds it to the dictionnary and the node pool u32 id = gf_node_get_id(node); if (id) { frame->pools.Add(node); // children of added node are not added to the dictionnary if (!parentAdded) AddEffective(node); parentAdded = true; } GF_FieldInfo field; GF_List * list; int count = gf_node_get_field_count(node); // tests all fields, if a field is a node then adds it and process its children recursively for (int i=0; i<count; i++) { gf_node_get_field(node, i, &field); // single value node field if (field.fieldType == GF_SG_VRML_SFNODE) AddRecursive( * ((GF_Node **) field.far_ptr), parentAdded ); // multiple value node field if (field.fieldType == GF_SG_VRML_MFNODE) { list = *( (GF_List **) field.far_ptr); for (u32 j=0; j<gf_list_count(list); j++) AddRecursive( (GF_Node *) gf_list_get(list, j), parentAdded ); } }}// AddEffective --void V4SceneGraph::AddEffective(GF_Node * node) { // gets the node type (equals pool number) u32 poolN = frame->pools.poolN(gf_node_get_tag(node)); // adds the node using a type specific function switch (poolN) { case DICT_GEN: { AddGen(node); break; } case DICT_GEOMETRY: { AddGeometry(node); break; } case DICT_APPEARANCE: { AddAppearance(node); break; } case DICT_TEXTURE: { AddTexture(node); break; } case DICT_MATERIAL: { AddMaterial(node); break; } // TODO : raise an exception when not found }}// RemoveFromDictionnary -- Removes _ONE_ item from the dictionnary, if some of the children are also in the dictionnary preserves themvoid V4SceneGraph::RemoveFromDictionnary(GF_Node * node) {}/******* Add element to dictionnary functions *******/// TODO : can add genericity around here// ATTENTION, all these functions thinks the node as already been assigned an ID// Add gen -- adds any element which can be a children of a switch nodevoid V4SceneGraph::AddGen(GF_Node * node) { // retrieves the chain of children (field number 0 named "choice") GF_FieldInfo field; GF_List * list; gf_node_get_field(dictionnary, 0, &field); list = *( (GF_List **) field.far_ptr); // adds a reference to that node in the dictionnary gf_list_add(list, node); gf_node_register(node, dictionnary);}// TODO : check if there is a dummy node with free space in it// AddGeometry -- adds any element which can be a children of a shape as a geometry nodevoid V4SceneGraph::AddGeometry(GF_Node * node) { // creates a dummy node to hold this one GF_Node * parent = CreateDummyNode(TAG_MPEG4_Shape, dictionnary, 0); // sets the parentship relation MakeChild(node, parent, 1); // geometry is field one in a shape}// AddAppearance -- adds any element which can be a children of a shape as an appearance nodevoid V4SceneGraph::AddAppearance(GF_Node * node) { // creates a dummy node to hold this one GF_Node * parent = CreateDummyNode(TAG_MPEG4_Shape, dictionnary, 0); // sets the parentship relation MakeChild(node, parent, 0); // appearance is field zero in a shape}// AddTexture -- adds any element which can be a children of an appearance as a texture nodevoid V4SceneGraph::AddTexture(GF_Node * node) { // creates dummy nodes to hold this one GF_Node * parent1 = CreateDummyNode(TAG_MPEG4_Shape, dictionnary, 0); GF_Node * parent2 = CreateDummyNode(TAG_MPEG4_Appearance, parent1, 3); // sets the parentship relation MakeChild(node, parent2, 1); // texture is field one in a appearance}// AddMaterial -- adds any element which can be a children of an appearance as a material nodevoid V4SceneGraph::AddMaterial(GF_Node * node) { // creates dummy nodes to hold this one GF_Node * parent1 = CreateDummyNode(TAG_MPEG4_Shape, dictionnary, 0); GF_Node * parent2 = CreateDummyNode(TAG_MPEG4_Appearance, parent1, 3); // sets the parentship relation MakeChild(node, parent2, 0); // material is field zero in appearance}// CreateDummyNode -- creates a node to hold another one, adds this node to given field of the given parent// (designed for use with nodes in the dictionnary)GF_Node * V4SceneGraph::CreateDummyNode(const u32 tag, GF_Node * parent, const u32 fieldIndex) { // creates a new node for this scene GF_Node * newNode = NewNode(tag); // sets the parentship relation !! AND registers the node !! MakeChild(newNode, parent, fieldIndex); return newNode;}// MakeChild -- Sets the first node as a child of the second using the given fieldvoid V4SceneGraph::MakeChild(GF_Node * child, GF_Node * parent, const u32 fieldIndex) { // get the field where we have to add the new child GF_FieldInfo field; gf_node_get_field(parent, fieldIndex, &field); // keeps the count of uses up to date gf_node_register(child, parent); // if the field is single valued if (field.fieldType == GF_SG_VRML_SFNODE) { *((GF_Node **) field.far_ptr) = child; } // if the field is multi valued if (field.fieldType == GF_SG_VRML_MFNODE) gf_list_add( *((GF_List **)field.far_ptr), child );}// GetDictionnary -- access to the dictionnaryGF_Node * V4SceneGraph::GetDictionnary() const { return dictionnary; }// HasDefParent -- checks if an ancestor of this node has an IDGF_Node * V4SceneGraph::HasDefParent(GF_Node * node) { assert(node); // also checks the node itself int count = gf_node_get_parent_count(node); GF_Node * parent; // loops through all the parents and recurses for (int i=0; i<count; i++) { parent = gf_node_get_parent(node, i); const char * name = gf_node_get_name(parent); if (name) return parent; parent = HasDefParent(parent); if (parent) return parent; } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -