Merge remote-tracking branch 'EsotericSoftware/3.6' into 3.6

This commit is contained in:
Stephen Gowen 2017-10-01 11:25:14 -04:00
commit 3ee1058628
13 changed files with 124 additions and 70 deletions

View File

@ -88,7 +88,7 @@ void main() {
vec4 texColor = texture2D(texture, v_texCoord); vec4 texColor = texture2D(texture, v_texCoord);
float alpha = texColor.a * v_light.a; float alpha = texColor.a * v_light.a;
gl_FragColor.a = alpha; gl_FragColor.a = alpha;
gl_FragColor.rgb = (1.0 - texColor.rgb) * v_dark.rgb * alpha + texColor.rgb * v_light.rgb; gl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;
} }
); );

View File

@ -192,7 +192,7 @@ static bool handlerQueued = false;
unsigned short* triangles = 0; unsigned short* triangles = 0;
int trianglesCount = 0; int trianglesCount = 0;
float r = 0, g = 0, b = 0, a = 0; float r = 0, g = 0, b = 0, a = 0;
float dr = 0, dg = 0, db = 0; float dr = 0, dg = 0, db = 0, da = _premultipliedAlpha ? 1 : 0;
for (int i = 0, n = _skeleton->slotsCount; i < n; i++) { for (int i = 0, n = _skeleton->slotsCount; i < n; i++) {
spSlot* slot = _skeleton->drawOrder[i]; spSlot* slot = _skeleton->drawOrder[i];
if (!slot->attachment) continue; if (!slot->attachment) continue;
@ -336,7 +336,7 @@ static bool handlerQueued = false;
dark.r = dr; dark.r = dr;
dark.g = dg; dark.g = dg;
dark.b = db; dark.b = db;
dark.a = 1; dark.a = da;
for (int i = 0; i * 2 < verticesCount; i++, verts++) { for (int i = 0; i * 2 < verticesCount; i++, verts++) {
spColor lightCopy = light; spColor lightCopy = light;
spColor darkCopy = dark; spColor darkCopy = dark;
@ -353,7 +353,7 @@ static bool handlerQueued = false;
verts->z = vertex.position.z; verts->z = vertex.position.z;
verts->w = vertex.position.w; verts->w = vertex.position.w;
verts->color = ((unsigned short)(lightCopy.r * 255))| ((unsigned short)(lightCopy.g * 255)) << 8 | ((unsigned short)(lightCopy.b * 255)) <<16 | ((unsigned short)(lightCopy.a * 255)) << 24; verts->color = ((unsigned short)(lightCopy.r * 255))| ((unsigned short)(lightCopy.g * 255)) << 8 | ((unsigned short)(lightCopy.b * 255)) <<16 | ((unsigned short)(lightCopy.a * 255)) << 24;
verts->color2 = ((unsigned short)(darkCopy.r * 255)) | ((unsigned short)(darkCopy.g * 255)) << 8 | ((unsigned short)(darkCopy.b * 255)) << 16 | ((unsigned short)(255)) << 24; verts->color2 = ((unsigned short)(darkCopy.r * 255)) | ((unsigned short)(darkCopy.g * 255)) << 8 | ((unsigned short)(darkCopy.b * 255)) << 16 | ((unsigned short)(darkCopy.a * 255)) << 24;
} }
} else { } else {
@ -366,7 +366,7 @@ static bool handlerQueued = false;
verts->z = vertex.position.z; verts->z = vertex.position.z;
verts->w = vertex.position.w; verts->w = vertex.position.w;
verts->color = ((unsigned short)(r * 255))| ((unsigned short)(g * 255)) << 8 | ((unsigned short)(b * 255)) <<16 | ((unsigned short)(a * 255)) << 24; verts->color = ((unsigned short)(r * 255))| ((unsigned short)(g * 255)) << 8 | ((unsigned short)(b * 255)) <<16 | ((unsigned short)(a * 255)) << 24;
verts->color2 = ((unsigned short)(dr * 255)) | ((unsigned short)(dg * 255)) << 8 | ((unsigned short)(db * 255)) << 16 | ((unsigned short)(255)) << 24; verts->color2 = ((unsigned short)(dr * 255)) | ((unsigned short)(dg * 255)) << 8 | ((unsigned short)(db * 255)) << 16 | ((unsigned short)(da * 255)) << 24;
verts->u = uvs[i * 2]; verts->u = uvs[i * 2];
verts->v = 1 - uvs[i * 2 + 1]; verts->v = 1 - uvs[i * 2 + 1];
} }

