bool CEditorGame::BuildEntitySerializationList(XmlNodeRef output) { if(!output) return false; typedef std::vector<IFlowGraph*> TFGVector; TSerializationData entityData; // all entities TFGVector flowGraphs; // all flowgraphs // build the all-entity list, and keep a record of those entities // which have a flowgraph attached IEntityIt* pIt = gEnv->pEntitySystem->GetEntityIterator(); while(IEntity* pEntity = pIt->Next()) { IEntityFlowGraphProxy* pFGProxy = static_cast<IEntityFlowGraphProxy*>(pEntity->GetProxy(ENTITY_PROXY_FLOWGRAPH)); if(pFGProxy) { flowGraphs.push_back(pFGProxy->GetFlowGraph()); MarkEntityForSerialize(entityData, pEntity, eST_FlowGraphContainer); } if (!stricmp(pEntity->GetClass()->GetName(), "Constraint")) { MarkEntityForSerialize(entityData, pEntity, eST_Class); float constraintRadius = -FLT_MAX; if (IScriptTable* entityTable = pEntity->GetScriptTable()) { SmartScriptTable props; if (entityTable->GetValue("Properties", props)) props->GetValue("radius", constraintRadius); } if (constraintRadius > 0.0f) { const Vec3 boxMin = pEntity->GetWorldPos() - Vec3(constraintRadius + 0.05f); const Vec3 boxMax = pEntity->GetWorldPos() + Vec3(constraintRadius + 0.05f); IPhysicalEntity** nearbyEntities = 0; if (size_t entityCount = gEnv->pPhysicalWorld->GetEntitiesInBox(boxMin, boxMax, nearbyEntities, ent_all)) { for (size_t i = 0; i < entityCount; ++i) { if (IEntity* nearbyEntity = gEnv->pEntitySystem->GetEntityFromPhysics(nearbyEntities[i])) MarkEntityForSerialize(entityData, nearbyEntity, eST_ConstraintNeighbour); } } } else { CryLogAlways("Failed to find a value radius property for constraint '%s'. " "Serialization for this constraint might not work.", pEntity->GetName()); } } else if(ShouldSaveEntityClass(pEntity)) // some classes should always be saved MarkEntityForSerialize(entityData, pEntity, eST_Class); } // for each FG, mark all entities referenced as needing saving for(TFGVector::const_iterator it = flowGraphs.begin(); it != flowGraphs.end(); ++it) { if(!*it) continue; IFlowNodeIteratorPtr nodeIt = (*it)->CreateNodeIterator(); TFlowNodeId nodeId = 0; while(IFlowNodeData* pNode = nodeIt->Next(nodeId)) { EntityId nodeEntity = (*it)->GetEntityId(nodeId); if(nodeEntity != 0) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(nodeEntity); MarkEntityForSerialize(entityData, pEntity, eST_FlowGraph); } } } // now do the same for entities moved by trackview for(int i=0; i<gEnv->pMovieSystem->GetNumSequences(); ++i) { IAnimSequence* pSeq = gEnv->pMovieSystem->GetSequence(i); int nodeCount = pSeq->GetNodeCount(); for(int j=0; j<nodeCount; ++j) { IAnimNode* pNode = pSeq->GetNode(j); if(pNode) { IEntity* pEntity = pNode->GetEntity(); if(pEntity && ShouldSaveTrackViewEntityClass(pEntity)) { MarkEntityForSerialize(entityData, pEntity, eST_TrackView); } if(EntityGUID* guid = pNode->GetEntityGuid()) { EntityId id = gEnv->pEntitySystem->FindEntityByGuid(*guid); if(id != 0) { IEntity* pEntity2 = gEnv->pEntitySystem->GetEntity(id); MarkEntityForSerialize(entityData, pEntity2, eST_TrackView); } } } } } // now check entity links: any entity linked to or from a serialized // entity must also be serialized for(TSerializationData::iterator it = entityData.begin(), end = entityData.end(); it != end; ++it) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(it->first); assert(pEntity); IEntityLink* pLink = pEntity->GetEntityLinks(); while(pLink) { IEntity* pLinkedEntity = gEnv->pEntitySystem->GetEntity(pLink->entityId); assert(pLinkedEntity); MarkEntityForSerialize(entityData, pLinkedEntity, eST_Linked); pLink = pLink->next; } } // output the final file, plus debug info #if SERIALIZATION_EXPORT_DEBUG int saveCount = 0; int totalCount = 0; int fgCount = 0; int fgRefCount = 0; int classCount = 0; int tvCount = 0; int childCount = 0; int parentCount = 0; int linkCount = 0; int fgUnique = 0; int fgRefUnique = 0; int classUnique = 0; int tvUnique = 0; int linkUnique = 0; typedef std::map<string, int> TClassSaveInfo; TClassSaveInfo classesNotSaved; TClassSaveInfo classesSaved; #endif output->setTag("EntitySerialization"); for(TSerializationData::const_iterator it = entityData.begin(); it != entityData.end(); ++it) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(it->first); #if SERIALIZATION_EXPORT_DEBUG ++totalCount; string reasons = "Saving: "; #endif if(it->second != eST_NotSerialized) { XmlNodeRef child = output->createNode("Entity"); child->setAttr("id", it->first); //child->setAttr("class", pEntity->GetClass()->GetName()); // debug check //child->setAttr("name", pEntity->GetName()); // debug check output->addChild(child); #if SERIALIZATION_EXPORT_DEBUG classesSaved[pEntity->GetClass()->GetName()]++; ++saveCount; if(it->second & eST_FlowGraphContainer) { reasons += "FG Container; "; ++fgCount; } if(it->second & eST_FlowGraph) { reasons += "FG reference; "; ++fgRefCount; } if(it->second & eST_Class) { reasons += "Class; "; ++classCount; } if(it->second & eST_TrackView) { reasons += "Trackview; "; ++tvCount; } if(it->second & eST_Child) { reasons += "Child; "; ++childCount; } if(it->second & eST_Parent) { reasons += "Parent; "; ++parentCount; } if(it->second & eST_Linked) { reasons += "Linked; "; ++linkCount; } // unique counts (things added as a result of only one condition) switch(it->second) { case eST_FlowGraph: ++fgRefUnique; break; case eST_FlowGraphContainer: ++fgUnique; break; case eST_Class: ++classUnique; break; case eST_TrackView: ++tvUnique; break; case eST_Linked: ++linkUnique; break; default: break; } } else { reasons = "Not saving"; classesNotSaved[pEntity->GetClass()->GetName()]++; } CryLogAlways("Entity %s (%d, class %s) : %s", pEntity->GetName(), it->first, pEntity->GetClass()->GetName(), reasons.c_str()); #endif } }
XmlNodeRef CAudioSystemEditor_wwise::CreateXMLNodeFromConnection(const TConnectionPtr pConnection, const EACEControlType eATLControlType) { const IAudioSystemControl* pControl = GetControl(pConnection->GetID()); if (pControl) { switch (pControl->GetType()) { case AudioControls::eWCT_WWISE_SWITCH: case AudioControls::eWCT_WWISE_SWITCH_GROUP: case AudioControls::eWCT_WWISE_GAME_STATE: case AudioControls::eWCT_WWISE_GAME_STATE_GROUP: { const IAudioSystemControl* pParent = pControl->GetParent(); if (pParent) { XmlNodeRef pSwitchNode = GetISystem()->CreateXmlNode(TypeToTag(pParent->GetType())); pSwitchNode->setAttr("wwise_name", pParent->GetName()); XmlNodeRef pStateNode = pSwitchNode->createNode("WwiseValue"); pStateNode->setAttr("wwise_name", pControl->GetName()); pSwitchNode->addChild(pStateNode); return pSwitchNode; } } break; case AudioControls::eWCT_WWISE_RTPC: { XmlNodeRef pConnectionNode; pConnectionNode = GetISystem()->CreateXmlNode(TypeToTag(pControl->GetType())); pConnectionNode->setAttr("wwise_name", pControl->GetName()); if (eATLControlType == eACET_RTPC) { std::shared_ptr<const CRtpcConnection> pRtpcConnection = std::static_pointer_cast<const CRtpcConnection>(pConnection); if (pRtpcConnection->fMult != 1.0f) { pConnectionNode->setAttr("atl_mult", pRtpcConnection->fMult); } if (pRtpcConnection->fShift != 0.0f) { pConnectionNode->setAttr("atl_shift", pRtpcConnection->fShift); } } else if (eATLControlType == eACET_SWITCH_STATE) { std::shared_ptr<const CStateToRtpcConnection> pStateConnection = std::static_pointer_cast<const CStateToRtpcConnection>(pConnection); pConnectionNode->setAttr("wwise_value", pStateConnection->fValue); } return pConnectionNode; } break; case AudioControls::eWCT_WWISE_EVENT: { XmlNodeRef pConnectionNode; pConnectionNode = GetISystem()->CreateXmlNode(TypeToTag(pControl->GetType())); pConnectionNode->setAttr("wwise_name", pControl->GetName()); return pConnectionNode; } break; case AudioControls::eWCT_WWISE_AUX_BUS: { XmlNodeRef pConnectionNode; pConnectionNode = GetISystem()->CreateXmlNode(TypeToTag(pControl->GetType())); pConnectionNode->setAttr("wwise_name", pControl->GetName()); return pConnectionNode; } break; case AudioControls::eWCT_WWISE_SOUND_BANK: { XmlNodeRef pConnectionNode = GetISystem()->CreateXmlNode(TypeToTag(pControl->GetType())); pConnectionNode->setAttr("wwise_name", pControl->GetName()); if (pControl->IsLocalised()) { pConnectionNode->setAttr("wwise_localised", "true"); } return pConnectionNode; } break; } } return nullptr; }