private static string GetFontPath(SpriteFontAsset asset, AssetCompilerResult result) { using (var factory = new Factory()) { Font font; using (var fontCollection = factory.GetSystemFontCollection(false)) { int index; if (!fontCollection.FindFamilyName(asset.FontName, out index)) { result.Error("Can't find font '{0}'.", asset.FontName); return(null); } using (var fontFamily = fontCollection.GetFontFamily(index)) { var weight = FontWeight.Regular; var style = SharpDX.DirectWrite.FontStyle.Normal; switch (asset.Style) { case FontStyle.Bold: weight = FontWeight.Bold; break; case FontStyle.Italic: weight = FontWeight.Regular; style = SharpDX.DirectWrite.FontStyle.Italic; break; case FontStyle.Regular: weight = FontWeight.Regular; break; } font = fontFamily.GetFirstMatchingFont(weight, FontStretch.Normal, style); if (font == null) { result.Error("Cannot find style '{0}' for font family {1}.", asset.Style, asset.FontName); return(null); } } } var fontFace = new FontFace(font); // get the font path on the hard drive var file = fontFace.GetFiles().First(); var referenceKey = file.GetReferenceKey(); var originalLoader = (FontFileLoaderNative)file.Loader; var loader = originalLoader.QueryInterface <LocalFontFileLoader>(); return(loader.GetFilePath(referenceKey)); } }
protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, SpriteFontAsset asset, AssetCompilerResult result) { var colorSpace = context.GetColorSpace(); if (asset.IsDynamic) { UFile fontPathOnDisk; if (!string.IsNullOrEmpty(asset.Source)) { var assetDirectory = assetAbsolutePath.GetParent(); fontPathOnDisk = UPath.Combine(assetDirectory, asset.Source); if (!File.Exists(fontPathOnDisk)) { result.Error("The font source '{0}' does not exist on the PC.", asset.FontName); return; } // set the source filename as font name instead of the font family. asset.FontName = fontPathOnDisk.GetFileName(); } else { fontPathOnDisk = GetFontPath(asset, result); if (fontPathOnDisk == null) { result.Error("The font named '{0}' could not be located on the PC.", asset.FontName); return; } } var fontImportLocation = FontHelper.GetFontPath(asset.FontName, asset.Style); result.BuildSteps = new AssetBuildStep(AssetItem) { new ImportStreamCommand { SourcePath = fontPathOnDisk, Location = fontImportLocation }, new DynamicFontCommand(urlInStorage, asset) }; } else { // copy the asset and transform the source and character set file path to absolute paths var assetClone = (SpriteFontAsset)AssetCloner.Clone(asset); var assetDirectory = assetAbsolutePath.GetParent(); assetClone.Source = !string.IsNullOrEmpty(asset.Source) ? UPath.Combine(assetDirectory, asset.Source): null; assetClone.CharacterSet = !string.IsNullOrEmpty(asset.CharacterSet) ? UPath.Combine(assetDirectory, asset.CharacterSet): null; result.BuildSteps = new AssetBuildStep(AssetItem) { new StaticFontCommand(urlInStorage, assetClone, colorSpace) }; } }
protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, EntityAsset asset, AssetCompilerResult result) { foreach (var entityData in asset.Hierarchy.Entities) { // TODO: How to make this code pluggable? var modelComponent = entityData.Components.Get(ModelComponent.Key); var spriteComponent = entityData.Components.Get(SpriteComponent.Key); var scriptComponent = entityData.Components.Get(ScriptComponent.Key); // determine the underlying source asset exists if (modelComponent != null) { if (modelComponent.Model == null) { result.Warning(string.Format("The entity [{0}:{1}] has a model component that does not reference any model.", urlInStorage, entityData.Name)); continue; } var modelAttachedReference = AttachedReferenceManager.GetAttachedReference(modelComponent.Model); var modelId = modelAttachedReference.Id; // compute the full path to the source asset. var assetItem = AssetItem.Package.Session.FindAsset(modelId); if (assetItem == null) { result.Error(string.Format("The entity [{0}:{1}] is referencing an unreachable model.", urlInStorage, entityData.Name)); continue; } } if (spriteComponent != null && spriteComponent.SpriteProvider == null) { result.Warning(string.Format("The entity [{0}:{1}] has a sprite component that does not reference any sprite group.", urlInStorage, entityData.Name)); } if (scriptComponent != null) { foreach (var script in scriptComponent.Scripts) { if (script is UnloadableScript) { result.Error(string.Format("The entity [{0}:{1}] reference an invalid script '{2}'.", urlInStorage, entityData.Name, script.GetType().Name)); } } } } result.BuildSteps = new AssetBuildStep(AssetItem) { new EntityCombineCommand(urlInStorage, AssetItem.Package, context, asset) }; }
protected override void Prepare(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (SkeletonAsset)assetItem.Asset; var assetSource = GetAbsolutePath(assetItem, asset.Source); var extension = assetSource.GetFileExtension(); var buildStep = new AssetBuildStep(assetItem); var importModelCommand = ImportModelCommand.Create(extension); if (importModelCommand == null) { result.Error($"No importer found for model extension '{extension}. The model '{assetSource}' can't be imported."); return; } importModelCommand.SourcePath = assetSource; importModelCommand.Location = targetUrlInStorage; importModelCommand.Mode = ImportModelCommand.ExportMode.Skeleton; importModelCommand.ScaleImport = asset.ScaleImport; importModelCommand.PivotPosition = asset.PivotPosition; importModelCommand.SkeletonNodesWithPreserveInfo = asset.NodesWithPreserveInfo; buildStep.Add(importModelCommand); result.BuildSteps = buildStep; }
/// <inheritdoc /> protected override void CompileThumbnail(ThumbnailCompilerContext context, string thumbnailStorageUrl, AssetItem assetItem, Package originalPackage, AssetCompilerResult result) { var thumbnailSize = context.ThumbnailResolution; UFile assetSource = null; var sourceValid = !string.IsNullOrEmpty(Asset.Source); if (sourceValid) { // Get absolute path of asset source on disk var assetDirectory = assetItem.FullPath.GetParent(); assetSource = UPath.Combine(assetDirectory, Asset.Source); sourceValid = File.Exists(assetSource); } if (sourceValid) { result.BuildSteps.Add(new ThumbnailBuildStep(new TextureThumbnailBuildCommand(context, thumbnailStorageUrl, assetItem, originalPackage, new TextureThumbnailParameters(Asset, assetSource, thumbnailStorageUrl, thumbnailSize)))); } else { var gameSettings = context.GetGameSettingsAsset(); result.Error($"Source is null or unreachable for Texture Asset [{Asset}]"); result.BuildSteps.Add(new StaticThumbnailCommand <TextureAsset>(thumbnailStorageUrl, DefaultThumbnails.TextureNoSource, thumbnailSize, gameSettings.GetOrCreate <RenderingSettings>().ColorSpace == ColorSpace.Linear, assetItem.Package)); } }
protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, SkeletonAsset asset, AssetCompilerResult result) { if (!EnsureSourcesExist(result, asset, assetAbsolutePath)) { return; } var assetSource = GetAbsolutePath(assetAbsolutePath, asset.Source); var extension = assetSource.GetFileExtension(); var buildStep = new AssetBuildStep(AssetItem); var importModelCommand = ImportModelCommand.Create(extension); if (importModelCommand == null) { result.Error("No importer found for model extension '{0}. The model '{1}' can't be imported.", extension, assetSource); return; } importModelCommand.SourcePath = assetSource; importModelCommand.Location = urlInStorage; importModelCommand.Mode = ImportModelCommand.ExportMode.Skeleton; importModelCommand.ScaleImport = asset.ScaleImport; importModelCommand.PivotPosition = asset.PivotPosition; importModelCommand.SkeletonNodesWithPreserveInfo = asset.NodesWithPreserveInfo; buildStep.Add(importModelCommand); result.BuildSteps = buildStep; }
protected override void Prepare(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (SpriteFontAsset)assetItem.Asset; UFile assetAbsolutePath = assetItem.FullPath; var colorSpace = context.GetColorSpace(); var fontTypeSdf = asset.FontType as SignedDistanceFieldSpriteFontType; if (fontTypeSdf != null) { // copy the asset and transform the source and character set file path to absolute paths var assetClone = AssetCloner.Clone(asset); var assetDirectory = assetAbsolutePath.GetParent(); assetClone.FontSource = asset.FontSource; fontTypeSdf.CharacterSet = !string.IsNullOrEmpty(fontTypeSdf.CharacterSet) ? UPath.Combine(assetDirectory, fontTypeSdf.CharacterSet) : null; result.BuildSteps = new AssetBuildStep(assetItem); result.BuildSteps.Add(new SignedDistanceFieldFontCommand(targetUrlInStorage, assetClone, assetItem.Package)); } else if (asset.FontType is RuntimeRasterizedSpriteFontType) { UFile fontPathOnDisk = asset.FontSource.GetFontPath(result); if (fontPathOnDisk == null) { result.Error($"Runtime rasterized font compilation failed. Font {asset.FontSource.GetFontName()} was not found on this machine."); result.BuildSteps = new AssetBuildStep(assetItem); result.BuildSteps.Add(new FailedFontCommand()); return; } var fontImportLocation = FontHelper.GetFontPath(asset.FontSource.GetFontName(), asset.FontSource.Style); result.BuildSteps = new AssetBuildStep(assetItem); result.BuildSteps.Add(new ImportStreamCommand { SourcePath = fontPathOnDisk, Location = fontImportLocation }); result.BuildSteps.Add(new RuntimeRasterizedFontCommand(targetUrlInStorage, asset, assetItem.Package)); } else { var fontTypeStatic = asset.FontType as OfflineRasterizedSpriteFontType; if (fontTypeStatic == null) { throw new ArgumentException("Tried to compile a non-offline rasterized sprite font with the compiler for offline resterized fonts!"); } // copy the asset and transform the source and character set file path to absolute paths var assetClone = AssetCloner.Clone(asset); var assetDirectory = assetAbsolutePath.GetParent(); assetClone.FontSource = asset.FontSource; fontTypeStatic.CharacterSet = !string.IsNullOrEmpty(fontTypeStatic.CharacterSet) ? UPath.Combine(assetDirectory, fontTypeStatic.CharacterSet): null; result.BuildSteps = new AssetBuildStep(assetItem); result.BuildSteps.Add(new OfflineRasterizedFontCommand(targetUrlInStorage, assetClone, colorSpace, assetItem.Package) { InputFilesGetter = () => GetInputFiles(assetItem) }); } }
/// <inheritdoc/> public override string GetFontPath(AssetCompilerResult result = null) { if (!File.Exists(Source)) { result?.Error($"Cannot find font file '{Source}'. Make sure it exists and is referenced correctly."); } return(Source); }
protected override void Prepare(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (ModelAsset)assetItem.Asset; // Get absolute path of asset source on disk var assetDirectory = assetItem.FullPath.GetParent(); var assetSource = UPath.Combine(assetDirectory, asset.Source); var gameSettingsAsset = context.GetGameSettingsAsset(); var renderingSettings = gameSettingsAsset.GetOrCreate <RenderingSettings>(); var allow32BitIndex = true; var maxInputSlots = 32; var allowUnsignedBlendIndices = true; var extension = asset.Source.GetFileExtension(); // Find skeleton asset, if any AssetItem skeleton = null; if (asset.Skeleton != null) { skeleton = assetItem.Package.FindAssetFromProxyObject(asset.Skeleton); } var importModelCommand = ImportModelCommand.Create(extension); if (importModelCommand is null) { result.Error($"No importer found for model extension '{extension}'. The model '{assetSource}' can't be imported."); return; } importModelCommand.InputFilesGetter = () => GetInputFiles(assetItem); importModelCommand.Mode = ImportModelCommand.ExportMode.Model; importModelCommand.SourcePath = assetSource; importModelCommand.Location = targetUrlInStorage; importModelCommand.Allow32BitIndex = allow32BitIndex; importModelCommand.MaxInputSlots = maxInputSlots; importModelCommand.AllowUnsignedBlendIndices = allowUnsignedBlendIndices; importModelCommand.Materials = asset.Materials; importModelCommand.ScaleImport = asset.ScaleImport; importModelCommand.PivotPosition = asset.PivotPosition; importModelCommand.MergeMeshes = asset.MergeMeshes; importModelCommand.DeduplicateMaterials = asset.DeduplicateMaterials; importModelCommand.ModelModifiers = asset.Modifiers; if (skeleton != null) { importModelCommand.SkeletonUrl = skeleton.Location; // NOTE: Skeleton override values importModelCommand.ScaleImport = ((SkeletonAsset)skeleton.Asset).ScaleImport; importModelCommand.PivotPosition = ((SkeletonAsset)skeleton.Asset).PivotPosition; } importModelCommand.Package = assetItem.Package; result.BuildSteps = new AssetBuildStep(assetItem); result.BuildSteps.Add(importModelCommand); }
protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, TGroupAsset asset, AssetCompilerResult result) { result.BuildSteps = new ListBuildStep(); // Evaluate if we need to use a separate the alpha texture SeparateAlphaTexture = TextureCommandHelper.ShouldSeparateAlpha(asset.Alpha, asset.Format, context.Platform, context.GetGraphicsProfile()); // create the registry containing the sprite assets texture index association SpriteToTextureIndex = new Dictionary <TImageInfo, int>(); // create and add import texture commands if (asset.Images != null) { // return compilation error if one or more of the sprite does not have a valid texture var noSourceAsset = asset.Images.FirstOrDefault(x => !TextureFileIsValid(x.Source)); if (noSourceAsset != null) { result.Error("The texture of image '{0}' either does not exist or is invalid", noSourceAsset.Name); return; } // sort sprites by referenced texture. var spriteByTextures = asset.Images.GroupBy(x => x.Source).ToArray(); for (int i = 0; i < spriteByTextures.Length; i++) { var spriteAssetArray = spriteByTextures[i].ToArray(); foreach (var spriteAsset in spriteAssetArray) { SpriteToTextureIndex[spriteAsset] = 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( ImageGroupAsset.BuildTextureUrl(urlInStorage, i), new TextureConvertParameters(assetSource, textureAsset, context.Platform, context.GetGraphicsPlatform(), context.GetGraphicsProfile(), context.GetTextureQuality(), SeparateAlphaTexture))); } result.BuildSteps.Add(new WaitBuildStep()); // wait the textures to be imported } }
protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, ModelAsset asset, AssetCompilerResult result) { if (!EnsureSourceExists(result, asset, assetAbsolutePath)) { return; } // Get absolute path of asset source on disk var assetDirectory = assetAbsolutePath.GetParent(); var assetSource = UPath.Combine(assetDirectory, asset.Source); var gameSettingsAsset = context.GetGameSettingsAsset(); var allow32BitIndex = gameSettingsAsset.DefaultGraphicsProfile >= GraphicsProfile.Level_9_2; var allowUnsignedBlendIndices = context.GetGraphicsPlatform() != GraphicsPlatform.OpenGLES; var extension = asset.Source.GetFileExtension(); if (ImportFbxCommand.IsSupportingExtensions(extension)) { result.BuildSteps = new AssetBuildStep(AssetItem) { new ImportFbxCommand { SourcePath = assetSource, Location = urlInStorage, Allow32BitIndex = allow32BitIndex, AllowUnsignedBlendIndices = allowUnsignedBlendIndices, Compact = asset.Compact, PreservedNodes = asset.PreservedNodes, Materials = asset.Materials, ScaleImport = asset.ScaleImport, }, }; } else if (ImportAssimpCommand.IsSupportingExtensions(extension)) { result.BuildSteps = new AssetBuildStep(AssetItem) { new ImportAssimpCommand { SourcePath = assetSource, Location = urlInStorage, Allow32BitIndex = allow32BitIndex, AllowUnsignedBlendIndices = allowUnsignedBlendIndices, Compact = asset.Compact, PreservedNodes = asset.PreservedNodes, Materials = asset.Materials, ScaleImport = asset.ScaleImport, }, }; } else { result.Error("No importer found for model extension '{0}. The model '{1}' can't be imported.", extension, assetSource); } }
public override string GetFontPath(AssetCompilerResult result = null) { using (var factory = new Factory()) { Font font; using (var fontCollection = factory.GetSystemFontCollection(false)) { int index; if (!fontCollection.FindFamilyName(FontName, out index)) { result?.Error($"Cannot find system font '{FontName}'. Make sure it is installed on this machine."); return(null); } using (var fontFamily = fontCollection.GetFontFamily(index)) { var weight = Style.IsBold() ? FontWeight.Bold : FontWeight.Regular; var style = Style.IsItalic() ? SharpDX.DirectWrite.FontStyle.Italic : SharpDX.DirectWrite.FontStyle.Normal; font = fontFamily.GetFirstMatchingFont(weight, FontStretch.Normal, style); if (font == null) { result?.Error($"Cannot find style '{Style}' for font family {FontName}. Make sure it is installed on this machine."); return(null); } } } var fontFace = new FontFace(font); // get the font path on the hard drive var file = fontFace.GetFiles().First(); var referenceKey = file.GetReferenceKey(); var originalLoader = (FontFileLoaderNative)file.Loader; var loader = originalLoader.QueryInterface <LocalFontFileLoader>(); return(loader.GetFilePath(referenceKey)); } }
private void WriteResult(AssetCompilerResult result, string componentName, string targetUrlInStorage, string entityName, string memberName, MemberRequiredReportType reportType) { var logMsg = $"The component {componentName} on entity [{targetUrlInStorage}:{entityName}] is missing a value on a required field '{memberName}'."; switch (reportType) { case MemberRequiredReportType.Warning: result.Warning(logMsg); break; case MemberRequiredReportType.Error: result.Error(logMsg); break; } }
protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, ModelAsset asset, AssetCompilerResult result) { if (!EnsureSourcesExist(result, asset, assetAbsolutePath)) { return; } // Get absolute path of asset source on disk var assetDirectory = assetAbsolutePath.GetParent(); var assetSource = UPath.Combine(assetDirectory, asset.Source); var gameSettingsAsset = context.GetGameSettingsAsset(); var renderingSettings = gameSettingsAsset.Get <RenderingSettings>(); var allow32BitIndex = renderingSettings.DefaultGraphicsProfile >= GraphicsProfile.Level_9_2; var allowUnsignedBlendIndices = context.GetGraphicsPlatform(AssetItem.Package) != GraphicsPlatform.OpenGLES; var extension = asset.Source.GetFileExtension(); // Find skeleton asset, if any AssetItem skeleton = null; if (asset.Skeleton != null) { skeleton = AssetItem.Package.FindAssetFromAttachedReference(asset.Skeleton); } var importModelCommand = ImportModelCommand.Create(extension); if (importModelCommand == null) { result.Error("No importer found for model extension '{0}. The model '{1}' can't be imported.", extension, assetSource); return; } importModelCommand.Mode = ImportModelCommand.ExportMode.Model; importModelCommand.SourcePath = assetSource; importModelCommand.Location = urlInStorage; importModelCommand.Allow32BitIndex = allow32BitIndex; importModelCommand.AllowUnsignedBlendIndices = allowUnsignedBlendIndices; importModelCommand.Materials = asset.Materials; importModelCommand.ScaleImport = asset.ScaleImport; importModelCommand.PivotPosition = asset.PivotPosition; importModelCommand.SkeletonUrl = skeleton?.Location; result.BuildSteps = new AssetBuildStep(AssetItem) { importModelCommand }; }
protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, TextureAsset asset, AssetCompilerResult result) { if (asset.Source == null) { result.Error("Source cannot be null for Texture Asset [{0}]", asset); return; } // Get absolute path of asset source on disk var assetDirectory = assetAbsolutePath.GetParent(); var assetSource = UPath.Combine(assetDirectory, asset.Source); result.BuildSteps = new ListBuildStep { new TextureConvertCommand(urlInStorage, new TextureConvertParameters(assetSource, asset, context.Platform, context.GetGraphicsPlatform(), context.GetGraphicsProfile(), context.GetTextureQuality(), false)) }; }
protected override void Compile(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (ModelAsset)assetItem.Asset; // Get absolute path of asset source on disk var assetDirectory = assetItem.FullPath.GetParent(); var assetSource = UPath.Combine(assetDirectory, asset.Source); var gameSettingsAsset = context.GetGameSettingsAsset(); var renderingSettings = gameSettingsAsset.Get <RenderingSettings>(); var allow32BitIndex = renderingSettings.DefaultGraphicsProfile >= GraphicsProfile.Level_9_2; var maxInputSlots = renderingSettings.DefaultGraphicsProfile >= GraphicsProfile.Level_10_1 ? 32 : 16; var allowUnsignedBlendIndices = context.GetGraphicsPlatform(assetItem.Package) != GraphicsPlatform.OpenGLES; var extension = asset.Source.GetFileExtension(); // Find skeleton asset, if any AssetItem skeleton = null; if (asset.Skeleton != null) { skeleton = assetItem.Package.FindAssetFromProxyObject(asset.Skeleton); } var importModelCommand = ImportModelCommand.Create(extension); if (importModelCommand == null) { result.Error($"No importer found for model extension '{extension}. The model '{assetSource}' can't be imported."); return; } importModelCommand.Mode = ImportModelCommand.ExportMode.Model; importModelCommand.SourcePath = assetSource; importModelCommand.Location = targetUrlInStorage; importModelCommand.Allow32BitIndex = allow32BitIndex; importModelCommand.MaxInputSlots = maxInputSlots; importModelCommand.AllowUnsignedBlendIndices = allowUnsignedBlendIndices; importModelCommand.Materials = asset.Materials; importModelCommand.ScaleImport = asset.ScaleImport; importModelCommand.PivotPosition = asset.PivotPosition; importModelCommand.SkeletonUrl = skeleton?.Location; result.BuildSteps = new AssetBuildStep(assetItem) { importModelCommand }; }
protected override void CompileThumbnail(ThumbnailCompilerContext context, string thumbnailStorageUrl, AssetItem assetItem, Package originalPackage, AssetCompilerResult result) { UFile fontPathOnDisk = Asset.FontSource.GetFontPath(); bool sourceIsValid = (fontPathOnDisk != null && File.Exists(fontPathOnDisk)); if (sourceIsValid) { result.BuildSteps.Add(new ThumbnailBuildStep(new FontThumbnailBuildCommand(context, thumbnailStorageUrl, assetItem, originalPackage, new ThumbnailCommandParameters(assetItem.Asset, thumbnailStorageUrl, context.ThumbnailResolution)))); } else { var thumbnailSize = context.ThumbnailResolution; var isLinear = context.GetGameSettingsAsset().GetOrCreate <RenderingSettings>().ColorSpace == ColorSpace.Linear; result.Error($"Source is null or unreachable for Texture Asset [{Asset}]"); result.BuildSteps.Add(new StaticThumbnailCommand <SpriteFontAsset>(thumbnailStorageUrl, DefaultThumbnails.AssetBrokenThumbnail, thumbnailSize, isLinear, assetItem.Package)); } }
protected override void Prepare(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (T)assetItem.Asset; foreach (var entityData in asset.Hierarchy.Parts.Values) { // TODO: How to make this code pluggable? var modelComponent = entityData.Entity.Components.Get <ModelComponent>(); if (modelComponent != null) { if (modelComponent.Model == null) { result.Warning($"The entity [{targetUrlInStorage}:{entityData.Entity.Name}] has a model component that does not reference any model."); } else { var modelAttachedReference = AttachedReferenceManager.GetAttachedReference(modelComponent.Model); var modelId = modelAttachedReference.Id; // compute the full path to the source asset. var modelAssetItem = assetItem.Package.Session.FindAsset(modelId); if (modelAssetItem == null) { result.Error($"The entity [{targetUrlInStorage}:{entityData.Entity.Name}] is referencing an unreachable model."); } } } var nodeLinkComponent = entityData.Entity.Components.Get <ModelNodeLinkComponent>(); if (nodeLinkComponent != null) { nodeLinkComponent.ValidityCheck(); if (!nodeLinkComponent.IsValid) { result.Warning($"The Model Node Link between {entityData.Entity.Name} and {nodeLinkComponent.Target?.Entity.Name} is invalid."); nodeLinkComponent.Target = null; } } } result.BuildSteps = new AssetBuildStep(assetItem); result.BuildSteps.Add(Create(targetUrlInStorage, asset, assetItem.Package)); }
/// <inheritdoc/> public void Check(EntityComponent component, Entity entity, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var modelComponent = component as ModelComponent; if (modelComponent.Model == null) { result.Warning($"The entity [{targetUrlInStorage}:{entity.Name}] has a model component that does not reference any model."); } else { var modelAttachedReference = AttachedReferenceManager.GetAttachedReference(modelComponent.Model); var modelId = modelAttachedReference.Id; // compute the full path to the source asset. var modelAssetItem = assetItem.Package.Session.FindAsset(modelId); if (modelAssetItem == null) { result.Error($"The entity [{targetUrlInStorage}:{entity.Name}] is referencing an unreachable model."); } } }
protected override void Compile(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (T)assetItem.Asset; foreach (var entityData in asset.Hierarchy.Parts) { // TODO: How to make this code pluggable? var modelComponent = entityData.Entity.Components.Get <ModelComponent>(); var spriteComponent = entityData.Entity.Components.Get <SpriteComponent>(); // determine the underlying source asset exists if (modelComponent != null) { if (modelComponent.Model == null) { result.Warning($"The entity [{targetUrlInStorage}:{entityData.Entity.Name}] has a model component that does not reference any model."); continue; } var modelAttachedReference = AttachedReferenceManager.GetAttachedReference(modelComponent.Model); var modelId = modelAttachedReference.Id; // compute the full path to the source asset. var modelAssetItem = assetItem.Package.Session.FindAsset(modelId); if (modelAssetItem == null) { result.Error($"The entity [{targetUrlInStorage}:{entityData.Entity.Name}] is referencing an unreachable model."); continue; } } if (spriteComponent != null && spriteComponent.SpriteProvider == null) { result.Warning($"The entity [{targetUrlInStorage}:{entityData.Entity.Name}] has a sprite component that does not reference any sprite group."); } } result.BuildSteps = new AssetBuildStep(assetItem) { Create(targetUrlInStorage, asset) }; }
protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, ModelAsset asset, AssetCompilerResult result) { if (asset.Source == null) { result.Error("Source cannot be null for Texture Asset [{0}]", asset); return; } // Get absolute path of asset source on disk var assetDirectory = assetAbsolutePath.GetParent(); var assetSource = UPath.Combine(assetDirectory, asset.Source); var allow32BitIndex = context.GetGraphicsProfile() >= GraphicsProfile.Level_9_2; var allowUnsignedBlendIndices = context.GetGraphicsPlatform() != GraphicsPlatform.OpenGLES; var extension = asset.Source.GetFileExtension(); // compute material and lighting configuration dictionaries here because some null reference can occur var materials = new Dictionary <string, Tuple <Guid, string> >(); var lightings = new Dictionary <string, Tuple <Guid, string> >(); foreach (var meshParam in asset.MeshParameters) { if (meshParam.Value.Material != null) { materials.Add(meshParam.Key, new Tuple <Guid, string>(meshParam.Value.Material.Id, meshParam.Value.Material.Location)); } // Transform AssetReference to Tuple<Guid,UFile> as AssetReference or ContentReference is not serializable (to generate the command hash) // TODO: temporary while the LightingParameters is a Member of MeshMaterialParameter class // TODO: should be passed directly in the Parameters of the mesh - no extra case is required if (meshParam.Value.LightingParameters != null) { lightings.Add(meshParam.Key, new Tuple <Guid, string>(meshParam.Value.LightingParameters.Id, meshParam.Value.LightingParameters.Location)); } } if (ImportFbxCommand.IsSupportingExtensions(extension)) { result.BuildSteps = new ListBuildStep { new ImportFbxCommand { SourcePath = assetSource, Location = urlInStorage, Allow32BitIndex = allow32BitIndex, AllowUnsignedBlendIndices = allowUnsignedBlendIndices, Compact = asset.Compact, PreservedNodes = asset.PreservedNodes, Materials = materials, Lightings = lightings, // TODO: remove when lighting parameters will be behind a key Parameters = asset.MeshParameters.ToDictionary(pair => pair.Key, pair => pair.Value.Parameters), ViewDirectionForTransparentZSort = asset.ViewDirectionForTransparentZSort.HasValue ? asset.ViewDirectionForTransparentZSort.Value : -Vector3.UnitZ, }, new WaitBuildStep(), }; } else if (ImportAssimpCommand.IsSupportingExtensions(extension)) { result.BuildSteps = new ListBuildStep { new ImportAssimpCommand { SourcePath = assetSource, Location = urlInStorage, Allow32BitIndex = allow32BitIndex, AllowUnsignedBlendIndices = allowUnsignedBlendIndices, Compact = asset.Compact, PreservedNodes = asset.PreservedNodes, Materials = materials, Lightings = lightings, // TODO: remove when lighting parameters will be behind a key Parameters = asset.MeshParameters.ToDictionary(pair => pair.Key, pair => pair.Value.Parameters), }, new WaitBuildStep(), }; } else { result.Error("No importer found for model extension '{0}. The model '{1}' can't be imported.", extension, assetSource); } }
protected override void Prepare(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (AnimationAsset)assetItem.Asset; var assetAbsolutePath = assetItem.FullPath; // Get absolute path of asset source on disk var assetDirectory = assetAbsolutePath.GetParent(); var assetSource = GetAbsolutePath(assetItem, 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.FindAssetFromProxyObject(asset.Skeleton); } var sourceBuildCommand = ImportModelCommand.Create(extension); if (sourceBuildCommand == null) { result.Error($"No importer found for model extension '{extension}. The model '{assetSource}' can't be imported."); return; } sourceBuildCommand.Mode = ImportModelCommand.ExportMode.Animation; sourceBuildCommand.SourcePath = assetSource; sourceBuildCommand.Location = targetUrlInStorage; sourceBuildCommand.AnimationRepeatMode = asset.RepeatMode; sourceBuildCommand.AnimationRootMotion = asset.RootMotion; sourceBuildCommand.ImportCustomAttributes = asset.ImportCustomAttributes; if (asset.ClipDuration.Enabled) { sourceBuildCommand.StartFrame = asset.ClipDuration.StartAnimationTime; sourceBuildCommand.EndFrame = asset.ClipDuration.EndAnimationTime; } else { sourceBuildCommand.StartFrame = TimeSpan.Zero; sourceBuildCommand.EndFrame = AnimationAsset.LongestTimeSpan; } sourceBuildCommand.ScaleImport = asset.ScaleImport; sourceBuildCommand.PivotPosition = asset.PivotPosition; if (skeleton != null) { sourceBuildCommand.SkeletonUrl = skeleton.Location; // Note: skeleton override values sourceBuildCommand.ScaleImport = ((SkeletonAsset)skeleton.Asset).ScaleImport; sourceBuildCommand.PivotPosition = ((SkeletonAsset)skeleton.Asset).PivotPosition; } if (asset.Type.Type == AnimationAssetTypeEnum.AnimationClip) { // Import the main animation buildStep.Add(sourceBuildCommand); } else if (asset.Type.Type == AnimationAssetTypeEnum.DifferenceClip) { var diffAnimationAsset = ((DifferenceAnimationAssetType)asset.Type); var referenceClip = diffAnimationAsset.BaseSource; var rebaseMode = diffAnimationAsset.Mode; var baseUrlInStorage = targetUrlInStorage + RefClipSuffix; var sourceUrlInStorage = targetUrlInStorage + SrcClipSuffix; var baseAssetSource = UPath.Combine(assetDirectory, referenceClip); var baseExtension = baseAssetSource.GetFileExtension(); sourceBuildCommand.Location = sourceUrlInStorage; var baseBuildCommand = ImportModelCommand.Create(extension); if (baseBuildCommand == null) { result.Error($"No importer found for model extension '{baseExtension}. The model '{baseAssetSource}' can't be imported."); return; } baseBuildCommand.FailOnEmptyAnimation = false; baseBuildCommand.Mode = ImportModelCommand.ExportMode.Animation; baseBuildCommand.SourcePath = baseAssetSource; baseBuildCommand.Location = baseUrlInStorage; baseBuildCommand.AnimationRepeatMode = asset.RepeatMode; baseBuildCommand.AnimationRootMotion = asset.RootMotion; if (diffAnimationAsset.ClipDuration.Enabled) { baseBuildCommand.StartFrame = diffAnimationAsset.ClipDuration.StartAnimationTimeBox; baseBuildCommand.EndFrame = diffAnimationAsset.ClipDuration.EndAnimationTimeBox; } else { baseBuildCommand.StartFrame = TimeSpan.Zero; baseBuildCommand.EndFrame = AnimationAsset.LongestTimeSpan; } baseBuildCommand.ScaleImport = asset.ScaleImport; baseBuildCommand.PivotPosition = asset.PivotPosition; if (skeleton != null) { baseBuildCommand.SkeletonUrl = skeleton.Location; // Note: skeleton override values baseBuildCommand.ScaleImport = ((SkeletonAsset)skeleton.Asset).ScaleImport; baseBuildCommand.PivotPosition = ((SkeletonAsset)skeleton.Asset).PivotPosition; } // Import base and main animation var sourceStep = new CommandBuildStep(sourceBuildCommand); buildStep.Add(sourceStep); var baseStep = new CommandBuildStep(baseBuildCommand); buildStep.Add(baseStep); IEnumerable <ObjectUrl> InputFilesGetter() { yield return(new ObjectUrl(UrlType.File, GetAbsolutePath(assetItem, diffAnimationAsset.BaseSource))); } var diffCommand = new AdditiveAnimationCommand(targetUrlInStorage, new AdditiveAnimationParameters(baseUrlInStorage, sourceUrlInStorage, rebaseMode), assetItem.Package) { InputFilesGetter = InputFilesGetter }; var diffStep = new CommandBuildStep(diffCommand); BuildStep.LinkBuildSteps(sourceStep, diffStep); BuildStep.LinkBuildSteps(baseStep, diffStep); // Generate the diff of those two animations buildStep.Add(diffStep); } else { throw new NotImplementedException("This type of animation asset is not supported yet!"); } result.BuildSteps = buildStep; }
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; }
public AssetCompilerResult Prepare(AssetCompilerContext context, AssetItem assetItem) { var compilerResult = new AssetCompilerResult(); Asset = (T)assetItem.Asset; var thumbnailCompilerContext = (ThumbnailCompilerContext)context; // Build the path of the thumbnail in the storage var thumbnailStorageUrl = BuildThumbnailStoreName(assetItem.Location); // Check if this asset produced any error // (dependent assets errors are generally ignored as long as thumbnail could be generated, // but we will add a thumbnail overlay to indicate the state is not good) var currentAssetHasErrors = false; try { CompileThumbnail(thumbnailCompilerContext, thumbnailStorageUrl, assetItem, assetItem.Package, compilerResult); } catch (Exception) { // If an exception occurs, ensure that the build of thumbnail will fail. compilerResult.Error($"An exception occurred while compiling the asset [{assetItem.Location}]"); } foreach (var logMessage in compilerResult.Messages) { // Ignore anything less than error if (!logMessage.IsAtLeast(LogMessageType.Error)) { continue; } // Check if there is any non-asset log message // (they are probably just emitted by current compiler, so they concern current asset) // TODO: Maybe we should wrap every message in AssetLogMessage before copying them in compilerResult? var assetLogMessage = logMessage as AssetLogMessage; if (assetLogMessage == null) { currentAssetHasErrors = true; break; } // If it was an asset log message, check it concerns current asset if (assetLogMessage.AssetReference != null && assetLogMessage.AssetReference.Location == assetItem.Location) { currentAssetHasErrors = true; break; } } if (currentAssetHasErrors) { // if a problem occurs while compiling, we add a special build step that will always fail. compilerResult.BuildSteps.Add(new ThumbnailFailureBuildStep(compilerResult.Messages)); } var currentAsset = assetItem; // copy the current asset item and embrace it in the callback compilerResult.BuildSteps.StepProcessed += (_, buildStepArgs) => OnThumbnailStepProcessed(thumbnailCompilerContext, currentAsset, thumbnailStorageUrl, buildStepArgs); return(compilerResult); }
protected override void Compile(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (AnimationAsset)assetItem.Asset; var assetAbsolutePath = assetItem.FullPath; // Get absolute path of asset source on disk var assetDirectory = assetAbsolutePath.GetParent(); var assetSource = GetAbsolutePath(assetItem, 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.FindAssetFromProxyObject(asset.Skeleton); } var sourceBuildStep = ImportModelCommand.Create(extension); if (sourceBuildStep == null) { result.Error($"No importer found for model extension '{extension}. The model '{assetSource}' can't be imported."); return; } sourceBuildStep.Mode = ImportModelCommand.ExportMode.Animation; sourceBuildStep.SourcePath = assetSource; sourceBuildStep.Location = targetUrlInStorage; sourceBuildStep.AnimationRepeatMode = asset.RepeatMode; sourceBuildStep.AnimationRootMotion = asset.RootMotion; if (asset.ClipDuration.Enabled) { sourceBuildStep.StartFrame = asset.ClipDuration.StartAnimationTime; sourceBuildStep.EndFrame = asset.ClipDuration.EndAnimationTime; } else { sourceBuildStep.StartFrame = TimeSpan.Zero; sourceBuildStep.EndFrame = AnimationAsset.LongestTimeSpan; } sourceBuildStep.ScaleImport = asset.ScaleImport; sourceBuildStep.PivotPosition = asset.PivotPosition; sourceBuildStep.SkeletonUrl = skeleton?.Location; if (asset.Type.Type == AnimationAssetTypeEnum.AnimationClip) { // Import the main animation buildStep.Add(sourceBuildStep); } else if (asset.Type.Type == AnimationAssetTypeEnum.DifferenceClip) { var diffAnimationAsset = ((DifferenceAnimationAssetType)asset.Type); var referenceClip = diffAnimationAsset.BaseSource; var rebaseMode = diffAnimationAsset.Mode; var baseUrlInStorage = targetUrlInStorage + RefClipSuffix; var sourceUrlInStorage = targetUrlInStorage + SrcClipSuffix; var baseAssetSource = UPath.Combine(assetDirectory, referenceClip); var baseExtension = baseAssetSource.GetFileExtension(); sourceBuildStep.Location = sourceUrlInStorage; var baseBuildStep = ImportModelCommand.Create(extension); if (baseBuildStep == null) { result.Error($"No importer found for model extension '{baseExtension}. The model '{baseAssetSource}' can't be imported."); return; } baseBuildStep.Mode = ImportModelCommand.ExportMode.Animation; baseBuildStep.SourcePath = baseAssetSource; baseBuildStep.Location = baseUrlInStorage; baseBuildStep.AnimationRepeatMode = asset.RepeatMode; baseBuildStep.AnimationRootMotion = asset.RootMotion; if (diffAnimationAsset.ClipDuration.Enabled) { baseBuildStep.StartFrame = diffAnimationAsset.ClipDuration.StartAnimationTimeBox; baseBuildStep.EndFrame = diffAnimationAsset.ClipDuration.EndAnimationTimeBox; } else { baseBuildStep.StartFrame = TimeSpan.Zero; baseBuildStep.EndFrame = AnimationAsset.LongestTimeSpan; } baseBuildStep.ScaleImport = asset.ScaleImport; baseBuildStep.PivotPosition = asset.PivotPosition; 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(targetUrlInStorage, new AdditiveAnimationParameters(baseUrlInStorage, sourceUrlInStorage, rebaseMode))); } else { throw new NotImplementedException("This type of animation asset is not supported yet!"); } result.BuildSteps = buildStep; }