View File

@ -227,6 +227,7 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
Color4F color; Color4F color;
Color4F darkColor; Color4F darkColor;
float darkPremultipliedAlpha = _premultipliedAlpha ? 255 : 0;
AttachmentVertices* attachmentVertices = nullptr; AttachmentVertices* attachmentVertices = nullptr;
TwoColorTrianglesCommand* lastTwoColorTrianglesCommand = nullptr; TwoColorTrianglesCommand* lastTwoColorTrianglesCommand = nullptr;
for (int i = 0, n = _skeleton->slotsCount; i < n; ++i) { for (int i = 0, n = _skeleton->slotsCount; i < n; ++i) {
@ -317,6 +318,7 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
darkColor.g = 0; darkColor.g = 0;
darkColor.b = 0; darkColor.b = 0;
} }
darkColor.a = darkPremultipliedAlpha;
color.a *= nodeColor.a * _skeleton->color.a * slot->color.a * 255; color.a *= nodeColor.a * _skeleton->color.a * slot->color.a * 255;
// skip rendering if the color of this attachment is 0 // skip rendering if the color of this attachment is 0
@ -482,7 +484,7 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
vertex->color2.r = (GLubyte)(darkCopy.r * 255); vertex->color2.r = (GLubyte)(darkCopy.r * 255);
vertex->color2.g = (GLubyte)(darkCopy.g * 255); vertex->color2.g = (GLubyte)(darkCopy.g * 255);
vertex->color2.b = (GLubyte)(darkCopy.b * 255); vertex->color2.b = (GLubyte)(darkCopy.b * 255);
vertex->color2.a = 1; vertex->color2.a = (GLubyte)darkColor.a;
} }
} else { } else {
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv += 2) { for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv += 2) {
@ -498,7 +500,7 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
vertex->color2.r = (GLubyte)darkColor.r; vertex->color2.r = (GLubyte)darkColor.r;
vertex->color2.g = (GLubyte)darkColor.g; vertex->color2.g = (GLubyte)darkColor.g;
vertex->color2.b = (GLubyte)darkColor.b; vertex->color2.b = (GLubyte)darkColor.b;
vertex->color2.a = 1; vertex->color2.a = (GLubyte)darkColor.a;
} }
} }
} else { } else {
@ -528,7 +530,7 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
vertex->color2.r = (GLubyte)(darkCopy.r * 255); vertex->color2.r = (GLubyte)(darkCopy.r * 255);
vertex->color2.g = (GLubyte)(darkCopy.g * 255); vertex->color2.g = (GLubyte)(darkCopy.g * 255);
vertex->color2.b = (GLubyte)(darkCopy.b * 255); vertex->color2.b = (GLubyte)(darkCopy.b * 255);
vertex->color2.a = 1; vertex->color2.a = (GLubyte)darkColor.a;
} }
} else { } else {
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) { for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
@ -540,7 +542,7 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
vertex->color2.r = (GLubyte)darkColor.r; vertex->color2.r = (GLubyte)darkColor.r;
vertex->color2.g = (GLubyte)darkColor.g; vertex->color2.g = (GLubyte)darkColor.g;
vertex->color2.b = (GLubyte)darkColor.b; vertex->color2.b = (GLubyte)darkColor.b;
vertex->color2.a = 1; vertex->color2.a = (GLubyte)darkColor.a;
} }
} }
} }

View File

@ -144,7 +144,7 @@ void main() {
vec4 texColor = texture2D(CC_Texture0, v_texCoord); vec4 texColor = texture2D(CC_Texture0, v_texCoord);
float alpha = texColor.a * v_light.a; float alpha = texColor.a * v_light.a;
gl_FragColor.a = alpha; gl_FragColor.a = alpha;
gl_FragColor.rgb = (1.0 - texColor.rgb) * v_dark.rgb * alpha + texColor.rgb * v_light.rgb; gl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;
} }
); );

