mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 01:36:02 +08:00
Merge branch '3.8' into 3.9-beta
This commit is contained in:
commit
262be9ff39
Binary file not shown.
@ -30,10 +30,12 @@
|
||||
package spine.animation {
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
public class Animation {
|
||||
internal var _name : String;
|
||||
public var _timelines : Vector.<Timeline>;
|
||||
internal var _timelineIds : Dictionary = new Dictionary();
|
||||
public var 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.");
|
||||
_name = name;
|
||||
_timelines = timelines;
|
||||
for (var i : Number = 0; i < timelines.length; i++)
|
||||
_timelineIds[timelines[i].getPropertyId()] = true;
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public function hasTimeline(id: Number) : Boolean {
|
||||
return _timelineIds[id] == true;
|
||||
}
|
||||
|
||||
public function get timelines() : Vector.<Timeline> {
|
||||
return _timelines;
|
||||
|
||||
@ -664,11 +664,11 @@ package spine.animation {
|
||||
if (contained != null) {
|
||||
timelineMode[i] = AnimationState.SUBSEQUENT;
|
||||
} 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;
|
||||
} else {
|
||||
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) {
|
||||
timelineMode[i] = AnimationState.HOLD_MIX;
|
||||
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 {
|
||||
if (trackIndex >= tracks.length) return null;
|
||||
return tracks[trackIndex];
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#define Spine_Animation_h
|
||||
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/HashMap.h>
|
||||
#include <spine/MixBlend.h>
|
||||
#include <spine/MixDirection.h>
|
||||
#include <spine/SpineObject.h>
|
||||
@ -94,6 +95,8 @@ public:
|
||||
|
||||
Vector<Timeline *> &getTimelines();
|
||||
|
||||
bool hasTimeline(int id);
|
||||
|
||||
float getDuration();
|
||||
|
||||
void setDuration(float inValue);
|
||||
@ -102,6 +105,7 @@ public:
|
||||
|
||||
private:
|
||||
Vector<Timeline *> _timelines;
|
||||
HashMap<int, bool> _timelineIds;
|
||||
float _duration;
|
||||
String _name;
|
||||
|
||||
|
||||
@ -393,7 +393,7 @@ namespace spine {
|
||||
Vector<Event*> _events;
|
||||
EventQueue* _queue;
|
||||
|
||||
Vector<int> _propertyIDs;
|
||||
HashMap<int, bool> _propertyIDs;
|
||||
bool _animationsChanged;
|
||||
|
||||
AnimationStateListener _listener;
|
||||
@ -429,8 +429,6 @@ namespace spine {
|
||||
void computeHold(TrackEntry *entry);
|
||||
|
||||
void computeNotLast(TrackEntry *entry);
|
||||
|
||||
bool hasTimeline(TrackEntry *entry, int inId);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#ifndef Spine_Extension_h
|
||||
#define Spine_Extension_h
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <spine/dll.h>
|
||||
|
||||
|
||||
@ -89,11 +89,17 @@ public:
|
||||
}
|
||||
|
||||
~HashMap() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
for (Entry *entry = _head; entry != NULL;) {
|
||||
Entry* next = entry->next;
|
||||
delete entry;
|
||||
entry = next;
|
||||
}
|
||||
_head = NULL;
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
size_t size() {
|
||||
|
||||
@ -44,9 +44,16 @@ using namespace spine;
|
||||
|
||||
Animation::Animation(const String &name, Vector<Timeline *> &timelines, float duration) :
|
||||
_timelines(timelines),
|
||||
_timelineIds(),
|
||||
_duration(duration),
|
||||
_name(name) {
|
||||
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() {
|
||||
|
||||
@ -976,7 +976,7 @@ void AnimationState::computeHold(TrackEntry *entry) {
|
||||
if (to != NULL && to->_holdPrevious) {
|
||||
for (size_t i = 0; i < timelinesCount; i++) {
|
||||
int id = timelines[i]->getPropertyId();
|
||||
if (!_propertyIDs.contains(id)) _propertyIDs.add(id);
|
||||
if (!_propertyIDs.containsKey(id)) _propertyIDs.put(id, true);
|
||||
timelineMode[i] = Hold;
|
||||
}
|
||||
return;
|
||||
@ -988,18 +988,18 @@ void AnimationState::computeHold(TrackEntry *entry) {
|
||||
for (; i < timelinesCount; ++i) {
|
||||
Timeline *timeline = timelines[i];
|
||||
int id = timeline->getPropertyId();
|
||||
if (_propertyIDs.contains(id)) {
|
||||
if (_propertyIDs.containsKey(id)) {
|
||||
timelineMode[i] = Subsequent;
|
||||
} else {
|
||||
_propertyIDs.add(id);
|
||||
_propertyIDs.put(id, true);
|
||||
|
||||
if (to == NULL || timeline->getRTTI().isExactly(AttachmentTimeline::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;
|
||||
} else {
|
||||
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) {
|
||||
timelineMode[i] = HoldMix;
|
||||
timelineHoldMix[i] = entry;
|
||||
@ -1022,17 +1022,10 @@ void AnimationState::computeNotLast(TrackEntry *entry) {
|
||||
for (size_t i = 0; i < timelinesCount; i++) {
|
||||
if (timelines[i]->getRTTI().isExactly(AttachmentTimeline::rtti)) {
|
||||
AttachmentTimeline *timeline = static_cast<AttachmentTimeline *>(timelines[i]);
|
||||
if (!_propertyIDs.contains(timeline->getSlotIndex()))
|
||||
_propertyIDs.add(timeline->getSlotIndex());
|
||||
if (!_propertyIDs.containsKey(timeline->getSlotIndex()))
|
||||
_propertyIDs.put(timeline->getSlotIndex(), true);
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
@ -50,8 +50,17 @@ function Animation.new (name, timelines, duration)
|
||||
local self = {
|
||||
name = name,
|
||||
timelines = timelines,
|
||||
timelineIds = {},
|
||||
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)
|
||||
if not skeleton then error("skeleton cannot be nil.", 2) end
|
||||
|
||||
@ -894,13 +894,13 @@ function AnimationState:computeHold(entry)
|
||||
if to == nil or timeline.type == Animation.TimelineType.attachment
|
||||
or timeline.type == Animation.TimelineType.drawOrder
|
||||
or timeline.type == Animation.TimelineType.event
|
||||
or not self:hasTimeline(to, id) then
|
||||
or not to.animation:hasTimeline(id) then
|
||||
timelineMode[i] = FIRST
|
||||
else
|
||||
local next = to.mixingTo
|
||||
skip = false
|
||||
while next do
|
||||
if not self:hasTimeline(id) then
|
||||
if not next.animation:hasTimeline(id) then
|
||||
if entry.mixDuration > 0 then
|
||||
timelineMode[i] = HOLD_MIX
|
||||
timelineHoldMix[i] = next
|
||||
@ -917,14 +917,6 @@ function AnimationState:computeHold(entry)
|
||||
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)
|
||||
return self.tracks[trackIndex]
|
||||
end
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -470,23 +470,9 @@ namespace Spine.Unity.Editor {
|
||||
string texturePath = assetPath + "/" + pageFiles[i];
|
||||
Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D));
|
||||
|
||||
if (SpineEditorUtilities.Preferences.setTextureImporterSettings) {
|
||||
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));
|
||||
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();
|
||||
if (SpineEditorUtilities.Preferences.setTextureImporterSettings &&
|
||||
!System.IO.File.Exists(texturePath + ".meta")) {
|
||||
SetDefaultTextureSettings(texturePath, atlasAsset);
|
||||
}
|
||||
|
||||
string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]);
|
||||
@ -505,7 +491,9 @@ namespace Spine.Unity.Editor {
|
||||
vestigialMaterials.Remove(mat);
|
||||
}
|
||||
|
||||
mat.mainTexture = texture;
|
||||
if (texture != null)
|
||||
mat.mainTexture = texture;
|
||||
|
||||
EditorUtility.SetDirty(mat);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
@ -559,6 +547,26 @@ namespace Spine.Unity.Editor {
|
||||
protectFromStackGarbageCollection.Remove(atlasAsset);
|
||||
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
|
||||
|
||||
#region Import SkeletonData (json or binary)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user