123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- /******************************************************************************
- * 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 System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using Spine;
- using Spine.Unity;
- namespace Spine.Unity {
- [CreateAssetMenu(menuName = "Spine/SkeletonData Modifiers/Blend Mode Materials", order = 200)]
- public class BlendModeMaterialsAsset : SkeletonDataModifierAsset {
- public Material multiplyMaterialTemplate;
- public Material screenMaterialTemplate;
- public Material additiveMaterialTemplate;
- public bool applyAdditiveMaterial = true;
- public override void Apply (SkeletonData skeletonData) {
- ApplyMaterials(skeletonData, multiplyMaterialTemplate, screenMaterialTemplate, additiveMaterialTemplate, applyAdditiveMaterial);
- }
- public static void ApplyMaterials (SkeletonData skeletonData, Material multiplyTemplate, Material screenTemplate, Material additiveTemplate, bool includeAdditiveSlots) {
- if (skeletonData == null) throw new ArgumentNullException("skeletonData");
- using (var materialCache = new AtlasMaterialCache()) {
- var entryBuffer = new List<Skin.SkinEntry>();
- var slotsItems = skeletonData.Slots.Items;
- for (int slotIndex = 0, slotCount = skeletonData.Slots.Count; slotIndex < slotCount; slotIndex++) {
- var slot = slotsItems[slotIndex];
- if (slot.blendMode == BlendMode.Normal) continue;
- if (!includeAdditiveSlots && slot.blendMode == BlendMode.Additive) continue;
- entryBuffer.Clear();
- foreach (var skin in skeletonData.Skins)
- skin.GetAttachments(slotIndex, entryBuffer);
- Material templateMaterial = null;
- switch (slot.blendMode) {
- case BlendMode.Multiply:
- templateMaterial = multiplyTemplate;
- break;
- case BlendMode.Screen:
- templateMaterial = screenTemplate;
- break;
- case BlendMode.Additive:
- templateMaterial = additiveTemplate;
- break;
- }
- if (templateMaterial == null) continue;
- foreach (var entry in entryBuffer) {
- var renderableAttachment = entry.Attachment as IHasRendererObject;
- if (renderableAttachment != null) {
- renderableAttachment.RendererObject = materialCache.CloneAtlasRegionWithMaterial((AtlasRegion)renderableAttachment.RendererObject, templateMaterial);
- }
- }
- }
- }
- //attachmentBuffer.Clear();
- }
- class AtlasMaterialCache : IDisposable {
- readonly Dictionary<KeyValuePair<AtlasPage, Material>, AtlasPage> cache = new Dictionary<KeyValuePair<AtlasPage, Material>, AtlasPage>();
- /// <summary>Creates a clone of an AtlasRegion that uses different Material settings, while retaining the original texture.</summary>
- public AtlasRegion CloneAtlasRegionWithMaterial (AtlasRegion originalRegion, Material materialTemplate) {
- var newRegion = originalRegion.Clone();
- newRegion.page = GetAtlasPageWithMaterial(originalRegion.page, materialTemplate);
- return newRegion;
- }
- AtlasPage GetAtlasPageWithMaterial (AtlasPage originalPage, Material materialTemplate) {
- if (originalPage == null) throw new ArgumentNullException("originalPage");
- AtlasPage newPage = null;
- var key = new KeyValuePair<AtlasPage, Material>(originalPage, materialTemplate);
- cache.TryGetValue(key, out newPage);
- if (newPage == null) {
- newPage = originalPage.Clone();
- var originalMaterial = originalPage.rendererObject as Material;
- newPage.rendererObject = new Material(materialTemplate) {
- name = originalMaterial.name + " " + materialTemplate.name,
- mainTexture = originalMaterial.mainTexture
- };
- cache.Add(key, newPage);
- }
- return newPage;
- }
- public void Dispose () {
- cache.Clear();
- }
- }
- }
- }
|