View File

@ -78,10 +78,11 @@ public class SkeletonRenderer {
region.computeWorldVertices(slot.getBone(), vertices, 0, 5); region.computeWorldVertices(slot.getBone(), vertices, 0, 5);
Color color = region.getColor(), slotColor = slot.getColor(); Color color = region.getColor(), slotColor = slot.getColor();
float alpha = a * slotColor.a * color.a * 255; float alpha = a * slotColor.a * color.a * 255;
float multiplier = premultipliedAlpha ? alpha : 255;
float c = NumberUtils.intToFloatColor(((int)alpha << 24) // float c = NumberUtils.intToFloatColor(((int)alpha << 24) //
| ((int)(b * slotColor.b * color.b * alpha) << 16) // | ((int)(b * slotColor.b * color.b * multiplier) << 16) //
| ((int)(g * slotColor.g * color.g * alpha) << 8) // | ((int)(g * slotColor.g * color.g * multiplier) << 8) //
| (int)(r * slotColor.r * color.r * alpha)); | (int)(r * slotColor.r * color.r * multiplier));
float[] uvs = region.getUVs(); float[] uvs = region.getUVs();
for (int u = 0, v = 2; u < 8; u += 2, v += 5) { for (int u = 0, v = 2; u < 8; u += 2, v += 5) {
vertices[v] = c; vertices[v] = c;
@ -173,10 +174,11 @@ public class SkeletonRenderer {
if (texture != null) { if (texture != null) {
Color slotColor = slot.getColor(); Color slotColor = slot.getColor();
float alpha = a * slotColor.a * color.a * 255; float alpha = a * slotColor.a * color.a * 255;
float multiplier = premultipliedAlpha ? alpha : 255;
float c = NumberUtils.intToFloatColor(((int)alpha << 24) // float c = NumberUtils.intToFloatColor(((int)alpha << 24) //
| ((int)(b * slotColor.b * color.b * alpha) << 16) // | ((int)(b * slotColor.b * color.b * multiplier) << 16) //
| ((int)(g * slotColor.g * color.g * alpha) << 8) // | ((int)(g * slotColor.g * color.g * multiplier) << 8) //
| (int)(r * slotColor.r * color.r * alpha)); | (int)(r * slotColor.r * color.r * multiplier));
BlendMode slotBlendMode = slot.data.getBlendMode(); BlendMode slotBlendMode = slot.data.getBlendMode();
if (slotBlendMode != blendMode) { if (slotBlendMode != blendMode) {
@ -238,6 +240,7 @@ public class SkeletonRenderer {
if (vertexEffect != null) vertexEffect.begin(skeleton); if (vertexEffect != null) vertexEffect.begin(skeleton);
boolean premultipliedAlpha = this.premultipliedAlpha; boolean premultipliedAlpha = this.premultipliedAlpha;
batch.setPremultipliedAlpha(premultipliedAlpha);
BlendMode blendMode = null; BlendMode blendMode = null;
int verticesLength = 0; int verticesLength = 0;
float[] vertices = null, uvs = null; float[] vertices = null, uvs = null;
@ -284,16 +287,19 @@ public class SkeletonRenderer {
if (texture != null) { if (texture != null) {
Color lightColor = slot.getColor(); Color lightColor = slot.getColor();
float alpha = a * lightColor.a * color.a * 255; float alpha = a * lightColor.a * color.a * 255;
float multiplier = premultipliedAlpha ? alpha : 255;
float red = r * color.r * multiplier;
float green = g * color.g * multiplier;
float blue = b * color.b * multiplier;
float light = NumberUtils.intToFloatColor(((int)alpha << 24) // float light = NumberUtils.intToFloatColor(((int)alpha << 24) //
| ((int)(b * lightColor.b * color.b * alpha) << 16) // | ((int)(blue * lightColor.b) << 16) //
| ((int)(g * lightColor.g * color.g * alpha) << 8) // | ((int)(green * lightColor.g) << 8) //
| (int)(r * lightColor.r * color.r * alpha)); | (int)(red * lightColor.r));
Color darkColor = slot.getDarkColor(); Color darkColor = slot.getDarkColor();
if (darkColor == null) darkColor = Color.BLACK; float dark = darkColor == null ? 0
float dark = NumberUtils.intToFloatColor( // : NumberUtils.intToFloatColor((int)(blue * darkColor.b) << 16 //
((int)(b * darkColor.b * color.b * 255) << 16) // | (int)(green * darkColor.g) << 8 //
| ((int)(g * darkColor.g * color.g * 255) << 8) // | (int)(red * darkColor.r));
| (int)(r * darkColor.r * color.r * 255));
BlendMode slotBlendMode = slot.data.getBlendMode(); BlendMode slotBlendMode = slot.data.getBlendMode();
if (slotBlendMode != blendMode) { if (slotBlendMode != blendMode) {

View File

@ -54,6 +54,9 @@ public class TwoColorPolygonBatch {
private boolean drawing; private boolean drawing;
private int blendSrcFunc = GL20.GL_SRC_ALPHA; private int blendSrcFunc = GL20.GL_SRC_ALPHA;
private int blendDstFunc = GL20.GL_ONE_MINUS_SRC_ALPHA; private int blendDstFunc = GL20.GL_ONE_MINUS_SRC_ALPHA;
private int blendSrcFuncAlpha = GL20.GL_SRC_ALPHA;
private int blendDstFuncAlpha = GL20.GL_ONE_MINUS_SRC_ALPHA;
private boolean premultipliedAlpha;
public TwoColorPolygonBatch (int size) { public TwoColorPolygonBatch (int size) {
this(size, size * 2); this(size, size * 2);
@ -69,7 +72,7 @@ public class TwoColorPolygonBatch {
mesh = new Mesh(vertexDataType, false, maxVertices, maxTriangles * 3, // mesh = new Mesh(vertexDataType, false, maxVertices, maxTriangles * 3, //
new VertexAttribute(Usage.Position, 2, "a_position"), // new VertexAttribute(Usage.Position, 2, "a_position"), //
new VertexAttribute(Usage.ColorPacked, 4, "a_light"), // new VertexAttribute(Usage.ColorPacked, 4, "a_light"), //
new VertexAttribute(Usage.ColorPacked, 4, "a_dark"), // new VertexAttribute(Usage.ColorPacked, 4, "a_dark"), // Dark alpha is unused, but colors are packed as 4 byte floats.
new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoord0")); new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoord0"));
vertices = new float[maxVertices * 6]; vertices = new float[maxVertices * 6];
@ -130,7 +133,7 @@ public class TwoColorPolygonBatch {
mesh.setVertices(vertices, 0, vertexIndex); mesh.setVertices(vertices, 0, vertexIndex);
mesh.setIndices(triangles, 0, triangleIndex); mesh.setIndices(triangles, 0, triangleIndex);
Gdx.gl.glEnable(GL20.GL_BLEND); Gdx.gl.glEnable(GL20.GL_BLEND);
if (blendSrcFunc != -1) Gdx.gl.glBlendFunc(blendSrcFunc, blendDstFunc); if (blendSrcFunc != -1) Gdx.gl.glBlendFuncSeparate(blendSrcFunc, blendDstFunc, blendSrcFuncAlpha, blendDstFuncAlpha);
mesh.render(shader, GL20.GL_TRIANGLES, 0, triangleIndex); mesh.render(shader, GL20.GL_TRIANGLES, 0, triangleIndex);
vertexIndex = 0; vertexIndex = 0;
@ -150,25 +153,39 @@ public class TwoColorPolygonBatch {
return transformMatrix; return transformMatrix;
} }
/** Flushes the batch. */
public void setProjectionMatrix (Matrix4 projection) { public void setProjectionMatrix (Matrix4 projection) {
if (drawing) flush(); if (drawing) flush();
projectionMatrix.set(projection); projectionMatrix.set(projection);
if (drawing) setupMatrices(); if (drawing) setupMatrices();
} }
/** Flushes the batch. */
public void setTransformMatrix (Matrix4 transform) { public void setTransformMatrix (Matrix4 transform) {
if (drawing) flush(); if (drawing) flush();
transformMatrix.set(transform); transformMatrix.set(transform);
if (drawing) setupMatrices(); if (drawing) setupMatrices();
} }
/** Specifies whether the texture colors have premultiplied alpha. Required for correct dark color tinting. Does not change the
* blending function. Flushes the batch if the setting was changed. */
public void setPremultipliedAlpha (boolean premultipliedAlpha) {
if (this.premultipliedAlpha == premultipliedAlpha) return;
if (drawing) flush();
this.premultipliedAlpha = premultipliedAlpha;
if (drawing) setupMatrices();
}
private void setupMatrices () { private void setupMatrices () {
combinedMatrix.set(projectionMatrix).mul(transformMatrix); combinedMatrix.set(projectionMatrix).mul(transformMatrix);
shader.setUniformf("u_pma", premultipliedAlpha ? 1 : 0);
shader.setUniformMatrix("u_projTrans", combinedMatrix); shader.setUniformMatrix("u_projTrans", combinedMatrix);
shader.setUniformi("u_texture", 0); shader.setUniformi("u_texture", 0);
} }
/** Flushes the batch if the shader was changed. */
public void setShader (ShaderProgram newShader) { public void setShader (ShaderProgram newShader) {
if (shader == newShader) return;
if (drawing) { if (drawing) {
flush(); flush();
shader.end(); shader.end();
@ -180,21 +197,30 @@ public class TwoColorPolygonBatch {
} }
} }
/** Flushes the batch if the blend function was changed. */
public void setBlendFunction (int srcFunc, int dstFunc) { public void setBlendFunction (int srcFunc, int dstFunc) {
if (blendSrcFunc == srcFunc && blendDstFunc == dstFunc) return; setBlendFunctionSeparate(srcFunc, dstFunc, srcFunc, dstFunc);
}
/** Flushes the batch if the blend function was changed. */
public void setBlendFunctionSeparate (int srcFuncColor, int dstFuncColor, int srcFuncAlpha, int dstFuncAlpha) {
if (blendSrcFunc == srcFuncColor && blendDstFunc == dstFuncColor && blendSrcFuncAlpha == srcFuncAlpha
&& blendDstFuncAlpha == dstFuncAlpha) return;
flush(); flush();
blendSrcFunc = srcFunc; blendSrcFunc = srcFuncColor;
blendDstFunc = dstFunc; blendDstFunc = dstFuncColor;
blendSrcFuncAlpha = srcFuncAlpha;
blendDstFuncAlpha = dstFuncAlpha;
} }
private ShaderProgram createDefaultShader () { private ShaderProgram createDefaultShader () {
String vertexShader = "attribute vec4 a_position;\n" // String vertexShader = "attribute vec4 a_position;\n" //
+ "attribute vec4 a_light;\n" // + "attribute vec4 a_light;\n" //
+ "attribute vec3 a_dark;\n" // + "attribute vec4 a_dark;\n" //
+ "attribute vec2 a_texCoord0;\n" // + "attribute vec2 a_texCoord0;\n" //
+ "uniform mat4 u_projTrans;\n" // + "uniform mat4 u_projTrans;\n" //
+ "varying vec4 v_light;\n" // + "varying vec4 v_light;\n" //
+ "varying vec3 v_dark;\n" // + "varying vec4 v_dark;\n" //
+ "varying vec2 v_texCoords;\n" // + "varying vec2 v_texCoords;\n" //
+ "\n" // + "\n" //
+ "void main()\n" // + "void main()\n" //
@ -212,14 +238,15 @@ public class TwoColorPolygonBatch {
+ "#define LOWP \n" // + "#define LOWP \n" //
+ "#endif\n" // + "#endif\n" //
+ "varying LOWP vec4 v_light;\n" // + "varying LOWP vec4 v_light;\n" //
+ "varying LOWP vec3 v_dark;\n" // + "varying LOWP vec4 v_dark;\n" //
+ "uniform float u_pma;\n" //
+ "varying vec2 v_texCoords;\n" // + "varying vec2 v_texCoords;\n" //
+ "uniform sampler2D u_texture;\n" // + "uniform sampler2D u_texture;\n" //
+ "void main()\n"// + "void main()\n"//
+ "{\n" // + "{\n" //
+ " vec4 texColor = texture2D(u_texture, v_texCoords);\n" // + " vec4 texColor = texture2D(u_texture, v_texCoords);\n" //
+ " gl_FragColor.a = texColor.a * v_light.a;\n" // + " gl_FragColor.a = texColor.a * v_light.a;\n" //
+ " gl_FragColor.rgb = (1.0 - texColor.rgb) * v_dark * gl_FragColor.a + texColor.rgb * v_light.rgb;\n" // + " gl_FragColor.rgb = ((texColor.a - 1.0) * u_pma + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n" //
+ "}"; + "}";
ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader); ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader);

View File

@ -904,26 +904,31 @@ public class SkeletonViewer extends ApplicationAdapter {
} }
void loadPrefs () { void loadPrefs () {
debugBonesCheckbox.setChecked(prefs.getBoolean("debugBones", true)); try {
debugRegionsCheckbox.setChecked(prefs.getBoolean("debugRegions", false)); debugBonesCheckbox.setChecked(prefs.getBoolean("debugBones", true));
debugMeshHullCheckbox.setChecked(prefs.getBoolean("debugMeshHull", false)); debugRegionsCheckbox.setChecked(prefs.getBoolean("debugRegions", false));
debugMeshTrianglesCheckbox.setChecked(prefs.getBoolean("debugMeshTriangles", false)); debugMeshHullCheckbox.setChecked(prefs.getBoolean("debugMeshHull", false));
debugPathsCheckbox.setChecked(prefs.getBoolean("debugPaths", true)); debugMeshTrianglesCheckbox.setChecked(prefs.getBoolean("debugMeshTriangles", false));
debugPointsCheckbox.setChecked(prefs.getBoolean("debugPoints", true)); debugPathsCheckbox.setChecked(prefs.getBoolean("debugPaths", true));
debugClippingCheckbox.setChecked(prefs.getBoolean("debugClipping", true)); debugPointsCheckbox.setChecked(prefs.getBoolean("debugPoints", true));
premultipliedCheckbox.setChecked(prefs.getBoolean("premultiplied", true)); debugClippingCheckbox.setChecked(prefs.getBoolean("debugClipping", true));
loopCheckbox.setChecked(prefs.getBoolean("loop", false)); premultipliedCheckbox.setChecked(prefs.getBoolean("premultiplied", true));
speedSlider.setValue(prefs.getFloat("speed", 0.3f)); loopCheckbox.setChecked(prefs.getBoolean("loop", false));
mixSlider.setValue(prefs.getFloat("mix", 0.3f)); speedSlider.setValue(prefs.getFloat("speed", 0.3f));
mixSlider.setValue(prefs.getFloat("mix", 0.3f));
zoomSlider.setValue(prefs.getFloat("zoom", 1)); zoomSlider.setValue(prefs.getFloat("zoom", 1));
camera.zoom = 1 / prefs.getFloat("zoom", 1); camera.zoom = 1 / prefs.getFloat("zoom", 1);
camera.position.x = prefs.getFloat("x", 0); camera.position.x = prefs.getFloat("x", 0);
camera.position.y = prefs.getFloat("y", 0); camera.position.y = prefs.getFloat("y", 0);
scaleSlider.setValue(prefs.getFloat("scale", 1)); scaleSlider.setValue(prefs.getFloat("scale", 1));
animationList.setSelected(prefs.getString("animationName", null)); animationList.setSelected(prefs.getString("animationName", null));
skinList.setSelected(prefs.getString("skinName", null)); skinList.setSelected(prefs.getString("skinName", null));
} catch (Exception ex) {
System.out.println("Unable to read preferences:");
ex.printStackTrace();
}
} }
} }

View File

@ -457,7 +457,7 @@ namespace Spine.Unity.Editor {
static Bone extractionBone; static Bone extractionBone;
static Slot extractionSlot; static Slot extractionSlot;
static Bone GetExtractionBone () { internal static Bone GetExtractionBone () {
if (extractionBone != null) if (extractionBone != null)
return extractionBone; return extractionBone;
@ -479,7 +479,7 @@ namespace Spine.Unity.Editor {
return extractionBone; return extractionBone;
} }
static Slot GetExtractionSlot () { internal static Slot GetExtractionSlot () {
if (extractionSlot != null) if (extractionSlot != null)
return extractionSlot; return extractionSlot;
@ -491,11 +491,14 @@ namespace Spine.Unity.Editor {
return extractionSlot; return extractionSlot;
} }
static Mesh ExtractRegionAttachment (string name, RegionAttachment attachment, Mesh mesh = null) { internal static Mesh ExtractRegionAttachment (string name, RegionAttachment attachment, Mesh mesh = null, bool centered = true) {
var bone = GetExtractionBone(); var bone = GetExtractionBone();
bone.X = -attachment.X; if (centered) {
bone.Y = -attachment.Y; bone.X = -attachment.X;
bone.Y = -attachment.Y;
}
bone.UpdateWorldTransform(); bone.UpdateWorldTransform();
Vector2[] uvs = ExtractUV(attachment.UVs); Vector2[] uvs = ExtractUV(attachment.UVs);
@ -504,12 +507,13 @@ namespace Spine.Unity.Editor {
Vector3[] verts = ExtractVerts(floatVerts); Vector3[] verts = ExtractVerts(floatVerts);
//unrotate verts now that they're centered //unrotate verts now that they're centered
for (int i = 0; i < verts.Length; i++) { if (centered) {
verts[i] = Quaternion.Euler(0, 0, -attachment.Rotation) * verts[i]; for (int i = 0; i < verts.Length; i++)
verts[i] = Quaternion.Euler(0, 0, -attachment.Rotation) * verts[i];
} }
int[] triangles = new int[6] { 1, 3, 0, 2, 3, 1 }; int[] triangles = { 1, 3, 0, 2, 3, 1 };
Color color = new Color(attachment.R, attachment.G, attachment.B, attachment.A); Color color = attachment.GetColor();
if (mesh == null) if (mesh == null)
mesh = new Mesh(); mesh = new Mesh();
@ -519,7 +523,7 @@ namespace Spine.Unity.Editor {
mesh.vertices = verts; mesh.vertices = verts;
mesh.uv = uvs; mesh.uv = uvs;
mesh.triangles = triangles; mesh.triangles = triangles;
mesh.colors = new Color[] { color, color, color, color }; mesh.colors = new [] { color, color, color, color };
mesh.RecalculateBounds(); mesh.RecalculateBounds();
mesh.RecalculateNormals(); mesh.RecalculateNormals();
mesh.name = name; mesh.name = name;
@ -527,7 +531,7 @@ namespace Spine.Unity.Editor {
return mesh; return mesh;
} }
static Mesh ExtractMeshAttachment (string name, MeshAttachment attachment, Mesh mesh = null) { internal static Mesh ExtractMeshAttachment (string name, MeshAttachment attachment, Mesh mesh = null) {
var slot = GetExtractionSlot(); var slot = GetExtractionSlot();
slot.Bone.X = 0; slot.Bone.X = 0;
@ -592,7 +596,7 @@ namespace Spine.Unity.Editor {
} }
} }
static Mesh ExtractWeightedMeshAttachment (string name, MeshAttachment attachment, int slotIndex, SkeletonData skeletonData, List<Transform> boneList, Mesh mesh = null) { internal static Mesh ExtractWeightedMeshAttachment (string name, MeshAttachment attachment, int slotIndex, SkeletonData skeletonData, List<Transform> boneList, Mesh mesh = null) {
if (attachment.Bones == null) if (attachment.Bones == null)
throw new System.ArgumentException("Mesh is not weighted.", "attachment"); throw new System.ArgumentException("Mesh is not weighted.", "attachment");
@ -708,7 +712,7 @@ namespace Spine.Unity.Editor {
return mesh; return mesh;
} }
static Vector2[] ExtractUV (float[] floats) { internal static Vector2[] ExtractUV (float[] floats) {
Vector2[] arr = new Vector2[floats.Length / 2]; Vector2[] arr = new Vector2[floats.Length / 2];
for (int i = 0; i < floats.Length; i += 2) { for (int i = 0; i < floats.Length; i += 2) {
@ -718,7 +722,7 @@ namespace Spine.Unity.Editor {
return arr; return arr;
} }
static Vector3[] ExtractVerts (float[] floats) { internal static Vector3[] ExtractVerts (float[] floats) {
Vector3[] arr = new Vector3[floats.Length / 2]; Vector3[] arr = new Vector3[floats.Length / 2];
for (int i = 0; i < floats.Length; i += 2) { for (int i = 0; i < floats.Length; i += 2) {

View File

@ -52,7 +52,7 @@ Shader "Spine/Skeleton Tint" {
float4 frag (VertexOutput i) : COLOR { float4 frag (VertexOutput i) : COLOR {
float4 texColor = tex2D(_MainTex, i.uv); float4 texColor = tex2D(_MainTex, i.uv);
return (texColor * i.vertexColor) + float4(((1-texColor.rgb) * texColor.a * _Black.rgb), 0); return (texColor * i.vertexColor) + float4(((1-texColor.rgb) * _Black.rgb * texColor.a*_Color.a*i.vertexColor.a), 0);
} }
ENDCG ENDCG
} }

View File

@ -110,7 +110,7 @@ Shader "Spine/SkeletonGraphic Tint Black (Premultiply Alpha)"
clip (texColor.a - 0.001); clip (texColor.a - 0.001);
#endif #endif
return (texColor * IN.color) + float4(((1-texColor.rgb) * texColor.a * (_Black.rgb + float3(IN.uv1.r, IN.uv1.g, IN.uv2.r))), 0); return (texColor * IN.color) + float4(((1-texColor.rgb) * (_Black.rgb + float3(IN.uv1.r, IN.uv1.g, IN.uv2.r)) * texColor.a*_Color.a*i.vertexColor.a), 0);
} }
ENDCG ENDCG
} }

View File

@ -61,7 +61,7 @@ Shader "Spine/Skeleton Tint Black" {
float4 frag (VertexOutput i) : COLOR { float4 frag (VertexOutput i) : COLOR {
float4 texColor = tex2D(_MainTex, i.uv); float4 texColor = tex2D(_MainTex, i.uv);
return (texColor * i.vertexColor) + float4(((1-texColor.rgb) * texColor.a * (_Black.rgb + float3(i.uv1.r, i.uv1.g, i.uv2.r))), 0); return (texColor * i.vertexColor) + float4(((1-texColor.rgb) * (_Black.rgb + float3(i.uv1.r, i.uv1.g, i.uv2.r)) * texColor.a*_Color.a*i.vertexColor.a), 0);
} }
ENDCG ENDCG
} }

View File

@ -144,6 +144,12 @@ namespace Spine.Unity {
return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation)); return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation));
} }
/// <summary>Gets a bone-local space UnityEngine.Quaternion representation of bone.rotation.</summary>
public static Quaternion GetLocalQuaternion (this Bone bone) {
var halfRotation = bone.rotation * Mathf.Deg2Rad * 0.5f;
return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation));
}
/// <summary>Gets the PointAttachment's Unity World position using its Spine GameObject Transform.</summary> /// <summary>Gets the PointAttachment's Unity World position using its Spine GameObject Transform.</summary>
public static Vector3 GetWorldPosition (this PointAttachment attachment, Slot slot, Transform spineGameObjectTransform) { public static Vector3 GetWorldPosition (this PointAttachment attachment, Slot slot, Transform spineGameObjectTransform) {
Vector3 skeletonSpacePosition; Vector3 skeletonSpacePosition;
@ -288,6 +294,10 @@ namespace Spine {
return va.bones != null && va.bones.Length > 0; return va.bones != null && va.bones.Length > 0;
} }
public static bool IsRenderable (this Attachment a) {
return a is RegionAttachment || a is MeshAttachment;
}
#region Transform Modes #region Transform Modes
public static bool InheritsRotation (this TransformMode mode) { public static bool InheritsRotation (this TransformMode mode) {
const int RotationBit = 0; const int RotationBit = 0;

View File

@ -213,7 +213,7 @@ namespace Spine.Unity {
for (int i = 0; i < separatorSlotNames.Length; i++) for (int i = 0; i < separatorSlotNames.Length; i++)
separatorSlots.Add(skeleton.FindSlot(separatorSlotNames[i])); separatorSlots.Add(skeleton.FindSlot(separatorSlotNames[i]));
LateUpdate(); LateUpdate(); // Generate mesh for the first frame it exists.
if (OnRebuild != null) if (OnRebuild != null)
OnRebuild(this); OnRebuild(this);