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); }
/// <summary> /// Adds an entity as a part asset. /// </summary> /// <param name="assetPartBase">The entity asset to be used as a part (must be created directly from <see cref="CreateChildAsset"/>)</param> /// <param name="rootEntityId">An optional entity id to attach the part to it. If null, the part will be attached to the root entities of this instance</param> public void AddPart(EntityGroupAssetBase assetPartBase, Guid? rootEntityId = null) { AddPartCore(assetPartBase); // If a RootEntityId is given and found in this instance, add them as children of entity if (rootEntityId.HasValue && this.Hierarchy.Entities.ContainsKey(rootEntityId.Value)) { var rootEntity = Hierarchy.Entities[rootEntityId.Value]; foreach (var entityId in assetPartBase.Hierarchy.RootEntities) { var entity = assetPartBase.Hierarchy.Entities[entityId]; rootEntity.Entity.Transform.Children.Add(entity.Entity.Transform); } } else { // Else add them as root this.Hierarchy.RootEntities.AddRange(assetPartBase.Hierarchy.RootEntities); } // Add all entities with the correct instance id foreach (var entityEntry in assetPartBase.Hierarchy.Entities) { entityEntry.Design.BasePartInstanceId = assetPartBase.Id; this.Hierarchy.Entities.Add(entityEntry); } }
public static EntityGroupAssetBase ExtractSceneClone(EntityGroupAssetBase 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].Entity; var subTreeHierarchy = new EntityHierarchyData { Entities = { subTreeRoot }, RootEntities = { sourceRootEntity } }; foreach (var subTreeEntity in subTreeRoot.EnumerateChildren(true)) subTreeHierarchy.Entities.Add(source.Hierarchy.Entities[subTreeEntity.Id]); // clone the entities of the sub-tree var clonedHierarchy = (EntityHierarchyData)AssetCloner.Clone(subTreeHierarchy); clonedHierarchy.Entities[sourceRootEntity].Entity.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 = (EntityGroupAssetBase)AssetCloner.Clone(source); clonedAsset.Hierarchy = clonedHierarchy; // revert the source hierarchy source.Hierarchy = sourceHierarchy; return clonedAsset; }
/// <summary> /// Initialize a new instance of <see cref="EntityGroupAssetMerge"/> /// </summary> /// <param name="baseAsset">The base asset used for merge (can be null).</param> /// <param name="newAsset">The new asset (cannot be null)</param> /// <param name="newBaseAsset">The new base asset (can be null)</param> /// <param name="newBaseParts">The new base parts (can be null)</param> public EntityGroupAssetMerge(EntityGroupAssetBase baseAsset, EntityGroupAssetBase newAsset, EntityGroupAssetBase newBaseAsset, List <AssetBase> newBaseParts) { if (newAsset == null) { throw new ArgumentNullException(nameof(newAsset)); } // We expect to have at least a baseAsset+newBaseAsset or newBaseParts if (baseAsset == null && newBaseAsset == null && (newBaseParts == null || newBaseParts.Count == 0)) { throw new InvalidOperationException("Cannot merge from base. No bases found"); } this.newAsset = newAsset; this.newBaseAsset = newBaseAsset; this.newBaseParts = newBaseParts; this.baseAsset = baseAsset; baseEntities = new Dictionary <GroupPartKey, EntityRemapEntry>(); newEntities = new Dictionary <GroupPartKey, EntityRemapEntry>(); newBaseEntities = new Dictionary <GroupPartKey, EntityRemapEntry>(); entitiesRemovedInNewBase = new HashSet <Guid>(); entitiesToRemoveFromNew = new HashSet <Guid>(); entitiesInHierarchy = new HashSet <Guid>(); rootEntitiesToAdd = new List <Guid>(); }
/// <summary> /// Adds an entity as a part asset. /// </summary> /// <param name="assetPartBase">The entity asset to be used as a part (must be created directly from <see cref="CreateChildAsset"/>)</param> /// <param name="rootEntityId">An optional entity id to attach the part to it. If null, the part will be attached to the root entities of this instance</param> public void AddPart(EntityGroupAssetBase assetPartBase, Guid?rootEntityId = null) { AddPartCore(assetPartBase); // If a RootEntityId is given and found in this instance, add them as children of entity if (rootEntityId.HasValue && this.Hierarchy.Entities.ContainsKey(rootEntityId.Value)) { var rootEntity = Hierarchy.Entities[rootEntityId.Value]; foreach (var entityId in assetPartBase.Hierarchy.RootEntities) { var entity = assetPartBase.Hierarchy.Entities[entityId]; rootEntity.Entity.Transform.Children.Add(entity.Entity.Transform); } } else { // Else add them as root this.Hierarchy.RootEntities.AddRange(assetPartBase.Hierarchy.RootEntities); } // Add all entities with the correct instance id foreach (var entityEntry in assetPartBase.Hierarchy.Entities) { entityEntry.Design.BasePartInstanceId = assetPartBase.Id; this.Hierarchy.Entities.Add(entityEntry); } }
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; }
/// <summary> /// Adds an entity as a part asset. /// </summary> /// <param name="assetPartBase">The entity asset to be used as a part (must be created directly from <see cref="CreateChildAsset"/>)</param> /// <param name="rootEntityId">An optional entity id to attach the part to it. If null, the part will be attached to the root entities of this instance</param> public void AddPart(EntityGroupAssetBase assetPartBase, Guid? rootEntityId = null) { if (assetPartBase == null) throw new ArgumentNullException(nameof(assetPartBase)); // The assetPartBase must be a plain child asset if (assetPartBase.Base == null) throw new InvalidOperationException($"Expecting a Base for {nameof(assetPartBase)}"); if (assetPartBase.BaseParts != null) throw new InvalidOperationException($"Expecting a null BaseParts for {nameof(assetPartBase)}"); // Check that the assetPartBase contains only entities from its base (no new entity, must be a plain ChildAsset) if (assetPartBase.Hierarchy.Entities.Any(entity => !entity.Design.BaseId.HasValue)) { throw new InvalidOperationException("An asset part base must contain only base assets"); } // The instance id will be the id of the assetPartBase var instanceId = assetPartBase.Id; if (this.BaseParts == null) { this.BaseParts = new List<AssetBasePart>(); } var basePart = this.BaseParts.FirstOrDefault(basePartIt => basePartIt.Base.Id == this.Id); if (basePart == null) { basePart = new AssetBasePart(assetPartBase.Base); this.BaseParts.Add(basePart); } basePart.InstanceIds.Add(instanceId); // If a RootEntityId is given and found in this instance, add them as children of entity if (rootEntityId.HasValue && this.Hierarchy.Entities.ContainsKey(rootEntityId.Value)) { var rootEntity = Hierarchy.Entities[rootEntityId.Value]; foreach (var entityId in assetPartBase.Hierarchy.RootEntities) { var entity = assetPartBase.Hierarchy.Entities[entityId]; rootEntity.Entity.Transform.Children.Add(entity.Entity.Transform); } } else { // Else add them as root this.Hierarchy.RootEntities.AddRange(assetPartBase.Hierarchy.RootEntities); } // Add all entities with the correct instance id foreach (var entityEntry in assetPartBase.Hierarchy.Entities) { entityEntry.Design.BasePartInstanceId = instanceId; this.Hierarchy.Entities.Add(entityEntry); } }
public static EntityGroupAssetBase ExtractSceneClone(EntityGroupAssetBase 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].Entity; var subTreeHierarchy = new EntityHierarchyData { Entities = { subTreeRoot }, RootEntities = { sourceRootEntity } }; foreach (var subTreeEntity in subTreeRoot.EnumerateChildren(true)) { subTreeHierarchy.Entities.Add(source.Hierarchy.Entities[subTreeEntity.Id]); } // clone the entities of the sub-tree var clonedHierarchy = (EntityHierarchyData)AssetCloner.Clone(subTreeHierarchy); clonedHierarchy.Entities[sourceRootEntity].Entity.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 = (EntityGroupAssetBase)AssetCloner.Clone(source); clonedAsset.Hierarchy = clonedHierarchy; // revert the source hierarchy source.Hierarchy = sourceHierarchy; return(clonedAsset); }
/// <summary> /// Fixups the entity references, by clearing invalid <see cref="EntityReference.Id"/>, and updating <see cref="EntityReference.Value"/> (same for components). /// </summary> /// <param name="entityAssetBase">The entity asset.</param> public static void FixupEntityReferences(EntityGroupAssetBase entityAssetBase) { FixupEntityReferences(entityAssetBase, entityAssetBase.Hierarchy); }