protected override void Prepare(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { result.BuildSteps.Add(new DummyAssetCommand <VideoAsset, Video.Video>(assetItem)); }
/// <summary> /// Performs analysis on the asset to figure out all the needed dependencies /// </summary> /// <param name="context">The compiler context</param> /// <returns>True if the node was updated, false otherwise.</returns> public bool Analyze(AssetCompilerContext context) { var assetVersion = AssetItem.Version; if (Interlocked.Exchange(ref version, assetVersion) == assetVersion) { // This node is up-to-date. Let's check if CompileAsset links are also up-to-date. // Otherwise we need to refresh this node since this kind of link can bring additional dependencies. var upToDate = true; foreach (var node in References) { if (node.HasOne(BuildDependencyType.CompileAsset)) { if (node.Target.Analyze(context)) { upToDate = false; } } } if (upToDate) { return(false); // Same version, skip analysis, do not clear links } } var mainCompiler = BuildDependencyManager.AssetCompilerRegistry.GetCompiler(AssetItem.Asset.GetType(), CompilationContext); if (mainCompiler == null) { return(false); // Scripts and such don't have compiler } var typesToInclude = new HashSet <BuildDependencyInfo>(mainCompiler.GetInputTypes(AssetItem)); var typesToExclude = new HashSet <Type>(mainCompiler.GetInputTypesToExclude(AssetItem)); // Clean up our references references.Clear(); // DependencyManager check AddDependencies(AssetItem, typesToInclude, typesToExclude); // Input files required foreach (var inputFile in new HashSet <ObjectUrl>(mainCompiler.GetInputFiles(AssetItem))) //directly resolve by input files, in the future we might just want this pass { if (inputFile.Type == UrlType.Content) { var asset = AssetItem.Package.Session.FindAsset(inputFile.Path); //this will search all packages if (asset == null) { continue; //this might be an error tho... but in the end compilation might fail so we let the build engine do the error reporting if it really was a issue } if (!typesToExclude.Contains(asset.GetType())) { // TODO: right now, we consider that assets returned by GetInputFiles must be compiled in AssetCompilationContext. At some point, we might need to be able to specify a custom context. var dependencyType = inputFile.Type == UrlType.Content ? BuildDependencyType.CompileContent : BuildDependencyType.CompileAsset; //Content means we need to load the content, the rest is just asset dependency var node = buildDependencyManager.FindOrCreateNode(asset, typeof(AssetCompilationContext)); var link = new BuildAssetLink(this, node, dependencyType); references.TryAdd(link, link); } } } bool shouldVisitTypes; context.Properties.TryGet(VisitRuntimeTypes, out shouldVisitTypes); if (shouldVisitTypes || mainCompiler.AlwaysCheckRuntimeTypes) { var collector = new RuntimeDependenciesCollector(mainCompiler.GetRuntimeTypes(AssetItem)); var deps = collector.GetDependencies(AssetItem); foreach (var reference in deps) { var asset = AssetItem.Package.FindAsset(reference.Id); if (asset != null) { // TODO: right now, we consider that assets found with RuntimeDependenciesCollector must be compiled in AssetCompilationContext. At some point, we might need to be able to specify a custom context. var dependencyType = BuildDependencyType.Runtime; var node = buildDependencyManager.FindOrCreateNode(asset, typeof(AssetCompilationContext)); var link = new BuildAssetLink(this, node, dependencyType); references.TryAdd(link, link); } } } return(true); }
private BuildResultCode BuildMaster() { try { PackageSessionPublicHelper.FindAndSetMSBuildVersion(); } catch (Exception e) { var message = "Could not find a compatible version of MSBuild.\r\n\r\n" + "Check that you have a valid installation with the required workloads, or go to [www.visualstudio.com/downloads](https://www.visualstudio.com/downloads) to install a new one.\r\n\r\n" + e; builderOptions.Logger.Error(message); return(BuildResultCode.BuildError); } AssetCompilerContext context = null; PackageSession projectSession = null; try { var sessionLoadParameters = new PackageLoadParameters { AutoCompileProjects = !builderOptions.DisableAutoCompileProjects, ExtraCompileProperties = builderOptions.ExtraCompileProperties, RemoveUnloadableObjects = true, BuildConfiguration = builderOptions.ProjectConfiguration, }; // Loads the root Package var projectSessionResult = PackageSession.Load(builderOptions.PackageFile, sessionLoadParameters); projectSessionResult.CopyTo(builderOptions.Logger); if (projectSessionResult.HasErrors) { return(BuildResultCode.BuildError); } projectSession = projectSessionResult.Session; // Find loaded package (either sdpkg or csproj) -- otherwise fallback to first one var packageFile = (UFile)builderOptions.PackageFile; var package = projectSession.Packages.FirstOrDefault(x => x.FullPath == packageFile || (x.Container is SolutionProject project && project.FullPath == packageFile)) ?? projectSession.LocalPackages.FirstOrDefault() ?? projectSession.Packages.FirstOrDefault(); // Setup variables var buildDirectory = builderOptions.BuildDirectory; var outputDirectory = builderOptions.OutputDirectory; // Process game settings asset var gameSettingsAsset = package.GetGameSettingsAsset(); if (gameSettingsAsset == null) { builderOptions.Logger.Warning($"Could not find game settings asset at location [{GameSettingsAsset.GameSettingsLocation}]. Use a Default One"); gameSettingsAsset = GameSettingsFactory.Create(); } // Create context context = new AssetCompilerContext { Platform = builderOptions.Platform, CompilationContext = typeof(AssetCompilationContext), BuildConfiguration = builderOptions.ProjectConfiguration, Package = package, }; // Command line properties foreach (var property in builderOptions.Properties) { context.OptionProperties.Add(property.Key, property.Value); } // Set current game settings context.SetGameSettingsAsset(gameSettingsAsset); // Builds the project var assetBuilder = new PackageCompiler(new RootPackageAssetEnumerator(package)); assetBuilder.AssetCompiled += RegisterBuildStepProcessedHandler; context.Properties.Set(BuildAssetNode.VisitRuntimeTypes, true); var assetBuildResult = assetBuilder.Prepare(context); assetBuildResult.CopyTo(builderOptions.Logger); if (assetBuildResult.HasErrors) { return(BuildResultCode.BuildError); } // Setup the remote process build var remoteBuilderHelper = new PackageBuilderRemoteHelper(projectSession.AssemblyContainer, builderOptions); var indexName = $"index.{package.Meta.Name}.{builderOptions.Platform}"; // Add runtime identifier (if any) to avoid clash when building multiple at the same time (this happens when using ExtrasBuildEachRuntimeIdentifier feature of MSBuild.Sdk.Extras) if (builderOptions.Properties.TryGetValue("RuntimeIdentifier", out var runtimeIdentifier)) { indexName += $".{runtimeIdentifier}"; } if (builderOptions.ExtraCompileProperties != null && builderOptions.ExtraCompileProperties.TryGetValue("StrideGraphicsApi", out var graphicsApi)) { indexName += $".{graphicsApi}"; } // Create the builder builder = new Builder(builderOptions.Logger, buildDirectory, indexName) { ThreadCount = builderOptions.ThreadCount, TryExecuteRemote = remoteBuilderHelper.TryExecuteRemote }; builder.MonitorPipeNames.AddRange(builderOptions.MonitorPipeNames); // Add build steps generated by AssetBuilder builder.Root.Add(assetBuildResult.BuildSteps); // Run builder var result = builder.Run(Builder.Mode.Build); builder.WriteIndexFile(false); // Fill list of bundles var bundlePacker = new BundlePacker(); var bundleFiles = new List <string>(); bundlePacker.Build(builderOptions.Logger, projectSession, package, indexName, outputDirectory, builder.DisableCompressionIds, context.GetCompilationMode() != CompilationMode.AppStore, bundleFiles); if (builderOptions.MSBuildUpToDateCheckFileBase != null) { SaveBuildUpToDateFile(builderOptions.MSBuildUpToDateCheckFileBase, builderOptions.PackageFile, package, bundleFiles); } return(result); } finally { builder?.Dispose(); // Dispose the session (in order to unload assemblies) projectSession?.Dispose(); context?.Dispose(); // Make sure that MSBuild doesn't hold anything else VSProjectHelper.Reset(); } }
protected override void Prepare(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (SkyboxAsset)assetItem.Asset; var colorSpace = context.GetColorSpace(); result.BuildSteps = new AssetBuildStep(assetItem); var prereqs = new Queue <BuildStep>(); // build the textures for windows (needed for skybox compilation) foreach (var dependency in asset.GetDependencies()) { var dependencyItem = assetItem.Package.Assets.Find(dependency.Id); if (dependencyItem?.Asset is TextureAsset) { var textureAsset = (TextureAsset)dependencyItem.Asset; // Get absolute path of asset source on disk var assetSource = GetAbsolutePath(dependencyItem, textureAsset.Source); // Create a synthetic url var textureUrl = SkyboxGenerator.BuildTextureForSkyboxGenerationLocation(dependencyItem.Location); var gameSettingsAsset = context.GetGameSettingsAsset(); var renderingSettings = gameSettingsAsset.GetOrCreate <RenderingSettings>(context.Platform); // Select the best graphics profile var graphicsProfile = renderingSettings.DefaultGraphicsProfile >= GraphicsProfile.Level_10_0 ? renderingSettings.DefaultGraphicsProfile : GraphicsProfile.Level_10_0; var textureAssetItem = new AssetItem(textureUrl, textureAsset); // Create and add the texture command. var textureParameters = new TextureConvertParameters(assetSource, textureAsset, PlatformType.Windows, GraphicsPlatform.Direct3D11, graphicsProfile, gameSettingsAsset.GetOrCreate <TextureSettings>().TextureQuality, colorSpace); var prereqStep = new AssetBuildStep(textureAssetItem); prereqStep.Add(new TextureAssetCompiler.TextureConvertCommand(textureUrl, textureParameters, assetItem.Package)); result.BuildSteps.Add(prereqStep); prereqs.Enqueue(prereqStep); } } // add the skybox command itself. IEnumerable <ObjectUrl> InputFilesGetter() { var skyboxAsset = (SkyboxAsset)assetItem.Asset; foreach (var dependency in skyboxAsset.GetDependencies()) { var dependencyItem = assetItem.Package.Assets.Find(dependency.Id); if (dependencyItem?.Asset is TextureAsset) { yield return(new ObjectUrl(UrlType.Content, dependency.Location)); } } } var assetStep = new CommandBuildStep(new SkyboxCompileCommand(targetUrlInStorage, asset, assetItem.Package) { InputFilesGetter = InputFilesGetter }); result.BuildSteps.Add(assetStep); while (prereqs.Count > 0) { var prereq = prereqs.Dequeue(); BuildStep.LinkBuildSteps(prereq, assetStep); } }
public NavmeshBuildCommand(string url, AssetItem assetItem, NavigationMeshAsset value, AssetCompilerContext context) : base(url, value, assetItem.Package) { gameSettingsAsset = context.GetGameSettingsAsset(); asset = value; assetUrl = url; Version = 1; // Removed separate debug model stored in the navigation mesh }
protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, ProceduralModelAsset asset, AssetCompilerResult result) { result.BuildSteps = new ListBuildStep { new GeometricPrimitiveCompileCommand(urlInStorage, asset) }; }
public static void SetGameSettingsAsset(this AssetCompilerContext context, GameSettingsAsset gameSettingsAsset) { context.Properties.Set(GameSettingsAssetKey, gameSettingsAsset); }
public MaterialCompileCommand(string url, AssetItem assetItem, MaterialAsset value, AssetCompilerContext context) : base(url, value, assetItem.Package) { Version = 5; this.assetItem = assetItem; colorSpace = context.GetColorSpace(); assetUrl = new UFile(url); graphicsProfile = context.GetGameSettingsAsset().GetOrCreate <RenderingSettings>(context.Platform).DefaultGraphicsProfile; }
public MaterialCompileCommand(string url, AssetItem assetItem, MaterialAsset value, AssetCompilerContext context) : base(url, value) { this.assetItem = assetItem; package = assetItem.Package; colorSpace = context.GetColorSpace(); assetUrl = new UFile(url); }
public EffectLogBuildStep(AssetCompilerContext context, UFile originalSourcePath) { this.context = context; this.originalSourcePath = originalSourcePath; }
protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, AnimationAsset asset, AssetCompilerResult result) { if (!EnsureSourceExists(result, asset, assetAbsolutePath)) { return; } // Get absolute path of asset source on disk var assetDirectory = assetAbsolutePath.GetParent(); var assetSource = GetAbsolutePath(assetAbsolutePath, asset.Source); var extension = assetSource.GetFileExtension(); var buildStep = new AssetBuildStep(AssetItem); // Find skeleton asset, if any AssetItem skeleton = null; if (asset.Skeleton != null) { skeleton = AssetItem.Package.FindAssetFromAttachedReference(asset.Skeleton); } var sourceBuildStep = ImportModelCommand.Create(extension); if (sourceBuildStep == null) { result.Error("No importer found for model extension '{0}. The model '{1}' can't be imported.", extension, assetSource); return; } sourceBuildStep.Mode = ImportModelCommand.ExportMode.Animation; sourceBuildStep.SourcePath = assetSource; sourceBuildStep.Location = urlInStorage; sourceBuildStep.AnimationRepeatMode = asset.RepeatMode; sourceBuildStep.AnimationRootMotion = asset.RootMotion; sourceBuildStep.ScaleImport = asset.ScaleImport; sourceBuildStep.SkeletonUrl = skeleton?.Location; var additiveAnimationAsset = asset as AdditiveAnimationAsset; if (additiveAnimationAsset != null) { var baseUrlInStorage = urlInStorage + "_animation_base"; var sourceUrlInStorage = urlInStorage + "_animation_source"; var baseAssetSource = UPath.Combine(assetDirectory, additiveAnimationAsset.BaseSource); var baseExtension = baseAssetSource.GetFileExtension(); sourceBuildStep.Location = sourceUrlInStorage; var baseBuildStep = ImportModelCommand.Create(extension); if (baseBuildStep == null) { result.Error("No importer found for model extension '{0}. The model '{1}' can't be imported.", baseExtension, baseAssetSource); return; } baseBuildStep.Mode = ImportModelCommand.ExportMode.Animation; baseBuildStep.SourcePath = baseAssetSource; baseBuildStep.Location = baseUrlInStorage; baseBuildStep.AnimationRepeatMode = asset.RepeatMode; baseBuildStep.AnimationRootMotion = asset.RootMotion; baseBuildStep.ScaleImport = asset.ScaleImport; baseBuildStep.SkeletonUrl = skeleton?.Location; // Import base and main animation buildStep.Add(sourceBuildStep); buildStep.Add(baseBuildStep); // Wait for both import fbx commands to be completed buildStep.Add(new WaitBuildStep()); // Generate the diff of those two animations buildStep.Add(new AdditiveAnimationCommand(urlInStorage, new AdditiveAnimationParameters(baseUrlInStorage, sourceUrlInStorage, additiveAnimationAsset.Mode))); } else { // Import the main animation buildStep.Add(sourceBuildStep); } result.BuildSteps = buildStep; }
private BuildResultCode BuildMaster() { // Only querying graphics platform, let's load package, print it and exit if (builderOptions.GetGraphicsPlatform) { return(BuildGetGraphicsPlatform()); } AssetCompilerContext context = null; PackageSession projectSession = null; try { // TODO handle solution file + package-id ? // When the current platform is not on windows, we need to make sure that all plugins are build, so we // setup auto-compile when loading the session var sessionLoadParameters = new PackageLoadParameters { AutoCompileProjects = builderOptions.Platform != PlatformType.Windows || !builderOptions.DisableAutoCompileProjects, ExtraCompileProperties = builderOptions.ExtraCompileProperties, }; // Loads the root Package var projectSessionResult = PackageSession.Load(builderOptions.PackageFile, sessionLoadParameters); if (projectSessionResult.HasErrors) { projectSessionResult.CopyTo(builderOptions.Logger); return(BuildResultCode.BuildError); } projectSession = projectSessionResult.Session; // Check build configuration var package = projectSession.LocalPackages.Last(); // Check build profile var sharedProfile = package.Profiles.FindSharedProfile(); var buildProfile = package.Profiles.FirstOrDefault(pair => pair.Name == builderOptions.BuildProfile); if (buildProfile == null) { builderOptions.Logger.Error("Unable to find profile [{0}] in package [{1}]", builderOptions.BuildProfile, package.FullPath); return(BuildResultCode.BuildError); } // Setup variables var buildDirectory = builderOptions.BuildDirectory; var outputDirectory = builderOptions.OutputDirectory; // Process game settings asset var gameSettingsAsset = package.GetGameSettingsAsset(); if (gameSettingsAsset == null) { builderOptions.Logger.Warning("Could not find game settings asset at location [{0}]. Use a Default One", GameSettingsAsset.GameSettingsLocation); gameSettingsAsset = GameSettingsFactory.Create(); } // Create context context = new AssetCompilerContext { Profile = builderOptions.BuildProfile, Platform = builderOptions.Platform, BuildConfiguration = builderOptions.ProjectConfiguration }; // Command line properties foreach (var property in builderOptions.Properties) { context.OptionProperties.Add(property.Key, property.Value); } // Set current game settings context.SetGameSettingsAsset(gameSettingsAsset); // Copy properties from shared profiles to context properties if (sharedProfile != null) { sharedProfile.Properties.CopyTo(context.PackageProperties, true); } // Copy properties from build profile buildProfile.Properties.CopyTo(context.PackageProperties, true); // Builds the project var assetBuilder = new PackageCompiler(new RootPackageAssetEnumerator(package)); assetBuilder.AssetCompiled += RegisterBuildStepProcessedHandler; var assetBuildResult = assetBuilder.Compile(context); assetBuildResult.CopyTo(builderOptions.Logger); if (assetBuildResult.HasErrors) { return(BuildResultCode.BuildError); } // Add specific steps to generate shaders // TODO: This doesn't really belong here, where should we move it? //assetBuildResult.BuildSteps.Add(new WaitBuildStep()); //assetBuildResult.BuildSteps.Add(new CompileDefaultSceneEffectCommand(context, package, assetBuildResult)); // Create the builder var indexName = "index." + builderOptions.BuildProfile; builder = new Builder(builderOptions.Logger, buildDirectory, builderOptions.BuildProfile, indexName) { ThreadCount = builderOptions.ThreadCount }; builder.MonitorPipeNames.AddRange(builderOptions.MonitorPipeNames); // Add build steps generated by AssetBuilder builder.Root.Add(assetBuildResult.BuildSteps); // Run builder var result = builder.Run(Builder.Mode.Build); builder.WriteIndexFile(false); // Fill list of bundles var bundlePacker = new BundlePacker(); bundlePacker.Build(builderOptions.Logger, projectSession, buildProfile, indexName, outputDirectory, builder.DisableCompressionIds); return(result); } finally { builder?.Dispose(); // Dispose the session (in order to unload assemblies) projectSession?.Dispose(); context?.Dispose(); } }
protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, SpriteSheetAsset asset, AssetCompilerResult result) { var gameSettingsAsset = context.GetGameSettingsAsset(); result.BuildSteps = new AssetBuildStep(AssetItem); // create the registry containing the sprite assets texture index association var imageToTextureUrl = new Dictionary <SpriteInfo, string>(); // create and add import texture commands if (asset.Sprites != null && !asset.Packing.Enabled) { // sort sprites by referenced texture. var spriteByTextures = asset.Sprites.GroupBy(x => x.Source).ToArray(); for (int i = 0; i < spriteByTextures.Length; i++) { // skip the texture if the file is not valid. var textureFile = spriteByTextures[i].Key; if (!TextureFileIsValid(textureFile)) { continue; } var spriteAssetArray = spriteByTextures[i].ToArray(); foreach (var spriteAsset in spriteAssetArray) { imageToTextureUrl[spriteAsset] = SpriteSheetAsset.BuildTextureUrl(urlInStorage, i); } // create an texture asset. var textureAsset = new TextureAsset { Id = Guid.Empty, // CAUTION: It is important to use an empty GUID here, as we don't want the command to be rebuilt (by default, a new asset is creating a new guid) Alpha = asset.Alpha, Format = asset.Format, GenerateMipmaps = asset.GenerateMipmaps, PremultiplyAlpha = asset.PremultiplyAlpha, ColorKeyColor = asset.ColorKeyColor, ColorKeyEnabled = asset.ColorKeyEnabled, }; // Get absolute path of asset source on disk var assetDirectory = assetAbsolutePath.GetParent(); var assetSource = UPath.Combine(assetDirectory, spriteAssetArray[0].Source); // add the texture build command. result.BuildSteps.Add( new TextureAssetCompiler.TextureConvertCommand( SpriteSheetAsset.BuildTextureUrl(urlInStorage, i), new TextureConvertParameters(assetSource, textureAsset, context.Platform, context.GetGraphicsPlatform(), gameSettingsAsset.DefaultGraphicsProfile, gameSettingsAsset.TextureQuality))); } result.BuildSteps.Add(new WaitBuildStep()); // wait the textures to be imported } if (!result.HasErrors) { var parameters = new SpriteSheetParameters(asset, imageToTextureUrl, context.Platform, context.GetGraphicsPlatform(), gameSettingsAsset.DefaultGraphicsProfile, gameSettingsAsset.TextureQuality); result.BuildSteps.Add(new SpriteSheetCommand(urlInStorage, parameters)); } }
public static GameSettingsAsset GetGameSettingsAsset(this AssetCompilerContext context) { return(context.Properties.Get(GameSettingsAssetKey)); }
public EffectLogBuildStep(AssetCompilerContext context, UFile originalSourcePath, AssetItem assetItem) { this.context = context; this.originalSourcePath = originalSourcePath; this.assetItem = assetItem; }
public static ColorSpace GetColorSpace(this AssetCompilerContext context) { var settings = context.GetGameSettingsAsset().GetOrCreate <RenderingSettings>(context.Platform); return(settings.ColorSpace); }
public EntityCombineCommand(string url, Package package, AssetCompilerContext context, SceneAsset assetParameters) : base(url, assetParameters) { this.package = package; this.context = context; }