Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ImageGroupCompiler.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 using System.Threading.Tasks;
6 
7 using SiliconStudio.Assets.Compiler;
8 using SiliconStudio.BuildEngine;
9 using SiliconStudio.Core;
10 using SiliconStudio.Core.Diagnostics;
11 using SiliconStudio.Core.IO;
12 using SiliconStudio.Core.Serialization;
13 using SiliconStudio.Core.Serialization.Assets;
14 using SiliconStudio.Paradox.Assets.Materials;
15 using SiliconStudio.Paradox.Assets.Texture;
16 using SiliconStudio.Paradox.Graphics;
17 using SiliconStudio.Paradox.Graphics.Data;
18 
19 namespace SiliconStudio.Paradox.Assets
20 {
21  /// <summary>
22  /// Texture asset compiler.
23  /// </summary>
24  internal class ImageGroupCompiler<TGroupAsset, TImageInfo> :
25  AssetCompilerBase<TGroupAsset>
26  where TGroupAsset : ImageGroupAsset<TImageInfo>
27  where TImageInfo: ImageInfo
28  {
29  protected bool SeparateAlphaTexture;
30 
31  protected Dictionary<TImageInfo, int> SpriteToTextureIndex;
32 
33  private bool TextureFileIsValid(UFile file)
34  {
35  return file != null && File.Exists(file);
36  }
37 
38  protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, TGroupAsset asset, AssetCompilerResult result)
39  {
40  result.BuildSteps = new ListBuildStep();
41 
42  // Evaluate if we need to use a separate the alpha texture
43  SeparateAlphaTexture = context.Platform == PlatformType.Android && asset.Alpha != AlphaFormat.None && asset.Format == TextureFormat.Compressed;
44 
45  // create the registry containing the sprite assets texture index association
46  SpriteToTextureIndex = new Dictionary<TImageInfo, int>();
47 
48  // create and add import texture commands
49  if (asset.Images != null)
50  {
51  // return compilation error if one or more of the sprite does not have a valid texture
52  var noSourceAsset = asset.Images.FirstOrDefault(x => !TextureFileIsValid(x.Source));
53  if (noSourceAsset != null)
54  {
55  result.Error("The texture of image '{0}' either does not exist or is invalid", noSourceAsset.Name);
56  return;
57  }
58 
59  // sort sprites by referenced texture.
60  var spriteByTextures = asset.Images.GroupBy(x => x.Source).ToArray();
61  for (int i = 0; i < spriteByTextures.Length; i++)
62  {
63  var spriteAssetArray = spriteByTextures[i].ToArray();
64  foreach (var spriteAsset in spriteAssetArray)
65  SpriteToTextureIndex[spriteAsset] = i;
66 
67  // create an texture asset.
68  var textureAsset = new TextureAsset
69  {
70  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)
71  Alpha = asset.Alpha,
72  Format = asset.Format,
73  GenerateMipmaps = asset.GenerateMipmaps,
75  ColorKeyColor = asset.ColorKeyColor,
76  ColorKeyEnabled = asset.ColorKeyEnabled,
77  };
78 
79  // Get absolute path of asset source on disk
80  var assetDirectory = assetAbsolutePath.GetParent();
81  var assetSource = UPath.Combine(assetDirectory, spriteAssetArray[0].Source);
82 
83  // add the texture build command.
84  result.BuildSteps.Add(
85  new TextureAssetCompiler.TextureConvertCommand(
86  ImageGroupAsset.BuildTextureUrl(urlInStorage, i),
87  new TextureConvertParameters(assetSource, textureAsset, context.Platform, context.GetGraphicsPlatform(), context.GetGraphicsProfile(), context.GetTextureQuality(), SeparateAlphaTexture)));
88  }
89 
90  result.BuildSteps.Add(new WaitBuildStep()); // wait the textures to be imported
91  }
92  }
93  }
94 
95  /// <summary>
96  /// Command used to convert the texture in the storage
97  /// </summary>
98  public class ImageGroupCommand<TGroupAsset, TImageInfo, TImageGroupData, TImageData> : AssetCommand<ImageGroupParameters<TGroupAsset>>
99  where TGroupAsset : ImageGroupAsset<TImageInfo>
100  where TImageInfo : ImageInfo
101  where TImageGroupData : ImageGroupData<TImageData>, new()
102  where TImageData : ImageFragmentData, new()
103  {
104  protected readonly bool UseSeparateAlphaTexture;
105 
106  protected readonly Dictionary<TImageInfo, int> ImageToTextureIndex;
107 
108  protected ImageGroupCommand(string url, ImageGroupParameters<TGroupAsset> asset, Dictionary<TImageInfo, int> imageToTextureIndex, bool useSeparateAlphaTexture)
109  : base(url, asset)
110  {
111  ImageToTextureIndex = imageToTextureIndex;
112  UseSeparateAlphaTexture = useSeparateAlphaTexture;
113  }
114 
116  {
117  for (int i = 0; i < ImageToTextureIndex.Values.Distinct().Count(); i++)
118  {
119  if (UseSeparateAlphaTexture)
120  {
121  var textureUrl = ImageGroupAsset.BuildTextureUrl(Url, i);
122  yield return new ObjectUrl(UrlType.Internal, TextureAlphaComponentSplitter.GenerateColorTextureURL(textureUrl));
123  yield return new ObjectUrl(UrlType.Internal, TextureAlphaComponentSplitter.GenerateAlphaTextureURL(textureUrl));
124  }
125  else
126  {
127  yield return new ObjectUrl(UrlType.Internal, ImageGroupAsset.BuildTextureUrl(Url, i));
128  }
129  }
130  }
131  protected override Task<ResultStatus> DoCommandOverride(ICommandContext commandContext)
132  {
133  var assetManager = new AssetManager();
134 
135  var imageGroupData = new TImageGroupData { Images = new List<TImageData>() };
136 
137  // add the sprite data to the sprite list.
138  foreach (var uiImage in asset.GroupAsset.Images)
139  {
140  var newImage = new TImageData
141  {
142  Name = uiImage.Name,
143  Region = uiImage.TextureRegion,
144  IsTransparent = asset.GroupAsset.Alpha != AlphaFormat.None, // todo analyze texture region texture data to auto-determine alpha?
146  };
147 
148  if (UseSeparateAlphaTexture)
149  {
150  var baseLocation = ImageGroupAsset.BuildTextureUrl(Url, ImageToTextureIndex[uiImage]);
151  newImage.Texture = new ContentReference<Texture2D> { Location = TextureAlphaComponentSplitter.GenerateColorTextureURL(baseLocation) };
152  newImage.TextureAlpha = new ContentReference<Texture2D> { Location = TextureAlphaComponentSplitter.GenerateAlphaTextureURL(baseLocation) };
153  }
154  else
155  {
156  newImage.Texture = new ContentReference<Texture2D> { Location = ImageGroupAsset.BuildTextureUrl(Url, ImageToTextureIndex[uiImage]) };
157  }
158 
159  SetImageSpecificFields(uiImage, newImage);
160 
161  imageGroupData.Images.Add(newImage);
162  }
163 
164  // save the imageData into the data base
165  assetManager.Save(Url, imageGroupData);
166 
167  return Task.FromResult(ResultStatus.Successful);
168  }
169 
170  protected virtual void SetImageSpecificFields(TImageInfo imageInfo, TImageData newImage)
171  {
172  }
173  }
174 
175  /// <summary>
176  /// Parameters used for converting/processing the texture in the storage.
177  /// </summary>
178  [DataContract]
179  public class ImageGroupParameters<T>
180  {
182  {
183  }
184 
185  public ImageGroupParameters(T groupAsset, PlatformType platform)
186  {
187  GroupAsset = groupAsset;
188  Platform = platform;
189  }
190 
191  public T GroupAsset;
192 
194  }
195 }
PlatformType Platform
Gets or sets the target platform for compiler is being used for.
Result of a compilation of assets when using IAssetCompiler.Compile
PlatformType
Describes the platform operating system.
Definition: PlatformType.cs:9
Utility class to split this material texture containing alpha into two texture materials: one contain...
static string BuildTextureUrl(UFile textureAbsolutePath, int spriteIndex)
A command processing an Asset.
Definition: AssetCommand.cs:11
The context used when compiling an asset in a Package.
When embedded in a EnumerableBuildStep, this build step will force all previous computations to be fi...
ImageGroupCommand(string url, ImageGroupParameters< TGroupAsset > asset, Dictionary< TImageInfo, int > imageToTextureIndex, bool useSeparateAlphaTexture)
Allow data to be stored in the alpha component.
Parameters used for converting/processing the texture in the storage.
Platform specific queries and functions.
Definition: Platform.cs:15
Describes various information about an image.
Definition: ImageInfo.cs:14
Data type for SiliconStudio.Paradox.Graphics.ImageFragment.
Definition: GraphicsData.cs:41
Android.Widget.Orientation Orientation
Definition: Section.cs:9
ImageGroupParameters(T groupAsset, PlatformType platform)
HRESULT PremultiplyAlpha(_In_ const Image &srcImage, _In_ DWORD flags, _Out_ ScratchImage &image)
Defines a normalized file path. See UPath for details. This class cannot be inherited.
Definition: UFile.cs:13
Describes an image group asset.