mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-14 19:11:36 +08:00
201 lines
6.2 KiB
Java
201 lines
6.2 KiB
Java
/******************************************************************************
|
|
* Spine Runtimes Software License
|
|
* Version 2.1
|
|
*
|
|
* Copyright (c) 2013, Esoteric Software
|
|
* All rights reserved.
|
|
*
|
|
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
|
* non-transferable license to install, execute and perform the Spine Runtimes
|
|
* Software (the "Software") solely for internal use. Without the written
|
|
* permission of Esoteric Software (typically granted by licensing Spine), you
|
|
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
|
* improvements of the Software or develop new applications using the Software
|
|
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
|
* trademark, patent or other intellectual property or proprietary rights
|
|
* notices on or in the Software, including any copy thereof. Redistributions
|
|
* in binary or source form must include this license and terms.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
* OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*****************************************************************************/
|
|
|
|
package com.esotericsoftware.spine.attachments;
|
|
|
|
import com.esotericsoftware.spine.Bone;
|
|
import com.esotericsoftware.spine.Skeleton;
|
|
import com.esotericsoftware.spine.Slot;
|
|
|
|
import com.badlogic.gdx.graphics.Color;
|
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
|
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
|
import com.badlogic.gdx.utils.FloatArray;
|
|
import com.badlogic.gdx.utils.NumberUtils;
|
|
|
|
/** Attachment that displays a texture region. */
|
|
public class MeshAttachment extends Attachment {
|
|
private TextureRegion region;
|
|
private String path;
|
|
private float[] vertices, regionUVs;
|
|
private short[] triangles;
|
|
private float[] worldVertices;
|
|
private final Color color = new Color(1, 1, 1, 1);
|
|
|
|
// Nonessential.
|
|
private int hullLength;
|
|
private int[] edges;
|
|
private float width, height;
|
|
|
|
public MeshAttachment (String name) {
|
|
super(name);
|
|
}
|
|
|
|
public void setRegion (TextureRegion region) {
|
|
if (region == null) throw new IllegalArgumentException("region cannot be null.");
|
|
this.region = region;
|
|
}
|
|
|
|
public TextureRegion getRegion () {
|
|
if (region == null) throw new IllegalStateException("Region has not been set: " + this);
|
|
return region;
|
|
}
|
|
|
|
public void updateUVs () {
|
|
int verticesLength = vertices.length;
|
|
int worldVerticesLength = verticesLength / 2 * 5;
|
|
if (worldVertices == null || worldVertices.length != worldVerticesLength) worldVertices = new float[worldVerticesLength];
|
|
|
|
float u, v, width, height;
|
|
if (region == null) {
|
|
u = v = 0;
|
|
width = height = 1;
|
|
} else {
|
|
u = region.getU();
|
|
v = region.getV();
|
|
width = region.getU2() - u;
|
|
height = region.getV2() - v;
|
|
}
|
|
float[] regionUVs = this.regionUVs;
|
|
if (region instanceof AtlasRegion && ((AtlasRegion)region).rotate) {
|
|
for (int i = 0, w = 3; i < verticesLength; i += 2, w += 5) {
|
|
worldVertices[w] = u + regionUVs[i + 1] * width;
|
|
worldVertices[w + 1] = v + height - regionUVs[i] * height;
|
|
}
|
|
} else {
|
|
for (int i = 0, w = 3; i < verticesLength; i += 2, w += 5) {
|
|
worldVertices[w] = u + regionUVs[i] * width;
|
|
worldVertices[w + 1] = v + regionUVs[i + 1] * height;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void updateWorldVertices (Slot slot, boolean premultipliedAlpha) {
|
|
Skeleton skeleton = slot.getSkeleton();
|
|
Color skeletonColor = skeleton.getColor();
|
|
Color slotColor = slot.getColor();
|
|
Color meshColor = color;
|
|
float a = skeletonColor.a * slotColor.a * meshColor.a * 255;
|
|
float multiplier = premultipliedAlpha ? a : 255;
|
|
float color = NumberUtils.intToFloatColor( //
|
|
((int)a << 24) //
|
|
| ((int)(skeletonColor.b * slotColor.b * meshColor.b * multiplier) << 16) //
|
|
| ((int)(skeletonColor.g * slotColor.g * meshColor.g * multiplier) << 8) //
|
|
| (int)(skeletonColor.r * slotColor.r * meshColor.r * multiplier));
|
|
|
|
float[] worldVertices = this.worldVertices;
|
|
FloatArray slotVertices = slot.getAttachmentVertices();
|
|
float[] vertices = this.vertices;
|
|
if (slotVertices.size == vertices.length) vertices = slotVertices.items;
|
|
Bone bone = slot.getBone();
|
|
float x = skeleton.getX() + bone.getWorldX(), y = skeleton.getY() + bone.getWorldY();
|
|
float m00 = bone.getM00(), m01 = bone.getM01(), m10 = bone.getM10(), m11 = bone.getM11();
|
|
for (int v = 0, w = 0, n = worldVertices.length; w < n; v += 2, w += 5) {
|
|
float vx = vertices[v];
|
|
float vy = vertices[v + 1];
|
|
worldVertices[w] = vx * m00 + vy * m01 + x;
|
|
worldVertices[w + 1] = vx * m10 + vy * m11 + y;
|
|
worldVertices[w + 2] = color;
|
|
}
|
|
}
|
|
|
|
public float[] getWorldVertices () {
|
|
return worldVertices;
|
|
}
|
|
|
|
public float[] getVertices () {
|
|
return vertices;
|
|
}
|
|
|
|
public void setVertices (float[] vertices) {
|
|
this.vertices = vertices;
|
|
}
|
|
|
|
public short[] getTriangles () {
|
|
return triangles;
|
|
}
|
|
|
|
public void setTriangles (short[] triangles) {
|
|
this.triangles = triangles;
|
|
}
|
|
|
|
public float[] getRegionUVs () {
|
|
return regionUVs;
|
|
}
|
|
|
|
public void setRegionUVs (float[] regionUVs) {
|
|
this.regionUVs = regionUVs;
|
|
}
|
|
|
|
public Color getColor () {
|
|
return color;
|
|
}
|
|
|
|
public String getPath () {
|
|
return path;
|
|
}
|
|
|
|
public void setPath (String path) {
|
|
this.path = path;
|
|
}
|
|
|
|
public int getHullLength () {
|
|
return hullLength;
|
|
}
|
|
|
|
public void setHullLength (int hullLength) {
|
|
this.hullLength = hullLength;
|
|
}
|
|
|
|
public int[] getEdges () {
|
|
return edges;
|
|
}
|
|
|
|
public void setEdges (int[] edges) {
|
|
this.edges = edges;
|
|
}
|
|
|
|
public float getWidth () {
|
|
return width;
|
|
}
|
|
|
|
public void setWidth (float width) {
|
|
this.width = width;
|
|
}
|
|
|
|
public float getHeight () {
|
|
return height;
|
|
}
|
|
|
|
public void setHeight (float height) {
|
|
this.height = height;
|
|
}
|
|
}
|