public static EntityHierarchyData ImportScene(UFile sourceUrl, EntityGroupAssetBase source, Guid sourceRootEntity) { if (source == null) { throw new ArgumentNullException("source"); } // Extract the scene starting from given root var newAsset = ExtractSceneClone(source, sourceRootEntity); // Generate entity mapping var reverseEntityMapping = new Dictionary <Guid, Guid>(); foreach (var entityDesign in newAsset.Hierarchy.Entities) { // Generate new Id var newEntityId = Guid.NewGuid(); // Update mappings reverseEntityMapping.Add(entityDesign.Entity.Id, newEntityId); // Update entity with new id entityDesign.Entity.Id = newEntityId; } // Rewrite entity references // Should we nullify invalid references? EntityAnalysis.RemapEntitiesId(newAsset.Hierarchy, reverseEntityMapping); return(newAsset.Hierarchy); }
void IDiffResolver.BeforeDiff(Asset baseAsset, Asset asset1, Asset asset2) { 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); }
/// <summary> /// Clones a sub-hierarchy of this asset. /// </summary> /// <param name="sourceRootEntity">The entity that is the root of the sub-hierarchy to clone</param> /// <param name="cleanReference">If true, any reference to an entity external to the cloned hierarchy will be set to null.</param> /// <param name="entityMapping">A dictionary containing the mapping of ids from the source entites to the new entities.</param> /// <returns>A <see cref="EntityHierarchyData"/> corresponding to the cloned entities.</returns> public EntityHierarchyData CloneSubHierarchy(Guid sourceRootEntity, bool cleanReference, out Dictionary <Guid, Guid> entityMapping) { if (!Hierarchy.Entities.ContainsKey(sourceRootEntity)) { throw new ArgumentException(@"The source root entity must be an entity of this asset.", nameof(sourceRootEntity)); } // 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. var subTreeRoot = Hierarchy.Entities[sourceRootEntity]; var subTreeHierarchy = new EntityHierarchyData { Entities = { subTreeRoot }, RootEntities = { sourceRootEntity } }; foreach (var subTreeEntity in EnumerateChildren(subTreeRoot, true)) { subTreeHierarchy.Entities.Add(Hierarchy.Entities[subTreeEntity.Entity.Id]); } // clone the entities of the sub-tree var clonedHierarchy = (EntityHierarchyData)AssetCloner.Clone(subTreeHierarchy); clonedHierarchy.Entities[sourceRootEntity].Entity.Transform.Parent = null; if (cleanReference) { // set to null reference outside of the sub-tree EntityAnalysis.FixupEntityReferences(clonedHierarchy); } // temporary nullify the hierarchy to avoid to clone it var sourceHierarchy = Hierarchy; Hierarchy = null; // revert the source hierarchy Hierarchy = sourceHierarchy; // Generate entity mapping entityMapping = new Dictionary <Guid, Guid>(); foreach (var entityDesign in clonedHierarchy.Entities) { // Generate new Id var newEntityId = Guid.NewGuid(); // Update mappings entityMapping.Add(entityDesign.Entity.Id, newEntityId); // Update entity with new id entityDesign.Entity.Id = newEntityId; } // Rewrite entity references // Should we nullify invalid references? EntityAnalysis.RemapEntitiesId(clonedHierarchy, entityMapping); return(clonedHierarchy); }
public override Asset CreateChildAsset(string location) { var newAsset = (EntityHierarchyAssetBase)base.CreateChildAsset(location); var newIdMaps = Hierarchy.Entities.ToDictionary(x => x.Entity.Id, x => Guid.NewGuid()); foreach (var entity in newAsset.Hierarchy.Entities) { // Store the baseid of the new version entity.Design.BaseId = entity.Entity.Id; // Make sure that we don't replicate the base part InstanceId entity.Design.BasePartInstanceId = null; // Apply the new Guid entity.Entity.Id = newIdMaps[entity.Entity.Id]; } EntityAnalysis.RemapEntitiesId(newAsset.Hierarchy, newIdMaps); return(newAsset); }
/// <summary> /// Clones a sub-hierarchy of this asset. /// </summary> /// <param name="sourceRootEntities">The entities that are the roots of the sub-hierarchies to clone</param> /// <param name="cleanReference">If true, any reference to an entity external to the cloned hierarchy will be set to null.</param> /// <param name="entityMapping">A dictionary containing the mapping of ids from the source entites to the new entities.</param> /// <returns>A <see cref="AssetCompositeHierarchyData{EntityDesign, Entity}"/> corresponding to the cloned entities.</returns> /// <remarks>The entities passed to this methods must be independent in the hierarchy.</remarks> public AssetCompositeHierarchyData <EntityDesign, Entity> CloneSubHierarchies(IEnumerable <Guid> sourceRootEntities, bool cleanReference, out Dictionary <Guid, Guid> entityMapping) { // 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. var subTreeHierarchy = new AssetCompositeHierarchyData <EntityDesign, Entity>(); foreach (var sourceRootEntity in sourceRootEntities) { if (!Hierarchy.Parts.ContainsKey(sourceRootEntity)) { throw new ArgumentException(@"The source root entities must be entities of this asset.", nameof(sourceRootEntities)); } var subTreeRoot = Hierarchy.Parts[sourceRootEntity].Entity; subTreeHierarchy.Parts.Add(new EntityDesign(subTreeRoot)); subTreeHierarchy.RootPartIds.Add(sourceRootEntity); foreach (var subTreeEntity in EnumerateChildParts(subTreeRoot, true)) { subTreeHierarchy.Parts.Add(Hierarchy.Parts[subTreeEntity.Id]); } } // clone the entities of the sub-tree var clonedHierarchy = (AssetCompositeHierarchyData <EntityDesign, Entity>)AssetCloner.Clone(subTreeHierarchy); foreach (var rootEntity in clonedHierarchy.RootPartIds) { clonedHierarchy.Parts[rootEntity].Entity.Transform.Parent = null; } if (cleanReference) { // set to null reference outside of the sub-tree var tempAsset = new PrefabAsset { Hierarchy = clonedHierarchy }; tempAsset.FixupPartReferences(); } // temporary nullify the hierarchy to avoid to clone it var sourceHierarchy = Hierarchy; Hierarchy = null; // revert the source hierarchy Hierarchy = sourceHierarchy; // Generate entity mapping entityMapping = new Dictionary <Guid, Guid>(); foreach (var entityDesign in clonedHierarchy.Parts) { // Generate new Id var newEntityId = Guid.NewGuid(); // Update mappings entityMapping.Add(entityDesign.Entity.Id, newEntityId); // Update entity with new id entityDesign.Entity.Id = newEntityId; } // Rewrite entity references // Should we nullify invalid references? EntityAnalysis.RemapEntitiesId(clonedHierarchy, entityMapping); return(clonedHierarchy); }