mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
Merge branch '3.7-beta' into 3.7-beta-cpp
This commit is contained in:
commit
7c398be3b6
@ -8,6 +8,7 @@
|
||||
* **Additions**
|
||||
* Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `TrackEntry#setMixBlend(MixBlend.add)` on each track. To specify the blend percentage, set `TrackEntry#alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion.
|
||||
* Support for stretchy IK
|
||||
* Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data).
|
||||
|
||||
### Starling
|
||||
* Added support for vertex effects. See `RaptorExample.as`
|
||||
@ -40,6 +41,7 @@
|
||||
* Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `spTrackEntry->mixBlend = SP_MIXBLEND_ADD)` on each track. To specify the blend percentage, set `spTrackEntry->alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion.
|
||||
* Optimized attachment lookup to give a 40x speed-up. See https://github.com/EsotericSoftware/spine-runtimes/commit/cab81276263890b65d07fa2329ace16db1e365ff
|
||||
* Support for stretchy IK
|
||||
* Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data).
|
||||
|
||||
### Cocos2d-Objc
|
||||
* Added vertex effect support to modify vertices of skeletons on the CPU. See `RaptorExample.m`.
|
||||
@ -97,6 +99,7 @@
|
||||
* **Additions**
|
||||
* Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `TrackEntry#MixBlend = MixBlend.add` on each track. To specify the blend percentage, set `TrackEntry#Alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion.
|
||||
* Support for stretchy IK
|
||||
* Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data).
|
||||
|
||||
### Unity
|
||||
* **Runtime and Editor, and Assembly Definition** Files and folders have been reorganized into "Runtime" and "Editor". Each of these have an `.asmdef` file that defines these separately as their own assembly in Unity. For projects not using assembly definition, you may delete the `.asmdef` files. These assembly definitions will be ignored by older versions of Unity that don't support it.
|
||||
@ -137,6 +140,7 @@
|
||||
* Added convenience method to add all attachments from one skin to another, see https://github.com/EsotericSoftware/spine-runtimes/commit/a0b7bb6c445efdfac12b0cdee2057afa3eff3ead
|
||||
* Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `TrackEntry#setMixBlend(MixBlend.add)` on each track. To specify the blend percentage, set `TrackEntry#alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion.
|
||||
* Support for stretchy IK
|
||||
* Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data).
|
||||
|
||||
### libGDX
|
||||
* Added `VertexEffect` interface, instances of which can be set on `SkeletonRenderer`. Allows to modify vertices before submitting them to GPU. See `SwirlEffect`, `JitterEffect` and `VertexEffectTest`.
|
||||
@ -154,6 +158,7 @@
|
||||
* Added `JitterEffect` and `SwirlEffect` and support for vertex effects in Corona and Love
|
||||
* Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `TrackEntry:setMixBlend(MixBlend.add)` on each track. To specify the blend percentage, set `TrackEntry.alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion.
|
||||
* Support for stretchy IK
|
||||
* Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data).
|
||||
|
||||
### Love2D
|
||||
* Added support for vertex effects. Set an implementation like "JitterEffect" on `Skeleton.vertexEffect`. See `main.lua` for an example.
|
||||
@ -170,6 +175,7 @@
|
||||
* Added additive animation blending. When playing back multiple animations on different tracks, where each animation modifies the same skeleton property, the results of tracks with lower indices are discarded, and only the result from the track with the highest index is used. With animation blending, the results of all tracks are mixed together. This allows effects like mixing multiple facial expressions (angry, happy, sad) with percentage mixes. By default the old behaviour is retained (results from lower tracks are discarded). To enable additive blending across animation tracks, call `TrackEntry#setMixBlend(MixBlend.add)` on each track. To specify the blend percentage, set `TrackEntry#alpha`. See http://esotericsoftware.com/forum/morph-target-track-animation-mix-mode-9459 for a discussion. See https://github.com/EsotericSoftware/spine-runtimes/blob/f045d221836fa56191ccda73dd42ae884d4731b8/spine-ts/webgl/tests/test-additive-animation-blending.html for an example.
|
||||
* Added work-around for iOS WebKit JIT bug, see https://github.com/EsotericSoftware/spine-runtimes/commit/c28bbebf804980f55cdd773fed9ff145e0e7e76c
|
||||
* Support for stretchy IK
|
||||
* Support for audio events, see `audioPath`, `volume` and `balance` fields on event (data).
|
||||
|
||||
### WebGL backend
|
||||
* Added `VertexEffect` interface, instances of which can be set on `SkeletonRenderer`. Allows to modify vertices before submitting them to GPU. See `SwirlEffect`, `JitterEffect`, and the example which allows to set effects.
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -90,7 +90,7 @@ cp -f ../raptor/export/raptor-pro.json ../../spine-corona/data
|
||||
cp -f ../raptor/export/raptor.atlas ../../spine-corona/data
|
||||
cp -f ../raptor/export/raptor.png ../../spine-corona/data
|
||||
|
||||
cp -f ../spineboy/export/spineboy-ess.json ../../spine-corona/data
|
||||
cp -f ../spineboy/export/spineboy-pro.json ../../spine-corona/data
|
||||
cp -f ../spineboy/export/spineboy.atlas ../../spine-corona/data
|
||||
cp -f ../spineboy/export/spineboy.png ../../spine-corona/data
|
||||
|
||||
@ -126,7 +126,7 @@ cp -f ../raptor/export/raptor-pro.json ../../spine-love/data
|
||||
cp -f ../raptor/export/raptor.atlas ../../spine-love/data
|
||||
cp -f ../raptor/export/raptor.png ../../spine-love/data
|
||||
|
||||
cp -f ../spineboy/export/spineboy-ess.json ../../spine-love/data
|
||||
cp -f ../spineboy/export/spineboy-pro.json ../../spine-love/data
|
||||
cp -f ../spineboy/export/spineboy.atlas ../../spine-love/data
|
||||
cp -f ../spineboy/export/spineboy.png ../../spine-love/data
|
||||
|
||||
@ -161,8 +161,8 @@ cp -f ../raptor/export/raptor-pro.skel ../../spine-sfml/c/data/
|
||||
cp -f ../raptor/export/raptor.atlas ../../spine-sfml/c/data/
|
||||
cp -f ../raptor/export/raptor.png ../../spine-sfml/c/data/
|
||||
|
||||
cp -f ../spineboy/export/spineboy-ess.json ../../spine-sfml/c/data/
|
||||
cp -f ../spineboy/export/spineboy-ess.skel ../../spine-sfml/c/data/
|
||||
cp -f ../spineboy/export/spineboy-pro.json ../../spine-sfml/c/data/
|
||||
cp -f ../spineboy/export/spineboy-pro.skel ../../spine-sfml/c/data/
|
||||
cp -f ../spineboy/export/spineboy.atlas ../../spine-sfml/c/data/
|
||||
cp -f ../spineboy/export/spineboy.png ../../spine-sfml/c/data/
|
||||
|
||||
@ -206,8 +206,8 @@ cp -f ../raptor/export/raptor-pro.skel ../../spine-sfml/cpp/data/
|
||||
cp -f ../raptor/export/raptor.atlas ../../spine-sfml/cpp/data/
|
||||
cp -f ../raptor/export/raptor.png ../../spine-sfml/cpp/data/
|
||||
|
||||
cp -f ../spineboy/export/spineboy-ess.json ../../spine-sfml/cpp/data/
|
||||
cp -f ../spineboy/export/spineboy-ess.skel ../../spine-sfml/cpp/data/
|
||||
cp -f ../spineboy/export/spineboy-pro.json ../../spine-sfml/cpp/data/
|
||||
cp -f ../spineboy/export/spineboy-pro.skel ../../spine-sfml/cpp/data/
|
||||
cp -f ../spineboy/export/spineboy.atlas ../../spine-sfml/cpp/data/
|
||||
cp -f ../spineboy/export/spineboy.png ../../spine-sfml/cpp/data/
|
||||
|
||||
@ -248,7 +248,7 @@ cp -f ../raptor/export/raptor-pro.json ../../spine-starling/spine-starling-examp
|
||||
cp -f ../raptor/export/raptor.atlas ../../spine-starling/spine-starling-example/src/
|
||||
cp -f ../raptor/export/raptor.png ../../spine-starling/spine-starling-example/src/
|
||||
|
||||
cp -f ../spineboy/export/spineboy-ess.json ../../spine-starling/spine-starling-example/src/
|
||||
cp -f ../spineboy/export/spineboy-pro.json ../../spine-starling/spine-starling-example/src/
|
||||
cp -f ../spineboy/export/spineboy.atlas ../../spine-starling/spine-starling-example/src/
|
||||
cp -f ../spineboy/export/spineboy.png ../../spine-starling/spine-starling-example/src/
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
||||
{"skeleton":{"hash":"B2ZPp7lIxBrN+g+ALWuTw4IWKYE","spine":"3.7.28-beta","width":1680,"height":1782.28,"images":"./images/","audio":""},"bones":[{"name":"root","y":-526.32},{"name":"leaves","parent":"root","x":-0.17,"y":1310.1},{"name":"logo","parent":"root","y":1332.03},{"name":"play","parent":"root","x":3.02,"y":-83.61},{"name":"quit","parent":"root","x":-2.86,"y":-201.21},{"name":"settings","parent":"root","x":3.02,"y":-144.37}],"slots":[{"name":"background","bone":"root"},{"name":"leaves","bone":"leaves","attachment":"leaves"},{"name":"logo","bone":"logo","attachment":"logo"},{"name":"play","bone":"play","color":"fff99dff","attachment":"play"},{"name":"quit","bone":"quit","color":"fff99dff","attachment":"quit"},{"name":"settings","bone":"settings","color":"fff99dff","attachment":"settings"}],"skins":{"default":{"leaves":{"leaves":{"y":-28.54,"width":1042,"height":522}},"logo":{"logo":{"y":-20.4,"width":917,"height":323}},"play":{"play":{"width":218,"height":77}},"quit":{"quit":{"width":216,"height":77}},"settings":{"settings":{"width":446,"height":76}}}},"animations":{"animation":{"slots":{"leaves":{"color":[{"time":0,"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}]},"logo":{"color":[{"time":0,"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}]},"play":{"color":[{"time":1.3333,"color":"fff99dff"},{"time":1.5667,"color":"ffffffff","curve":"stepped"},{"time":1.8333,"color":"ffffffff"},{"time":2.0667,"color":"fff99dff"}]},"quit":{"color":[{"time":2.4,"color":"fff99dff"},{"time":2.6333,"color":"ffffffff"}]},"settings":{"color":[{"time":1.8667,"color":"fff99dff"},{"time":2.1,"color":"ffffffff","curve":"stepped"},{"time":2.3667,"color":"ffffffff"},{"time":2.6,"color":"fff99dff"}]}},"bones":{"logo":{"translate":[{"time":0,"x":0,"y":40.8,"curve":[0.043,0.15,0.345,1.27]},{"time":0.3333,"x":0,"y":-597.72,"curve":[0.425,0.17,0.592,1]},{"time":1,"x":0,"y":-583.72,"curve":[0.402,0,0.603,1]},{"time":1.6667,"x":0,"y":-592.12,"curve":[0.408,0.01,0.655,0.99]},{"time":2.3333,"x":0,"y":-583.72,"curve":[0.402,0,0.603,1]},{"time":3,"x":0,"y":-592.12,"curve":[0.408,0.01,0.655,0.99]},{"time":3.6667,"x":0,"y":-583.72}],"scale":[{"time":0,"x":0.342,"y":0.342,"curve":[0,0,0.744,0.4]},{"time":0.3333,"x":1,"y":1,"curve":[0.19,0.38,0.658,0.99]},{"time":1,"x":1.02,"y":1.03,"curve":[0.371,0,0.661,1]},{"time":1.6667,"x":1,"y":1,"curve":[0.388,0.01,0.687,1]},{"time":2.3333,"x":1.02,"y":1.03,"curve":[0.371,0,0.661,1]},{"time":3,"x":1,"y":1,"curve":[0.388,0.01,0.687,1]},{"time":3.6667,"x":1.02,"y":1.03}]},"play":{"translate":[{"time":0.6667,"x":0,"y":0,"curve":[0,0,0.448,1.63]},{"time":0.8667,"x":0,"y":480.2}],"scale":[{"time":1.3333,"x":1,"y":1,"curve":[0,0,0.526,2.46]},{"time":1.5667,"x":1.231,"y":1.231,"curve":"stepped"},{"time":1.8333,"x":1.231,"y":1.231,"curve":[0,0,0.526,2.46]},{"time":2.0667,"x":1,"y":1}]},"settings":{"translate":[{"time":0.8,"x":0,"y":0,"curve":[0,0,0.448,1.63]},{"time":1,"x":0,"y":431.2}],"scale":[{"time":1.8667,"x":1,"y":1,"curve":[0,0,0.526,2.46]},{"time":2.1,"x":1.23,"y":1.23,"curve":"stepped"},{"time":2.3667,"x":1.23,"y":1.23,"curve":[0,0,0.526,2.46]},{"time":2.6,"x":1,"y":1}]},"quit":{"translate":[{"time":0.9333,"x":0,"y":0,"curve":[0,0,0.448,1.63]},{"time":1.1333,"x":0,"y":376.32}],"scale":[{"time":2.4,"x":1,"y":1,"curve":[0,0,0.526,2.46]},{"time":2.6333,"x":1.23,"y":1.23}]},"leaves":{"translate":[{"time":0,"x":0,"y":0,"curve":[0.043,0.15,0.345,1.27]},{"time":0.3333,"x":0.17,"y":-601.24,"curve":[0.425,0.17,0.592,1]},{"time":1.3333,"x":0.17,"y":-580.84,"curve":[0.402,0,0.603,1]},{"time":2,"x":0.17,"y":-595.12},{"time":2.6667,"x":0.17,"y":-580.84,"curve":[0.402,0,0.603,1]},{"time":3.3333,"x":0.17,"y":-595.12}],"scale":[{"time":0,"x":0.34,"y":0.34,"curve":[0,0,0.744,0.4]},{"time":0.3333,"x":1,"y":1},{"time":1.3333,"x":1.03,"y":1.02},{"time":2,"x":1,"y":1},{"time":2.6667,"x":1.03,"y":1.02},{"time":3.3333,"x":1,"y":1}]}}}}}
|
||||
{"skeleton":{"hash":"B2ZPp7lIxBrN+g+ALWuTw4IWKYE","spine":"3.7.29-beta","width":1680,"height":1782.28,"images":"./images/","audio":""},"bones":[{"name":"root","y":-526.32},{"name":"leaves","parent":"root","x":-0.17,"y":1310.1},{"name":"logo","parent":"root","y":1332.03},{"name":"play","parent":"root","x":3.02,"y":-83.61},{"name":"quit","parent":"root","x":-2.86,"y":-201.21},{"name":"settings","parent":"root","x":3.02,"y":-144.37}],"slots":[{"name":"background","bone":"root"},{"name":"leaves","bone":"leaves","attachment":"leaves"},{"name":"logo","bone":"logo","attachment":"logo"},{"name":"play","bone":"play","color":"fff99dff","attachment":"play"},{"name":"quit","bone":"quit","color":"fff99dff","attachment":"quit"},{"name":"settings","bone":"settings","color":"fff99dff","attachment":"settings"}],"skins":{"default":{"leaves":{"leaves":{"y":-28.54,"width":1042,"height":522}},"logo":{"logo":{"y":-20.4,"width":917,"height":323}},"play":{"play":{"width":218,"height":77}},"quit":{"quit":{"width":216,"height":77}},"settings":{"settings":{"width":446,"height":76}}}},"animations":{"animation":{"slots":{"leaves":{"color":[{"time":0,"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}]},"logo":{"color":[{"time":0,"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}]},"play":{"color":[{"time":1.3333,"color":"fff99dff"},{"time":1.5667,"color":"ffffffff","curve":"stepped"},{"time":1.8333,"color":"ffffffff"},{"time":2.0667,"color":"fff99dff"}]},"quit":{"color":[{"time":2.4,"color":"fff99dff"},{"time":2.6333,"color":"ffffffff"}]},"settings":{"color":[{"time":1.8667,"color":"fff99dff"},{"time":2.1,"color":"ffffffff","curve":"stepped"},{"time":2.3667,"color":"ffffffff"},{"time":2.6,"color":"fff99dff"}]}},"bones":{"logo":{"translate":[{"time":0,"x":0,"y":40.8,"curve":[0.043,0.15,0.345,1.27]},{"time":0.3333,"x":0,"y":-597.72,"curve":[0.425,0.17,0.592,1]},{"time":1,"x":0,"y":-583.72,"curve":[0.402,0,0.603,1]},{"time":1.6667,"x":0,"y":-592.12,"curve":[0.408,0.01,0.655,0.99]},{"time":2.3333,"x":0,"y":-583.72,"curve":[0.402,0,0.603,1]},{"time":3,"x":0,"y":-592.12,"curve":[0.408,0.01,0.655,0.99]},{"time":3.6667,"x":0,"y":-583.72}],"scale":[{"time":0,"x":0.342,"y":0.342,"curve":[0,0,0.744,0.4]},{"time":0.3333,"x":1,"y":1,"curve":[0.19,0.38,0.658,0.99]},{"time":1,"x":1.02,"y":1.03,"curve":[0.371,0,0.661,1]},{"time":1.6667,"x":1,"y":1,"curve":[0.388,0.01,0.687,1]},{"time":2.3333,"x":1.02,"y":1.03,"curve":[0.371,0,0.661,1]},{"time":3,"x":1,"y":1,"curve":[0.388,0.01,0.687,1]},{"time":3.6667,"x":1.02,"y":1.03}]},"play":{"translate":[{"time":0.6667,"x":0,"y":0,"curve":[0,0,0.448,1.63]},{"time":0.8667,"x":0,"y":480.2}],"scale":[{"time":1.3333,"x":1,"y":1,"curve":[0,0,0.526,2.46]},{"time":1.5667,"x":1.231,"y":1.231,"curve":"stepped"},{"time":1.8333,"x":1.231,"y":1.231,"curve":[0,0,0.526,2.46]},{"time":2.0667,"x":1,"y":1}]},"settings":{"translate":[{"time":0.8,"x":0,"y":0,"curve":[0,0,0.448,1.63]},{"time":1,"x":0,"y":431.2}],"scale":[{"time":1.8667,"x":1,"y":1,"curve":[0,0,0.526,2.46]},{"time":2.1,"x":1.23,"y":1.23,"curve":"stepped"},{"time":2.3667,"x":1.23,"y":1.23,"curve":[0,0,0.526,2.46]},{"time":2.6,"x":1,"y":1}]},"quit":{"translate":[{"time":0.9333,"x":0,"y":0,"curve":[0,0,0.448,1.63]},{"time":1.1333,"x":0,"y":376.32}],"scale":[{"time":2.4,"x":1,"y":1,"curve":[0,0,0.526,2.46]},{"time":2.6333,"x":1.23,"y":1.23}]},"leaves":{"translate":[{"time":0,"x":0,"y":0,"curve":[0.043,0.15,0.345,1.27]},{"time":0.3333,"x":0.17,"y":-601.24,"curve":[0.425,0.17,0.592,1]},{"time":1.3333,"x":0.17,"y":-580.84,"curve":[0.402,0,0.603,1]},{"time":2,"x":0.17,"y":-595.12},{"time":2.6667,"x":0.17,"y":-580.84,"curve":[0.402,0,0.603,1]},{"time":3.3333,"x":0.17,"y":-595.12}],"scale":[{"time":0,"x":0.34,"y":0.34,"curve":[0,0,0.744,0.4]},{"time":0.3333,"x":1,"y":1},{"time":1.3333,"x":1.03,"y":1.02},{"time":2,"x":1,"y":1},{"time":2.6667,"x":1.03,"y":1.02},{"time":3.3333,"x":1,"y":1}]}}}}}
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -35,6 +35,8 @@ package spine {
|
||||
public var intValue : int;
|
||||
public var floatValue : Number;
|
||||
public var stringValue : String;
|
||||
public var volume: Number = 1;
|
||||
public var balance: Number = 0;
|
||||
|
||||
public function Event(time : Number, data : EventData) {
|
||||
if (data == null) throw new ArgumentError("data cannot be null.");
|
||||
|
||||
@ -31,10 +31,12 @@
|
||||
package spine {
|
||||
public class EventData {
|
||||
internal var _name : String;
|
||||
public var intValue : int;
|
||||
;
|
||||
public var intValue : int;
|
||||
public var floatValue : Number;
|
||||
public var stringValue : String;
|
||||
public var audioPath: String;
|
||||
public var volume: Number = 1;
|
||||
public var balance: Number = 0;
|
||||
|
||||
public function EventData(name : String) {
|
||||
if (name == null) throw new ArgumentError("name cannot be null.");
|
||||
|
||||
@ -266,6 +266,11 @@ package spine {
|
||||
eventData.intValue = eventMap["int"] || 0;
|
||||
eventData.floatValue = eventMap["float"] || 0;
|
||||
eventData.stringValue = eventMap["string"] || "";
|
||||
eventData.audioPath = eventMap["audio"] || null;
|
||||
if (eventData.audioPath != null) {
|
||||
eventData.volume = eventMap["volume"] || 1;
|
||||
eventData.balance = eventMap["balance"] || 0;
|
||||
}
|
||||
skeletonData.events.push(eventData);
|
||||
}
|
||||
}
|
||||
@ -714,6 +719,10 @@ package spine {
|
||||
event.intValue = eventMap.hasOwnProperty("int") ? eventMap["int"] : eventData.intValue;
|
||||
event.floatValue = eventMap.hasOwnProperty("float") ? eventMap["float"] : eventData.floatValue;
|
||||
event.stringValue = eventMap.hasOwnProperty("string") ? eventMap["string"] : eventData.stringValue;
|
||||
if (eventData.audioPath != null) {
|
||||
event.volume = eventMap.hasOwnProperty("volume") ? eventMap["volume"] : 1;
|
||||
event.balance = eventMap.hasOwnProperty("balance") ? eventMap["balance"] : 0;
|
||||
}
|
||||
eventTimeline.setFrame(frameIndex++, event);
|
||||
}
|
||||
timelines[timelines.length] = eventTimeline;
|
||||
|
||||
@ -44,6 +44,8 @@ typedef struct spEvent {
|
||||
int intValue;
|
||||
float floatValue;
|
||||
const char* stringValue;
|
||||
float volume;
|
||||
float balance;
|
||||
|
||||
#ifdef __cplusplus
|
||||
spEvent() :
|
||||
@ -51,7 +53,9 @@ typedef struct spEvent {
|
||||
time(0),
|
||||
intValue(0),
|
||||
floatValue(0),
|
||||
stringValue(0) {
|
||||
stringValue(0),
|
||||
volume(0),
|
||||
balance(0) {
|
||||
}
|
||||
#endif
|
||||
} spEvent;
|
||||
|
||||
@ -43,6 +43,8 @@ typedef struct spEventData {
|
||||
float floatValue;
|
||||
const char* stringValue;
|
||||
const char* audioPath;
|
||||
float volume;
|
||||
float balance;
|
||||
|
||||
#ifdef __cplusplus
|
||||
spEventData() :
|
||||
@ -50,7 +52,9 @@ typedef struct spEventData {
|
||||
intValue(0),
|
||||
floatValue(0),
|
||||
stringValue(0),
|
||||
audioPath(0) {
|
||||
audioPath(0),
|
||||
volume(0),
|
||||
balance(0) {
|
||||
}
|
||||
#endif
|
||||
} spEventData;
|
||||
|
||||
@ -592,6 +592,10 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
|
||||
event->stringValue = readString(input);
|
||||
else
|
||||
MALLOC_STR(event->stringValue, eventData->stringValue);
|
||||
if (eventData->audioPath) {
|
||||
event->volume = readFloat(input);
|
||||
event->balance = readFloat(input);
|
||||
}
|
||||
spEventTimeline_setFrame(timeline, i, event);
|
||||
}
|
||||
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
||||
@ -1077,6 +1081,10 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
|
||||
eventData->floatValue = readFloat(input);
|
||||
eventData->stringValue = readString(input);
|
||||
eventData->audioPath = readString(input);
|
||||
if (eventData->audioPath) {
|
||||
eventData->volume = readFloat(input);
|
||||
eventData->balance = readFloat(input);
|
||||
}
|
||||
skeletonData->events[i] = eventData;
|
||||
}
|
||||
|
||||
|
||||
@ -502,6 +502,10 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
|
||||
event->floatValue = Json_getFloat(valueMap, "float", eventData->floatValue);
|
||||
stringValue = Json_getString(valueMap, "string", eventData->stringValue);
|
||||
if (stringValue) MALLOC_STR(event->stringValue, stringValue);
|
||||
if (eventData->audioPath) {
|
||||
event->volume = Json_getFloat(valueMap, "volume", 1);
|
||||
event->balance = Json_getFloat(valueMap, "volume", 0);
|
||||
}
|
||||
spEventTimeline_setFrame(timeline, frameIndex, event);
|
||||
}
|
||||
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
|
||||
@ -1081,6 +1085,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
||||
if (events) {
|
||||
Json *eventMap;
|
||||
const char* stringValue;
|
||||
const char* audioPath;
|
||||
skeletonData->eventsCount = events->size;
|
||||
skeletonData->events = MALLOC(spEventData*, events->size);
|
||||
for (eventMap = events->child, i = 0; eventMap; eventMap = eventMap->next, ++i) {
|
||||
@ -1089,6 +1094,12 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
||||
eventData->floatValue = Json_getFloat(eventMap, "float", 0);
|
||||
stringValue = Json_getString(eventMap, "string", 0);
|
||||
if (stringValue) MALLOC_STR(eventData->stringValue, stringValue);
|
||||
audioPath = Json_getString(eventMap, "audio", 0);
|
||||
if (audioPath) {
|
||||
MALLOC_STR(eventData->audioPath, audioPath);
|
||||
eventData->volume = Json_getFloat(eventMap, "volume", 1);
|
||||
eventData->balance = Json_getFloat(eventMap, "balance", 0);
|
||||
}
|
||||
skeletonData->events[i] = eventData;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
spine-corona/data/spineboy-pro.json
Normal file
1
spine-corona/data/spineboy-pro.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -60,7 +60,7 @@ function loadSkeleton(atlasFile, jsonFile, x, y, scale, animation, skin)
|
||||
print(entry.trackIndex.." dispose: "..entry.animation.name)
|
||||
end
|
||||
animationState.onEvent = function (entry, event)
|
||||
print(entry.trackIndex.." event: "..entry.animation.name..", "..event.data.name..", "..event.intValue..", "..event.floatValue..", '"..(event.stringValue or "").."'")
|
||||
print(entry.trackIndex.." event: "..entry.animation.name..", "..event.data.name..", "..event.intValue..", "..event.floatValue..", '"..(event.stringValue or "").."'" .. ", " .. event.volume .. ", " .. event.balance)
|
||||
end
|
||||
|
||||
if atlasFile == "spineboy.atlas" then
|
||||
@ -81,9 +81,9 @@ function loadSkeleton(atlasFile, jsonFile, x, y, scale, animation, skin)
|
||||
return { skeleton = skeleton, state = animationState }
|
||||
end
|
||||
|
||||
table.insert(skeletons, loadSkeleton("spineboy.atlas", "spineboy-pro.json", 240, 300, 0.4, "walk"))
|
||||
table.insert(skeletons, loadSkeleton("stretchyman.atlas", "stretchyman-stretchy-ik.json", 40, 300, 0.5, "sneak"))
|
||||
table.insert(skeletons, loadSkeleton("coin.atlas", "coin-pro.json", 240, 300, 0.4, "rotate"))
|
||||
table.insert(skeletons, loadSkeleton("spineboy.atlas", "spineboy-ess.json", 240, 300, 0.4, "walk"))
|
||||
table.insert(skeletons, loadSkeleton("raptor.atlas", "raptor-pro.json", 200, 300, 0.25, "walk"))
|
||||
table.insert(skeletons, loadSkeleton("goblins.atlas", "goblins-pro.json", 240, 300, 0.8, "walk", "goblin"))
|
||||
table.insert(skeletons, loadSkeleton("stretchyman.atlas", "stretchyman-pro.json", 40, 300, 0.5, "sneak"))
|
||||
|
||||
@ -65,12 +65,22 @@ public:
|
||||
|
||||
void setStringValue(const String &inValue);
|
||||
|
||||
float getVolume();
|
||||
|
||||
void setVolume(float inValue);
|
||||
|
||||
float getBalance();
|
||||
|
||||
void setBalance(float inValue);
|
||||
|
||||
private:
|
||||
const EventData &_data;
|
||||
const float _time;
|
||||
int _intValue;
|
||||
float _floatValue;
|
||||
String _stringValue;
|
||||
float _volume;
|
||||
float _balance;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -61,11 +61,26 @@ public:
|
||||
|
||||
void setStringValue(const String &inValue);
|
||||
|
||||
const String &getAudioPath();
|
||||
|
||||
void setAudioPath(const String &inValue);
|
||||
|
||||
float getVolume();
|
||||
|
||||
void setVolume(float inValue);
|
||||
|
||||
float getBalance();
|
||||
|
||||
void setBalance(float inValue);
|
||||
|
||||
private:
|
||||
const String _name;
|
||||
int _intValue;
|
||||
float _floatValue;
|
||||
String _stringValue;
|
||||
String _audioPath;
|
||||
float _volume;
|
||||
float _balance;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +41,9 @@ spine::Event::Event(float time, const spine::EventData &data) :
|
||||
_time(time),
|
||||
_intValue(0),
|
||||
_floatValue(0),
|
||||
_stringValue() {
|
||||
_stringValue(),
|
||||
_volume(1),
|
||||
_balance(0) {
|
||||
}
|
||||
|
||||
const spine::EventData &spine::Event::getData() {
|
||||
@ -75,3 +77,20 @@ const spine::String &spine::Event::getStringValue() {
|
||||
void spine::Event::setStringValue(const spine::String &inValue) {
|
||||
_stringValue = inValue;
|
||||
}
|
||||
|
||||
|
||||
float Event::getVolume() {
|
||||
return _volume;
|
||||
}
|
||||
|
||||
void Event::setVolume(float inValue) {
|
||||
_volume = inValue;
|
||||
}
|
||||
|
||||
float Event::getBalance() {
|
||||
return _balance;
|
||||
}
|
||||
|
||||
void Event::setBalance(float inValue) {
|
||||
_balance = inValue;
|
||||
}
|
||||
|
||||
@ -38,9 +38,12 @@
|
||||
|
||||
spine::EventData::EventData(const spine::String &name) :
|
||||
_name(name),
|
||||
_intValue((int)0),
|
||||
_floatValue(0.0f)
|
||||
{
|
||||
_intValue(0),
|
||||
_floatValue(0),
|
||||
_stringValue(),
|
||||
_audioPath(),
|
||||
_volume(1),
|
||||
_balance(0) {
|
||||
assert(_name.length() > 0);
|
||||
}
|
||||
|
||||
@ -72,3 +75,28 @@ const spine::String &spine::EventData::getStringValue() {
|
||||
void spine::EventData::setStringValue(const spine::String &inValue) {
|
||||
this->_stringValue = inValue;
|
||||
}
|
||||
|
||||
const String &EventData::getAudioPath() {
|
||||
return _audioPath;
|
||||
}
|
||||
|
||||
void EventData::setAudioPath(const String &inValue) {
|
||||
_audioPath = inValue;
|
||||
}
|
||||
|
||||
|
||||
float EventData::getVolume() {
|
||||
return _volume;
|
||||
}
|
||||
|
||||
void EventData::setVolume(float inValue) {
|
||||
_volume = inValue;
|
||||
}
|
||||
|
||||
float EventData::getBalance() {
|
||||
return _balance;
|
||||
}
|
||||
|
||||
void EventData::setBalance(float inValue) {
|
||||
_balance = inValue;
|
||||
}
|
||||
|
||||
@ -315,7 +315,11 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
||||
eventData->_intValue = readVarint(input, false);
|
||||
eventData->_floatValue = readFloat(input);
|
||||
eventData->_stringValue.own(readString(input));
|
||||
String(readString(input), true); // skip audio path
|
||||
eventData->_audioPath.own(readString(input)); // skip audio path
|
||||
if (!eventData->_audioPath.isEmpty()) {
|
||||
eventData->_volume = readFloat(input);
|
||||
eventData->_balance = readFloat(input);
|
||||
}
|
||||
skeletonData->_events[i] = eventData;
|
||||
}
|
||||
|
||||
@ -1016,6 +1020,11 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
|
||||
if (freeString) {
|
||||
SpineExtension::free(event_stringValue, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
if (!eventData->_audioPath.isEmpty()) {
|
||||
event->_volume = readFloat(input);
|
||||
event->_balance = readFloat(input);
|
||||
}
|
||||
timeline->setFrame(i, event);
|
||||
}
|
||||
|
||||
|
||||
@ -678,6 +678,12 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
|
||||
eventData->_floatValue = Json::getFloat(eventMap, "float", 0);
|
||||
const char *stringValue = Json::getString(eventMap, "string", 0);
|
||||
eventData->_stringValue = stringValue;
|
||||
const char *audioPath = Json::getString(eventMap, "audio", 0);
|
||||
eventData->_audioPath = audioPath;
|
||||
if (audioPath) {
|
||||
eventData->_volume = Json::getFloat(eventMap, "volume", 1);
|
||||
eventData->_balance = Json::getFloat(eventMap, "balance", 0);
|
||||
}
|
||||
skeletonData->_events[i] = eventData;
|
||||
}
|
||||
}
|
||||
@ -1175,6 +1181,10 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
|
||||
event->_intValue = Json::getInt(valueMap, "int", eventData->_intValue);
|
||||
event->_floatValue = Json::getFloat(valueMap, "float", eventData->_floatValue);
|
||||
event->_stringValue = Json::getString(valueMap, "string", eventData->_stringValue.buffer());
|
||||
if (!eventData->_audioPath.isEmpty()) {
|
||||
event->_volume = Json::getFloat(valueMap, "volume", 1);
|
||||
event->_balance = Json::getFloat(valueMap, "balance", 0);
|
||||
}
|
||||
timeline->setFrame(frameIndex, event);
|
||||
}
|
||||
timelines.add(timeline);
|
||||
|
||||
@ -34,17 +34,16 @@ using System.Collections.Generic;
|
||||
namespace Spine {
|
||||
public class AnimationState {
|
||||
static readonly Animation EmptyAnimation = new Animation("<empty>", new ExposedList<Timeline>(), 0);
|
||||
internal const int Subsequent = 0, First = 1, Dip = 2, DipMix = 3;
|
||||
internal const int Subsequent = 0, First = 1, Hold = 2, HoldMix = 3;
|
||||
|
||||
private AnimationStateData data;
|
||||
|
||||
Pool<TrackEntry> trackEntryPool = new Pool<TrackEntry>();
|
||||
private readonly Pool<TrackEntry> trackEntryPool = new Pool<TrackEntry>();
|
||||
private readonly ExposedList<TrackEntry> tracks = new ExposedList<TrackEntry>();
|
||||
private readonly ExposedList<Event> events = new ExposedList<Event>();
|
||||
private readonly EventQueue queue; // Initialized by constructor.
|
||||
|
||||
private readonly HashSet<int> propertyIDs = new HashSet<int>();
|
||||
private readonly ExposedList<TrackEntry> mixingTo = new ExposedList<TrackEntry>();
|
||||
private bool animationsChanged;
|
||||
|
||||
private float timeScale = 1;
|
||||
@ -119,6 +118,7 @@ namespace Spine {
|
||||
// End mixing from entries once all have completed.
|
||||
var from = current.mixingFrom;
|
||||
current.mixingFrom = null;
|
||||
if (from != null) from.mixingTo = null;
|
||||
while (from != null) {
|
||||
queue.End(from);
|
||||
from = from.mixingFrom;
|
||||
@ -146,6 +146,7 @@ namespace Spine {
|
||||
// Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame).
|
||||
if (from.totalAlpha == 0 || to.mixDuration == 0) {
|
||||
to.mixingFrom = from.mixingFrom;
|
||||
if (from.mixingFrom != null) from.mixingFrom.mixingTo = to;
|
||||
to.interruptAlpha = from.interruptAlpha;
|
||||
queue.End(from);
|
||||
}
|
||||
@ -187,11 +188,11 @@ namespace Spine {
|
||||
int timelineCount = current.animation.timelines.Count;
|
||||
var timelines = current.animation.timelines;
|
||||
var timelinesItems = timelines.Items;
|
||||
if (mix == 1 || blend == MixBlend.Add) {
|
||||
if (i == 0 && (mix == 1 || blend == MixBlend.Add)) {
|
||||
for (int ii = 0; ii < timelineCount; ii++)
|
||||
timelinesItems[ii].Apply(skeleton, animationLast, animationTime, events, mix, blend, MixDirection.In);
|
||||
} else {
|
||||
var timelineData = current.timelineData.Items;
|
||||
var timelineMode = current.timelineMode.Items;
|
||||
|
||||
bool firstFrame = current.timelinesRotation.Count == 0;
|
||||
if (firstFrame) current.timelinesRotation.EnsureCapacity(timelines.Count << 1);
|
||||
@ -199,7 +200,7 @@ namespace Spine {
|
||||
|
||||
for (int ii = 0; ii < timelineCount; ii++) {
|
||||
Timeline timeline = timelinesItems[ii];
|
||||
MixBlend timelineBlend = timelineData[ii] >= AnimationState.Subsequent ? blend : MixBlend.Setup;
|
||||
MixBlend timelineBlend = timelineMode[ii] >= AnimationState.Subsequent ? blend : MixBlend.Setup;
|
||||
var rotateTimeline = timeline as RotateTimeline;
|
||||
if (rotateTimeline != null)
|
||||
ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
|
||||
@ -237,14 +238,14 @@ namespace Spine {
|
||||
var timelines = from.animation.timelines;
|
||||
int timelineCount = timelines.Count;
|
||||
var timelinesItems = timelines.Items;
|
||||
float alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix);
|
||||
float alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
|
||||
|
||||
if (blend == MixBlend.Add) {
|
||||
for (int i = 0; i < timelineCount; i++)
|
||||
(timelinesItems[i]).Apply(skeleton, animationLast, animationTime, eventBuffer, alphaMix, blend, MixDirection.Out);
|
||||
} else {
|
||||
var timelineData = from.timelineData.Items;
|
||||
var timelineDipMix = from.timelineDipMix.Items;
|
||||
var timelineMode = from.timelineMode.Items;
|
||||
var timelineHoldMix = from.timelineHoldMix.Items;
|
||||
|
||||
bool firstFrame = from.timelinesRotation.Count == 0;
|
||||
if (firstFrame) from.timelinesRotation.Resize(timelines.Count << 1); // from.timelinesRotation.setSize
|
||||
@ -255,7 +256,7 @@ namespace Spine {
|
||||
Timeline timeline = timelinesItems[i];
|
||||
MixBlend timelineBlend;
|
||||
float alpha;
|
||||
switch (timelineData[i]) {
|
||||
switch (timelineMode[i]) {
|
||||
case AnimationState.Subsequent:
|
||||
if (!attachments && timeline is AttachmentTimeline)
|
||||
continue;
|
||||
@ -268,14 +269,14 @@ namespace Spine {
|
||||
timelineBlend = MixBlend.Setup;
|
||||
alpha = alphaMix;
|
||||
break;
|
||||
case AnimationState.Dip:
|
||||
case AnimationState.Hold:
|
||||
timelineBlend = MixBlend.Setup;
|
||||
alpha = alphaDip;
|
||||
alpha = alphaHold;
|
||||
break;
|
||||
default:
|
||||
timelineBlend = MixBlend.Setup;
|
||||
TrackEntry dipMix = timelineDipMix[i];
|
||||
alpha = alphaDip * Math.Max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
|
||||
TrackEntry holdMix = timelineHoldMix[i];
|
||||
alpha = alphaHold * Math.Max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
|
||||
break;
|
||||
}
|
||||
from.totalAlpha += alpha;
|
||||
@ -428,6 +429,7 @@ namespace Spine {
|
||||
if (from == null) break;
|
||||
queue.End(from);
|
||||
entry.mixingFrom = null;
|
||||
entry.mixingTo = null;
|
||||
entry = from;
|
||||
}
|
||||
|
||||
@ -444,6 +446,7 @@ namespace Spine {
|
||||
if (from != null) {
|
||||
if (interrupt) queue.Interrupt(from);
|
||||
current.mixingFrom = from;
|
||||
current.mixingTo = current;
|
||||
current.mixTime = 0;
|
||||
|
||||
// Store interrupted mix percentage.
|
||||
@ -599,6 +602,7 @@ namespace Spine {
|
||||
entry.trackIndex = trackIndex;
|
||||
entry.animation = animation;
|
||||
entry.loop = loop;
|
||||
entry.holdPrevious = false;
|
||||
|
||||
entry.eventThreshold = 0;
|
||||
entry.attachmentThreshold = 0;
|
||||
@ -636,17 +640,71 @@ namespace Spine {
|
||||
private void AnimationsChanged () {
|
||||
animationsChanged = false;
|
||||
|
||||
var propertyIDs = this.propertyIDs;
|
||||
propertyIDs.Clear();
|
||||
var mixingTo = this.mixingTo;
|
||||
this.propertyIDs.Clear();
|
||||
|
||||
var tracksItems = tracks.Items;
|
||||
for (int i = 0, n = tracks.Count; i < n; i++) {
|
||||
var entry = tracksItems[i];
|
||||
if (entry != null && (i == 0 || entry.mixBlend != MixBlend.Add)) entry.SetTimelineData(null, mixingTo, propertyIDs);
|
||||
if (entry == null) continue;
|
||||
// Move to last entry, then iterate in reverse (the order animations are applied).
|
||||
while (entry.mixingFrom != null)
|
||||
entry = entry.mixingFrom;
|
||||
|
||||
do {
|
||||
if (entry.mixingTo == null || entry.mixBlend != MixBlend.Add) SetTimelineModes(entry);
|
||||
entry = entry.mixingTo;
|
||||
} while (entry != null);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void SetTimelineModes (TrackEntry entry) {
|
||||
var to = entry.mixingTo;
|
||||
var timelines = entry.animation.timelines.Items;
|
||||
int timelinesCount = entry.animation.timelines.Count;
|
||||
var timelineMode = entry.timelineMode.Resize(timelinesCount).Items; //timelineMode.setSize(timelinesCount);
|
||||
entry.timelineHoldMix.Clear();
|
||||
var timelineHoldMix = entry.timelineHoldMix.Resize(timelinesCount).Items; //timelineHoldMix.setSize(timelinesCount);
|
||||
var propertyIDs = this.propertyIDs;
|
||||
|
||||
if (to != null && to.holdPrevious) {
|
||||
for (int i = 0; i < timelinesCount; i++) {
|
||||
propertyIDs.Add(timelines[i].PropertyId);
|
||||
timelineMode[i] = AnimationState.Hold;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// outer:
|
||||
for (int i = 0; i < timelinesCount; i++) {
|
||||
int id = timelines[i].PropertyId;
|
||||
if (!propertyIDs.Add(id))
|
||||
timelineMode[i] = AnimationState.Subsequent;
|
||||
else if (to == null || !HasTimeline(to, id))
|
||||
timelineMode[i] = AnimationState.First;
|
||||
else {
|
||||
for (TrackEntry next = to.mixingTo; next != null; next = next.mixingTo) {
|
||||
if (HasTimeline(next, id)) continue;
|
||||
if (next.mixDuration > 0) {
|
||||
timelineMode[i] = AnimationState.HoldMix;
|
||||
timelineHoldMix[i] = next;
|
||||
goto continue_outer; // continue outer;
|
||||
}
|
||||
break;
|
||||
}
|
||||
timelineMode[i] = AnimationState.Hold;
|
||||
}
|
||||
continue_outer: {}
|
||||
}
|
||||
}
|
||||
|
||||
static bool HasTimeline (TrackEntry entry, int id) {
|
||||
var timelines = entry.animation.timelines.Items;
|
||||
for (int i = 0, n = entry.animation.timelines.Count; i < n; i++)
|
||||
if (timelines[i].PropertyId == id) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <returns>The track entry for the animation currently playing on the track, or null if no animation is currently playing.</returns>
|
||||
public TrackEntry GetCurrent (int trackIndex) {
|
||||
return (trackIndex >= tracks.Count) ? null : tracks.Items[trackIndex];
|
||||
@ -675,17 +733,17 @@ namespace Spine {
|
||||
public class TrackEntry : Pool<TrackEntry>.IPoolable {
|
||||
internal Animation animation;
|
||||
|
||||
internal TrackEntry next, mixingFrom;
|
||||
internal TrackEntry next, mixingFrom, mixingTo;
|
||||
internal int trackIndex;
|
||||
|
||||
internal bool loop;
|
||||
internal bool loop, holdPrevious;
|
||||
internal float eventThreshold, attachmentThreshold, drawOrderThreshold;
|
||||
internal float animationStart, animationEnd, animationLast, nextAnimationLast;
|
||||
internal float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale = 1f;
|
||||
internal float alpha, mixTime, mixDuration, interruptAlpha, totalAlpha;
|
||||
internal MixBlend mixBlend = MixBlend.Replace;
|
||||
internal readonly ExposedList<int> timelineData = new ExposedList<int>();
|
||||
internal readonly ExposedList<TrackEntry> timelineDipMix = new ExposedList<TrackEntry>();
|
||||
internal readonly ExposedList<int> timelineMode = new ExposedList<int>();
|
||||
internal readonly ExposedList<TrackEntry> timelineHoldMix = new ExposedList<TrackEntry>();
|
||||
internal readonly ExposedList<float> timelinesRotation = new ExposedList<float>();
|
||||
|
||||
// IPoolable.Reset()
|
||||
@ -693,8 +751,8 @@ namespace Spine {
|
||||
next = null;
|
||||
mixingFrom = null;
|
||||
animation = null;
|
||||
timelineData.Clear();
|
||||
timelineDipMix.Clear();
|
||||
timelineMode.Clear();
|
||||
timelineHoldMix.Clear();
|
||||
timelinesRotation.Clear();
|
||||
|
||||
Start = null;
|
||||
@ -705,47 +763,6 @@ namespace Spine {
|
||||
Event = null;
|
||||
}
|
||||
|
||||
/// <summary>Sets the timeline data.</summary>
|
||||
/// <param name="to">May be null.</param>
|
||||
internal TrackEntry SetTimelineData (TrackEntry to, ExposedList<TrackEntry> mixingToArray, HashSet<int> propertyIDs) {
|
||||
if (to != null) mixingToArray.Add(to);
|
||||
var lastEntry = mixingFrom != null ? mixingFrom.SetTimelineData(this, mixingToArray, propertyIDs) : this;
|
||||
if (to != null) mixingToArray.Pop();
|
||||
|
||||
var mixingTo = mixingToArray.Items;
|
||||
int mixingToLast = mixingToArray.Count - 1;
|
||||
var timelines = animation.timelines.Items;
|
||||
int timelinesCount = animation.timelines.Count;
|
||||
var timelineDataItems = timelineData.Resize(timelinesCount).Items; // timelineData.setSize(timelinesCount);
|
||||
timelineDipMix.Clear();
|
||||
var timelineDipMixItems = timelineDipMix.Resize(timelinesCount).Items; //timelineDipMix.setSize(timelinesCount);
|
||||
|
||||
// outer:
|
||||
for (int i = 0; i < timelinesCount; i++) {
|
||||
int id = timelines[i].PropertyId;
|
||||
if (!propertyIDs.Add(id)) {
|
||||
timelineDataItems[i] = AnimationState.Subsequent;
|
||||
} else if (to == null || !to.HasTimeline(id)) {
|
||||
timelineDataItems[i] = AnimationState.First;
|
||||
} else {
|
||||
for (int ii = mixingToLast; ii >= 0; ii--) {
|
||||
var entry = mixingTo[ii];
|
||||
if (!entry.HasTimeline(id)) {
|
||||
if (entry.mixDuration > 0) {
|
||||
timelineDataItems[i] = AnimationState.DipMix;
|
||||
timelineDipMixItems[i] = entry;
|
||||
goto continue_outer; // continue outer;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
timelineDataItems[i] = AnimationState.Dip;
|
||||
}
|
||||
continue_outer: {}
|
||||
}
|
||||
return lastEntry;
|
||||
}
|
||||
|
||||
bool HasTimeline (int id) {
|
||||
var timelines = animation.timelines.Items;
|
||||
for (int i = 0, n = animation.timelines.Count; i < n; i++)
|
||||
@ -903,6 +920,15 @@ namespace Spine {
|
||||
/// mixing is currently occuring. When mixing from multiple animations, MixingFrom makes up a linked list.</summary>
|
||||
public TrackEntry MixingFrom { get { return mixingFrom; } }
|
||||
|
||||
/// <summary>
|
||||
/// If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead of being mixed out.
|
||||
///
|
||||
/// When mixing between animations that key the same property, if a lower track also keys that property then the value will briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0% while the second animation mixes from 0% to 100%. Setting HoldPrevious to true applies the first animation at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which keys the property, only when a higher track also keys the property.
|
||||
///
|
||||
/// Snapping will occur if HoldPrevious is true and this animation does not key all the same properties as the previous animation.
|
||||
/// </summary>
|
||||
public bool HoldPrevious { get { return holdPrevious; } set { holdPrevious = value; } }
|
||||
|
||||
public event AnimationState.TrackEntryDelegate Start, Interrupt, End, Dispose, Complete;
|
||||
public event AnimationState.TrackEntryEventDelegate Event;
|
||||
internal void OnStart () { if (Start != null) Start(this); }
|
||||
|
||||
@ -38,6 +38,8 @@ namespace Spine {
|
||||
internal int intValue;
|
||||
internal float floatValue;
|
||||
internal string stringValue;
|
||||
internal float volume;
|
||||
internal float balance;
|
||||
|
||||
public EventData Data { get { return data; } }
|
||||
/// <summary>The animation time this event was keyed.</summary>
|
||||
@ -47,6 +49,9 @@ namespace Spine {
|
||||
public float Float { get { return floatValue; } set { floatValue = value; } }
|
||||
public string String { get { return stringValue; } set { stringValue = value; } }
|
||||
|
||||
public float Volume { get { return volume; } set { volume = value; } }
|
||||
public float Balance { get { return balance; } set { balance = value; } }
|
||||
|
||||
public Event (float time, EventData data) {
|
||||
if (data == null) throw new ArgumentNullException("data", "data cannot be null.");
|
||||
this.time = time;
|
||||
|
||||
@ -40,7 +40,10 @@ namespace Spine {
|
||||
public int Int { get; set; }
|
||||
public float Float { get; set; }
|
||||
public string @String { get; set; }
|
||||
|
||||
public string AudioPath { get; set; }
|
||||
public float Volume { get; set; }
|
||||
public float Balance { get; set; }
|
||||
|
||||
public EventData (string name) {
|
||||
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
|
||||
|
||||
@ -288,6 +288,10 @@ namespace Spine {
|
||||
data.Float = ReadFloat(input);
|
||||
data.String = ReadString(input);
|
||||
data.AudioPath = ReadString(input);
|
||||
if (data.AudioPath != null) {
|
||||
data.Volume = ReadFloat(input);
|
||||
data.Balance = ReadFloat(input);
|
||||
}
|
||||
skeletonData.events.Add(data);
|
||||
}
|
||||
|
||||
@ -804,10 +808,15 @@ namespace Spine {
|
||||
for (int i = 0; i < eventCount; i++) {
|
||||
float time = ReadFloat(input);
|
||||
EventData eventData = skeletonData.events.Items[ReadVarint(input, true)];
|
||||
Event e = new Event(time, eventData);
|
||||
e.Int = ReadVarint(input, false);
|
||||
e.Float = ReadFloat(input);
|
||||
e.String = ReadBoolean(input) ? ReadString(input) : eventData.String;
|
||||
Event e = new Event(time, eventData) {
|
||||
Int = ReadVarint(input, false),
|
||||
Float = ReadFloat(input),
|
||||
String = ReadBoolean(input) ? ReadString(input) : eventData.String
|
||||
};
|
||||
if (e.data.AudioPath != null) {
|
||||
e.volume = ReadFloat(input);
|
||||
e.balance = ReadFloat(input);
|
||||
}
|
||||
timeline.SetFrame(i, e);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
|
||||
@ -296,7 +296,11 @@ namespace Spine {
|
||||
data.Int = GetInt(entryMap, "int", 0);
|
||||
data.Float = GetFloat(entryMap, "float", 0);
|
||||
data.String = GetString(entryMap, "string", string.Empty);
|
||||
data.AudioPath = GetString(entryMap, "audio", string.Empty);
|
||||
data.AudioPath = GetString(entryMap, "audio", null);
|
||||
if (data.AudioPath != null) {
|
||||
data.Volume = GetFloat(entryMap, "volume", 1);
|
||||
data.Balance = GetFloat(entryMap, "balance", 0);
|
||||
}
|
||||
skeletonData.events.Add(data);
|
||||
}
|
||||
}
|
||||
@ -779,10 +783,15 @@ namespace Spine {
|
||||
foreach (Dictionary<string, Object> eventMap in eventsMap) {
|
||||
EventData eventData = skeletonData.FindEvent((string)eventMap["name"]);
|
||||
if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
|
||||
var e = new Event((float)eventMap["time"], eventData);
|
||||
e.Int = GetInt(eventMap, "int", eventData.Int);
|
||||
e.Float = GetFloat(eventMap, "float", eventData.Float);
|
||||
e.String = GetString(eventMap, "string", eventData.String);
|
||||
var e = new Event((float)eventMap["time"], eventData) {
|
||||
intValue = GetInt(eventMap, "int", eventData.Int),
|
||||
floatValue = GetFloat(eventMap, "float", eventData.Float),
|
||||
stringValue = GetString(eventMap, "string", eventData.String)
|
||||
};
|
||||
if (e.data.AudioPath != null) {
|
||||
e.volume = GetFloat(eventMap, "volume", eventData.Volume);
|
||||
e.balance = GetFloat(eventMap, "balance", eventData.Balance);
|
||||
}
|
||||
timeline.SetFrame(frameIndex++, e);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -666,7 +666,6 @@ public class AnimationState {
|
||||
private void animationsChanged () {
|
||||
animationsChanged = false;
|
||||
|
||||
IntSet propertyIDs = this.propertyIDs;
|
||||
propertyIDs.clear(2048);
|
||||
|
||||
for (int i = 0, n = tracks.size; i < n; i++) {
|
||||
|
||||
@ -44,6 +44,7 @@ public class Event {
|
||||
int intValue;
|
||||
float floatValue;
|
||||
String stringValue;
|
||||
float volume, balance;
|
||||
final float time;
|
||||
|
||||
public Event (float time, EventData data) {
|
||||
@ -76,6 +77,22 @@ public class Event {
|
||||
this.stringValue = stringValue;
|
||||
}
|
||||
|
||||
public float getVolume () {
|
||||
return volume;
|
||||
}
|
||||
|
||||
public void setVolume (float volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
public float getBalance () {
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setBalance (float balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
/** The animation time this event was keyed. */
|
||||
public float getTime () {
|
||||
return time;
|
||||
|
||||
@ -38,6 +38,7 @@ public class EventData {
|
||||
int intValue;
|
||||
float floatValue;
|
||||
String stringValue, audioPath;
|
||||
float volume, balance;
|
||||
|
||||
public EventData (String name) {
|
||||
if (name == null) throw new IllegalArgumentException("name cannot be null.");
|
||||
@ -76,6 +77,22 @@ public class EventData {
|
||||
this.audioPath = audioPath;
|
||||
}
|
||||
|
||||
public float getVolume () {
|
||||
return volume;
|
||||
}
|
||||
|
||||
public void setVolume (float volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
public float getBalance () {
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setBalance (float balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
/** The name of the event, which is unique within the skeleton. */
|
||||
public String getName () {
|
||||
return name;
|
||||
|
||||
@ -310,6 +310,10 @@ public class SkeletonBinary {
|
||||
data.floatValue = input.readFloat();
|
||||
data.stringValue = input.readString();
|
||||
data.audioPath = input.readString();
|
||||
if (data.audioPath != null) {
|
||||
data.volume = input.readFloat();
|
||||
data.balance = input.readFloat();
|
||||
}
|
||||
skeletonData.events.add(data);
|
||||
}
|
||||
|
||||
@ -821,6 +825,10 @@ public class SkeletonBinary {
|
||||
event.intValue = input.readInt(false);
|
||||
event.floatValue = input.readFloat();
|
||||
event.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue;
|
||||
if (event.getData().audioPath != null) {
|
||||
event.volume = input.readFloat();
|
||||
event.balance = input.readFloat();
|
||||
}
|
||||
timeline.setFrame(i, event);
|
||||
}
|
||||
timelines.add(timeline);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user