/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
namespace Spine.Unity.AttachmentTools {
public static class AttachmentCloneExtensions {
///
/// Clones the attachment.
public static Attachment GetCopy (this Attachment o, bool cloneMeshesAsLinked) {
var meshAttachment = o as MeshAttachment;
if (meshAttachment != null && cloneMeshesAsLinked)
return meshAttachment.NewLinkedMesh();
return o.Copy();
}
#region Runtime Linked MeshAttachments
///
/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to the AtlasRegion provided.
public static MeshAttachment GetLinkedMesh (this MeshAttachment o, string newLinkedMeshName, AtlasRegion region) {
if (region == null) throw new System.ArgumentNullException("region");
MeshAttachment mesh = o.NewLinkedMesh();
mesh.SetRegion(region, false);
return mesh;
}
///
/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader.
/// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool)
public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Shader shader, Material materialPropertySource = null) {
var m = new Material(shader);
if (materialPropertySource != null) {
m.CopyPropertiesFromMaterial(materialPropertySource);
m.shaderKeywords = materialPropertySource.shaderKeywords;
}
return o.GetLinkedMesh(sprite.name, sprite.ToAtlasRegion());
}
///
/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader.
/// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool)
public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Material materialPropertySource) {
return o.GetLinkedMesh(sprite, materialPropertySource.shader, materialPropertySource);
}
#endregion
#region RemappedClone Convenience Methods
///
/// Gets a clone of the attachment remapped with a sprite image.
/// The remapped clone.
/// The original attachment.
/// The sprite whose texture to use.
/// The source material used to copy the shader and material properties from.
/// If true, a premultiply alpha clone of the original texture will be created.
/// See remarks below for additional info.
/// If true MeshAttachments will be cloned as linked meshes and will inherit animation from the original attachment.
/// If true the size of the original attachment will be followed, instead of using the Sprite size.
/// If true and the original Attachment is a MeshAttachment, then
/// a non-central sprite pivot will shift uv coords in the opposite direction. Vertices will not be offset in
/// any case when the original Attachment is a MeshAttachment.
/// If true and the original Attachment is a RegionAttachment, then
/// the original region's scale value is used instead of the Sprite's pixels per unit property. Since uniform scale is used,
/// x scale of the original attachment (width scale) is used, scale in y direction (height scale) is ignored.
/// When parameter premultiplyAlpha is set to true, a premultiply alpha clone of the
/// original texture will be created. Additionally, this PMA Texture clone is cached for later re-use,
/// which might steadily increase the Texture memory footprint when used excessively.
/// See on how to clear these cached textures.
public static Attachment GetRemappedClone (this Attachment o, Sprite sprite, Material sourceMaterial,
bool premultiplyAlpha = true, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false,
bool pivotShiftsMeshUVCoords = true, bool useOriginalRegionScale = false) {
var atlasRegion = premultiplyAlpha ? sprite.ToAtlasRegionPMAClone(sourceMaterial) : sprite.ToAtlasRegion(new Material(sourceMaterial) { mainTexture = sprite.texture } );
if (!pivotShiftsMeshUVCoords && o is MeshAttachment) {
// prevent non-central sprite pivot setting offsetX/Y and shifting uv coords out of mesh bounds
atlasRegion.offsetX = 0;
atlasRegion.offsetY = 0;
}
float scale = 1f / sprite.pixelsPerUnit;
if (useOriginalRegionScale) {
var regionAttachment = o as RegionAttachment;
if (regionAttachment != null)
scale = regionAttachment.width / regionAttachment.regionOriginalWidth;
}
return o.GetRemappedClone(atlasRegion, cloneMeshAsLinked, useOriginalRegionSize, scale);
}
///
/// Gets a clone of the attachment remapped with an atlasRegion image.
/// The remapped clone.
/// The original attachment.
/// Atlas region.
/// If true MeshAttachments will be cloned as linked meshes and will inherit animation from the original attachment.
/// If true the size of the original attachment will be followed, instead of using the Sprite size.
/// Unity units per pixel scale used to scale the atlas region size when not using the original region size.
public static Attachment GetRemappedClone (this Attachment o, AtlasRegion atlasRegion, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false, float scale = 0.01f) {
var regionAttachment = o as RegionAttachment;
if (regionAttachment != null) {
RegionAttachment newAttachment = (RegionAttachment)regionAttachment.Copy();
newAttachment.SetRegion(atlasRegion, false);
if (!useOriginalRegionSize) {
newAttachment.width = atlasRegion.width * scale;
newAttachment.height = atlasRegion.height * scale;
}
newAttachment.UpdateOffset();
return newAttachment;
} else {
var meshAttachment = o as MeshAttachment;
if (meshAttachment != null) {
MeshAttachment newAttachment = cloneMeshAsLinked ? meshAttachment.NewLinkedMesh() : (MeshAttachment)meshAttachment.Copy();
newAttachment.SetRegion(atlasRegion);
return newAttachment;
}
}
return o.GetCopy(true); // Non-renderable Attachments will return as normal cloned attachments.
}
#endregion
}
}