public IEnumerable<IReference> EnumerateCompileTimeDependencies(PackageSession session)
        {
            if (Prefab != null)
            {
                // Return the prefab itself
                yield return Prefab;
                // Then we need to return used models and materials because they affects how the meshes are generated
                var prefab = session.FindAsset(Prefab.Location)?.Asset as PrefabAsset;
                if (prefab != null)
                {
                    // Use a dictionary to ensure each reference is yielded only once
                    var references = new Dictionary<AssetId, IReference>();
                    foreach (var entity in prefab.Hierarchy.Parts)
                    {
                        // Gather all entities with a model component and a valid model
                        var modelComponent = entity.Entity.Get<ModelComponent>();
                        if (modelComponent?.Model != null)
                        {
                            var modelReference = AttachedReferenceManager.GetAttachedReference(modelComponent.Model);
                            var model = session.FindAsset(modelReference.Url)?.Asset as IModelAsset;
                            if (model != null)
                            {
                                // Build the list of material for this model
                                var materialList = model.Materials.Select(x => x.MaterialInstance.Material).ToList();
                                for (var i = 0; i < modelComponent.Materials.Count && i < materialList.Count; i++)
                                foreach (var material in modelComponent.Materials)
                                {
                                    // Apply any material override from the model component
                                    materialList[material.Key] = material.Value;
                                }

                                // Add the model and the related materials to the list of reference
                                references[modelReference.Id] = modelReference;
                                foreach (var material in materialList)
                                {
                                    var materialReference = AttachedReferenceManager.GetAttachedReference(material);
                                    references[materialReference.Id] = materialReference;
                                }
                            }
                        }
                    }
                    // Finally return all the referenced models and materials
                    foreach (var reference in references.Values)
                    {
                        yield return reference;
                    }
                }
            }
        }
Beispiel #2
0
        public IIdentifiable ResolvePart(PackageSession session)
        {
            var assetItem = session.FindAsset(BasePartAsset.Id);
            var asset     = assetItem?.Asset as AssetComposite;

            return(asset?.FindPart(BasePartId));
        }
        /// <summary>
        /// Create a <see cref="PackageSession"/> that can be used to compile an <see cref="AssetItem"/> by analyzing and resolving its dependencies.
        /// </summary>
        /// <returns>The package packageSession that can be used to compile the asset item.</returns>
        public static PackageSession CreateCompilePackageFromAsset(this PackageSession session, AssetItem originalAssetItem)
        {
            if (originalAssetItem == null)
            {
                throw new ArgumentNullException("originalAssetItem");
            }

            // Find the asset from the session
            var assetItem = session.FindAsset(originalAssetItem.Id);

            if (assetItem == null)
            {
                throw new ArgumentException("Cannot find the specified AssetItem instance in the session");
            }

            // Calculate dependencies
            var dependencies        = session.DependencyManager.ComputeDependencies(assetItem, AssetDependencySearchOptions.Out | AssetDependencySearchOptions.Recursive);
            var assetItemRootCloned = dependencies.Item.Clone();

            // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages
            assetItemRootCloned.SourceFolder = assetItem.FullPath.GetParent();

            // create the compile root package and package session
            var assetPackageCloned    = new Package();
            var compilePackageSession = new PackageSession(assetPackageCloned);

            assetPackageCloned.Assets.Add(assetItemRootCloned);

            // For each asset item dependency, clone it in the new package
            foreach (var assetLink in dependencies.LinksOut)
            {
                // Only add assets not already added (in case of circular dependencies)
                if (assetPackageCloned.Assets.Find(assetLink.Item.Id) == null)
                {
                    // create a copy of the asset item and add it to the appropriate compile package
                    var itemCloned = assetLink.Item.Clone();

                    // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages
                    itemCloned.SourceFolder = assetLink.Item.FullPath.GetParent();
                    assetPackageCloned.Assets.Add(itemCloned);
                }
            }

            return(compilePackageSession);
        }
