/// <summary> /// Converts a materials <see cref="Material.mainTexture"/> property into a <see cref="GenericImage{T}"/> type takes into account the /// materials <see cref="Material.mainTextureOffset"/> and <see cref="Material.mainTextureScale"/> properties. See remarks. /// </summary> /// <param name="material">The source material to get the <see cref="Material.mainTexture"/> reference from.</param> /// <returns>Returns a <see cref="GenericImage{T}"/> type representing the materials texture co-ordinates.</returns> /// <remarks>This method does not return the original texture specified by the <see cref="Material.mainTexture"/> property but rather /// takes into account the materials <see cref="Material.mainTextureOffset"/> and <see cref="Material.mainTextureScale"/> properties /// in order to generate a <see cref="GenericImage{T}"/> type.</remarks> /// <exception cref="InvalidCastException">If <see cref="Material.mainTexture"/> cannot be cast to a <see cref="Texture2D"/> type.</exception> /// <exception cref="ArgumentNullException">If the <see cref="material"/> parameter is null.</exception> public static GenericImage<Color> ToGenericImage(this Material material) { // ensure material specified if (material == null) { throw new ArgumentNullException("material"); } // if no main texture then also return null if (material.mainTexture == null) { return null; } var texture = material.mainTexture as Texture2D; // ensure material texture is a Texture2D type if (texture == null) { throw new InvalidCastException("Material texture is not a Texture2D!"); } // create a generic image. var image = texture.CreateGenericImage(); var data = image.ToUnityColor32Array(); var tempImage = new GenericImage<Color>(image.Width, image.Height); tempImage.SetPixels(Array.ConvertAll(data, input => new Color(input.r, input.g, input.b, input.a))); var offset = material.mainTextureOffset; var position = new Point( (int)((offset.x * texture.width) % texture.width), (int)(texture.height - ((offset.y * texture.height) % texture.height))); var scale = material.mainTextureScale; var size = new Size((int)(scale.x * texture.width), (int)(scale.y * texture.height)); var subImage = new GenericImage<Color>(size.Width, size.Height); subImage.Draw(tempImage, 0, 0, position.X, position.Y - size.Height, size.Width, size.Height, (source, blendWith) => blendWith); // convert and return a generic image return subImage; }
/// <summary> /// Initializes static members of the <see cref="Size"/> struct. /// </summary> static Size() { Empty = new Size(); }
/// <summary> /// Subtracts the width and height of one <see cref="Size"/> structure from the width and height of another <see cref="Size"/> structure. /// </summary> /// <returns> /// A <see cref="Size"/> structure that is a result of the subtraction operation. /// </returns> /// <param name="a"> /// The <see cref="Size"/> structure on the left side of the subtraction operator. /// </param> /// <param name="b"> /// The <see cref="Size"/> structure on the right side of the subtraction operator. /// </param> public static Size Subtract(Size a, Size b) { return new Size(a.Width - b.Width, a.Height - b.Height); }
/// <summary> /// Adds the width and height of one <see cref="Size"/> structure to the width and height of another <see cref="Size"/> structure. /// </summary> /// <returns> /// A <see cref="Size"/> structure that is the result of the addition operation. /// </returns> /// <param name="a"> /// The first <see cref="Size"/> structure to add. /// </param> /// <param name="b"> /// The second <see cref="Size"/> structure to add. /// </param> public static Size Add(Size a, Size b) { return new Size(a.Width + b.Width, a.Height + b.Height); }
/// <summary> /// Handles the event for tile selection. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">An System.EventArgs that contains no event data.</param> private void MainPreviewTileSelection(object sender, TileSelectionEventArgs e) { // do nothing until selection has completed or if no texture selected if (e.Status != TileSelectionStatus.Complete || this.materialControls.TextureAsset == null) { return; } // check if already has entry for a texture // var textureId = this.materialControls.TextureAsset.GetInstanceID(); var textureId = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetOrScenePath(this.materialControls.TextureAsset)); if (!this.tileMaterials.ContainsKey(textureId)) { // no entry so add one this.tileMaterials.Add(textureId, new List<TileSelectionModel>()); // generate a generic image for the texture so it can be used for previews this.images.Add(textureId, this.materialControls.TextureAsset.CreateGenericImage()); } // get entry list var list = this.tileMaterials[textureId]; // get tile size, shader name & color var size = new Size(this.mainPreview.TileWidth, this.mainPreview.TileHeight); var shaderName = this.materialControls.SelectedShaderName; var color = this.materialControls.MaterialColor; var settings = SettingsManager.Instance; var shaderListStyle = settings.GetSetting(GlobalConstants.AutoMaterialCreationShaderListStyleKey, 0); // check for matching top/left bottom/right, size, shader name & color values var result = list.FirstOrDefault(x => e.Min == x.Min && e.Max == x.Max && size == x.TileSize && shaderName == x.ShaderName && color == x.Color); var local = Localization.LocalizationManager.Instance; if (result == null) { // attempt to create a a new material var model = new TileSelectionModel(); try { shaderName = shaderListStyle == 1 ? shaderName.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) : shaderName; var shader = Shader.Find(shaderName); model.Material = new Material(shader); } catch (Exception ex) { // report error EditorUtility.DisplayDialog(local.Get("Warning"), ex.Message, local.Get("Close")); return; } // get texture co-ordinates for the material var textureCoordinates = this.mainPreview.GetTextureCoordinates(this.materialControls, 0); model.Material.mainTextureOffset = new Vector2(textureCoordinates.xMin, textureCoordinates.yMin); model.Material.mainTextureScale = new Vector2(textureCoordinates.width, textureCoordinates.height); model.Material.mainTexture = this.materialControls.TextureAsset; model.Material.color = color; model.Min = e.Min; model.Max = e.Max; model.IsDirty = true; model.TileSize = size; model.ShaderName = shaderName; // set model preview texture var image = model.Material.ToGenericImage(); image.Tint(color, TintType.Alpha); model.TexturePreview = image.ToTexture2D(); list.Add(model); result = model; // save material selections to settings to keep a record of selections this.SaveToSettings(result); } // set current material GridMappingService.Instance.CurrentMaterial = result.Material; #if DEBUG Debug.Log(string.Format("{0} textures {1} unique", this.tileMaterials.Count, this.tileMaterials.Sum(x => x.Value.Count))); #endif }