Merge branch '3.8' into 3.9-beta

This commit is contained in:
badlogic 2019-09-11 16:20:00 +02:00
commit db166b1b7b
17 changed files with 244 additions and 108 deletions

View File

@ -247,12 +247,12 @@ package spine.animation {
var alpha : Number = 0;
switch (timelineMode[i] & (NOT_LAST - 1)) {
case SUBSEQUENT:
timelineBlend = blend;
if (!attachments && timeline is AttachmentTimeline) {
if ((timelineMode[i] & NOT_LAST) == NOT_LAST) continue;
blend = MixBlend.setup;
timelineBlend = MixBlend.setup;
}
if (!drawOrder && timeline is DrawOrderTimeline) continue;
timelineBlend = blend;
alpha = alphaMix;
break;
case FIRST:

View File

@ -467,12 +467,12 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
switch (timelineMode->items[i] & (NOT_LAST - 1)) {
case SUBSEQUENT:
timelineBlend = blend;
if (!attachments && timeline->type == SP_TIMELINE_ATTACHMENT) {
if ((timelineMode->items[i] & NOT_LAST) == NOT_LAST) continue;
blend = SP_MIX_BLEND_SETUP;
timelineBlend = SP_MIX_BLEND_SETUP;
}
if (!drawOrder && timeline->type == SP_TIMELINE_DRAWORDER) continue;
timelineBlend = blend;
alpha = alphaMix;
break;
case FIRST:

View File

@ -153,7 +153,7 @@ xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\BoundingBoxAttachment.cpp" />
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\ClippingAttachment.cpp" />
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\ColorTimeline.cpp" />
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\Constraint.cpp" />
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\ConstraintData.cpp" />
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\CurveTimeline.cpp" />
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\DeformTimeline.cpp" />
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\DrawOrderTimeline.cpp" />
@ -211,6 +211,7 @@ xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
<ClCompile Include="..\Classes\BatchingExample.cpp" />
<ClCompile Include="..\Classes\CoinExample.cpp" />
<ClCompile Include="..\Classes\GoblinsExample.cpp" />
<ClCompile Include="..\Classes\MixAndMatchExample.cpp" />
<ClCompile Include="..\Classes\RaptorExample.cpp" />
<ClCompile Include="..\Classes\SkeletonRendererSeparatorExample.cpp" />
<ClCompile Include="..\Classes\SpineboyExample.cpp" />
@ -234,7 +235,6 @@ xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
<ClInclude Include="..\..\..\spine-cpp\spine-cpp\include\spine\ClippingAttachment.h" />
<ClInclude Include="..\..\..\spine-cpp\spine-cpp\include\spine\Color.h" />
<ClInclude Include="..\..\..\spine-cpp\spine-cpp\include\spine\ColorTimeline.h" />
<ClInclude Include="..\..\..\spine-cpp\spine-cpp\include\spine\Constraint.h" />
<ClInclude Include="..\..\..\spine-cpp\spine-cpp\include\spine\ContainerUtil.h" />
<ClInclude Include="..\..\..\spine-cpp\spine-cpp\include\spine\CurveTimeline.h" />
<ClInclude Include="..\..\..\spine-cpp\spine-cpp\include\spine\Debug.h" />
@ -309,6 +309,7 @@ xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
<ClInclude Include="..\Classes\BatchingExample.h" />
<ClInclude Include="..\Classes\CoinExample.h" />
<ClInclude Include="..\Classes\GoblinsExample.h" />
<ClInclude Include="..\Classes\MixAndMatchExample.h" />
<ClInclude Include="..\Classes\RaptorExample.h" />
<ClInclude Include="..\Classes\SkeletonRendererSeparatorExample.h" />
<ClInclude Include="..\Classes\SpineboyExample.h" />

View File

@ -78,9 +78,6 @@
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\ColorTimeline.cpp">
<Filter>spine</Filter>
</ClCompile>
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\Constraint.cpp">
<Filter>spine</Filter>
</ClCompile>
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\CurveTimeline.cpp">
<Filter>spine</Filter>
</ClCompile>
@ -246,6 +243,12 @@
<ClCompile Include="..\Classes\TankExample.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\spine-cpp\spine-cpp\src\spine\ConstraintData.cpp">
<Filter>spine</Filter>
</ClCompile>
<ClCompile Include="..\Classes\MixAndMatchExample.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="main.h">
@ -344,9 +347,6 @@
<ClInclude Include="..\..\..\spine-cpp\spine-cpp\include\spine\ColorTimeline.h">
<Filter>spine</Filter>
</ClInclude>
<ClInclude Include="..\..\..\spine-cpp\spine-cpp\include\spine\Constraint.h">
<Filter>spine</Filter>
</ClInclude>
<ClInclude Include="..\..\..\spine-cpp\spine-cpp\include\spine\ContainerUtil.h">
<Filter>spine</Filter>
</ClInclude>
@ -536,6 +536,9 @@
<ClInclude Include="..\..\..\spine-cpp\spine-cpp\include\spine\Vertices.h">
<Filter>spine</Filter>
</ClInclude>
<ClInclude Include="..\Classes\MixAndMatchExample.h">
<Filter>src</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="game.rc">

View File

@ -434,7 +434,8 @@ namespace spine {
const cocos2d::Color4B color4B = ColorToColor4B(color);
const cocos2d::Color4B darkColor4B = ColorToColor4B(darkColor);
const BlendFunc blendFunc = makeBlendFunc(slot->getData().getBlendMode(), _premultipliedAlpha);
const BlendFunc blendFunc = makeBlendFunc(slot->getData().getBlendMode(), attachmentVertices->_texture->hasPremultipliedAlpha());
_blendFunc = blendFunc;
if (hasSingleTint) {
if (_clipper->isClipping()) {

View File

@ -784,12 +784,12 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
float alpha;
switch (timelineMode[i] & (NotLast - 1)) {
case Subsequent:
timelineBlend = blend;
if (!attachments && (timeline->getRTTI().isExactly(AttachmentTimeline::rtti))) {
if ((timelineMode[i] & NotLast) == NotLast) continue;
blend = MixBlend_Setup;
timelineBlend = MixBlend_Setup;
}
if (!drawOrder && (timeline->getRTTI().isExactly(DrawOrderTimeline::rtti))) continue;
timelineBlend = blend;
alpha = alphaMix;
break;
case First:

View File

@ -299,12 +299,12 @@ namespace Spine {
float alpha;
switch (timelineMode[i] & AnimationState.NotLast - 1) {
case AnimationState.Subsequent:
timelineBlend = blend;
if (!attachments && timeline is AttachmentTimeline) {
if ((timelineMode[i] & AnimationState.NotLast) == AnimationState.NotLast) continue;
blend = MixBlend.Setup;
timelineBlend = MixBlend.Setup;
}
if (!drawOrder && timeline is DrawOrderTimeline) continue;
timelineBlend = blend;
alpha = alphaMix;
break;
case AnimationState.First:

View File

@ -291,12 +291,12 @@ public class AnimationState {
float alpha;
switch (timelineMode[i] & NOT_LAST - 1) {
case SUBSEQUENT:
timelineBlend = blend;
if (!attachments && timeline instanceof AttachmentTimeline) {
if ((timelineMode[i] & NOT_LAST) == NOT_LAST) continue;
blend = MixBlend.setup;
timelineBlend = MixBlend.setup;
}
if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
timelineBlend = blend;
alpha = alphaMix;
break;
case FIRST:
@ -695,7 +695,7 @@ public class AnimationState {
entry.next = null;
}
private void animationsChanged () {
void animationsChanged () {
animationsChanged = false;
// Process in the order that animations are applied.

View File

@ -35,7 +35,7 @@ import com.esotericsoftware.spine.AnimationState.TrackEntry;
/** Stores mix (crossfade) durations to be applied when {@link AnimationState} animations are changed. */
public class AnimationStateData {
final SkeletonData skeletonData;
final ObjectFloatMap<Key> animationToMixTime = new ObjectFloatMap();
final ObjectFloatMap<Key> animationToMixTime = new ObjectFloatMap(51, 0.8f);
final Key tempKey = new Key();
float defaultMix;

View File

@ -0,0 +1,137 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
package com.esotericsoftware.spine.utils;
import com.badlogic.gdx.assets.AssetDescriptor;
import com.badlogic.gdx.assets.AssetLoaderParameters;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.assets.loaders.AsynchronousAssetLoader;
import com.badlogic.gdx.assets.loaders.FileHandleResolver;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.utils.Array;
import com.esotericsoftware.spine.SkeletonBinary;
import com.esotericsoftware.spine.SkeletonData;
import com.esotericsoftware.spine.SkeletonJson;
import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader;
import com.esotericsoftware.spine.attachments.AttachmentLoader;
/** An asset loader to create and load skeleton data. The data file is assumed to be binary if it ends with <code>.skel</code>,
* otherwise JSON is assumed. The {@link SkeletonDataParameter} can provide a texture atlas name or an {@link AttachmentLoader}.
* If neither is provided, a texture atlas name based on the skeleton file name with an <code>.atlas</code> extension is used.
* When a texture atlas name is used, the texture atlas is loaded by the asset manager as a dependency.
* <p>
* Example:
*
* <pre>
* // Load skeleton.json and skeleton.atlas:
* assetManager.load("skeleton.json", SkeletonData.class);
* // Or specify the atlas/AttachmentLoader and scale:
* assetManager.setLoader(SkeletonData.class, new SkeletonDataLoader(new InternalFileHandleResolver()));
* SkeletonDataParameter parameter = new SkeletonDataParameter("skeleton2x.atlas", 2);
* assetManager.load("skeleton.json", SkeletonData.class, parameter);
* </pre>
*/
public class SkeletonDataLoader extends AsynchronousAssetLoader<SkeletonData, SkeletonDataLoader.SkeletonDataParameter> {
private SkeletonData skeletonData;
public SkeletonDataLoader (FileHandleResolver resolver) {
super(resolver);
}
/** @param parameter May be null. */
public void loadAsync (AssetManager manager, String fileName, FileHandle file, SkeletonDataParameter parameter) {
float scale = 1;
AttachmentLoader attachmentLoader = null;
if (parameter != null) {
scale = parameter.scale;
if (parameter.attachmentLoader != null)
attachmentLoader = parameter.attachmentLoader;
else if (parameter.atlasName != null)
attachmentLoader = new AtlasAttachmentLoader(manager.get(parameter.atlasName, TextureAtlas.class));
}
if (attachmentLoader == null)
attachmentLoader = new AtlasAttachmentLoader(manager.get(file.pathWithoutExtension() + ".atlas", TextureAtlas.class));
if (file.extension().equalsIgnoreCase("skel")) {
SkeletonBinary skeletonBinary = new SkeletonBinary(attachmentLoader);
skeletonBinary.setScale(scale);
skeletonData = skeletonBinary.readSkeletonData(file);
} else {
SkeletonJson skeletonJson = new SkeletonJson(attachmentLoader);
skeletonJson.setScale(scale);
skeletonData = skeletonJson.readSkeletonData(file);
}
}
/** @param parameter May be null. */
public SkeletonData loadSync (AssetManager manager, String fileName, FileHandle file, SkeletonDataParameter parameter) {
SkeletonData skeletonData = this.skeletonData;
this.skeletonData = null;
return skeletonData;
}
/** @param parameter May be null. */
public Array<AssetDescriptor> getDependencies (String fileName, FileHandle file, SkeletonDataParameter parameter) {
if (parameter == null) return null;
if (parameter.attachmentLoader != null) return null;
Array<AssetDescriptor> dependencies = new Array();
dependencies.add(new AssetDescriptor(parameter.atlasName, TextureAtlas.class));
return dependencies;
}
static public class SkeletonDataParameter extends AssetLoaderParameters<SkeletonData> {
public String atlasName;
public AttachmentLoader attachmentLoader;
public float scale = 1;
public SkeletonDataParameter () {
}
public SkeletonDataParameter (String atlasName) {
this.atlasName = atlasName;
}
public SkeletonDataParameter (String atlasName, float scale) {
this.atlasName = atlasName;
this.scale = scale;
}
public SkeletonDataParameter (AttachmentLoader attachmentLoader) {
this.attachmentLoader = attachmentLoader;
}
public SkeletonDataParameter (AttachmentLoader attachmentLoader, float scale) {
this.attachmentLoader = attachmentLoader;
this.scale = scale;
}
}
}

View File

@ -135,8 +135,14 @@ public class JsonRollback {
if (map.isObject() && map.parent.isArray()) { // Probably a key.
if (!map.has("time")) map.addChild("time", new JsonValue(0f));
if (map.parent.name != null && map.parent.name.equals("rotate") && !map.has("angle"))
if (map.parent.name != null) {
if (map.parent.name.equals("rotate") && !map.has("angle"))
map.addChild("angle", new JsonValue(0f));
else if (map.parent.name.equals("scale")) {
if (!map.has("x")) map.addChild("x", new JsonValue(1f));
if (!map.has("y")) map.addChild("y", new JsonValue(1f));
}
}
}
JsonValue curve = map.get("curve");
@ -149,8 +155,8 @@ public class JsonRollback {
curve.addChild(new JsonValue(curve.asFloat()));
curve.setType(ValueType.array);
curve.addChild(new JsonValue(map.getFloat("c2", 0)));
curve.addChild(new JsonValue(map.getFloat("c3", 0)));
curve.addChild(new JsonValue(map.getFloat("c4", 0)));
curve.addChild(new JsonValue(map.getFloat("c3", 1)));
curve.addChild(new JsonValue(map.getFloat("c4", 1)));
map.remove("c2");
map.remove("c3");
map.remove("c4");

View File

@ -423,15 +423,15 @@ function AnimationState:applyMixingFrom (to, skeleton, blend)
local timelineBlend = MixBlend.setup
local alpha = 0
if clearBit(timelineMode[i], NOT_LAST) == SUBSEQUENT then
timelineBlend = blend
if not attachments and timeline.type == Animation.TimelineType.attachment then
if testBit(timelineMode[i], NOT_LAST) then
skipSubsequent = true
else
blend = MixBlend.setup
timelineBlend = MixBlend.setup
end
end
if not drawOrder and timeline.type == Animation.TimelineType.drawOrder then skipSubsequent = true end
timelineBlend = blend
alpha = alphaMix
elseif clearBit(timelineMode[i], NOT_LAST) == FIRST then
timelineBlend = MixBlend.setup

View File

@ -235,12 +235,12 @@ module spine {
let alpha = 0;
switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
case AnimationState.SUBSEQUENT:
timelineBlend = blend;
if (!attachments && timeline instanceof AttachmentTimeline) {
if ((timelineMode[i] & AnimationState.NOT_LAST) == AnimationState.NOT_LAST) continue;
blend = MixBlend.setup;
timelineBlend = MixBlend.setup;
}
if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
timelineBlend = blend;
alpha = alphaMix;
break;
case AnimationState.FIRST:

View File

@ -17,7 +17,7 @@ var additiveBlendingDemo = function(canvas, bgColor) {
var left, right, up, down;
var cursor;
var clientMouseX = 0, clientMouseY = 0;
var clientMouseX = 0, clientMouseY = 0, mouseMoved;
var DEMO_NAME = "AdditiveBlendingDemo";
@ -53,21 +53,18 @@ var additiveBlendingDemo = function(canvas, bgColor) {
state = new spine.AnimationState(new spine.AnimationStateData(skeleton.data));
state.setAnimation(0, "idle", true);
left = state.setAnimation(1, "blink", true);
state.setAnimation(1, "blink", true);
left = state.setAnimation(2, "left", true);
right = state.setAnimation(3, "right", true);
up = state.setAnimation(4, "up", true);
down = state.setAnimation(5, "down", true);
left.mixBlend = spine.MixBlend.add;
left.alpha = 0;
right.mixBlend = spine.MixBlend.add;
right.alpha = 0;
up.mixBlend = spine.MixBlend.add;
up.alpha = 0;
down.mixBlend = spine.MixBlend.add;
left.alpha = 0;
right.alpha = 0;
up.alpha = 0;
down.alpha = 0;
state.apply(skeleton);
@ -86,21 +83,13 @@ var additiveBlendingDemo = function(canvas, bgColor) {
}
function calculateBlend (x, y, isPageCoords) {
if (isPageCoords) {
var canvasBounds = canvas.getBoundingClientRect();
x = Math.max(0, Math.min(canvasBounds.width, x - canvasBounds.x));
y = Math.max(0, Math.min(canvasBounds.height, y - canvasBounds.y));
}
x = x / canvas.width;
y = y / canvas.height;
if (x > 1) x = 1;
if (x < 0) x = 0;
if (y > 1) y = 1;
if (y < 0) y = 0;
left.alpha = (Math.max(x, 0.5) - 0.5) * 2;
right.alpha = (0.5 - Math.min(x, 0.5)) * 2;
up.alpha = (0.5 - Math.min(y, 0.5)) * 2;
down.alpha = (Math.max(y, 0.5) - 0.5) * 2;
var centerX = canvasBounds.x + canvasBounds.width / 2;
var centerY = canvasBounds.y + canvasBounds.height / 2;
right.alpha = x < centerX ? 1 - x / centerX : 0;
left.alpha = x > centerX ? (x - centerX) / (window.innerWidth - centerX): 0;
up.alpha = y < centerY ? 1 - y / centerY : 0;
down.alpha = y > centerY ? (y - centerY) / (window.innerHeight - centerY): 0;
}
function setupInput () {
@ -108,6 +97,7 @@ var additiveBlendingDemo = function(canvas, bgColor) {
document.addEventListener("mousemove", function (event) {
clientMouseX = event.clientX;
clientMouseY = event.clientY;
mouseMoved = true;
}, false);
} else {
var input = new spine.webgl.Input(canvas);
@ -134,9 +124,7 @@ var additiveBlendingDemo = function(canvas, bgColor) {
}
function render () {
if (!isMobileDevice()) {
calculateBlend(clientMouseX, clientMouseY, true);
}
if (!isMobileDevice() && mouseMoved) calculateBlend(clientMouseX, clientMouseY, true);
timeKeeper.update();
var delta = timeKeeper.delta;