Beispiel #4
0
        /// <summary>
        /// Saves this package and all dirty assets. See remarks.
        /// </summary>
        /// <param name="log">The log.</param>
        /// <exception cref="System.ArgumentNullException">log</exception>
        /// <remarks>When calling this method directly, it does not handle moving assets between packages.
        /// Call <see cref="PackageSession.Save" /> instead.</remarks>
        public void Save(ILogger log)
        {
            if (log == null)
            {
                throw new ArgumentNullException("log");
            }

            if (FullPath == null)
            {
                log.Error(this, null, AssetMessageCode.PackageCannotSave, "null");
                return;
            }

            // Use relative paths when saving
            var analysis = new PackageAnalysis(this, new PackageAnalysisParameters()
            {
                SetDirtyFlagOnAssetWhenFixingUFile = false,
                ConvertUPathTo     = UPathType.Relative,
                IsProcessingUPaths = true
            });

            analysis.Run(log);

            try
            {
                // Update source folders
                UpdateSourceFolders();

                if (IsDirty)
                {
                    try
                    {
                        // Notifies the dependency manager that a package with the specified path is being saved
                        if (session != null && session.HasDependencyManager)
                        {
                            session.DependencyManager.AddFileBeingSaveDuringSessionSave(FullPath);
                        }

                        AssetSerializer.Save(FullPath, this);

                        IsDirty = false;
                    }
                    catch (Exception ex)
                    {
                        log.Error(this, null, AssetMessageCode.PackageCannotSave, ex, FullPath);
                        return;
                    }
                }

                foreach (var asset in Assets)
                {
                    if (asset.IsDirty)
                    {
                        var assetPath = asset.FullPath;
                        try
                        {
                            // Notifies the dependency manager that an asset with the specified path is being saved
                            if (session != null && session.HasDependencyManager)
                            {
                                session.DependencyManager.AddFileBeingSaveDuringSessionSave(assetPath);
                            }

                            // Incject a copy of the base into the current asset when saving
                            var assetBase = asset.Asset.Base;
                            if (assetBase != null && !assetBase.IsRootImport)
                            {
                                var assetBaseItem = session != null?session.FindAsset(assetBase.Id) : Assets.Find(assetBase.Id);

                                if (assetBaseItem != null)
                                {
                                    var newBase = (Asset)AssetCloner.Clone(assetBaseItem.Asset);
                                    newBase.Base     = null;
                                    asset.Asset.Base = new AssetBase(asset.Asset.Base.Location, newBase);
                                }
                            }

                            AssetSerializer.Save(assetPath, asset.Asset);
                            asset.IsDirty = false;
                        }
                        catch (Exception ex)
                        {
                            log.Error(this, asset.ToReference(), AssetMessageCode.AssetCannotSave, ex, assetPath);
                        }
                    }
                }

                Assets.IsDirty = false;

                // Save properties like the Paradox version used
                PackageSessionHelper.SaveProperties(this);
            }
            finally
            {
                // Rollback all relative UFile to absolute paths
                analysis.Parameters.ConvertUPathTo = UPathType.Absolute;
                analysis.Run();
            }
        }
        public IEnumerable<IReference> EnumerateCompileTimeDependencies(PackageSession session)
        {
            if (Scene != null)
            {
                var reference = AttachedReferenceManager.GetAttachedReference(Scene);
                var sceneAsset = (SceneAsset)session.FindAsset(reference.Url)?.Asset;

                var referencedColliderShapes = new HashSet<AssetId>();

                // Find collider assets to reference
                if (sceneAsset != null)
                {
                    List<Entity> sceneEntities = sceneAsset.Hierarchy.Parts.Select(x => x.Entity).ToList();
                    foreach (var entity in sceneEntities)
                    {
                        StaticColliderComponent collider = entity.Get<StaticColliderComponent>();
                        bool colliderEnabled = collider != null && ((CollisionFilterGroupFlags)collider.CollisionGroup & IncludedCollisionGroups) != 0 && collider.Enabled;
                        if (colliderEnabled)
                        {
                            var assetShapes = collider.ColliderShapes.OfType<ColliderShapeAssetDesc>();
                            foreach (var assetShape in assetShapes)
                            {
                                if (assetShape.Shape == null)
                                    continue;

                                // Reference all asset collider shapes
                                reference = AttachedReferenceManager.GetAttachedReference(assetShape.Shape);

                                // Only need to reference each shape once
                                if (referencedColliderShapes.Contains(reference.Id))
                                    continue;

                                yield return new AssetReference(reference.Id, reference.Url);
                                referencedColliderShapes.Add(reference.Id);
                            }
                        }
                    }
                }
            }
        }