void IDiffResolver.BeforeDiff(Asset baseAsset, Asset asset1, Asset asset2) { Guid newId; var baseEntityAsset = (EntityAsset)baseAsset; var entityAsset1 = (EntityAsset)asset1; var entityAsset2 = (EntityAsset)asset2; // Let's remap IDs in asset2 (if it comes from a FBX or such, we need to do that) var oldBaseTree = new EntityTreeAsset(baseEntityAsset.Hierarchy); var newBaseTree = new EntityTreeAsset(entityAsset2.Hierarchy); var idRemapping = new Dictionary <Guid, Guid>(); // Try to transfer ID from old base to new base var mergeResult = AssetMerge.Merge(oldBaseTree, newBaseTree, oldBaseTree, node => { if (typeof(Guid).IsAssignableFrom(node.InstanceType) && node.BaseNode != null && node.Asset1Node != null) { idRemapping.Add((Guid)node.Asset1Node.Instance, (Guid)node.BaseNode.Instance); } return(AssetMergePolicies.MergePolicyAsset2AsNewBaseOfAsset1(node)); }); if (mergeResult.HasErrors) { //mergeResult.CopyTo(); } EntityAnalysis.RemapEntitiesId(entityAsset2.Hierarchy, idRemapping); }
public override object ReadYaml(ref ObjectContext objectContext) { if (recursionLevel++ == 0) { SetupMaxExpectedDepth(objectContext); } ++levelSinceScriptComponent; if (objectContext.Descriptor.Type == typeof(ScriptComponent)) { levelSinceScriptComponent = 0; } try { var result = base.ReadYaml(ref objectContext); if (objectContext.Descriptor.Type == typeof(EntityHierarchyData)) { // Let's fixup entity references after serialization EntityAnalysis.FixupEntityReferences((EntityHierarchyData)objectContext.Instance); } return(result); } finally { recursionLevel--; levelSinceScriptComponent--; } }
public static EntityAsset ExtractSceneClone(EntityAsset source, Guid sourceRootEntity) { if (source == null) { throw new ArgumentNullException("source"); } // Note: Instead of copying the whole asset (with its potentially big hierarchy), we first copy the asset only (without the hierarchy), then the sub-hierarchy to extract. // create the hierarchy of the sub-tree var subTreeRoot = source.Hierarchy.Entities[sourceRootEntity]; var subTreeHierarchy = new EntityHierarchyData { Entities = { subTreeRoot }, RootEntities = { sourceRootEntity } }; foreach (var subTreeEntity in subTreeRoot.EnumerateChildren(true)) { subTreeHierarchy.Entities.Add(subTreeEntity); } // clone the entities of the sub-tree var clonedHierarchy = (EntityHierarchyData)AssetCloner.Clone(subTreeHierarchy); clonedHierarchy.Entities[sourceRootEntity].Transform.Parent = null; // set to null reference outside of the sub-tree EntityAnalysis.FixupEntityReferences(clonedHierarchy); // temporary nullify the hierarchy to avoid to clone it var sourceHierarchy = source.Hierarchy; source.Hierarchy = null; // clone asset without hierarchy var clonedAsset = (EntityAsset)AssetCloner.Clone(source); clonedAsset.Hierarchy = clonedHierarchy; // revert the source hierarchy source.Hierarchy = sourceHierarchy; return(clonedAsset); }
public void ApplyChanges() { // "Garbage collect" entities that are not referenced in hierarchy tree anymore var entityHashes = new HashSet <Guid>(); CollectEntities(entityHashes, source.RootEntity); source.Entities.Clear(); foreach (var item in this) { if (entityHashes.Contains(item.Key)) { source.Entities.Add(item.Value); } } // Fixup references EntityAnalysis.FixupEntityReferences(source); }
public override object ReadYaml(ref ObjectContext objectContext) { EnterNode(ref objectContext); try { var result = base.ReadYaml(ref objectContext); if (objectContext.Descriptor.Type == typeof(EntityHierarchyData)) { // Let's fixup entity references after serialization EntityAnalysis.FixupEntityReferences((EntityHierarchyData)objectContext.Instance); } return(result); } finally { LeaveNode(ref objectContext); } }
public static EntityHierarchyData ImportScene(UFile sourceUrl, EntityAsset source, Guid sourceRootEntity, out EntityBase entityBase) { if (source == null) { throw new ArgumentNullException("source"); } // Extract the scene starting from given root var newAsset = ExtractSceneClone(source, sourceRootEntity); // Generate entity mapping var entityMapping = new Dictionary <Guid, Guid>(); var reverseEntityMapping = new Dictionary <Guid, Guid>(); foreach (var entity in newAsset.Hierarchy.Entities) { // Generate new Id var newEntityId = Guid.NewGuid(); // Update mappings entityMapping.Add(newEntityId, entity.Id); reverseEntityMapping.Add(entity.Id, newEntityId); // Update entity with new id entity.Id = newEntityId; } // Rewrite entity references // Should we nullify invalid references? EntityAnalysis.RemapEntitiesId(newAsset.Hierarchy, reverseEntityMapping); // Add asset base entityBase = new EntityBase { Base = new AssetBase(sourceUrl, newAsset), SourceRoot = sourceRootEntity, IdMapping = entityMapping }; return(newAsset.Hierarchy); }