📄 v4scenemanager.cpp
字号:
#include "V4SceneManager.h"#include "V4StudioFrame.h"#include <gpac/scene_manager.h>#include <gpac/nodes_mpeg4.h>#include <gpac/internal/scenegraph_dev.h>#include <gpac/constants.h>V4SceneManager::V4SceneManager(V4StudioFrame *parent) : frame(parent){ m_pSm = NULL; m_pIs = NULL; units = 1000; // used to calculate AU timings}V4SceneManager::~V4SceneManager(){ // m_pIs should be deleted here or by the terminal // m_pSm should be deleted here or by the terminal // TODO : pquoi fallait il commenter cette ligne ? //if (m_pSm) gf_sm_del(m_pSm); delete m_gpac_panel; m_gpac_panel = NULL;}void v4s_node_init(void *cbkObject, u32 type, GF_Node *node, void *param){ if (type==GF_SG_CALLBACK_INIT) { switch (gf_node_get_tag(node)) { case TAG_MPEG4_Conditional: case TAG_MPEG4_QuantizationParameter: break; default: gf_sr_on_node_init(((V4SceneManager *)cbkObject)->GetSceneRenderer(), node); break; } }}void V4SceneManager::LoadNew() { m_pIs = gf_is_new(NULL); gf_sg_set_private(m_pIs->graph, this); gf_sg_set_node_callback(m_pIs->graph, v4s_node_init); m_gpac_panel = new wxGPACPanel(this, NULL); GF_Terminal *term = m_gpac_panel->GetMPEG4Terminal(); gf_sr_set_scene(term->renderer, m_pIs->graph); m_pSm = gf_sm_new(m_pIs->graph); /* Create a BIFS stream with one AU with on ReplaceScene */ GF_StreamContext *sc = gf_sm_stream_new(m_pSm, 1, GF_STREAM_SCENE, 0); GF_AUContext *au = gf_sm_stream_au_new(sc, 0, 0, 1); GF_Command *command = gf_sg_command_new(m_pIs->graph, GF_SG_SCENE_REPLACE); gf_list_add(au->commands, command); SetLength(50); SetFrameRate(25); // reinitializes the node pool pools.Clear();}void V4SceneManager::LoadFileOld(const char *path) { m_gpac_panel = new wxGPACPanel(this, path); GF_Terminal *term = m_gpac_panel->GetMPEG4Terminal(); // Get the RootScene created by the terminal. m_pIs = term->root_scene; if (0) { //Create a Scene Manager based on the current scene_graph m_pSm = gf_sm_new(m_pIs->graph); /* Loading of a file (BT, MP4 ...) and modification of the SceneManager */ GF_SceneLoader load; memset(&load, 0, sizeof(GF_SceneLoader)); load.fileName = path; load.ctx = m_pSm; if (strstr(path, ".mp4") || strstr(path, ".MP4") ) load.isom = gf_isom_open(path, GF_ISOM_OPEN_READ, NULL); gf_sm_load_init(&load); gf_sm_load_run(&load); gf_sm_load_done(&load); if (load.isom) gf_isom_delete(load.isom); /* SceneManager should be initialized and filled correctly */ gf_sg_set_scene_size_info(m_pIs->graph, m_pSm->scene_width, m_pSm->scene_height, m_pSm->is_pixel_metrics); // TODO : replace with GetBifsStream GF_StreamContext *sc = (GF_StreamContext *) gf_list_get(m_pSm->streams,0); gf_list_count(m_pSm->streams); if (sc->streamType == 3) { GF_AUContext *au = (GF_AUContext *) gf_list_get(sc->AUs,0); gf_list_count(sc->AUs); GF_Command *c = (GF_Command *) gf_list_get(au->commands,0); gf_list_count(au->commands); gf_sg_command_apply(m_pIs->graph, c, 0); /* This is a patch to solve the save pb: When ApplyCommand is made on a Scene Replace Command The command node is set to NULL When we save a BIFS stream whose first command is of this kind, the file saver thinks the bifs commands should come from an NHNT file This is a temporary patch */ if (c->tag == GF_SG_SCENE_REPLACE) { c->node = m_pIs->graph->RootNode; } } gf_sr_set_scene(term->renderer, m_pIs->graph); // retrieves all the node from the tree and adds them to the node pool GF_Node * root = gf_sg_get_root_node(m_pIs->graph); CreateDictionnary(); }}void V4SceneManager::LoadFile(const char *path) { m_gpac_panel = new wxGPACPanel(this, NULL); GF_Terminal *term = m_gpac_panel->GetMPEG4Terminal(); // initializes a new scene // We need an GF_InlineScene, a SceneManager and an GF_ObjectManager m_pIs = gf_is_new(NULL); m_pSm = gf_sm_new(m_pIs->graph); m_pIs->root_od = gf_odm_new(); m_pIs->root_od->parentscene = NULL; m_pIs->root_od->subscene = m_pIs; m_pIs->root_od->term = term; term->root_scene = m_pIs; /* Loading of a file (BT, MP4 ...) and modification of the SceneManager */ GF_SceneLoader load; memset(&load, 0, sizeof(GF_SceneLoader)); load.fileName = path; load.ctx = m_pSm; if (strstr(path, ".mp4") || strstr(path, ".MP4") ) load.isom = gf_isom_open(path, GF_ISOM_OPEN_READ, NULL); gf_sm_load_init(&load); gf_sm_load_run(&load); gf_sm_load_done(&load); if (load.isom) gf_isom_delete(load.isom); /* SceneManager should be initialized and filled correctly */ gf_sg_set_scene_size_info(m_pIs->graph, m_pSm->scene_width, m_pSm->scene_height, m_pSm->is_pixel_metrics); // TODO : replace with GetBifsStream GF_StreamContext *sc = (GF_StreamContext *) gf_list_get(m_pSm->streams,0); if (sc->streamType == 3) { GF_AUContext *au = (GF_AUContext *) gf_list_get(sc->AUs,0); GF_Command *c = (GF_Command *) gf_list_get(au->commands,0); gf_sg_command_apply(m_pIs->graph, c, 0); /* This is a patch to solve the save pb: When ApplyCommand is made on a Scene Replace Command The command node is set to NULL When we save a BIFS stream whose first command is of this kind, the file saver thinks the bifs commands should come from an NHNT file This is a temporary patch */ if (c->tag == GF_SG_SCENE_REPLACE) { c->node = m_pIs->graph->RootNode; } } gf_sr_set_scene(term->renderer, m_pIs->graph); // TODO : read actual values from file SetLength(50); SetFrameRate(25); // retrieves all the node from the tree and adds them to the node pool GF_Node * root = gf_sg_get_root_node(m_pIs->graph); CreateDictionnary();}void V4SceneManager::SaveFile(const char *path) { GF_SMEncodeOptions opts; char rad_name[5000]; strcpy(rad_name, "dump"); gf_sm_dump(m_pSm, rad_name, 0); GF_ISOFile *mp4 = gf_isom_open(path, GF_ISOM_WRITE_EDIT, NULL); m_pSm->max_node_id = gf_sg_get_max_node_id(m_pSm->scene_graph); memset(&opts, 0, sizeof(opts)); opts.flags = GF_SM_LOAD_MPEG4_STRICT; gf_sm_encode_to_file(m_pSm, mp4, &opts); gf_isom_close(mp4);}void V4SceneManager::SetSceneSize(int w, int h){ gf_sg_set_scene_size_info(m_pIs->graph, w,h, 1); /*reassign scene graph to update scene size in renderer*/ gf_sr_set_scene(m_gpac_panel->GetMPEG4Terminal()->renderer, m_pIs->graph);}void V4SceneManager::GetSceneSize(wxSize &size) { gf_sg_get_scene_size_info(m_pIs->graph, (u32 *)&(size.x), (u32 *)&(size.y)); }GF_Node *V4SceneManager::SetTopNode(u32 tag) { M_OrderedGroup * root = (M_OrderedGroup *)NewNode(TAG_MPEG4_OrderedGroup); gf_sg_set_root_node(m_pIs->graph, (GF_Node *)root); return (GF_Node *)root;}GF_Node *V4SceneManager::NewNode(u32 tag){ GF_Node *n = gf_node_new(m_pIs->graph, tag); if (!n) return NULL; gf_node_init(n); return n;}GF_Node *V4SceneManager::CopyNode(GF_Node *node, GF_Node *parent, bool copy) { if (copy) return CloneNodeForEditing(m_pIs->graph, node); u32 nodeID = gf_node_get_id(node); if (!nodeID) { nodeID = gf_sg_get_next_available_node_id(m_pIs->graph); gf_node_set_id(node, nodeID, NULL); gf_node_register(node, parent); } return node;}extern "C" {GF_Node *CloneNodeForEditing(GF_SceneGraph *inScene, GF_Node *orig) //, GF_Node *cloned_parent){ u32 i, j, count; GF_Node *node, *child, *tmp; GF_List *list, *list2; GF_FieldInfo field_orig, field; /*this is not a mistake*/ if (!orig) return NULL; /*check for DEF/USE if (orig->sgprivate->NodeID) { node = gf_sg_find_node(inScene, orig->sgprivate->NodeID); //node already created, USE if (node) { gf_node_register(node, cloned_parent); return node; } } */ /*create a node*//* if (orig->sgprivate->tag == TAG_MPEG4_ProtoNode) { proto_node = ((GF_ProtoInstance *)orig)->proto_interface; //create the instance but don't load the code -c we MUST wait for ISed routes to be cloned before node = gf_sg_proto_create_node(inScene, proto_node, (GF_ProtoInstance *) orig); } else {*/ node = gf_node_new(inScene, gf_node_get_tag(orig));// } count = gf_node_get_field_count(orig); /*copy each field*/ for (i=0; i<count; i++) { gf_node_get_field(orig, i, &field_orig); /*get target ptr*/ gf_node_get_field(node, i, &field); assert(field.eventType==field_orig.eventType); assert(field.fieldType==field_orig.fieldType); /*duplicate it*/ switch (field.fieldType) { case GF_SG_VRML_SFNODE: child = CloneNodeForEditing(inScene, (GF_Node *) (* ((GF_Node **) field_orig.far_ptr)));//, node); *((GF_Node **) field.far_ptr) = child; break; case GF_SG_VRML_MFNODE: list = *( (GF_List **) field_orig.far_ptr); list2 = *( (GF_List **) field.far_ptr); for (j=0; j<gf_list_count(list); j++) { tmp = (GF_Node *)gf_list_get(list, j); child = CloneNodeForEditing(inScene, tmp);//, node); gf_list_add(list2, child); } break; default: gf_sg_vrml_field_copy(field.far_ptr, field_orig.far_ptr, field.fieldType); break; } } /*register node if (orig->sgprivate->NodeID) { Node_SetID(node, orig->sgprivate->NodeID); gf_node_register(node, cloned_parent); }*/ /*init node before creating ISed routes so the eventIn handler are in place*/ if (gf_node_get_tag(node) != TAG_ProtoNode) gf_node_init(node); return node;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -