Example #1
0
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;
}