Merge branch '3.8' into 3.9-beta

This commit is contained in:
badlogic 2019-09-26 16:52:13 +02:00
commit 262be9ff39
14 changed files with 73 additions and 54 deletions

View File

@ -30,10 +30,12 @@
package spine.animation { package spine.animation {
import spine.Event; import spine.Event;
import spine.Skeleton; import spine.Skeleton;
import flash.utils.Dictionary;
public class Animation { public class Animation {
internal var _name : String; internal var _name : String;
public var _timelines : Vector.<Timeline>; public var _timelines : Vector.<Timeline>;
internal var _timelineIds : Dictionary = new Dictionary();
public var duration : Number; public var duration : Number;
public function Animation(name : String, timelines : Vector.<Timeline>, duration : Number) { public function Animation(name : String, timelines : Vector.<Timeline>, duration : Number) {
@ -41,8 +43,14 @@ package spine.animation {
if (timelines == null) throw new ArgumentError("timelines cannot be null."); if (timelines == null) throw new ArgumentError("timelines cannot be null.");
_name = name; _name = name;
_timelines = timelines; _timelines = timelines;
for (var i : Number = 0; i < timelines.length; i++)
_timelineIds[timelines[i].getPropertyId()] = true;
this.duration = duration; this.duration = duration;
} }
public function hasTimeline(id: Number) : Boolean {
return _timelineIds[id] == true;
}
public function get timelines() : Vector.<Timeline> { public function get timelines() : Vector.<Timeline> {
return _timelines; return _timelines;

View File

@ -664,11 +664,11 @@ package spine.animation {
if (contained != null) { if (contained != null) {
timelineMode[i] = AnimationState.SUBSEQUENT; timelineMode[i] = AnimationState.SUBSEQUENT;
} else if (to == null || timeline is AttachmentTimeline || timeline is DrawOrderTimeline } else if (to == null || timeline is AttachmentTimeline || timeline is DrawOrderTimeline
|| timeline is EventTimeline || !hasTimeline(to, intId)) { || timeline is EventTimeline || !to.animation.hasTimeline(intId)) {
timelineMode[i] = AnimationState.FIRST; timelineMode[i] = AnimationState.FIRST;
} else { } else {
for (var next : TrackEntry = to.mixingTo; next != null; next = next.mixingTo) { for (var next : TrackEntry = to.mixingTo; next != null; next = next.mixingTo) {
if (hasTimeline(next, intId)) continue; if (next.animation.hasTimeline(intId)) continue;
if (entry.mixDuration > 0) { if (entry.mixDuration > 0) {
timelineMode[i] = AnimationState.HOLD_MIX; timelineMode[i] = AnimationState.HOLD_MIX;
timelineHoldMix[i] = entry; timelineHoldMix[i] = entry;
@ -681,13 +681,6 @@ package spine.animation {
} }
} }
private static function hasTimeline (entry: TrackEntry, id : int) : Boolean {
var timelines : Vector.<Timeline> = entry.animation.timelines;
for (var i : int = 0, n : int = entry.animation.timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id) return true;
return false;
}
public function getCurrent(trackIndex : int) : TrackEntry { public function getCurrent(trackIndex : int) : TrackEntry {
if (trackIndex >= tracks.length) return null; if (trackIndex >= tracks.length) return null;
return tracks[trackIndex]; return tracks[trackIndex];

View File

@ -31,6 +31,7 @@
#define Spine_Animation_h #define Spine_Animation_h
#include <spine/Vector.h> #include <spine/Vector.h>
#include <spine/HashMap.h>
#include <spine/MixBlend.h> #include <spine/MixBlend.h>
#include <spine/MixDirection.h> #include <spine/MixDirection.h>
#include <spine/SpineObject.h> #include <spine/SpineObject.h>
@ -94,6 +95,8 @@ public:
Vector<Timeline *> &getTimelines(); Vector<Timeline *> &getTimelines();
bool hasTimeline(int id);
float getDuration(); float getDuration();
void setDuration(float inValue); void setDuration(float inValue);
@ -102,6 +105,7 @@ public:
private: private:
Vector<Timeline *> _timelines; Vector<Timeline *> _timelines;
HashMap<int, bool> _timelineIds;
float _duration; float _duration;
String _name; String _name;

View File

@ -393,7 +393,7 @@ namespace spine {
Vector<Event*> _events; Vector<Event*> _events;
EventQueue* _queue; EventQueue* _queue;
Vector<int> _propertyIDs; HashMap<int, bool> _propertyIDs;
bool _animationsChanged; bool _animationsChanged;
AnimationStateListener _listener; AnimationStateListener _listener;
@ -429,8 +429,6 @@ namespace spine {
void computeHold(TrackEntry *entry); void computeHold(TrackEntry *entry);
void computeNotLast(TrackEntry *entry); void computeNotLast(TrackEntry *entry);
bool hasTimeline(TrackEntry *entry, int inId);
}; };
} }

View File

@ -30,6 +30,7 @@
#ifndef Spine_Extension_h #ifndef Spine_Extension_h
#define Spine_Extension_h #define Spine_Extension_h
#include <stdlib.h> #include <stdlib.h>
#include <spine/dll.h> #include <spine/dll.h>

View File

@ -89,11 +89,17 @@ public:
} }
~HashMap() { ~HashMap() {
clear();
}
void clear() {
for (Entry *entry = _head; entry != NULL;) { for (Entry *entry = _head; entry != NULL;) {
Entry* next = entry->next; Entry* next = entry->next;
delete entry; delete entry;
entry = next; entry = next;
} }
_head = NULL;
_size = 0;
} }
size_t size() { size_t size() {

View File

@ -44,9 +44,16 @@ using namespace spine;
Animation::Animation(const String &name, Vector<Timeline *> &timelines, float duration) : Animation::Animation(const String &name, Vector<Timeline *> &timelines, float duration) :
_timelines(timelines), _timelines(timelines),
_timelineIds(),
_duration(duration), _duration(duration),
_name(name) { _name(name) {
assert(_name.length() > 0); assert(_name.length() > 0);
for (int i = 0; i < (int)timelines.size(); i++)
_timelineIds.put(timelines[i]->getPropertyId(), true);
}
bool Animation::hasTimeline(int id) {
return _timelineIds.containsKey(id);
} }
Animation::~Animation() { Animation::~Animation() {

View File

@ -976,7 +976,7 @@ void AnimationState::computeHold(TrackEntry *entry) {
if (to != NULL && to->_holdPrevious) { if (to != NULL && to->_holdPrevious) {
for (size_t i = 0; i < timelinesCount; i++) { for (size_t i = 0; i < timelinesCount; i++) {
int id = timelines[i]->getPropertyId(); int id = timelines[i]->getPropertyId();
if (!_propertyIDs.contains(id)) _propertyIDs.add(id); if (!_propertyIDs.containsKey(id)) _propertyIDs.put(id, true);
timelineMode[i] = Hold; timelineMode[i] = Hold;
} }
return; return;
@ -988,18 +988,18 @@ void AnimationState::computeHold(TrackEntry *entry) {
for (; i < timelinesCount; ++i) { for (; i < timelinesCount; ++i) {
Timeline *timeline = timelines[i]; Timeline *timeline = timelines[i];
int id = timeline->getPropertyId(); int id = timeline->getPropertyId();
if (_propertyIDs.contains(id)) { if (_propertyIDs.containsKey(id)) {
timelineMode[i] = Subsequent; timelineMode[i] = Subsequent;
} else { } else {
_propertyIDs.add(id); _propertyIDs.put(id, true);
if (to == NULL || timeline->getRTTI().isExactly(AttachmentTimeline::rtti) || if (to == NULL || timeline->getRTTI().isExactly(AttachmentTimeline::rtti) ||
timeline->getRTTI().isExactly(DrawOrderTimeline::rtti) || timeline->getRTTI().isExactly(DrawOrderTimeline::rtti) ||
timeline->getRTTI().isExactly(EventTimeline::rtti) || !hasTimeline(to, id)) { timeline->getRTTI().isExactly(EventTimeline::rtti) || !to->_animation->hasTimeline(id)) {
timelineMode[i] = First; timelineMode[i] = First;
} else { } else {
for (TrackEntry *next = to->_mixingTo; next != NULL; next = next->_mixingTo) { for (TrackEntry *next = to->_mixingTo; next != NULL; next = next->_mixingTo) {
if (hasTimeline(next, id)) continue; if (next->_animation->hasTimeline(id)) continue;
if (entry->_mixDuration > 0) { if (entry->_mixDuration > 0) {
timelineMode[i] = HoldMix; timelineMode[i] = HoldMix;
timelineHoldMix[i] = entry; timelineHoldMix[i] = entry;
@ -1022,17 +1022,10 @@ void AnimationState::computeNotLast(TrackEntry *entry) {
for (size_t i = 0; i < timelinesCount; i++) { for (size_t i = 0; i < timelinesCount; i++) {
if (timelines[i]->getRTTI().isExactly(AttachmentTimeline::rtti)) { if (timelines[i]->getRTTI().isExactly(AttachmentTimeline::rtti)) {
AttachmentTimeline *timeline = static_cast<AttachmentTimeline *>(timelines[i]); AttachmentTimeline *timeline = static_cast<AttachmentTimeline *>(timelines[i]);
if (!_propertyIDs.contains(timeline->getSlotIndex())) if (!_propertyIDs.containsKey(timeline->getSlotIndex()))
_propertyIDs.add(timeline->getSlotIndex()); _propertyIDs.put(timeline->getSlotIndex(), true);
else else
timelineMode[i] |= NotLast; timelineMode[i] |= NotLast;
} }
} }
} }
bool AnimationState::hasTimeline(TrackEntry* entry, int inId) {
Vector<Timeline *> &timelines = entry->_animation->_timelines;
for (size_t i = 0, n = timelines.size(); i < n; ++i)
if (timelines[i]->getPropertyId() == inId) return true;
return false;
}

View File

@ -50,8 +50,17 @@ function Animation.new (name, timelines, duration)
local self = { local self = {
name = name, name = name,
timelines = timelines, timelines = timelines,
timelineIds = {},
duration = duration duration = duration
} }
for i,timeline in ipairs(self.timelines) do
self.timelineIds[timeline:getPropertyId()] = true
end
function self:hasTimeline(id)
return self.timelineIds[id] == true
end
function self:apply (skeleton, lastTime, time, loop, events, alpha, blend, direction) function self:apply (skeleton, lastTime, time, loop, events, alpha, blend, direction)
if not skeleton then error("skeleton cannot be nil.", 2) end if not skeleton then error("skeleton cannot be nil.", 2) end

View File

@ -894,13 +894,13 @@ function AnimationState:computeHold(entry)
if to == nil or timeline.type == Animation.TimelineType.attachment if to == nil or timeline.type == Animation.TimelineType.attachment
or timeline.type == Animation.TimelineType.drawOrder or timeline.type == Animation.TimelineType.drawOrder
or timeline.type == Animation.TimelineType.event or timeline.type == Animation.TimelineType.event
or not self:hasTimeline(to, id) then or not to.animation:hasTimeline(id) then
timelineMode[i] = FIRST timelineMode[i] = FIRST
else else
local next = to.mixingTo local next = to.mixingTo
skip = false skip = false
while next do while next do
if not self:hasTimeline(id) then if not next.animation:hasTimeline(id) then
if entry.mixDuration > 0 then if entry.mixDuration > 0 then
timelineMode[i] = HOLD_MIX timelineMode[i] = HOLD_MIX
timelineHoldMix[i] = next timelineHoldMix[i] = next
@ -917,14 +917,6 @@ function AnimationState:computeHold(entry)
end end
end end
function AnimationState:hasTimeline(entry, id)
local timelines = entry.animation.timelines
for i,timeline in ipairs(timelines) do
if timeline:getPropertyId() == id then return true end
end
return false
end
function AnimationState:getCurrent (trackIndex) function AnimationState:getCurrent (trackIndex)
return self.tracks[trackIndex] return self.tracks[trackIndex]
end end

View File

@ -470,23 +470,9 @@ namespace Spine.Unity.Editor {
string texturePath = assetPath + "/" + pageFiles[i]; string texturePath = assetPath + "/" + pageFiles[i];
Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)); Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D));
if (SpineEditorUtilities.Preferences.setTextureImporterSettings) { if (SpineEditorUtilities.Preferences.setTextureImporterSettings &&
TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath); !System.IO.File.Exists(texturePath + ".meta")) {
if (texImporter == null) { SetDefaultTextureSettings(texturePath, atlasAsset);
Debug.LogWarning(string.Format("{0} ::: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath));
continue;
}
texImporter.textureCompression = TextureImporterCompression.Uncompressed;
texImporter.alphaSource = TextureImporterAlphaSource.FromInput;
texImporter.mipmapEnabled = false;
texImporter.alphaIsTransparency = false; // Prevent the texture importer from applying bleed to the transparent parts for PMA.
texImporter.spriteImportMode = SpriteImportMode.None;
texImporter.maxTextureSize = 2048;
EditorUtility.SetDirty(texImporter);
AssetDatabase.ImportAsset(texturePath);
AssetDatabase.SaveAssets();
} }
string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]); string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]);
@ -505,7 +491,9 @@ namespace Spine.Unity.Editor {
vestigialMaterials.Remove(mat); vestigialMaterials.Remove(mat);
} }
mat.mainTexture = texture; if (texture != null)
mat.mainTexture = texture;
EditorUtility.SetDirty(mat); EditorUtility.SetDirty(mat);
AssetDatabase.SaveAssets(); AssetDatabase.SaveAssets();
@ -559,6 +547,26 @@ namespace Spine.Unity.Editor {
protectFromStackGarbageCollection.Remove(atlasAsset); protectFromStackGarbageCollection.Remove(atlasAsset);
return (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAssetBase)); return (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAssetBase));
} }
static bool SetDefaultTextureSettings (string texturePath, SpineAtlasAsset atlasAsset) {
TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath);
if (texImporter == null) {
Debug.LogWarning(string.Format("{0}: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath));
return false;
}
texImporter.textureCompression = TextureImporterCompression.Uncompressed;
texImporter.alphaSource = TextureImporterAlphaSource.FromInput;
texImporter.mipmapEnabled = false;
texImporter.alphaIsTransparency = false; // Prevent the texture importer from applying bleed to the transparent parts for PMA.
texImporter.spriteImportMode = SpriteImportMode.None;
texImporter.maxTextureSize = 2048;
EditorUtility.SetDirty(texImporter);
AssetDatabase.ImportAsset(texturePath);
AssetDatabase.SaveAssets();
return true;
}
#endregion #endregion
#region Import SkeletonData (json or binary) #region Import SkeletonData (json or binary)