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

@ -246,13 +246,13 @@ package spine.animation {
var timelineBlend: MixBlend;
var alpha : Number = 0;
switch (timelineMode[i] & (NOT_LAST - 1)) {
case SUBSEQUENT:
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

@ -32,12 +32,12 @@
#import <spine/extension.h>
typedef struct _TrackEntryListeners {
spStartListener startListener;
spInterruptListener interruptListener;
spEndListener endListener;
spDisposeListener disposeListener;
spCompleteListener completeListener;
spEventListener eventListener;
spStartListener startListener;
spInterruptListener interruptListener;
spEndListener endListener;
spDisposeListener disposeListener;
spCompleteListener completeListener;
spEventListener eventListener;
} _TrackEntryListeners;
static void animationCallback (spAnimationState* state, spEventType type, spTrackEntry* entry, spEvent* event) {
@ -46,16 +46,16 @@ static void animationCallback (spAnimationState* state, spEventType type, spTrac
void trackEntryCallback (spAnimationState* state, spEventType type, spTrackEntry* entry, spEvent* event) {
[(SkeletonAnimation*)state->rendererObject onTrackEntryEvent:entry type:type event:event];
if (type == SP_ANIMATION_DISPOSE) {
if (entry->rendererObject) {
_TrackEntryListeners* listeners = (_TrackEntryListeners*)entry->rendererObject;
[listeners->startListener release];
[listeners->endListener release];
[listeners->completeListener release];
[listeners->eventListener release];
FREE(listeners);
}
}
if (type == SP_ANIMATION_DISPOSE) {
if (entry->rendererObject) {
_TrackEntryListeners* listeners = (_TrackEntryListeners*)entry->rendererObject;
[listeners->startListener release];
[listeners->endListener release];
[listeners->completeListener release];
[listeners->eventListener release];
FREE(listeners);
}
}
}
static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
@ -95,7 +95,7 @@ static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
- (void) initialize {
_ownsAnimationStateData = true;
_timeScale = 1;
_timeScale = 1;
_state = spAnimationState_create(spAnimationStateData_create(_skeleton->data));
_state->rendererObject = self;
@ -136,9 +136,9 @@ static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
spAnimationState_dispose(_state);
[_startListener release];
[_interruptListener release];
[_interruptListener release];
[_endListener release];
[_disposeListener release];
[_disposeListener release];
[_completeListener release];
[_eventListener release];
@ -204,17 +204,17 @@ static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
case SP_ANIMATION_START:
if (_startListener) _startListener(entry);
break;
case SP_ANIMATION_INTERRUPT:
if (_interruptListener) _interruptListener(entry);
break;
case SP_ANIMATION_INTERRUPT:
if (_interruptListener) _interruptListener(entry);
break;
case SP_ANIMATION_END:
if (_endListener) _endListener(entry);
break;
case SP_ANIMATION_DISPOSE:
if (_disposeListener) _disposeListener(entry);
break;
case SP_ANIMATION_DISPOSE:
if (_disposeListener) _disposeListener(entry);
break;
case SP_ANIMATION_COMPLETE:
if (_completeListener) _completeListener(entry);
if (_completeListener) _completeListener(entry);
break;
case SP_ANIMATION_EVENT:
if (_eventListener) _eventListener(entry, event);
@ -229,15 +229,15 @@ static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
case SP_ANIMATION_START:
if (listeners->startListener) listeners->startListener(entry);
break;
case SP_ANIMATION_INTERRUPT:
if (listeners->interruptListener) listeners->interruptListener(entry);
break;
case SP_ANIMATION_INTERRUPT:
if (listeners->interruptListener) listeners->interruptListener(entry);
break;
case SP_ANIMATION_END:
if (listeners->endListener) listeners->endListener(entry);
break;
case SP_ANIMATION_DISPOSE:
if (listeners->disposeListener) listeners->disposeListener(entry);
break;
case SP_ANIMATION_DISPOSE:
if (listeners->disposeListener) listeners->disposeListener(entry);
break;
case SP_ANIMATION_COMPLETE:
if (listeners->completeListener) listeners->completeListener(entry);
break;
@ -252,7 +252,7 @@ static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
}
- (void) setListenerForEntry:(spTrackEntry*)entry onInterrupt:(spInterruptListener)listener {
getListeners(entry)->interruptListener = [listener copy];
getListeners(entry)->interruptListener = [listener copy];
}
- (void) setListenerForEntry:(spTrackEntry*)entry onEnd:(spEndListener)listener {
@ -260,7 +260,7 @@ static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
}
- (void) setListenerForEntry:(spTrackEntry*)entry onDispose:(spDisposeListener)listener {
getListeners(entry)->disposeListener = [listener copy];
getListeners(entry)->disposeListener = [listener copy];
}
- (void) setListenerForEntry:(spTrackEntry*)entry onComplete:(spCompleteListener)listener {

View File

@ -111,11 +111,11 @@ static bool handlerQueued = false;
spSkeletonJson* json = spSkeletonJson_create(atlas);
json->scale = scale;
spSkeletonData* skeletonData = nil;
@synchronized(self.class) {
spSkeletonJson_readSkeletonDataFile(json, [skeletonDataFile UTF8String]);
}
spSkeletonData* skeletonData = nil;
@synchronized(self.class) {
spSkeletonJson_readSkeletonDataFile(json, [skeletonDataFile UTF8String]);
}
NSAssert(skeletonData, ([NSString stringWithFormat:@"Error reading skeleton data file: %@\nError: %s", skeletonDataFile, json->error]));
spSkeletonJson_dispose(json);
if (!skeletonData) return 0;
@ -129,19 +129,19 @@ static bool handlerQueued = false;
self = [super init];
if (!self) return nil;
@synchronized(self.class) {
_atlas = spAtlas_createFromFile([atlasFile UTF8String], 0);
}
@synchronized(self.class) {
_atlas = spAtlas_createFromFile([atlasFile UTF8String], 0);
}
NSAssert(_atlas, ([NSString stringWithFormat:@"Error reading atlas file: %@", atlasFile]));
if (!_atlas) return 0;
spSkeletonJson* json = spSkeletonJson_create(_atlas);
json->scale = scale;
spSkeletonData* skeletonData;
@synchronized(self.class) {
skeletonData = spSkeletonJson_readSkeletonDataFile(json, [skeletonDataFile UTF8String]);
}
spSkeletonData* skeletonData;
@synchronized(self.class) {
skeletonData = spSkeletonJson_readSkeletonDataFile(json, [skeletonDataFile UTF8String]);
}
NSAssert(skeletonData, ([NSString stringWithFormat:@"Error reading skeleton data file: %@\nError: %s", skeletonDataFile, json->error]));
spSkeletonJson_dispose(json);
if (!skeletonData) return 0;

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

@ -1460,11 +1460,11 @@ public class TwoColorPolygonBatch implements PolygonBatch {
+ "\n" //
+ "void main()\n" //
+ "{\n" //
+ " v_light = a_light;\n" //
+ " v_light.a = v_light.a * (255.0/254.0);\n" //
+ " v_dark = a_dark;\n" //
+ " v_texCoords = a_texCoord0;\n" //
+ " gl_Position = u_projTrans * a_position;\n" //
+ " v_light = a_light;\n" //
+ " v_light.a = v_light.a * (255.0/254.0);\n" //
+ " v_dark = a_dark;\n" //
+ " v_texCoords = a_texCoord0;\n" //
+ " gl_Position = u_projTrans * a_position;\n" //
+ "}\n";
String fragmentShader = "#ifdef GL_ES\n" //
+ "#define LOWP lowp\n" //

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"))
map.addChild("angle", new JsonValue(0f));
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 canvasBounds = canvas.getBoundingClientRect();
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;