mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-11 09:38:44 +08:00
Merge branch '3.8' into 4.0-beta
This commit is contained in:
commit
bf4df3b5f3
@ -375,6 +375,7 @@
|
||||
* Now providing `BeforeApply` update callbacks at all skeleton animation components (`SkeletonAnimation`, `SkeletonMecanim` and `SkeletonGraphic`).
|
||||
* Added `BoundingBoxFollowerGraphic` component. This class is a counterpart of `BoundingBoxFollower` that can be used with `SkeletonGraphic`.
|
||||
* Added Inspector context menu functions `SkeletonRenderer - Add all BoundingBoxFollower GameObjects` and `SkeletonGraphic - Add all BoundingBoxFollowerGraphic GameObjects` that automatically generate bounding box follower GameObjects for every `BoundingBoxAttachment` for all skins of a skeleton.
|
||||
* `GetRemappedClone()` now provides an additional parameter `pivotShiftsMeshUVCoords` for `MeshAttachment` to prevent uv shifts at a non-central Sprite pivot. This parameter defaults to `true` to maintain previous behaviour.
|
||||
|
||||
* **Changes of default values**
|
||||
* `SkeletonMecanim`'s `Layer Mix Mode` now defaults to `MixMode.MixNext` instead of `MixMode.MixAlways`.
|
||||
|
||||
@ -94,13 +94,13 @@ namespace Spine.Unity.Examples {
|
||||
// Let's do this for the visor.
|
||||
int visorSlotIndex = skeleton.FindSlotIndex(visorSlot); // You can access GetAttachment and SetAttachment via string, but caching the slotIndex is faster.
|
||||
Attachment templateAttachment = templateSkin.GetAttachment(visorSlotIndex, visorKey); // STEP 1.1
|
||||
Attachment newAttachment = templateAttachment.GetRemappedClone(visorSprite, sourceMaterial); // STEP 1.2 - 1.3
|
||||
Attachment newAttachment = templateAttachment.GetRemappedClone(visorSprite, sourceMaterial, pivotShiftsMeshUVCoords : false); // STEP 1.2 - 1.3
|
||||
customSkin.SetAttachment(visorSlotIndex, visorKey, newAttachment); // STEP 1.4
|
||||
|
||||
// And now for the gun.
|
||||
int gunSlotIndex = skeleton.FindSlotIndex(gunSlot);
|
||||
Attachment templateGun = templateSkin.GetAttachment(gunSlotIndex, gunKey); // STEP 1.1
|
||||
Attachment newGun = templateGun.GetRemappedClone(gunSprite, sourceMaterial); // STEP 1.2 - 1.3
|
||||
Attachment newGun = templateGun.GetRemappedClone(gunSprite, sourceMaterial, pivotShiftsMeshUVCoords: false); // STEP 1.2 - 1.3
|
||||
if (newGun != null) customSkin.SetAttachment(gunSlotIndex, gunKey, newGun); // STEP 1.4
|
||||
|
||||
// customSkin.RemoveAttachment(gunSlotIndex, gunKey); // To remove an item.
|
||||
|
||||
@ -115,6 +115,8 @@ namespace Spine.Unity {
|
||||
nameTable.Clear();
|
||||
|
||||
var skeleton = skeletonRenderer.skeleton;
|
||||
if (skeleton == null)
|
||||
return;
|
||||
slot = skeleton.FindSlot(slotName);
|
||||
int slotIndex = skeleton.FindSlotIndex(slotName);
|
||||
|
||||
|
||||
@ -115,6 +115,8 @@ namespace Spine.Unity {
|
||||
nameTable.Clear();
|
||||
|
||||
var skeleton = skeletonGraphic.Skeleton;
|
||||
if (skeleton == null)
|
||||
return;
|
||||
slot = skeleton.FindSlot(slotName);
|
||||
int slotIndex = skeleton.FindSlotIndex(slotName);
|
||||
|
||||
|
||||
@ -45,8 +45,18 @@ namespace Spine.Unity.AttachmentTools {
|
||||
/// <param name="premultiplyAlpha">If <c>true</c>, a premultiply alpha clone of the original texture will be created.</param>
|
||||
/// <param name="cloneMeshAsLinked">If <c>true</c> MeshAttachments will be cloned as linked meshes and will inherit animation from the original attachment.</param>
|
||||
/// <param name="useOriginalRegionSize">If <c>true</c> the size of the original attachment will be followed, instead of using the Sprite size.</param>
|
||||
public static Attachment GetRemappedClone (this Attachment o, Sprite sprite, Material sourceMaterial, bool premultiplyAlpha = true, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false) {
|
||||
/// <param name="pivotShiftsMeshUVCoords">If <c>true</c> 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.</param>
|
||||
public static Attachment GetRemappedClone (this Attachment o, Sprite sprite, Material sourceMaterial,
|
||||
bool premultiplyAlpha = true, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false,
|
||||
bool pivotShiftsMeshUVCoords = true) {
|
||||
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;
|
||||
}
|
||||
return o.GetRemappedClone(atlasRegion, cloneMeshAsLinked, useOriginalRegionSize, 1f/sprite.pixelsPerUnit);
|
||||
}
|
||||
|
||||
|
||||
@ -1,195 +1,195 @@
|
||||
/******************************************************************************
|
||||
* 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.Generic;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Spine {
|
||||
public struct VertexPositionColorTextureColor : IVertexType {
|
||||
public Vector3 Position;
|
||||
public Color Color;
|
||||
public Vector2 TextureCoordinate;
|
||||
public Color Color2;
|
||||
|
||||
public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
|
||||
(
|
||||
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
|
||||
new VertexElement(12, VertexElementFormat.Color, VertexElementUsage.Color, 0),
|
||||
new VertexElement(16, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
|
||||
new VertexElement(24, VertexElementFormat.Color, VertexElementUsage.Color, 1)
|
||||
);
|
||||
|
||||
VertexDeclaration IVertexType.VertexDeclaration {
|
||||
get { return VertexDeclaration; }
|
||||
}
|
||||
}
|
||||
|
||||
// #region License
|
||||
// /*
|
||||
// Microsoft Public License (Ms-PL)
|
||||
// MonoGame - Copyright <20> 2009 The MonoGame Team
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
|
||||
// accept the license, do not use the software.
|
||||
//
|
||||
// 1. Definitions
|
||||
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
|
||||
// U.S. copyright law.
|
||||
//
|
||||
// A "contribution" is the original software, or any additions or changes to the software.
|
||||
// A "contributor" is any person that distributes its contribution under this license.
|
||||
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
|
||||
//
|
||||
// 2. Grant of Rights
|
||||
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
|
||||
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
|
||||
//
|
||||
// 3. Conditions and Limitations
|
||||
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
|
||||
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
|
||||
// your patent license from such contributor to the software ends automatically.
|
||||
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
|
||||
// notices that are present in the software.
|
||||
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
|
||||
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
|
||||
// code form, you may only do so under a license that complies with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
|
||||
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
|
||||
// permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
|
||||
// purpose and non-infringement.
|
||||
// */
|
||||
// #endregion License
|
||||
//
|
||||
|
||||
/// <summary>Draws batched meshes.</summary>
|
||||
public class MeshBatcher {
|
||||
private readonly List<MeshItem> items;
|
||||
private readonly Queue<MeshItem> freeItems;
|
||||
private VertexPositionColorTextureColor[] vertexArray = { };
|
||||
private short[] triangles = { };
|
||||
|
||||
public MeshBatcher () {
|
||||
items = new List<MeshItem>(256);
|
||||
freeItems = new Queue<MeshItem>(256);
|
||||
EnsureCapacity(256, 512);
|
||||
}
|
||||
|
||||
/// <summary>Returns a pooled MeshItem.</summary>
|
||||
public MeshItem NextItem (int vertexCount, int triangleCount) {
|
||||
MeshItem item = freeItems.Count > 0 ? freeItems.Dequeue() : new MeshItem();
|
||||
if (item.vertices.Length < vertexCount) item.vertices = new VertexPositionColorTextureColor[vertexCount];
|
||||
if (item.triangles.Length < triangleCount) item.triangles = new int[triangleCount];
|
||||
item.vertexCount = vertexCount;
|
||||
item.triangleCount = triangleCount;
|
||||
items.Add(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
private void EnsureCapacity (int vertexCount, int triangleCount) {
|
||||
if (vertexArray.Length < vertexCount) vertexArray = new VertexPositionColorTextureColor[vertexCount];
|
||||
if (triangles.Length < triangleCount) triangles = new short[triangleCount];
|
||||
}
|
||||
|
||||
public void Draw (GraphicsDevice device) {
|
||||
if (items.Count == 0) return;
|
||||
|
||||
int itemCount = items.Count;
|
||||
int vertexCount = 0, triangleCount = 0;
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
MeshItem item = items[i];
|
||||
vertexCount += item.vertexCount;
|
||||
triangleCount += item.triangleCount;
|
||||
}
|
||||
EnsureCapacity(vertexCount, triangleCount);
|
||||
|
||||
vertexCount = 0;
|
||||
triangleCount = 0;
|
||||
Texture2D lastTexture = null;
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
MeshItem item = items[i];
|
||||
int itemVertexCount = item.vertexCount;
|
||||
|
||||
if (item.texture != lastTexture || vertexCount + itemVertexCount > short.MaxValue) {
|
||||
FlushVertexArray(device, vertexCount, triangleCount);
|
||||
vertexCount = 0;
|
||||
triangleCount = 0;
|
||||
lastTexture = item.texture;
|
||||
device.Textures[0] = lastTexture;
|
||||
if (item.textureLayers != null) {
|
||||
for (int layer = 1; layer < item.textureLayers.Length; ++layer)
|
||||
device.Textures[layer] = item.textureLayers[layer];
|
||||
}
|
||||
}
|
||||
|
||||
int[] itemTriangles = item.triangles;
|
||||
int itemTriangleCount = item.triangleCount;
|
||||
for (int ii = 0, t = triangleCount; ii < itemTriangleCount; ii++, t++)
|
||||
triangles[t] = (short)(itemTriangles[ii] + vertexCount);
|
||||
triangleCount += itemTriangleCount;
|
||||
|
||||
Array.Copy(item.vertices, 0, vertexArray, vertexCount, itemVertexCount);
|
||||
vertexCount += itemVertexCount;
|
||||
}
|
||||
FlushVertexArray(device, vertexCount, triangleCount);
|
||||
}
|
||||
|
||||
public void AfterLastDrawPass () {
|
||||
int itemCount = items.Count;
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
var item = items[i];
|
||||
item.texture = null;
|
||||
freeItems.Enqueue(item);
|
||||
}
|
||||
items.Clear();
|
||||
}
|
||||
|
||||
private void FlushVertexArray (GraphicsDevice device, int vertexCount, int triangleCount) {
|
||||
if (vertexCount == 0) return;
|
||||
device.DrawUserIndexedPrimitives(
|
||||
PrimitiveType.TriangleList,
|
||||
vertexArray, 0, vertexCount,
|
||||
triangles, 0, triangleCount / 3,
|
||||
VertexPositionColorTextureColor.VertexDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
public class MeshItem {
|
||||
public Texture2D texture = null;
|
||||
public Texture2D[] textureLayers = null;
|
||||
public int vertexCount, triangleCount;
|
||||
public VertexPositionColorTextureColor[] vertices = { };
|
||||
public int[] triangles = { };
|
||||
}
|
||||
}
|
||||
/******************************************************************************
|
||||
* 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.Generic;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Spine {
|
||||
public struct VertexPositionColorTextureColor : IVertexType {
|
||||
public Vector3 Position;
|
||||
public Color Color;
|
||||
public Vector2 TextureCoordinate;
|
||||
public Color Color2;
|
||||
|
||||
public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
|
||||
(
|
||||
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
|
||||
new VertexElement(12, VertexElementFormat.Color, VertexElementUsage.Color, 0),
|
||||
new VertexElement(16, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
|
||||
new VertexElement(24, VertexElementFormat.Color, VertexElementUsage.Color, 1)
|
||||
);
|
||||
|
||||
VertexDeclaration IVertexType.VertexDeclaration {
|
||||
get { return VertexDeclaration; }
|
||||
}
|
||||
}
|
||||
|
||||
// #region License
|
||||
// /*
|
||||
// Microsoft Public License (Ms-PL)
|
||||
// MonoGame - Copyright <20> 2009 The MonoGame Team
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
|
||||
// accept the license, do not use the software.
|
||||
//
|
||||
// 1. Definitions
|
||||
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
|
||||
// U.S. copyright law.
|
||||
//
|
||||
// A "contribution" is the original software, or any additions or changes to the software.
|
||||
// A "contributor" is any person that distributes its contribution under this license.
|
||||
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
|
||||
//
|
||||
// 2. Grant of Rights
|
||||
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
|
||||
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
|
||||
//
|
||||
// 3. Conditions and Limitations
|
||||
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
|
||||
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
|
||||
// your patent license from such contributor to the software ends automatically.
|
||||
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
|
||||
// notices that are present in the software.
|
||||
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
|
||||
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
|
||||
// code form, you may only do so under a license that complies with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
|
||||
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
|
||||
// permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
|
||||
// purpose and non-infringement.
|
||||
// */
|
||||
// #endregion License
|
||||
//
|
||||
|
||||
/// <summary>Draws batched meshes.</summary>
|
||||
public class MeshBatcher {
|
||||
private readonly List<MeshItem> items;
|
||||
private readonly Queue<MeshItem> freeItems;
|
||||
private VertexPositionColorTextureColor[] vertexArray = { };
|
||||
private short[] triangles = { };
|
||||
|
||||
public MeshBatcher () {
|
||||
items = new List<MeshItem>(256);
|
||||
freeItems = new Queue<MeshItem>(256);
|
||||
EnsureCapacity(256, 512);
|
||||
}
|
||||
|
||||
/// <summary>Returns a pooled MeshItem.</summary>
|
||||
public MeshItem NextItem (int vertexCount, int triangleCount) {
|
||||
MeshItem item = freeItems.Count > 0 ? freeItems.Dequeue() : new MeshItem();
|
||||
if (item.vertices.Length < vertexCount) item.vertices = new VertexPositionColorTextureColor[vertexCount];
|
||||
if (item.triangles.Length < triangleCount) item.triangles = new int[triangleCount];
|
||||
item.vertexCount = vertexCount;
|
||||
item.triangleCount = triangleCount;
|
||||
items.Add(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
private void EnsureCapacity (int vertexCount, int triangleCount) {
|
||||
if (vertexArray.Length < vertexCount) vertexArray = new VertexPositionColorTextureColor[vertexCount];
|
||||
if (triangles.Length < triangleCount) triangles = new short[triangleCount];
|
||||
}
|
||||
|
||||
public void Draw (GraphicsDevice device) {
|
||||
if (items.Count == 0) return;
|
||||
|
||||
int itemCount = items.Count;
|
||||
int vertexCount = 0, triangleCount = 0;
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
MeshItem item = items[i];
|
||||
vertexCount += item.vertexCount;
|
||||
triangleCount += item.triangleCount;
|
||||
}
|
||||
EnsureCapacity(vertexCount, triangleCount);
|
||||
|
||||
vertexCount = 0;
|
||||
triangleCount = 0;
|
||||
Texture2D lastTexture = null;
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
MeshItem item = items[i];
|
||||
int itemVertexCount = item.vertexCount;
|
||||
|
||||
if (item.texture != lastTexture || vertexCount + itemVertexCount > short.MaxValue) {
|
||||
FlushVertexArray(device, vertexCount, triangleCount);
|
||||
vertexCount = 0;
|
||||
triangleCount = 0;
|
||||
lastTexture = item.texture;
|
||||
device.Textures[0] = lastTexture;
|
||||
if (item.textureLayers != null) {
|
||||
for (int layer = 1; layer < item.textureLayers.Length; ++layer)
|
||||
device.Textures[layer] = item.textureLayers[layer];
|
||||
}
|
||||
}
|
||||
|
||||
int[] itemTriangles = item.triangles;
|
||||
int itemTriangleCount = item.triangleCount;
|
||||
for (int ii = 0, t = triangleCount; ii < itemTriangleCount; ii++, t++)
|
||||
triangles[t] = (short)(itemTriangles[ii] + vertexCount);
|
||||
triangleCount += itemTriangleCount;
|
||||
|
||||
Array.Copy(item.vertices, 0, vertexArray, vertexCount, itemVertexCount);
|
||||
vertexCount += itemVertexCount;
|
||||
}
|
||||
FlushVertexArray(device, vertexCount, triangleCount);
|
||||
}
|
||||
|
||||
public void AfterLastDrawPass () {
|
||||
int itemCount = items.Count;
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
var item = items[i];
|
||||
item.texture = null;
|
||||
freeItems.Enqueue(item);
|
||||
}
|
||||
items.Clear();
|
||||
}
|
||||
|
||||
private void FlushVertexArray (GraphicsDevice device, int vertexCount, int triangleCount) {
|
||||
if (vertexCount == 0) return;
|
||||
device.DrawUserIndexedPrimitives(
|
||||
PrimitiveType.TriangleList,
|
||||
vertexArray, 0, vertexCount,
|
||||
triangles, 0, triangleCount / 3,
|
||||
VertexPositionColorTextureColor.VertexDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
public class MeshItem {
|
||||
public Texture2D texture = null;
|
||||
public Texture2D[] textureLayers = null;
|
||||
public int vertexCount, triangleCount;
|
||||
public VertexPositionColorTextureColor[] vertices = { };
|
||||
public int[] triangles = { };
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,79 +1,79 @@
|
||||
/******************************************************************************
|
||||
* 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.IO;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
#if WINDOWS_STOREAPP
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
#endif
|
||||
|
||||
namespace Spine {
|
||||
|
||||
static public class Util {
|
||||
#if WINDOWS_STOREAPP
|
||||
private static async Task<Texture2D> LoadFile(GraphicsDevice device, String path) {
|
||||
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
|
||||
var file = await folder.GetFileAsync(path).AsTask().ConfigureAwait(false);
|
||||
try {
|
||||
return Util.LoadTexture(device, await file.OpenStreamForReadAsync().ConfigureAwait(false));
|
||||
} catch (Exception ex) {
|
||||
throw new Exception("Error reading texture file: " + path, ex);
|
||||
}
|
||||
}
|
||||
|
||||
static public Texture2D LoadTexture (GraphicsDevice device, String path) {
|
||||
return LoadFile(device, path).Result;
|
||||
}
|
||||
#else
|
||||
static public Texture2D LoadTexture (GraphicsDevice device, String path) {
|
||||
|
||||
#if WINDOWS_PHONE
|
||||
Stream stream = Microsoft.Xna.Framework.TitleContainer.OpenStream(path);
|
||||
using (Stream input = stream) {
|
||||
#else
|
||||
using (Stream input = new FileStream(path, FileMode.Open, FileAccess.Read)) {
|
||||
#endif
|
||||
try {
|
||||
return Util.LoadTexture(device, input);
|
||||
} catch (Exception ex) {
|
||||
throw new Exception("Error reading texture file: " + path, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static public Texture2D LoadTexture (GraphicsDevice device, Stream input) {
|
||||
return Texture2D.FromStream(device, input);
|
||||
}
|
||||
}
|
||||
}
|
||||
/******************************************************************************
|
||||
* 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.IO;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
#if WINDOWS_STOREAPP
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
#endif
|
||||
|
||||
namespace Spine {
|
||||
|
||||
static public class Util {
|
||||
#if WINDOWS_STOREAPP
|
||||
private static async Task<Texture2D> LoadFile(GraphicsDevice device, String path) {
|
||||
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
|
||||
var file = await folder.GetFileAsync(path).AsTask().ConfigureAwait(false);
|
||||
try {
|
||||
return Util.LoadTexture(device, await file.OpenStreamForReadAsync().ConfigureAwait(false));
|
||||
} catch (Exception ex) {
|
||||
throw new Exception("Error reading texture file: " + path, ex);
|
||||
}
|
||||
}
|
||||
|
||||
static public Texture2D LoadTexture (GraphicsDevice device, String path) {
|
||||
return LoadFile(device, path).Result;
|
||||
}
|
||||
#else
|
||||
static public Texture2D LoadTexture (GraphicsDevice device, String path) {
|
||||
|
||||
#if WINDOWS_PHONE
|
||||
Stream stream = Microsoft.Xna.Framework.TitleContainer.OpenStream(path);
|
||||
using (Stream input = stream) {
|
||||
#else
|
||||
using (Stream input = new FileStream(path, FileMode.Open, FileAccess.Read)) {
|
||||
#endif
|
||||
try {
|
||||
return Util.LoadTexture(device, input);
|
||||
} catch (Exception ex) {
|
||||
throw new Exception("Error reading texture file: " + path, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static public Texture2D LoadTexture (GraphicsDevice device, Stream input) {
|
||||
return Texture2D.FromStream(device, input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,94 +1,94 @@
|
||||
/******************************************************************************
|
||||
* 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.IO;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Spine {
|
||||
public class XnaTextureLoader : TextureLoader {
|
||||
GraphicsDevice device;
|
||||
string[] textureLayerSuffixes = null;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="device">The graphics device to be used.</param>
|
||||
/// <param name="loadMultipleTextureLayers">If <c>true</c> multiple textures layers
|
||||
/// (e.g. a diffuse/albedo texture and a normal map) are loaded instead of a single texture.
|
||||
/// Names are constructed based on suffixes added according to the <c>textureSuffixes</c> parameter.</param>
|
||||
/// <param name="textureSuffixes">If <c>loadMultipleTextureLayers</c> is <c>true</c>, the strings of this array
|
||||
/// define the path name suffix of each layer to be loaded. Array size must be equal to the number of layers to be loaded.
|
||||
/// The first array entry is the suffix to be <c>replaced</c> (e.g. "_albedo", or "" for a first layer without a suffix),
|
||||
/// subsequent array entries contain the suffix to replace the first entry with (e.g. "_normals").
|
||||
///
|
||||
/// An example would be:
|
||||
/// <code>new string[] { "", "_normals" }</code> for loading a base diffuse texture named "skeletonname.png" and
|
||||
/// a normalmap named "skeletonname_normals.png".</param>
|
||||
public XnaTextureLoader (GraphicsDevice device, bool loadMultipleTextureLayers = false, string[] textureSuffixes = null) {
|
||||
this.device = device;
|
||||
if (loadMultipleTextureLayers)
|
||||
this.textureLayerSuffixes = textureSuffixes;
|
||||
}
|
||||
|
||||
public void Load (AtlasPage page, String path) {
|
||||
Texture2D texture = Util.LoadTexture(device, path);
|
||||
page.width = texture.Width;
|
||||
page.height = texture.Height;
|
||||
|
||||
if (textureLayerSuffixes == null) {
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
else {
|
||||
Texture2D[] textureLayersArray = new Texture2D[textureLayerSuffixes.Length];
|
||||
textureLayersArray[0] = texture;
|
||||
for (int layer = 1; layer < textureLayersArray.Length; ++layer) {
|
||||
string layerPath = GetLayerName(path, textureLayerSuffixes[0], textureLayerSuffixes[layer]);
|
||||
textureLayersArray[layer] = Util.LoadTexture(device, layerPath);
|
||||
}
|
||||
page.rendererObject = textureLayersArray;
|
||||
}
|
||||
}
|
||||
|
||||
public void Unload (Object texture) {
|
||||
((Texture2D)texture).Dispose();
|
||||
}
|
||||
|
||||
private string GetLayerName (string firstLayerPath, string firstLayerSuffix, string replacementSuffix) {
|
||||
|
||||
int suffixLocation = firstLayerPath.LastIndexOf(firstLayerSuffix + ".");
|
||||
if (suffixLocation == -1) {
|
||||
throw new Exception(string.Concat("Error composing texture layer name: first texture layer name '", firstLayerPath,
|
||||
"' does not contain suffix to be replaced: '", firstLayerSuffix, "'"));
|
||||
}
|
||||
return firstLayerPath.Remove(suffixLocation, firstLayerSuffix.Length).Insert(suffixLocation, replacementSuffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
/******************************************************************************
|
||||
* 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.IO;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Spine {
|
||||
public class XnaTextureLoader : TextureLoader {
|
||||
GraphicsDevice device;
|
||||
string[] textureLayerSuffixes = null;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="device">The graphics device to be used.</param>
|
||||
/// <param name="loadMultipleTextureLayers">If <c>true</c> multiple textures layers
|
||||
/// (e.g. a diffuse/albedo texture and a normal map) are loaded instead of a single texture.
|
||||
/// Names are constructed based on suffixes added according to the <c>textureSuffixes</c> parameter.</param>
|
||||
/// <param name="textureSuffixes">If <c>loadMultipleTextureLayers</c> is <c>true</c>, the strings of this array
|
||||
/// define the path name suffix of each layer to be loaded. Array size must be equal to the number of layers to be loaded.
|
||||
/// The first array entry is the suffix to be <c>replaced</c> (e.g. "_albedo", or "" for a first layer without a suffix),
|
||||
/// subsequent array entries contain the suffix to replace the first entry with (e.g. "_normals").
|
||||
///
|
||||
/// An example would be:
|
||||
/// <code>new string[] { "", "_normals" }</code> for loading a base diffuse texture named "skeletonname.png" and
|
||||
/// a normalmap named "skeletonname_normals.png".</param>
|
||||
public XnaTextureLoader (GraphicsDevice device, bool loadMultipleTextureLayers = false, string[] textureSuffixes = null) {
|
||||
this.device = device;
|
||||
if (loadMultipleTextureLayers)
|
||||
this.textureLayerSuffixes = textureSuffixes;
|
||||
}
|
||||
|
||||
public void Load (AtlasPage page, String path) {
|
||||
Texture2D texture = Util.LoadTexture(device, path);
|
||||
page.width = texture.Width;
|
||||
page.height = texture.Height;
|
||||
|
||||
if (textureLayerSuffixes == null) {
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
else {
|
||||
Texture2D[] textureLayersArray = new Texture2D[textureLayerSuffixes.Length];
|
||||
textureLayersArray[0] = texture;
|
||||
for (int layer = 1; layer < textureLayersArray.Length; ++layer) {
|
||||
string layerPath = GetLayerName(path, textureLayerSuffixes[0], textureLayerSuffixes[layer]);
|
||||
textureLayersArray[layer] = Util.LoadTexture(device, layerPath);
|
||||
}
|
||||
page.rendererObject = textureLayersArray;
|
||||
}
|
||||
}
|
||||
|
||||
public void Unload (Object texture) {
|
||||
((Texture2D)texture).Dispose();
|
||||
}
|
||||
|
||||
private string GetLayerName (string firstLayerPath, string firstLayerSuffix, string replacementSuffix) {
|
||||
|
||||
int suffixLocation = firstLayerPath.LastIndexOf(firstLayerSuffix + ".");
|
||||
if (suffixLocation == -1) {
|
||||
throw new Exception(string.Concat("Error composing texture layer name: first texture layer name '", firstLayerPath,
|
||||
"' does not contain suffix to be replaced: '", firstLayerSuffix, "'"));
|
||||
}
|
||||
return firstLayerPath.Remove(suffixLocation, firstLayerSuffix.Length).Insert(suffixLocation, replacementSuffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user