no message
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "spine-creator-support/AttachmentVertices.h"
|
||||
|
||||
using namespace cc; // NOLINT(google-build-using-namespace)
|
||||
|
||||
namespace spine {
|
||||
|
||||
AttachmentVertices::AttachmentVertices(middleware::Texture2D *texture, int verticesCount, uint16_t *triangles, int trianglesCount) {
|
||||
_texture = texture;
|
||||
if (_texture) _texture->addRef();
|
||||
|
||||
_triangles = new middleware::Triangles();
|
||||
_triangles->verts = new middleware::V3F_T2F_C4B[verticesCount];
|
||||
_triangles->vertCount = verticesCount;
|
||||
_triangles->indices = triangles;
|
||||
_triangles->indexCount = trianglesCount;
|
||||
}
|
||||
|
||||
AttachmentVertices::~AttachmentVertices() {
|
||||
delete[] _triangles->verts;
|
||||
delete _triangles;
|
||||
if (_texture) _texture->release();
|
||||
}
|
||||
|
||||
AttachmentVertices *AttachmentVertices::copy() {
|
||||
AttachmentVertices *atv = new AttachmentVertices(nullptr, _triangles->vertCount, _triangles->indices, _triangles->indexCount);
|
||||
return atv;
|
||||
}
|
||||
|
||||
} // namespace spine
|
||||
@@ -0,0 +1,48 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base/Macros.h"
|
||||
#include "middleware-adapter.h"
|
||||
|
||||
namespace spine {
|
||||
/**
|
||||
* Store attachment vertex and indice list
|
||||
*/
|
||||
class AttachmentVertices {
|
||||
public:
|
||||
AttachmentVertices(cc::middleware::Texture2D *texture, int verticesCount, uint16_t *triangles, int trianglesCount);
|
||||
virtual ~AttachmentVertices();
|
||||
AttachmentVertices *copy();
|
||||
|
||||
cc::middleware::Texture2D *_texture = nullptr;
|
||||
cc::middleware::Triangles *_triangles = nullptr;
|
||||
};
|
||||
} // namespace spine
|
||||
323
cocos/editor-support/spine-creator-support/SkeletonAnimation.cpp
Normal file
323
cocos/editor-support/spine-creator-support/SkeletonAnimation.cpp
Normal file
@@ -0,0 +1,323 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "spine-creator-support/SkeletonAnimation.h"
|
||||
#include <algorithm>
|
||||
#include "base/DeferredReleasePool.h"
|
||||
#include "base/Log.h"
|
||||
#include "spine-creator-support/spine-cocos2dx.h"
|
||||
#include "spine/Extension.h"
|
||||
|
||||
namespace spine {
|
||||
|
||||
struct TrackEntryListeners {
|
||||
StartListener startListener;
|
||||
InterruptListener interruptListener;
|
||||
EndListener endListener;
|
||||
DisposeListener disposeListener;
|
||||
CompleteListener completeListener;
|
||||
EventListener eventListener;
|
||||
};
|
||||
|
||||
void animationCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
|
||||
(static_cast<SkeletonAnimation *>(state->getRendererObject()))->onAnimationStateEvent(entry, type, event);
|
||||
}
|
||||
|
||||
void trackEntryCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
|
||||
(static_cast<SkeletonAnimation *>(state->getRendererObject()))->onTrackEntryEvent(entry, type, event);
|
||||
if (type == EventType_Dispose) {
|
||||
if (entry->getRendererObject()) {
|
||||
delete static_cast<spine::TrackEntryListeners *>(entry->getRendererObject());
|
||||
entry->setRendererObject(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static TrackEntryListeners *getListeners(TrackEntry *entry) {
|
||||
if (!entry->getRendererObject()) {
|
||||
entry->setRendererObject(new spine::TrackEntryListeners());
|
||||
entry->setListener(trackEntryCallback);
|
||||
}
|
||||
return static_cast<TrackEntryListeners *>(entry->getRendererObject());
|
||||
}
|
||||
|
||||
float SkeletonAnimation::GlobalTimeScale = 1.0F;
|
||||
void SkeletonAnimation::setGlobalTimeScale(float timeScale) {
|
||||
GlobalTimeScale = timeScale;
|
||||
}
|
||||
|
||||
SkeletonAnimation *SkeletonAnimation::create() {
|
||||
auto *skeleton = new SkeletonAnimation();
|
||||
return skeleton;
|
||||
}
|
||||
|
||||
SkeletonAnimation *SkeletonAnimation::createWithData(SkeletonData *skeletonData, bool ownsSkeletonData) {
|
||||
auto *node = new SkeletonAnimation();
|
||||
node->initWithData(skeletonData, ownsSkeletonData);
|
||||
return node;
|
||||
}
|
||||
|
||||
SkeletonAnimation *SkeletonAnimation::createWithJsonFile(const std::string &skeletonJsonFile, const std::string &atlasFile, float scale) {
|
||||
auto *node = new SkeletonAnimation();
|
||||
node->initWithJsonFile(skeletonJsonFile, atlasFile, scale);
|
||||
return node;
|
||||
}
|
||||
|
||||
SkeletonAnimation *SkeletonAnimation::createWithBinaryFile(const std::string &skeletonBinaryFile, const std::string &atlasFile, float scale) {
|
||||
auto *node = new SkeletonAnimation();
|
||||
node->initWithBinaryFile(skeletonBinaryFile, atlasFile, scale);
|
||||
return node;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::initialize() {
|
||||
super::initialize();
|
||||
|
||||
_ownsAnimationStateData = true;
|
||||
_state = new (__FILE__, __LINE__) AnimationState(new (__FILE__, __LINE__) AnimationStateData(_skeleton->getData()));
|
||||
_state->setRendererObject(this);
|
||||
_state->setListener(animationCallback);
|
||||
}
|
||||
|
||||
SkeletonAnimation::SkeletonAnimation() = default;
|
||||
|
||||
SkeletonAnimation::~SkeletonAnimation() {
|
||||
_startListener = nullptr;
|
||||
_interruptListener = nullptr;
|
||||
_endListener = nullptr;
|
||||
_disposeListener = nullptr;
|
||||
_completeListener = nullptr;
|
||||
_eventListener = nullptr;
|
||||
|
||||
if (_state) {
|
||||
if (_ownsAnimationStateData) delete _state->getData();
|
||||
delete _state;
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonAnimation::update(float deltaTime) {
|
||||
if (!_skeleton) return;
|
||||
if (!_paused) {
|
||||
deltaTime *= _timeScale * GlobalTimeScale;
|
||||
if (_ownsSkeleton) _skeleton->update(deltaTime);
|
||||
_state->update(deltaTime);
|
||||
_state->apply(*_skeleton);
|
||||
_skeleton->updateWorldTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setAnimationStateData(AnimationStateData *stateData) {
|
||||
CC_ASSERT(stateData);
|
||||
|
||||
if (_state) {
|
||||
if (_ownsAnimationStateData) delete _state->getData();
|
||||
delete _state;
|
||||
}
|
||||
|
||||
_ownsAnimationStateData = false;
|
||||
_state = new (__FILE__, __LINE__) AnimationState(stateData);
|
||||
_state->setRendererObject(this);
|
||||
_state->setListener(animationCallback);
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setMix(const std::string &fromAnimation, const std::string &toAnimation, float duration) {
|
||||
if (_state) {
|
||||
_state->getData()->setMix(fromAnimation.c_str(), toAnimation.c_str(), duration);
|
||||
}
|
||||
}
|
||||
|
||||
TrackEntry *SkeletonAnimation::setAnimation(int trackIndex, const std::string &name, bool loop) {
|
||||
if (!_skeleton) return nullptr;
|
||||
Animation *animation = _skeleton->getData()->findAnimation(name.c_str());
|
||||
if (!animation) {
|
||||
CC_LOG_WARNING("Spine: Animation not found: %s", name.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
auto *trackEntry = _state->setAnimation(trackIndex, animation, loop);
|
||||
_state->apply(*_skeleton);
|
||||
return trackEntry;
|
||||
}
|
||||
|
||||
TrackEntry *SkeletonAnimation::addAnimation(int trackIndex, const std::string &name, bool loop, float delay) {
|
||||
if (!_skeleton) return nullptr;
|
||||
Animation *animation = _skeleton->getData()->findAnimation(name.c_str());
|
||||
if (!animation) {
|
||||
CC_LOG_WARNING("Spine: Animation not found: %s", name.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
return _state->addAnimation(trackIndex, animation, loop, delay);
|
||||
}
|
||||
|
||||
TrackEntry *SkeletonAnimation::setEmptyAnimation(int trackIndex, float mixDuration) {
|
||||
if (_state) {
|
||||
return _state->setEmptyAnimation(trackIndex, mixDuration);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setEmptyAnimations(float mixDuration) {
|
||||
if (_state) {
|
||||
_state->setEmptyAnimations(mixDuration);
|
||||
}
|
||||
}
|
||||
|
||||
TrackEntry *SkeletonAnimation::addEmptyAnimation(int trackIndex, float mixDuration, float delay) {
|
||||
if (_state) {
|
||||
return _state->addEmptyAnimation(trackIndex, mixDuration, delay);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Animation *SkeletonAnimation::findAnimation(const std::string &name) const {
|
||||
if (_skeleton) {
|
||||
return _skeleton->getData()->findAnimation(name.c_str());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TrackEntry *SkeletonAnimation::getCurrent(int trackIndex) {
|
||||
if (_state) {
|
||||
return _state->getCurrent(trackIndex);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::clearTracks() {
|
||||
if (_state) {
|
||||
_state->clearTracks();
|
||||
super::setToSetupPose();
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonAnimation::clearTrack(int trackIndex) {
|
||||
if (_state) {
|
||||
_state->clearTrack(trackIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonAnimation::onAnimationStateEvent(TrackEntry *entry, EventType type, Event *event) {
|
||||
switch (type) {
|
||||
case EventType_Start:
|
||||
if (_startListener) _startListener(entry);
|
||||
break;
|
||||
case EventType_Interrupt:
|
||||
if (_interruptListener) _interruptListener(entry);
|
||||
break;
|
||||
case EventType_End:
|
||||
if (_endListener) _endListener(entry);
|
||||
break;
|
||||
case EventType_Dispose:
|
||||
if (_disposeListener) _disposeListener(entry);
|
||||
break;
|
||||
case EventType_Complete:
|
||||
if (_completeListener) _completeListener(entry);
|
||||
break;
|
||||
case EventType_Event:
|
||||
if (_eventListener) _eventListener(entry, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonAnimation::onTrackEntryEvent(TrackEntry *entry, EventType type, Event *event) {
|
||||
if (!entry->getRendererObject()) return;
|
||||
auto *listeners = static_cast<TrackEntryListeners *>(entry->getRendererObject());
|
||||
switch (type) {
|
||||
case EventType_Start:
|
||||
if (listeners->startListener) listeners->startListener(entry);
|
||||
break;
|
||||
case EventType_Interrupt:
|
||||
if (listeners->interruptListener) listeners->interruptListener(entry);
|
||||
break;
|
||||
case EventType_End:
|
||||
if (listeners->endListener) listeners->endListener(entry);
|
||||
break;
|
||||
case EventType_Dispose:
|
||||
if (listeners->disposeListener) listeners->disposeListener(entry);
|
||||
break;
|
||||
case EventType_Complete:
|
||||
if (listeners->completeListener) listeners->completeListener(entry);
|
||||
break;
|
||||
case EventType_Event:
|
||||
if (listeners->eventListener) listeners->eventListener(entry, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setStartListener(const StartListener &listener) {
|
||||
_startListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setInterruptListener(const InterruptListener &listener) {
|
||||
_interruptListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setEndListener(const EndListener &listener) {
|
||||
_endListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setDisposeListener(const DisposeListener &listener) {
|
||||
_disposeListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setCompleteListener(const CompleteListener &listener) {
|
||||
_completeListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setEventListener(const EventListener &listener) {
|
||||
_eventListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setTrackStartListener(TrackEntry *entry, const StartListener &listener) { // NOLINT(readability-convert-member-functions-to-static)
|
||||
getListeners(entry)->startListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setTrackInterruptListener(TrackEntry *entry, const InterruptListener &listener) { // NOLINT(readability-convert-member-functions-to-static)
|
||||
getListeners(entry)->interruptListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setTrackEndListener(TrackEntry *entry, const EndListener &listener) { // NOLINT(readability-convert-member-functions-to-static)
|
||||
getListeners(entry)->endListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setTrackDisposeListener(TrackEntry *entry, const DisposeListener &listener) { // NOLINT(readability-convert-member-functions-to-static)
|
||||
getListeners(entry)->disposeListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setTrackCompleteListener(TrackEntry *entry, const CompleteListener &listener) { // NOLINT(readability-convert-member-functions-to-static)
|
||||
getListeners(entry)->completeListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setTrackEventListener(TrackEntry *entry, const EventListener &listener) { // NOLINT(readability-convert-member-functions-to-static)
|
||||
getListeners(entry)->eventListener = listener;
|
||||
}
|
||||
|
||||
AnimationState *SkeletonAnimation::getState() const {
|
||||
return _state;
|
||||
}
|
||||
|
||||
} // namespace spine
|
||||
108
cocos/editor-support/spine-creator-support/SkeletonAnimation.h
Normal file
108
cocos/editor-support/spine-creator-support/SkeletonAnimation.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/******************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "spine-creator-support/SkeletonRenderer.h"
|
||||
#include "spine/spine.h"
|
||||
|
||||
namespace spine {
|
||||
|
||||
typedef std::function<void(TrackEntry *entry)> StartListener;
|
||||
typedef std::function<void(TrackEntry *entry)> InterruptListener;
|
||||
typedef std::function<void(TrackEntry *entry)> EndListener;
|
||||
typedef std::function<void(TrackEntry *entry)> DisposeListener;
|
||||
typedef std::function<void(TrackEntry *entry)> CompleteListener;
|
||||
typedef std::function<void(TrackEntry *entry, Event *event)> EventListener;
|
||||
|
||||
/** Draws an animated skeleton, providing an AnimationState for applying one or more animations and queuing animations to be
|
||||
* played later. */
|
||||
class SkeletonAnimation : public SkeletonRenderer {
|
||||
public:
|
||||
static SkeletonAnimation *create();
|
||||
static SkeletonAnimation *createWithData(SkeletonData *skeletonData, bool ownsSkeletonData = false);
|
||||
static SkeletonAnimation *createWithJsonFile(const std::string &skeletonJsonFile, const std::string &atlasFile, float scale = 1);
|
||||
static SkeletonAnimation *createWithBinaryFile(const std::string &skeletonBinaryFile, const std::string &atlasFile, float scale = 1);
|
||||
static void setGlobalTimeScale(float timeScale);
|
||||
|
||||
virtual void update(float deltaTime) override;
|
||||
|
||||
void setAnimationStateData(AnimationStateData *stateData);
|
||||
void setMix(const std::string &fromAnimation, const std::string &toAnimation, float duration);
|
||||
|
||||
TrackEntry *setAnimation(int trackIndex, const std::string &name, bool loop);
|
||||
TrackEntry *addAnimation(int trackIndex, const std::string &name, bool loop, float delay = 0);
|
||||
TrackEntry *setEmptyAnimation(int trackIndex, float mixDuration);
|
||||
void setEmptyAnimations(float mixDuration);
|
||||
TrackEntry *addEmptyAnimation(int trackIndex, float mixDuration, float delay = 0);
|
||||
Animation *findAnimation(const std::string &name) const;
|
||||
TrackEntry *getCurrent(int trackIndex = 0);
|
||||
void clearTracks();
|
||||
void clearTrack(int trackIndex = 0);
|
||||
|
||||
void setStartListener(const StartListener &listener);
|
||||
void setInterruptListener(const InterruptListener &listener);
|
||||
void setEndListener(const EndListener &listener);
|
||||
void setDisposeListener(const DisposeListener &listener);
|
||||
void setCompleteListener(const CompleteListener &listener);
|
||||
void setEventListener(const EventListener &listener);
|
||||
|
||||
void setTrackStartListener(TrackEntry *entry, const StartListener &listener);
|
||||
void setTrackInterruptListener(TrackEntry *entry, const InterruptListener &listener);
|
||||
void setTrackEndListener(TrackEntry *entry, const EndListener &listener);
|
||||
void setTrackDisposeListener(TrackEntry *entry, const DisposeListener &listener);
|
||||
void setTrackCompleteListener(TrackEntry *entry, const CompleteListener &listener);
|
||||
void setTrackEventListener(TrackEntry *entry, const EventListener &listener);
|
||||
|
||||
virtual void onAnimationStateEvent(TrackEntry *entry, EventType type, Event *event);
|
||||
virtual void onTrackEntryEvent(TrackEntry *entry, EventType type, Event *event);
|
||||
|
||||
AnimationState *getState() const;
|
||||
|
||||
SkeletonAnimation();
|
||||
virtual ~SkeletonAnimation();
|
||||
virtual void initialize() override;
|
||||
|
||||
public:
|
||||
static float GlobalTimeScale;
|
||||
|
||||
protected:
|
||||
AnimationState *_state = nullptr;
|
||||
bool _ownsAnimationStateData = false;
|
||||
StartListener _startListener = nullptr;
|
||||
InterruptListener _interruptListener = nullptr;
|
||||
EndListener _endListener = nullptr;
|
||||
DisposeListener _disposeListener = nullptr;
|
||||
CompleteListener _completeListener = nullptr;
|
||||
EventListener _eventListener = nullptr;
|
||||
|
||||
private:
|
||||
typedef SkeletonRenderer super;
|
||||
};
|
||||
|
||||
} // namespace spine
|
||||
546
cocos/editor-support/spine-creator-support/SkeletonCache.cpp
Normal file
546
cocos/editor-support/spine-creator-support/SkeletonCache.cpp
Normal file
@@ -0,0 +1,546 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SkeletonCache.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "spine-creator-support/AttachmentVertices.h"
|
||||
|
||||
USING_NS_MW; // NOLINT(google-build-using-namespace)
|
||||
using namespace cc; // NOLINT(google-build-using-namespace)
|
||||
|
||||
namespace spine {
|
||||
|
||||
float SkeletonCache::FrameTime = 1.0F / 60.0F;
|
||||
float SkeletonCache::MaxCacheTime = 120.0F;
|
||||
|
||||
SkeletonCache::SegmentData::SegmentData() = default;
|
||||
|
||||
SkeletonCache::SegmentData::~SegmentData() {
|
||||
CC_SAFE_RELEASE_NULL(_texture);
|
||||
}
|
||||
|
||||
void SkeletonCache::SegmentData::setTexture(cc::middleware::Texture2D *value) {
|
||||
CC_SAFE_ADD_REF(value);
|
||||
CC_SAFE_RELEASE(_texture);
|
||||
_texture = value;
|
||||
}
|
||||
|
||||
cc::middleware::Texture2D *SkeletonCache::SegmentData::getTexture() const {
|
||||
return _texture;
|
||||
}
|
||||
|
||||
SkeletonCache::FrameData::FrameData() = default;
|
||||
|
||||
SkeletonCache::FrameData::~FrameData() {
|
||||
for (auto &bone : _bones) {
|
||||
delete bone;
|
||||
}
|
||||
_bones.clear();
|
||||
|
||||
for (auto &color : _colors) {
|
||||
delete color;
|
||||
}
|
||||
_colors.clear();
|
||||
|
||||
for (auto &segment : _segments) {
|
||||
delete segment;
|
||||
}
|
||||
_segments.clear();
|
||||
}
|
||||
|
||||
SkeletonCache::BoneData *SkeletonCache::FrameData::buildBoneData(std::size_t index) {
|
||||
if (index > _bones.size()) return nullptr;
|
||||
if (index == _bones.size()) {
|
||||
auto *boneData = new BoneData;
|
||||
_bones.push_back(boneData);
|
||||
}
|
||||
return _bones[index];
|
||||
}
|
||||
|
||||
std::size_t SkeletonCache::FrameData::getBoneCount() const {
|
||||
return _bones.size();
|
||||
}
|
||||
|
||||
SkeletonCache::ColorData *SkeletonCache::FrameData::buildColorData(std::size_t index) {
|
||||
if (index > _colors.size()) return nullptr;
|
||||
if (index == _colors.size()) {
|
||||
auto *colorData = new ColorData;
|
||||
_colors.push_back(colorData);
|
||||
}
|
||||
return _colors[index];
|
||||
}
|
||||
|
||||
std::size_t SkeletonCache::FrameData::getColorCount() const {
|
||||
return _colors.size();
|
||||
}
|
||||
|
||||
SkeletonCache::SegmentData *SkeletonCache::FrameData::buildSegmentData(std::size_t index) {
|
||||
if (index > _segments.size()) return nullptr;
|
||||
if (index == _segments.size()) {
|
||||
auto *segmentData = new SegmentData;
|
||||
_segments.push_back(segmentData);
|
||||
}
|
||||
return _segments[index];
|
||||
}
|
||||
|
||||
std::size_t SkeletonCache::FrameData::getSegmentCount() const {
|
||||
return _segments.size();
|
||||
}
|
||||
|
||||
SkeletonCache::AnimationData::AnimationData() = default;
|
||||
|
||||
SkeletonCache::AnimationData::~AnimationData() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void SkeletonCache::AnimationData::reset() {
|
||||
for (auto &frame : _frames) {
|
||||
delete frame;
|
||||
}
|
||||
_frames.clear();
|
||||
_isComplete = false;
|
||||
_totalTime = 0.0F;
|
||||
}
|
||||
|
||||
bool SkeletonCache::AnimationData::needUpdate(int toFrameIdx) const {
|
||||
return !_isComplete && _totalTime <= MaxCacheTime && (toFrameIdx == -1 || _frames.size() < toFrameIdx + 1);
|
||||
}
|
||||
|
||||
SkeletonCache::FrameData *SkeletonCache::AnimationData::buildFrameData(std::size_t frameIdx) {
|
||||
if (frameIdx > _frames.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (frameIdx == _frames.size()) {
|
||||
auto *frameData = new FrameData();
|
||||
_frames.push_back(frameData);
|
||||
}
|
||||
return _frames[frameIdx];
|
||||
}
|
||||
|
||||
SkeletonCache::FrameData *SkeletonCache::AnimationData::getFrameData(std::size_t frameIdx) const {
|
||||
if (frameIdx >= _frames.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
return _frames[frameIdx];
|
||||
}
|
||||
|
||||
std::size_t SkeletonCache::AnimationData::getFrameCount() const {
|
||||
return _frames.size();
|
||||
}
|
||||
|
||||
SkeletonCache::SkeletonCache() = default;
|
||||
|
||||
SkeletonCache::~SkeletonCache() {
|
||||
for (auto &animationCache : _animationCaches) {
|
||||
delete animationCache.second;
|
||||
}
|
||||
_animationCaches.clear();
|
||||
}
|
||||
|
||||
SkeletonCache::AnimationData *SkeletonCache::buildAnimationData(const std::string &animationName) {
|
||||
AnimationData *aniData = nullptr;
|
||||
auto it = _animationCaches.find(animationName);
|
||||
if (it == _animationCaches.end()) {
|
||||
auto *animation = findAnimation(animationName);
|
||||
if (animation == nullptr) return nullptr;
|
||||
|
||||
aniData = new AnimationData();
|
||||
aniData->_animationName = animationName;
|
||||
_animationCaches[animationName] = aniData;
|
||||
} else {
|
||||
aniData = it->second;
|
||||
}
|
||||
return aniData;
|
||||
}
|
||||
|
||||
SkeletonCache::AnimationData *SkeletonCache::getAnimationData(const std::string &animationName) {
|
||||
auto it = _animationCaches.find(animationName);
|
||||
if (it == _animationCaches.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void SkeletonCache::update(float deltaTime) {
|
||||
if (!_skeleton) return;
|
||||
if (_ownsSkeleton) _skeleton->update(deltaTime);
|
||||
_state->update(deltaTime);
|
||||
_state->apply(*_skeleton);
|
||||
_skeleton->updateWorldTransform();
|
||||
}
|
||||
|
||||
void SkeletonCache::updateToFrame(const std::string &animationName, int toFrameIdx /*= -1*/) {
|
||||
auto it = _animationCaches.find(animationName);
|
||||
if (it == _animationCaches.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AnimationData *animationData = it->second;
|
||||
if (!animationData || !animationData->needUpdate(toFrameIdx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_curAnimationName != animationName) {
|
||||
updateToFrame(_curAnimationName);
|
||||
_curAnimationName = animationName;
|
||||
}
|
||||
|
||||
// init animation
|
||||
if (animationData->getFrameCount() == 0) {
|
||||
setAnimation(0, animationName, false);
|
||||
}
|
||||
|
||||
do {
|
||||
update(FrameTime);
|
||||
renderAnimationFrame(animationData);
|
||||
animationData->_totalTime += FrameTime;
|
||||
} while (animationData->needUpdate(toFrameIdx));
|
||||
}
|
||||
|
||||
void SkeletonCache::renderAnimationFrame(AnimationData *animationData) {
|
||||
std::size_t frameIndex = animationData->getFrameCount();
|
||||
FrameData *frameData = animationData->buildFrameData(frameIndex);
|
||||
|
||||
if (!_skeleton) return;
|
||||
|
||||
// If opacity is 0,then return.
|
||||
if (_skeleton->getColor().a == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Color4F preColor(-1.0F, -1.0F, -1.0F, -1.0F);
|
||||
Color4F preDarkColor(-1.0F, -1.0F, -1.0F, -1.0F);
|
||||
// range [0.0, 1.0]
|
||||
Color4F color;
|
||||
Color4F darkColor;
|
||||
Color4B finalColor;
|
||||
Color4B finalDardk;
|
||||
|
||||
AttachmentVertices *attachmentVertices = nullptr;
|
||||
middleware::IOBuffer &vb = frameData->vb;
|
||||
middleware::IOBuffer &ib = frameData->ib;
|
||||
|
||||
// vertex size int bytes with two color
|
||||
int vbs2 = sizeof(V3F_T2F_C4B_C4B);
|
||||
// vertex size in floats with two color
|
||||
int vs2 = static_cast<int32_t>(vbs2 / sizeof(float));
|
||||
|
||||
int vbSize = 0;
|
||||
int ibSize = 0;
|
||||
|
||||
int preBlendMode = -1;
|
||||
int preTextureIndex = -1;
|
||||
int curTextureIndex = -1;
|
||||
|
||||
int preISegWritePos = -1;
|
||||
int curISegLen = 0;
|
||||
int curVSegLen = 0;
|
||||
|
||||
int materialLen = 0;
|
||||
Slot *slot = nullptr;
|
||||
|
||||
middleware::Texture2D *texture = nullptr;
|
||||
|
||||
auto flush = [&]() {
|
||||
// fill pre segment count field
|
||||
if (preISegWritePos != -1) {
|
||||
SegmentData *preSegmentData = frameData->buildSegmentData(materialLen - 1);
|
||||
preSegmentData->indexCount = curISegLen;
|
||||
preSegmentData->vertexFloatCount = curVSegLen;
|
||||
}
|
||||
|
||||
SegmentData *segmentData = frameData->buildSegmentData(materialLen);
|
||||
segmentData->setTexture(texture);
|
||||
segmentData->blendMode = slot->getData().getBlendMode();
|
||||
|
||||
// save new segment count pos field
|
||||
preISegWritePos = static_cast<int>(ib.getCurPos() / sizeof(uint16_t));
|
||||
// reset pre blend mode to current
|
||||
preBlendMode = static_cast<int>(slot->getData().getBlendMode());
|
||||
// reset pre texture index to current
|
||||
preTextureIndex = curTextureIndex;
|
||||
// reset index segmentation count
|
||||
curISegLen = 0;
|
||||
// reset vertex segmentation count
|
||||
curVSegLen = 0;
|
||||
// material length increased
|
||||
materialLen++;
|
||||
};
|
||||
|
||||
auto &bones = _skeleton->getBones();
|
||||
for (std::size_t i = 0, n = bones.size(); i < n; i++) {
|
||||
auto &bone = bones[i];
|
||||
auto boneCount = frameData->getBoneCount();
|
||||
BoneData *boneData = frameData->buildBoneData(boneCount);
|
||||
auto &matm = boneData->globalTransformMatrix.m;
|
||||
matm[0] = bone->getA();
|
||||
matm[1] = bone->getC();
|
||||
matm[4] = bone->getB();
|
||||
matm[5] = bone->getD();
|
||||
matm[12] = bone->getWorldX();
|
||||
matm[13] = bone->getWorldY();
|
||||
}
|
||||
|
||||
auto &drawOrder = _skeleton->getDrawOrder();
|
||||
for (size_t i = 0, n = drawOrder.size(); i < n; ++i) {
|
||||
slot = drawOrder[i];
|
||||
|
||||
if (slot->getBone().isActive() == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!slot->getAttachment()) {
|
||||
_clipper->clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
const spine::Color &slotColor = slot->getColor();
|
||||
|
||||
TwoColorTriangles trianglesTwoColor;
|
||||
spine::Color attachmentColor;
|
||||
if (slot->getAttachment()->getRTTI().isExactly(RegionAttachment::rtti)) {
|
||||
auto *attachment = dynamic_cast<RegionAttachment *>(slot->getAttachment());
|
||||
attachmentVertices = static_cast<AttachmentVertices *>(attachment->getRendererObject());
|
||||
|
||||
// Early exit if attachment is invisible
|
||||
if (attachment->getColor().a == 0) {
|
||||
_clipper->clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
trianglesTwoColor.vertCount = attachmentVertices->_triangles->vertCount;
|
||||
vbSize = static_cast<int32_t>(trianglesTwoColor.vertCount * sizeof(V3F_T2F_C4B_C4B));
|
||||
vb.checkSpace(vbSize, true);
|
||||
trianglesTwoColor.verts = reinterpret_cast<V3F_T2F_C4B_C4B *>(vb.getCurBuffer());
|
||||
for (int ii = 0; ii < trianglesTwoColor.vertCount; ii++) {
|
||||
trianglesTwoColor.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord;
|
||||
}
|
||||
attachment->computeWorldVertices(slot->getBone(), reinterpret_cast<float *>(trianglesTwoColor.verts), 0, vs2);
|
||||
|
||||
trianglesTwoColor.indexCount = attachmentVertices->_triangles->indexCount;
|
||||
ibSize = static_cast<int32_t>(trianglesTwoColor.indexCount * sizeof(uint16_t));
|
||||
ib.checkSpace(ibSize, true);
|
||||
trianglesTwoColor.indices = reinterpret_cast<uint16_t *>(ib.getCurBuffer());
|
||||
memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize);
|
||||
|
||||
attachmentColor = attachment->getColor();
|
||||
|
||||
} else if (slot->getAttachment()->getRTTI().isExactly(MeshAttachment::rtti)) {
|
||||
auto *attachment = dynamic_cast<MeshAttachment *>(slot->getAttachment());
|
||||
attachmentVertices = static_cast<AttachmentVertices *>(attachment->getRendererObject());
|
||||
|
||||
// Early exit if attachment is invisible
|
||||
if (attachment->getColor().a == 0) {
|
||||
_clipper->clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
trianglesTwoColor.vertCount = attachmentVertices->_triangles->vertCount;
|
||||
vbSize = static_cast<int32_t>(trianglesTwoColor.vertCount * sizeof(V3F_T2F_C4B_C4B));
|
||||
vb.checkSpace(vbSize, true);
|
||||
trianglesTwoColor.verts = reinterpret_cast<V3F_T2F_C4B_C4B *>(vb.getCurBuffer());
|
||||
for (int ii = 0; ii < trianglesTwoColor.vertCount; ii++) {
|
||||
trianglesTwoColor.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord;
|
||||
}
|
||||
attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), reinterpret_cast<float *>(trianglesTwoColor.verts), 0, vs2);
|
||||
|
||||
trianglesTwoColor.indexCount = attachmentVertices->_triangles->indexCount;
|
||||
ibSize = static_cast<int32_t>(trianglesTwoColor.indexCount * sizeof(uint16_t));
|
||||
ib.checkSpace(ibSize, true);
|
||||
trianglesTwoColor.indices = reinterpret_cast<uint16_t *>(ib.getCurBuffer());
|
||||
memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize);
|
||||
attachmentColor = attachment->getColor();
|
||||
} else if (slot->getAttachment()->getRTTI().isExactly(ClippingAttachment::rtti)) {
|
||||
auto *clip = dynamic_cast<ClippingAttachment *>(slot->getAttachment());
|
||||
_clipper->clipStart(*slot, clip);
|
||||
continue;
|
||||
} else {
|
||||
_clipper->clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
color.a = _skeleton->getColor().a * slotColor.a * attachmentColor.a * 255;
|
||||
// skip rendering if the color of this attachment is 0
|
||||
if (color.a == 0) {
|
||||
_clipper->clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
float red = _skeleton->getColor().r * attachmentColor.r * 255;
|
||||
float green = _skeleton->getColor().g * attachmentColor.g * 255;
|
||||
float blue = _skeleton->getColor().b * attachmentColor.b * 255;
|
||||
|
||||
color.r = red * slotColor.r;
|
||||
color.g = green * slotColor.g;
|
||||
color.b = blue * slotColor.b;
|
||||
|
||||
if (slot->hasDarkColor()) {
|
||||
darkColor.r = red * slot->getDarkColor().r;
|
||||
darkColor.g = green * slot->getDarkColor().g;
|
||||
darkColor.b = blue * slot->getDarkColor().b;
|
||||
darkColor.a = 0;
|
||||
} else {
|
||||
darkColor.r = 0;
|
||||
darkColor.g = 0;
|
||||
darkColor.b = 0;
|
||||
darkColor.a = 0;
|
||||
}
|
||||
|
||||
finalColor.r = static_cast<uint8_t>(std::round(color.r));
|
||||
finalColor.g = static_cast<uint8_t>(std::round(color.g));
|
||||
finalColor.b = static_cast<uint8_t>(std::round(color.b));
|
||||
finalColor.a = static_cast<uint8_t>(std::round(color.a));
|
||||
|
||||
finalDardk.r = static_cast<uint8_t>(std::round(darkColor.r));
|
||||
finalDardk.g = static_cast<uint8_t>(std::round(darkColor.g));
|
||||
finalDardk.b = static_cast<uint8_t>(std::round(darkColor.b));
|
||||
finalDardk.a = static_cast<uint8_t>(std::round(darkColor.a));
|
||||
|
||||
if (preColor != color || preDarkColor != darkColor) {
|
||||
preColor = color;
|
||||
preDarkColor = darkColor;
|
||||
auto colorCount = frameData->getColorCount();
|
||||
if (colorCount > 0) {
|
||||
ColorData *preColorData = frameData->buildColorData(colorCount - 1);
|
||||
preColorData->vertexFloatOffset = static_cast<int>(vb.getCurPos() / sizeof(float));
|
||||
}
|
||||
ColorData *colorData = frameData->buildColorData(colorCount);
|
||||
colorData->finalColor = finalColor;
|
||||
colorData->darkColor = finalDardk;
|
||||
}
|
||||
|
||||
// Two color tint logic
|
||||
if (_clipper->isClipping()) {
|
||||
_clipper->clipTriangles(reinterpret_cast<float *>(&trianglesTwoColor.verts[0].vertex), trianglesTwoColor.indices, trianglesTwoColor.indexCount, reinterpret_cast<float *>(&trianglesTwoColor.verts[0].texCoord), vs2);
|
||||
|
||||
if (_clipper->getClippedTriangles().size() == 0) {
|
||||
_clipper->clipEnd(*slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
trianglesTwoColor.vertCount = static_cast<int>(_clipper->getClippedVertices().size()) >> 1;
|
||||
vbSize = static_cast<int32_t>(trianglesTwoColor.vertCount * sizeof(V3F_T2F_C4B_C4B));
|
||||
vb.checkSpace(vbSize, true);
|
||||
trianglesTwoColor.verts = reinterpret_cast<V3F_T2F_C4B_C4B *>(vb.getCurBuffer());
|
||||
|
||||
trianglesTwoColor.indexCount = static_cast<int>(_clipper->getClippedTriangles().size());
|
||||
ibSize = static_cast<int32_t>(trianglesTwoColor.indexCount * sizeof(uint16_t));
|
||||
ib.checkSpace(ibSize, true);
|
||||
trianglesTwoColor.indices = reinterpret_cast<uint16_t *>(ib.getCurBuffer());
|
||||
memcpy(trianglesTwoColor.indices, _clipper->getClippedTriangles().buffer(), sizeof(uint16_t) * _clipper->getClippedTriangles().size());
|
||||
|
||||
float *verts = _clipper->getClippedVertices().buffer();
|
||||
float *uvs = _clipper->getClippedUVs().buffer();
|
||||
|
||||
for (int v = 0, vn = trianglesTwoColor.vertCount, vv = 0; v < vn; ++v, vv += 2) {
|
||||
V3F_T2F_C4B_C4B *vertex = trianglesTwoColor.verts + v;
|
||||
vertex->vertex.x = verts[vv];
|
||||
vertex->vertex.y = verts[vv + 1];
|
||||
vertex->texCoord.u = uvs[vv];
|
||||
vertex->texCoord.v = uvs[vv + 1];
|
||||
vertex->color = finalColor;
|
||||
vertex->color2 = finalDardk;
|
||||
}
|
||||
} else {
|
||||
for (int v = 0, vn = trianglesTwoColor.vertCount; v < vn; ++v) {
|
||||
V3F_T2F_C4B_C4B *vertex = trianglesTwoColor.verts + v;
|
||||
vertex->color = finalColor;
|
||||
vertex->color2 = finalDardk;
|
||||
}
|
||||
}
|
||||
|
||||
texture = attachmentVertices->_texture;
|
||||
curTextureIndex = attachmentVertices->_texture->getRealTextureIndex();
|
||||
// If texture or blendMode change,will change material.
|
||||
if (preTextureIndex != curTextureIndex || preBlendMode != slot->getData().getBlendMode()) {
|
||||
flush();
|
||||
}
|
||||
|
||||
if (vbSize > 0 && ibSize > 0) {
|
||||
auto vertexOffset = curVSegLen / vs2;
|
||||
|
||||
if (vertexOffset > 0) {
|
||||
auto *ibBuffer = reinterpret_cast<uint16_t *>(ib.getCurBuffer());
|
||||
for (uint32_t ii = 0, nn = ibSize / sizeof(uint16_t); ii < nn; ii++) {
|
||||
ibBuffer[ii] += vertexOffset;
|
||||
}
|
||||
}
|
||||
vb.move(vbSize);
|
||||
ib.move(ibSize);
|
||||
|
||||
// Record this turn index segmentation count,it will store in material buffer in the end.
|
||||
curISegLen += static_cast<int32_t>(ibSize / sizeof(uint16_t));
|
||||
curVSegLen += static_cast<int32_t>(vbSize / sizeof(float));
|
||||
}
|
||||
|
||||
_clipper->clipEnd(*slot);
|
||||
} // End slot traverse
|
||||
|
||||
_clipper->clipEnd();
|
||||
|
||||
if (preISegWritePos != -1) {
|
||||
SegmentData *preSegmentData = frameData->buildSegmentData(materialLen - 1);
|
||||
preSegmentData->indexCount = curISegLen;
|
||||
preSegmentData->vertexFloatCount = curVSegLen;
|
||||
}
|
||||
|
||||
auto colorCount = frameData->getColorCount();
|
||||
if (colorCount > 0) {
|
||||
ColorData *preColorData = frameData->buildColorData(colorCount - 1);
|
||||
preColorData->vertexFloatOffset = static_cast<int>(vb.getCurPos() / sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonCache::onAnimationStateEvent(TrackEntry *entry, EventType type, Event *event) {
|
||||
SkeletonAnimation::onAnimationStateEvent(entry, type, event);
|
||||
if (type == EventType_Complete && entry) {
|
||||
Animation *ani = entry->getAnimation();
|
||||
if (!ani) return;
|
||||
std::string aniName = ani->getName().buffer();
|
||||
if (aniName == _curAnimationName) {
|
||||
AnimationData *aniData = getAnimationData(_curAnimationName);
|
||||
if (!aniData) return;
|
||||
aniData->_isComplete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonCache::resetAllAnimationData() {
|
||||
for (auto &animationCache : _animationCaches) {
|
||||
animationCache.second->reset();
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonCache::resetAnimationData(const std::string &animationName) {
|
||||
for (auto &animationCache : _animationCaches) {
|
||||
if (animationCache.second->_animationName == animationName) {
|
||||
animationCache.second->reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace spine
|
||||
157
cocos/editor-support/spine-creator-support/SkeletonCache.h
Normal file
157
cocos/editor-support/spine-creator-support/SkeletonCache.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "IOBuffer.h"
|
||||
#include "SkeletonAnimation.h"
|
||||
#include "middleware-adapter.h"
|
||||
|
||||
namespace spine {
|
||||
class SkeletonCache : public SkeletonAnimation {
|
||||
public:
|
||||
struct SegmentData {
|
||||
friend class SkeletonCache;
|
||||
|
||||
SegmentData();
|
||||
~SegmentData();
|
||||
|
||||
void setTexture(cc::middleware::Texture2D *value);
|
||||
cc::middleware::Texture2D *getTexture() const;
|
||||
|
||||
public:
|
||||
int indexCount = 0;
|
||||
int vertexFloatCount = 0;
|
||||
int blendMode = 0;
|
||||
|
||||
private:
|
||||
cc::middleware::Texture2D *_texture = nullptr;
|
||||
};
|
||||
|
||||
struct BoneData {
|
||||
cc::Mat4 globalTransformMatrix;
|
||||
};
|
||||
|
||||
struct ColorData {
|
||||
cc::middleware::Color4B finalColor;
|
||||
cc::middleware::Color4B darkColor;
|
||||
int vertexFloatOffset = 0;
|
||||
};
|
||||
|
||||
struct FrameData {
|
||||
friend class SkeletonCache;
|
||||
|
||||
FrameData();
|
||||
~FrameData();
|
||||
|
||||
const std::vector<BoneData *> &getBones() const {
|
||||
return _bones;
|
||||
}
|
||||
std::size_t getBoneCount() const;
|
||||
|
||||
const std::vector<ColorData *> &getColors() const {
|
||||
return _colors;
|
||||
}
|
||||
std::size_t getColorCount() const;
|
||||
|
||||
const std::vector<SegmentData *> &getSegments() const {
|
||||
return _segments;
|
||||
}
|
||||
std::size_t getSegmentCount() const;
|
||||
|
||||
private:
|
||||
// if segment data is empty, it will build new one.
|
||||
SegmentData *buildSegmentData(std::size_t index);
|
||||
// if color data is empty, it will build new one.
|
||||
ColorData *buildColorData(std::size_t index);
|
||||
// if bone data is empty, it will build new one.
|
||||
BoneData *buildBoneData(std::size_t index);
|
||||
|
||||
std::vector<BoneData *> _bones;
|
||||
std::vector<ColorData *> _colors;
|
||||
std::vector<SegmentData *> _segments;
|
||||
|
||||
public:
|
||||
cc::middleware::IOBuffer ib;
|
||||
cc::middleware::IOBuffer vb;
|
||||
};
|
||||
|
||||
struct AnimationData {
|
||||
friend class SkeletonCache;
|
||||
|
||||
AnimationData();
|
||||
~AnimationData();
|
||||
void reset();
|
||||
|
||||
FrameData *getFrameData(std::size_t frameIdx) const;
|
||||
std::size_t getFrameCount() const;
|
||||
|
||||
bool isComplete() const { return _isComplete; }
|
||||
bool needUpdate(int toFrameIdx) const;
|
||||
|
||||
private:
|
||||
// if frame is empty, it will build new one.
|
||||
FrameData *buildFrameData(std::size_t frameIdx);
|
||||
|
||||
private:
|
||||
std::string _animationName = "";
|
||||
bool _isComplete = false;
|
||||
float _totalTime = 0.0f;
|
||||
std::vector<FrameData *> _frames;
|
||||
};
|
||||
|
||||
SkeletonCache();
|
||||
virtual ~SkeletonCache();
|
||||
|
||||
virtual void beginSchedule() override {}
|
||||
virtual void stopSchedule() override {}
|
||||
virtual void update(float deltaTime) override;
|
||||
virtual void render(float deltaTime) override {}
|
||||
virtual void onAnimationStateEvent(TrackEntry *entry, EventType type, Event *event) override;
|
||||
|
||||
void updateToFrame(const std::string &animationName, int toFrameIdx = -1);
|
||||
// if animation data is empty, it will build new one.
|
||||
AnimationData *buildAnimationData(const std::string &animationName);
|
||||
AnimationData *getAnimationData(const std::string &animationName);
|
||||
void resetAllAnimationData();
|
||||
void resetAnimationData(const std::string &animationName);
|
||||
|
||||
private:
|
||||
void renderAnimationFrame(AnimationData *animationData);
|
||||
|
||||
public:
|
||||
static float FrameTime;
|
||||
static float MaxCacheTime;
|
||||
|
||||
private:
|
||||
std::string _curAnimationName = "";
|
||||
std::map<std::string, AnimationData *> _animationCaches;
|
||||
};
|
||||
} // namespace spine
|
||||
@@ -0,0 +1,604 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SkeletonCacheAnimation.h"
|
||||
#include "2d/renderer/RenderDrawInfo.h"
|
||||
#include "2d/renderer/RenderEntity.h"
|
||||
#include "MiddlewareMacro.h"
|
||||
#include "SharedBufferManager.h"
|
||||
#include "SkeletonCacheMgr.h"
|
||||
#include "base/TypeDef.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "gfx-base/GFXDef.h"
|
||||
#include "math/Math.h"
|
||||
#include "renderer/core/MaterialInstance.h"
|
||||
|
||||
USING_NS_MW; // NOLINT(google-build-using-namespace)
|
||||
|
||||
using namespace cc; // NOLINT(google-build-using-namespace)
|
||||
using namespace cc::gfx; // NOLINT(google-build-using-namespace)
|
||||
static const std::string TECH_STAGE = "opaque";
|
||||
static const std::string TEXTURE_KEY = "texture";
|
||||
|
||||
namespace spine {
|
||||
|
||||
SkeletonCacheAnimation::SkeletonCacheAnimation(const std::string &uuid, bool isShare) {
|
||||
if (isShare) {
|
||||
_skeletonCache = SkeletonCacheMgr::getInstance()->buildSkeletonCache(uuid);
|
||||
_skeletonCache->addRef();
|
||||
} else {
|
||||
_skeletonCache = new SkeletonCache();
|
||||
_skeletonCache->addRef();
|
||||
_skeletonCache->initWithUUID(uuid);
|
||||
}
|
||||
|
||||
// store global TypedArray begin and end offset
|
||||
_sharedBufferOffset = new IOTypedArray(se::Object::TypedArrayType::UINT32, sizeof(uint32_t) * 2);
|
||||
}
|
||||
|
||||
SkeletonCacheAnimation::~SkeletonCacheAnimation() {
|
||||
if (_sharedBufferOffset) {
|
||||
delete _sharedBufferOffset;
|
||||
_sharedBufferOffset = nullptr;
|
||||
}
|
||||
|
||||
if (_skeletonCache) {
|
||||
_skeletonCache->release();
|
||||
_skeletonCache = nullptr;
|
||||
}
|
||||
while (!_animationQueue.empty()) {
|
||||
auto *ani = _animationQueue.front();
|
||||
_animationQueue.pop();
|
||||
delete ani;
|
||||
}
|
||||
for (auto *draw : _drawInfoArray) {
|
||||
CC_SAFE_DELETE(draw);
|
||||
}
|
||||
|
||||
for (auto &item : _materialCaches) {
|
||||
CC_SAFE_DELETE(item.second);
|
||||
}
|
||||
stopSchedule();
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::update(float dt) {
|
||||
if (_paused) return;
|
||||
|
||||
auto gTimeScale = SkeletonAnimation::GlobalTimeScale;
|
||||
dt *= _timeScale * gTimeScale;
|
||||
|
||||
if (_isAniComplete) {
|
||||
if (_animationQueue.empty() && !_headAnimation) {
|
||||
if (_animationData && !_animationData->isComplete()) {
|
||||
_skeletonCache->updateToFrame(_animationName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!_headAnimation) {
|
||||
_headAnimation = _animationQueue.front();
|
||||
_animationQueue.pop();
|
||||
}
|
||||
if (!_headAnimation) {
|
||||
return;
|
||||
}
|
||||
_accTime += dt;
|
||||
if (_accTime > _headAnimation->delay) {
|
||||
std::string name = _headAnimation->animationName;
|
||||
bool loop = _headAnimation->loop;
|
||||
delete _headAnimation;
|
||||
_headAnimation = nullptr;
|
||||
setAnimation(name, loop);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_animationData) return;
|
||||
|
||||
if (_accTime <= 0.00001 && _playCount == 0) {
|
||||
if (_startListener) {
|
||||
_startListener(_animationName);
|
||||
}
|
||||
}
|
||||
|
||||
_accTime += dt;
|
||||
int frameIdx = floor(_accTime / SkeletonCache::FrameTime);
|
||||
if (!_animationData->isComplete()) {
|
||||
_skeletonCache->updateToFrame(_animationName, frameIdx);
|
||||
}
|
||||
|
||||
int finalFrameIndex = static_cast<int>(_animationData->getFrameCount()) - 1;
|
||||
if (_animationData->isComplete() && frameIdx >= finalFrameIndex) {
|
||||
_playCount++;
|
||||
_accTime = 0.0F;
|
||||
if (_playTimes > 0 && _playCount >= _playTimes) {
|
||||
frameIdx = finalFrameIndex;
|
||||
_playCount = 0;
|
||||
_isAniComplete = true;
|
||||
} else {
|
||||
frameIdx = 0;
|
||||
}
|
||||
if (_endListener) {
|
||||
_endListener(_animationName);
|
||||
}
|
||||
if (_completeListener) {
|
||||
_completeListener(_animationName);
|
||||
}
|
||||
}
|
||||
_curFrameIndex = frameIdx;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::render(float /*dt*/) {
|
||||
if (!_animationData) return;
|
||||
SkeletonCache::FrameData *frameData = _animationData->getFrameData(_curFrameIndex);
|
||||
if (!frameData) return;
|
||||
auto *entity = _entity;
|
||||
entity->clearDynamicRenderDrawInfos();
|
||||
|
||||
const auto &segments = frameData->getSegments();
|
||||
const auto &colors = frameData->getColors();
|
||||
if (segments.empty() || colors.empty()) return;
|
||||
|
||||
auto *mgr = MiddlewareManager::getInstance();
|
||||
if (!mgr->isRendering) return;
|
||||
|
||||
_sharedBufferOffset->reset();
|
||||
_sharedBufferOffset->clear();
|
||||
|
||||
auto *attachMgr = mgr->getAttachInfoMgr();
|
||||
auto *attachInfo = attachMgr->getBuffer();
|
||||
if (!attachInfo) return;
|
||||
|
||||
// store attach info offset
|
||||
_sharedBufferOffset->writeUint32(static_cast<uint32_t>(attachInfo->getCurPos()) / sizeof(uint32_t));
|
||||
|
||||
auto vertexFormat = _useTint ? VF_XYZUVCC : VF_XYZUVC;
|
||||
middleware::MeshBuffer *mb = mgr->getMeshBuffer(vertexFormat);
|
||||
middleware::IOBuffer &vb = mb->getVB();
|
||||
middleware::IOBuffer &ib = mb->getIB();
|
||||
const auto &srcVB = frameData->vb;
|
||||
const auto &srcIB = frameData->ib;
|
||||
|
||||
// vertex size int bytes with one color
|
||||
int vbs1 = sizeof(V3F_T2F_C4B);
|
||||
// vertex size in floats with one color
|
||||
int vs1 = static_cast<int32_t>(vbs1 / sizeof(float));
|
||||
// vertex size int bytes with two color
|
||||
int vbs2 = sizeof(V3F_T2F_C4B_C4B);
|
||||
// vertex size in floats with two color
|
||||
int vs2 = static_cast<int32_t>(vbs2 / sizeof(float));
|
||||
|
||||
int vs = _useTint ? vs2 : vs1;
|
||||
int vbs = _useTint ? vbs2 : vbs1;
|
||||
|
||||
auto &nodeWorldMat = entity->getNode()->getWorldMatrix();
|
||||
|
||||
int colorOffset = 0;
|
||||
SkeletonCache::ColorData *nowColor = colors[colorOffset++];
|
||||
auto maxVFOffset = nowColor->vertexFloatOffset;
|
||||
|
||||
Color4B finalColor;
|
||||
Color4B darkColor;
|
||||
float tempR = 0.0F;
|
||||
float tempG = 0.0F;
|
||||
float tempB = 0.0F;
|
||||
float tempA = 0.0F;
|
||||
float multiplier = 1.0F;
|
||||
int srcVertexBytesOffset = 0;
|
||||
int srcVertexBytes = 0;
|
||||
int vertexBytes = 0;
|
||||
int vertexFloats = 0;
|
||||
int tintBytes = 0;
|
||||
int srcIndexBytesOffset = 0;
|
||||
int indexBytes = 0;
|
||||
double effectHash = 0;
|
||||
int blendMode = 0;
|
||||
int dstVertexOffset = 0;
|
||||
int dstIndexOffset = 0;
|
||||
float *dstVertexBuffer = nullptr;
|
||||
unsigned int *dstColorBuffer = nullptr;
|
||||
uint16_t *dstIndexBuffer = nullptr;
|
||||
bool needColor = false;
|
||||
int curBlendSrc = -1;
|
||||
int curBlendDst = -1;
|
||||
cc::Texture2D *curTexture = nullptr;
|
||||
RenderDrawInfo *curDrawInfo = nullptr;
|
||||
|
||||
if (abs(_nodeColor.r - 1.0F) > 0.0001F ||
|
||||
abs(_nodeColor.g - 1.0F) > 0.0001F ||
|
||||
abs(_nodeColor.b - 1.0F) > 0.0001F ||
|
||||
abs(_nodeColor.a - 1.0F) > 0.0001F ||
|
||||
_premultipliedAlpha) {
|
||||
needColor = true;
|
||||
}
|
||||
|
||||
auto handleColor = [&](SkeletonCache::ColorData *colorData) {
|
||||
tempA = colorData->finalColor.a * _nodeColor.a;
|
||||
multiplier = _premultipliedAlpha ? tempA / 255 : 1;
|
||||
tempR = _nodeColor.r * multiplier;
|
||||
tempG = _nodeColor.g * multiplier;
|
||||
tempB = _nodeColor.b * multiplier;
|
||||
|
||||
finalColor.r = static_cast<uint8_t>(std::round(colorData->finalColor.r * tempR));
|
||||
finalColor.g = static_cast<uint8_t>(std::round(colorData->finalColor.g * tempG));
|
||||
finalColor.b = static_cast<uint8_t>(std::round(colorData->finalColor.b * tempB));
|
||||
finalColor.a = static_cast<uint8_t>(std::round(tempA));
|
||||
|
||||
darkColor.r = static_cast<uint8_t>(std::round(colorData->darkColor.r * tempR));
|
||||
darkColor.g = static_cast<uint8_t>(std::round(colorData->darkColor.g * tempG));
|
||||
darkColor.b = static_cast<uint8_t>(std::round(colorData->darkColor.b * tempB));
|
||||
darkColor.a = _premultipliedAlpha ? 255 : 0;
|
||||
};
|
||||
|
||||
handleColor(nowColor);
|
||||
int segmentCount = 0;
|
||||
for (auto *segment : segments) {
|
||||
srcVertexBytes = static_cast<int32_t>(segment->vertexFloatCount * sizeof(float));
|
||||
if (!_useTint) {
|
||||
tintBytes = static_cast<int32_t>(segment->vertexFloatCount / vs2 * sizeof(float));
|
||||
vertexBytes = srcVertexBytes - tintBytes;
|
||||
vertexFloats = static_cast<int32_t>(vertexBytes / sizeof(float));
|
||||
} else {
|
||||
vertexBytes = srcVertexBytes;
|
||||
vertexFloats = segment->vertexFloatCount;
|
||||
}
|
||||
curDrawInfo = requestDrawInfo(segmentCount++);
|
||||
entity->addDynamicRenderDrawInfo(curDrawInfo);
|
||||
// fill new texture index
|
||||
curTexture = static_cast<cc::Texture2D *>(segment->getTexture()->getRealTexture());
|
||||
gfx::Texture *texture = curTexture->getGFXTexture();
|
||||
gfx::Sampler *sampler = curTexture->getGFXSampler();
|
||||
curDrawInfo->setTexture(texture);
|
||||
curDrawInfo->setSampler(sampler);
|
||||
|
||||
blendMode = segment->blendMode;
|
||||
switch (blendMode) {
|
||||
case BlendMode_Additive:
|
||||
curBlendSrc = static_cast<int>(_premultipliedAlpha ? BlendFactor::ONE : BlendFactor::SRC_ALPHA);
|
||||
curBlendDst = static_cast<int>(BlendFactor::ONE);
|
||||
break;
|
||||
case BlendMode_Multiply:
|
||||
curBlendSrc = static_cast<int>(BlendFactor::DST_COLOR);
|
||||
curBlendDst = static_cast<int>(BlendFactor::ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
case BlendMode_Screen:
|
||||
curBlendSrc = static_cast<int>(BlendFactor::ONE);
|
||||
curBlendDst = static_cast<int>(BlendFactor::ONE_MINUS_SRC_COLOR);
|
||||
break;
|
||||
default:
|
||||
curBlendSrc = static_cast<int>(_premultipliedAlpha ? BlendFactor::ONE : BlendFactor::SRC_ALPHA);
|
||||
curBlendDst = static_cast<int>(BlendFactor::ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
// fill new blend src and dst
|
||||
auto *material = requestMaterial(curBlendSrc, curBlendDst);
|
||||
curDrawInfo->setMaterial(material);
|
||||
|
||||
// fill vertex buffer
|
||||
vb.checkSpace(vertexBytes, true);
|
||||
dstVertexOffset = static_cast<int>(vb.getCurPos()) / vbs;
|
||||
dstVertexBuffer = reinterpret_cast<float *>(vb.getCurBuffer());
|
||||
dstColorBuffer = reinterpret_cast<unsigned int *>(vb.getCurBuffer());
|
||||
if (!_useTint) {
|
||||
char *srcBuffer = reinterpret_cast<char *>(srcVB.getBuffer()) + srcVertexBytesOffset;
|
||||
for (std::size_t srcBufferIdx = 0; srcBufferIdx < srcVertexBytes; srcBufferIdx += vbs2) {
|
||||
vb.writeBytes(srcBuffer + srcBufferIdx, vbs);
|
||||
}
|
||||
} else {
|
||||
vb.writeBytes(reinterpret_cast<char *>(srcVB.getBuffer()) + srcVertexBytesOffset, vertexBytes);
|
||||
}
|
||||
// batch handle
|
||||
if (_enableBatch) {
|
||||
cc::Vec3 *point = nullptr;
|
||||
for (auto posIndex = 0; posIndex < vertexFloats; posIndex += vs) {
|
||||
point = reinterpret_cast<cc::Vec3 *>(dstVertexBuffer + posIndex);
|
||||
point->z = 0;
|
||||
point->transformMat4(*point, nodeWorldMat);
|
||||
}
|
||||
}
|
||||
// handle vertex color
|
||||
if (needColor) {
|
||||
int srcVertexFloatOffset = static_cast<int16_t>(srcVertexBytesOffset / sizeof(float));
|
||||
if (_useTint) {
|
||||
for (auto colorIndex = 0; colorIndex < vertexFloats; colorIndex += vs, srcVertexFloatOffset += vs2) {
|
||||
if (srcVertexFloatOffset >= maxVFOffset) {
|
||||
nowColor = colors[colorOffset++];
|
||||
handleColor(nowColor);
|
||||
maxVFOffset = nowColor->vertexFloatOffset;
|
||||
}
|
||||
memcpy(dstColorBuffer + colorIndex + 5, &finalColor, sizeof(finalColor));
|
||||
memcpy(dstColorBuffer + colorIndex + 6, &darkColor, sizeof(darkColor));
|
||||
}
|
||||
} else {
|
||||
for (auto colorIndex = 0; colorIndex < vertexFloats; colorIndex += vs, srcVertexFloatOffset += vs2) {
|
||||
if (srcVertexFloatOffset >= maxVFOffset) {
|
||||
nowColor = colors[colorOffset++];
|
||||
handleColor(nowColor);
|
||||
maxVFOffset = nowColor->vertexFloatOffset;
|
||||
}
|
||||
memcpy(dstColorBuffer + colorIndex + 5, &finalColor, sizeof(finalColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// move src vertex buffer offset
|
||||
srcVertexBytesOffset += srcVertexBytes;
|
||||
|
||||
// fill index buffer
|
||||
indexBytes = static_cast<int32_t>(segment->indexCount * sizeof(uint16_t));
|
||||
ib.checkSpace(indexBytes, true);
|
||||
dstIndexOffset = static_cast<int32_t>(ib.getCurPos() / sizeof(uint16_t));
|
||||
dstIndexBuffer = reinterpret_cast<uint16_t *>(ib.getCurBuffer());
|
||||
ib.writeBytes(reinterpret_cast<char *>(srcIB.getBuffer()) + srcIndexBytesOffset, indexBytes);
|
||||
for (auto indexPos = 0; indexPos < segment->indexCount; indexPos++) {
|
||||
dstIndexBuffer[indexPos] += dstVertexOffset;
|
||||
}
|
||||
srcIndexBytesOffset += indexBytes;
|
||||
|
||||
// fill new index and vertex buffer id
|
||||
UIMeshBuffer *uiMeshBuffer = mb->getUIMeshBuffer();
|
||||
curDrawInfo->setMeshBuffer(uiMeshBuffer);
|
||||
|
||||
// fill new index offset
|
||||
curDrawInfo->setIndexOffset(dstIndexOffset);
|
||||
// fill new indice segamentation count
|
||||
curDrawInfo->setIbCount(segment->indexCount);
|
||||
}
|
||||
|
||||
if (_useAttach) {
|
||||
const auto &bonesData = frameData->getBones();
|
||||
auto boneCount = frameData->getBoneCount();
|
||||
|
||||
for (std::size_t i = 0, n = boneCount; i < n; i++) {
|
||||
auto *bone = bonesData[i];
|
||||
attachInfo->checkSpace(sizeof(cc::Mat4), true);
|
||||
attachInfo->writeBytes(reinterpret_cast<const char *>(&bone->globalTransformMatrix), sizeof(cc::Mat4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Skeleton *SkeletonCacheAnimation::getSkeleton() const {
|
||||
return _skeletonCache->getSkeleton();
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setTimeScale(float scale) {
|
||||
_timeScale = scale;
|
||||
}
|
||||
|
||||
float SkeletonCacheAnimation::getTimeScale() const {
|
||||
return _timeScale;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::paused(bool value) {
|
||||
_paused = value;
|
||||
}
|
||||
|
||||
Bone *SkeletonCacheAnimation::findBone(const std::string &boneName) const {
|
||||
return _skeletonCache->findBone(boneName);
|
||||
}
|
||||
|
||||
Slot *SkeletonCacheAnimation::findSlot(const std::string &slotName) const {
|
||||
return _skeletonCache->findSlot(slotName);
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setSkin(const std::string &skinName) {
|
||||
_skeletonCache->setSkin(skinName);
|
||||
_skeletonCache->resetAllAnimationData();
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setSkin(const char *skinName) {
|
||||
_skeletonCache->setSkin(skinName);
|
||||
_skeletonCache->resetAllAnimationData();
|
||||
}
|
||||
|
||||
Attachment *SkeletonCacheAnimation::getAttachment(const std::string &slotName, const std::string &attachmentName) const {
|
||||
return _skeletonCache->getAttachment(slotName, attachmentName);
|
||||
}
|
||||
|
||||
bool SkeletonCacheAnimation::setAttachment(const std::string &slotName, const std::string &attachmentName) {
|
||||
auto ret = _skeletonCache->setAttachment(slotName, attachmentName);
|
||||
_skeletonCache->resetAllAnimationData();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool SkeletonCacheAnimation::setAttachment(const std::string &slotName, const char *attachmentName) {
|
||||
auto ret = _skeletonCache->setAttachment(slotName, attachmentName);
|
||||
_skeletonCache->resetAllAnimationData();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setColor(float r, float g, float b, float a) {
|
||||
_nodeColor.r = r / 255.0F;
|
||||
_nodeColor.g = g / 255.0F;
|
||||
_nodeColor.b = b / 255.0F;
|
||||
_nodeColor.a = a / 255.0F;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setBatchEnabled(bool enabled) {
|
||||
if (_enableBatch != enabled) {
|
||||
for (auto &item : _materialCaches) {
|
||||
CC_SAFE_DELETE(item.second);
|
||||
}
|
||||
_materialCaches.clear();
|
||||
_enableBatch = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setOpacityModifyRGB(bool value) {
|
||||
_premultipliedAlpha = value;
|
||||
}
|
||||
|
||||
bool SkeletonCacheAnimation::isOpacityModifyRGB() const {
|
||||
return _premultipliedAlpha;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::beginSchedule() {
|
||||
MiddlewareManager::getInstance()->addTimer(this);
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::stopSchedule() {
|
||||
MiddlewareManager::getInstance()->removeTimer(this);
|
||||
|
||||
if (_sharedBufferOffset) {
|
||||
_sharedBufferOffset->reset();
|
||||
_sharedBufferOffset->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::onEnable() {
|
||||
beginSchedule();
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::onDisable() {
|
||||
stopSchedule();
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setUseTint(bool enabled) {
|
||||
// cache mode default enable use tint
|
||||
// _useTint = enabled;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setAttachEnabled(bool enabled) {
|
||||
_useAttach = enabled;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setAnimation(const std::string &name, bool loop) {
|
||||
_playTimes = loop ? 0 : 1;
|
||||
_animationName = name;
|
||||
_animationData = _skeletonCache->buildAnimationData(_animationName);
|
||||
_isAniComplete = false;
|
||||
_accTime = 0.0F;
|
||||
_playCount = 0;
|
||||
_curFrameIndex = 0;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::addAnimation(const std::string &name, bool loop, float delay) {
|
||||
auto *aniInfo = new AniQueueData();
|
||||
aniInfo->animationName = name;
|
||||
aniInfo->loop = loop;
|
||||
aniInfo->delay = delay;
|
||||
_animationQueue.push(aniInfo);
|
||||
}
|
||||
|
||||
Animation *SkeletonCacheAnimation::findAnimation(const std::string &name) const {
|
||||
return _skeletonCache->findAnimation(name);
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setStartListener(const CacheFrameEvent &listener) {
|
||||
_startListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setEndListener(const CacheFrameEvent &listener) {
|
||||
_endListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setCompleteListener(const CacheFrameEvent &listener) {
|
||||
_completeListener = listener;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::updateAnimationCache(const std::string &animationName) {
|
||||
_skeletonCache->resetAnimationData(animationName);
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::updateAllAnimationCache() {
|
||||
_skeletonCache->resetAllAnimationData();
|
||||
}
|
||||
|
||||
se_object_ptr SkeletonCacheAnimation::getSharedBufferOffset() const {
|
||||
if (_sharedBufferOffset) {
|
||||
return _sharedBufferOffset->getTypeArray();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setToSetupPose() {
|
||||
if (_skeletonCache) {
|
||||
_skeletonCache->setToSetupPose();
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setBonesToSetupPose() {
|
||||
if (_skeletonCache) {
|
||||
_skeletonCache->setBonesToSetupPose();
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setSlotsToSetupPose() {
|
||||
if (_skeletonCache) {
|
||||
_skeletonCache->setSlotsToSetupPose();
|
||||
}
|
||||
}
|
||||
void SkeletonCacheAnimation::setRenderEntity(cc::RenderEntity *entity) {
|
||||
_entity = entity;
|
||||
}
|
||||
|
||||
void SkeletonCacheAnimation::setMaterial(cc::Material *material) {
|
||||
_material = material;
|
||||
for (auto &item : _materialCaches) {
|
||||
CC_SAFE_DELETE(item.second);
|
||||
}
|
||||
_materialCaches.clear();
|
||||
}
|
||||
|
||||
cc::RenderDrawInfo *SkeletonCacheAnimation::requestDrawInfo(int idx) {
|
||||
if (_drawInfoArray.size() < idx + 1) {
|
||||
cc::RenderDrawInfo *draw = new cc::RenderDrawInfo();
|
||||
draw->setDrawInfoType(static_cast<uint32_t>(RenderDrawInfoType::MIDDLEWARE));
|
||||
_drawInfoArray.push_back(draw);
|
||||
}
|
||||
return _drawInfoArray[idx];
|
||||
}
|
||||
|
||||
cc::Material *SkeletonCacheAnimation::requestMaterial(uint16_t blendSrc, uint16_t blendDst) {
|
||||
uint32_t key = static_cast<uint32_t>(blendSrc) << 16 | static_cast<uint32_t>(blendDst);
|
||||
if (_materialCaches.find(key) == _materialCaches.end()) {
|
||||
const IMaterialInstanceInfo info{
|
||||
(Material *)_material,
|
||||
0};
|
||||
MaterialInstance *materialInstance = new MaterialInstance(info);
|
||||
PassOverrides overrides;
|
||||
BlendStateInfo stateInfo;
|
||||
stateInfo.blendColor = gfx::Color{1.0F, 1.0F, 1.0F, 1.0F};
|
||||
BlendTargetInfo targetInfo;
|
||||
targetInfo.blendEq = gfx::BlendOp::ADD;
|
||||
targetInfo.blendAlphaEq = gfx::BlendOp::ADD;
|
||||
targetInfo.blendSrc = (gfx::BlendFactor)blendSrc;
|
||||
targetInfo.blendDst = (gfx::BlendFactor)blendDst;
|
||||
targetInfo.blendSrcAlpha = (gfx::BlendFactor)blendSrc;
|
||||
targetInfo.blendDstAlpha = (gfx::BlendFactor)blendDst;
|
||||
BlendTargetInfoList targetList{targetInfo};
|
||||
stateInfo.targets = targetList;
|
||||
overrides.blendState = stateInfo;
|
||||
materialInstance->overridePipelineStates(overrides);
|
||||
const MacroRecord macros{{"TWO_COLORED", _useTint}, {"USE_LOCAL", !_enableBatch}};
|
||||
materialInstance->recompileShaders(macros);
|
||||
_materialCaches[key] = materialInstance;
|
||||
}
|
||||
return _materialCaches[key];
|
||||
}
|
||||
|
||||
} // namespace spine
|
||||
@@ -0,0 +1,145 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <queue>
|
||||
#include "MiddlewareManager.h"
|
||||
#include "SkeletonCache.h"
|
||||
#include "base/RefCounted.h"
|
||||
#include "middleware-adapter.h"
|
||||
#include "spine/spine.h"
|
||||
|
||||
namespace cc {
|
||||
class RenderEntity;
|
||||
class RenderDrawInfo;
|
||||
class Material;
|
||||
};
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SkeletonCacheAnimation : public cc::RefCounted, public cc::middleware::IMiddleware {
|
||||
public:
|
||||
SkeletonCacheAnimation(const std::string &uuid, bool isShare);
|
||||
~SkeletonCacheAnimation() override;
|
||||
|
||||
void update(float dt) override;
|
||||
void render(float dt) override;
|
||||
|
||||
Skeleton *getSkeleton() const;
|
||||
|
||||
void setTimeScale(float scale);
|
||||
float getTimeScale() const;
|
||||
|
||||
void paused(bool value);
|
||||
|
||||
Bone *findBone(const std::string &boneName) const;
|
||||
Slot *findSlot(const std::string &slotName) const;
|
||||
|
||||
void setSkin(const std::string &skinName);
|
||||
void setSkin(const char *skinName);
|
||||
|
||||
Attachment *getAttachment(const std::string &slotName, const std::string &attachmentName) const;
|
||||
bool setAttachment(const std::string &slotName, const std::string &attachmentName);
|
||||
bool setAttachment(const std::string &slotName, const char *attachmentName);
|
||||
void setColor(float r, float g, float b, float a);
|
||||
void setBatchEnabled(bool enabled);
|
||||
void setAttachEnabled(bool enabled);
|
||||
|
||||
void setOpacityModifyRGB(bool value);
|
||||
bool isOpacityModifyRGB() const;
|
||||
|
||||
void beginSchedule();
|
||||
void stopSchedule();
|
||||
void onEnable();
|
||||
void onDisable();
|
||||
void setUseTint(bool enabled);
|
||||
|
||||
void setAnimation(const std::string &name, bool loop);
|
||||
void addAnimation(const std::string &name, bool loop, float delay = 0);
|
||||
Animation *findAnimation(const std::string &name) const;
|
||||
|
||||
using CacheFrameEvent = std::function<void(std::string)>;
|
||||
void setStartListener(const CacheFrameEvent &listener);
|
||||
void setEndListener(const CacheFrameEvent &listener);
|
||||
void setCompleteListener(const CacheFrameEvent &listener);
|
||||
void updateAnimationCache(const std::string &animationName);
|
||||
void updateAllAnimationCache();
|
||||
|
||||
void setToSetupPose();
|
||||
void setBonesToSetupPose();
|
||||
void setSlotsToSetupPose();
|
||||
|
||||
/**
|
||||
* @return shared buffer offset, it's a Uint32Array
|
||||
* format |render info offset|attach info offset|
|
||||
*/
|
||||
se_object_ptr getSharedBufferOffset() const;
|
||||
|
||||
cc::RenderDrawInfo *requestDrawInfo(int idx);
|
||||
cc::Material *requestMaterial(uint16_t blendSrc, uint16_t blendDst);
|
||||
void setMaterial(cc::Material *material);
|
||||
void setRenderEntity(cc::RenderEntity* entity);
|
||||
private:
|
||||
float _timeScale = 1;
|
||||
bool _paused = false;
|
||||
bool _useAttach = false;
|
||||
cc::middleware::Color4F _nodeColor = cc::middleware::Color4F::WHITE;
|
||||
bool _premultipliedAlpha = false;
|
||||
|
||||
CacheFrameEvent _startListener = nullptr;
|
||||
CacheFrameEvent _endListener = nullptr;
|
||||
CacheFrameEvent _completeListener = nullptr;
|
||||
|
||||
SkeletonCache *_skeletonCache = nullptr;
|
||||
SkeletonCache::AnimationData *_animationData = nullptr;
|
||||
int _curFrameIndex = -1;
|
||||
|
||||
float _accTime = 0.0F;
|
||||
int _playCount = 0;
|
||||
int _playTimes = 0;
|
||||
bool _isAniComplete = true;
|
||||
std::string _animationName;
|
||||
bool _useTint = true;
|
||||
bool _enableBatch = false;
|
||||
|
||||
struct AniQueueData {
|
||||
std::string animationName;
|
||||
bool loop = false;
|
||||
float delay = 0.0F;
|
||||
};
|
||||
std::queue<AniQueueData *> _animationQueue;
|
||||
AniQueueData *_headAnimation = nullptr;
|
||||
|
||||
cc::middleware::IOTypedArray *_sharedBufferOffset = nullptr;
|
||||
cc::RenderEntity *_entity = nullptr;
|
||||
cc::Material *_material = nullptr;
|
||||
ccstd::vector<cc::RenderDrawInfo *> _drawInfoArray;
|
||||
ccstd::unordered_map<uint32_t, cc::Material*> _materialCaches;
|
||||
};
|
||||
} // namespace spine
|
||||
@@ -0,0 +1,53 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SkeletonCacheMgr.h"
|
||||
#include "base/DeferredReleasePool.h"
|
||||
|
||||
namespace spine {
|
||||
SkeletonCacheMgr *SkeletonCacheMgr::instance = nullptr;
|
||||
SkeletonCache *SkeletonCacheMgr::buildSkeletonCache(const std::string &uuid) {
|
||||
SkeletonCache *animation = _caches.at(uuid);
|
||||
if (!animation) {
|
||||
animation = new SkeletonCache();
|
||||
animation->addRef();
|
||||
animation->initWithUUID(uuid);
|
||||
_caches.insert(uuid, animation);
|
||||
cc::DeferredReleasePool::add(animation);
|
||||
}
|
||||
return animation;
|
||||
}
|
||||
|
||||
void SkeletonCacheMgr::removeSkeletonCache(const std::string &uuid) {
|
||||
auto it = _caches.find(uuid);
|
||||
if (it != _caches.end()) {
|
||||
_caches.erase(it);
|
||||
}
|
||||
}
|
||||
} // namespace spine
|
||||
@@ -0,0 +1,60 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "SkeletonCache.h"
|
||||
#include "base/RefMap.h"
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SkeletonCacheMgr {
|
||||
public:
|
||||
static SkeletonCacheMgr *getInstance() {
|
||||
if (instance == nullptr) {
|
||||
instance = new SkeletonCacheMgr();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void destroyInstance() {
|
||||
if (instance) {
|
||||
delete instance;
|
||||
instance = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void removeSkeletonCache(const std::string &uuid);
|
||||
SkeletonCache *buildSkeletonCache(const std::string &uuid);
|
||||
|
||||
private:
|
||||
static SkeletonCacheMgr *instance;
|
||||
cc::RefMap<std::string, SkeletonCache *> _caches;
|
||||
};
|
||||
|
||||
} // namespace spine
|
||||
116
cocos/editor-support/spine-creator-support/SkeletonDataMgr.cpp
Normal file
116
cocos/editor-support/spine-creator-support/SkeletonDataMgr.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SkeletonDataMgr.h"
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
using namespace spine; //NOLINT
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SkeletonDataInfo {
|
||||
public:
|
||||
SkeletonDataInfo() = default;
|
||||
|
||||
~SkeletonDataInfo() {
|
||||
if (data) {
|
||||
delete data;
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
if (atlas) {
|
||||
delete atlas;
|
||||
atlas = nullptr;
|
||||
}
|
||||
|
||||
if (attachmentLoader) {
|
||||
delete attachmentLoader;
|
||||
attachmentLoader = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
SkeletonData *data = nullptr;
|
||||
Atlas *atlas = nullptr;
|
||||
AttachmentLoader *attachmentLoader = nullptr;
|
||||
std::vector<int> texturesIndex;
|
||||
};
|
||||
|
||||
} // namespace spine
|
||||
|
||||
SkeletonDataMgr *SkeletonDataMgr::instance = nullptr;
|
||||
|
||||
SkeletonDataMgr::~SkeletonDataMgr() {
|
||||
_destroyCallback = nullptr;
|
||||
for (auto &e : _dataMap) {
|
||||
delete e.second;
|
||||
}
|
||||
_dataMap.clear();
|
||||
}
|
||||
|
||||
bool SkeletonDataMgr::hasSkeletonData(const std::string &uuid) {
|
||||
auto it = _dataMap.find(uuid);
|
||||
return it != _dataMap.end();
|
||||
}
|
||||
|
||||
void SkeletonDataMgr::setSkeletonData(const std::string &uuid, SkeletonData *data, Atlas *atlas, AttachmentLoader *attachmentLoader, const std::vector<int> &texturesIndex) {
|
||||
auto it = _dataMap.find(uuid);
|
||||
if (it != _dataMap.end()) {
|
||||
releaseByUUID(uuid);
|
||||
}
|
||||
auto *info = new SkeletonDataInfo();
|
||||
info->data = data;
|
||||
info->atlas = atlas;
|
||||
info->attachmentLoader = attachmentLoader;
|
||||
info->texturesIndex = texturesIndex;
|
||||
_dataMap[uuid] = info;
|
||||
}
|
||||
|
||||
SkeletonData *SkeletonDataMgr::retainByUUID(const std::string &uuid) {
|
||||
auto dataIt = _dataMap.find(uuid);
|
||||
if (dataIt == _dataMap.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return dataIt->second->data;
|
||||
}
|
||||
|
||||
void SkeletonDataMgr::releaseByUUID(const std::string &uuid) {
|
||||
auto dataIt = _dataMap.find(uuid);
|
||||
if (dataIt == _dataMap.end()) {
|
||||
return;
|
||||
}
|
||||
SkeletonDataInfo *info = dataIt->second;
|
||||
_dataMap.erase(dataIt);
|
||||
if (_destroyCallback) {
|
||||
for (auto &item : info->texturesIndex) {
|
||||
_destroyCallback(item);
|
||||
}
|
||||
}
|
||||
delete info;
|
||||
}
|
||||
84
cocos/editor-support/spine-creator-support/SkeletonDataMgr.h
Normal file
84
cocos/editor-support/spine-creator-support/SkeletonDataMgr.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "base/RefCounted.h"
|
||||
#include "spine/SkeletonData.h"
|
||||
#include "spine/spine.h"
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SkeletonDataInfo;
|
||||
|
||||
/**
|
||||
* Cache skeleton data.
|
||||
*/
|
||||
class SkeletonDataMgr final {
|
||||
public:
|
||||
static SkeletonDataMgr *getInstance() {
|
||||
if (instance == nullptr) {
|
||||
instance = new SkeletonDataMgr();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void destroyInstance() {
|
||||
if (instance) {
|
||||
delete instance;
|
||||
instance = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
SkeletonDataMgr() = default;
|
||||
~SkeletonDataMgr();
|
||||
|
||||
bool hasSkeletonData(const std::string &uuid);
|
||||
void setSkeletonData(const std::string &uuid, SkeletonData *data, Atlas *atlas, AttachmentLoader *attachmentLoader, const std::vector<int> &texturesIndex);
|
||||
// equal to 'findByUUID'
|
||||
SkeletonData *retainByUUID(const std::string &uuid);
|
||||
// equal to 'deleteByUUID'
|
||||
void releaseByUUID(const std::string &uuid);
|
||||
|
||||
using destroyCallback = std::function<void(int)>;
|
||||
void setDestroyCallback(destroyCallback callback) {
|
||||
_destroyCallback = std::move(callback);
|
||||
}
|
||||
|
||||
private:
|
||||
static SkeletonDataMgr *instance;
|
||||
destroyCallback _destroyCallback = nullptr;
|
||||
std::map<std::string, SkeletonDataInfo *> _dataMap;
|
||||
};
|
||||
|
||||
} // namespace spine
|
||||
1125
cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp
Normal file
1125
cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
192
cocos/editor-support/spine-creator-support/SkeletonRenderer.h
Normal file
192
cocos/editor-support/spine-creator-support/SkeletonRenderer.h
Normal file
@@ -0,0 +1,192 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "IOTypedArray.h"
|
||||
#include "MiddlewareManager.h"
|
||||
#include "Object.h"
|
||||
#include "base/Macros.h"
|
||||
#include "base/RefCounted.h"
|
||||
#include "base/RefMap.h"
|
||||
#include "core/assets/Texture2D.h"
|
||||
#include "middleware-adapter.h"
|
||||
#include "spine-creator-support/VertexEffectDelegate.h"
|
||||
#include "spine/spine.h"
|
||||
|
||||
namespace cc {
|
||||
class RenderEntity;
|
||||
class RenderDrawInfo;
|
||||
class Material;
|
||||
}; // namespace cc
|
||||
|
||||
namespace spine {
|
||||
|
||||
class AttachmentVertices;
|
||||
|
||||
/** Draws a skeleton.
|
||||
*/
|
||||
class SkeletonRenderer : public cc::RefCounted, public cc::middleware::IMiddleware {
|
||||
public:
|
||||
static SkeletonRenderer *create();
|
||||
static SkeletonRenderer *createWithSkeleton(Skeleton *skeleton, bool ownsSkeleton = false, bool ownsSkeletonData = false);
|
||||
static SkeletonRenderer *createWithData(SkeletonData *skeletonData, bool ownsSkeletonData = false);
|
||||
static SkeletonRenderer *createWithFile(const std::string &skeletonDataFile, const std::string &atlasFile, float scale = 1);
|
||||
|
||||
void update(float deltaTime) override {}
|
||||
void render(float deltaTime) override;
|
||||
virtual cc::Rect getBoundingBox() const;
|
||||
|
||||
Skeleton *getSkeleton() const;
|
||||
|
||||
void setTimeScale(float scale);
|
||||
float getTimeScale() const;
|
||||
|
||||
void updateWorldTransform();
|
||||
|
||||
void setToSetupPose();
|
||||
void setBonesToSetupPose();
|
||||
void setSlotsToSetupPose();
|
||||
void paused(bool value);
|
||||
|
||||
/* Returns 0 if the bone was not found. */
|
||||
Bone *findBone(const std::string &boneName) const;
|
||||
/* Returns 0 if the slot was not found. */
|
||||
Slot *findSlot(const std::string &slotName) const;
|
||||
|
||||
/* Sets the skin used to look up attachments not found in the SkeletonData defaultSkin. Attachments from the new skin are
|
||||
* attached if the corresponding attachment from the old skin was attached.
|
||||
* @param skin May be empty string ("") for no skin.*/
|
||||
void setSkin(const std::string &skinName);
|
||||
/** @param skin May be 0 for no skin.*/
|
||||
void setSkin(const char *skinName);
|
||||
|
||||
/* Returns 0 if the slot or attachment was not found. */
|
||||
Attachment *getAttachment(const std::string &slotName, const std::string &attachmentName) const;
|
||||
/* Returns false if the slot or attachment was not found.
|
||||
* @param attachmentName May be empty string ("") for no attachment. */
|
||||
bool setAttachment(const std::string &slotName, const std::string &attachmentName);
|
||||
/* @param attachmentName May be 0 for no attachment. */
|
||||
bool setAttachment(const std::string &slotName, const char *attachmentName);
|
||||
|
||||
/* Enables/disables two color tinting for this instance. May break batching */
|
||||
void setUseTint(bool enabled);
|
||||
|
||||
/* Sets the vertex effect to be used, set to 0 to disable vertex effects */
|
||||
void setVertexEffectDelegate(VertexEffectDelegate *effectDelegate);
|
||||
/* Sets the range of slots that should be rendered. Use -1, -1 to clear the range */
|
||||
void setSlotsRange(int startSlotIndex, int endSlotIndex);
|
||||
|
||||
/**
|
||||
* @return debug data, it's a Float32Array,
|
||||
* format |debug bones length|[beginX|beginY|toX|toY|...loop...]
|
||||
*/
|
||||
se_object_ptr getDebugData() const;
|
||||
/**
|
||||
* @return shared buffer offset, it's a Uint32Array
|
||||
* format |render info offset|attach info offset|
|
||||
*/
|
||||
se_object_ptr getSharedBufferOffset() const;
|
||||
|
||||
void setColor(float r, float g, float b, float a);
|
||||
void setBatchEnabled(bool enabled);
|
||||
void setDebugBonesEnabled(bool enabled);
|
||||
void setDebugSlotsEnabled(bool enabled);
|
||||
void setDebugMeshEnabled(bool enabled);
|
||||
void setAttachEnabled(bool enabled);
|
||||
|
||||
void setOpacityModifyRGB(bool value);
|
||||
bool isOpacityModifyRGB() const;
|
||||
|
||||
virtual void beginSchedule();
|
||||
virtual void stopSchedule();
|
||||
void onEnable();
|
||||
void onDisable();
|
||||
|
||||
SkeletonRenderer();
|
||||
explicit SkeletonRenderer(Skeleton *skeleton, bool ownsSkeleton = false, bool ownsSkeletonData = false, bool ownsAtlas = false);
|
||||
explicit SkeletonRenderer(SkeletonData *skeletonData, bool ownsSkeletonData = false);
|
||||
SkeletonRenderer(const std::string &skeletonDataFile, const std::string &atlasFile, float scale = 1);
|
||||
|
||||
~SkeletonRenderer() override;
|
||||
|
||||
void initWithUUID(const std::string &uuid);
|
||||
void initWithSkeleton(Skeleton *skeleton, bool ownsSkeleton = false, bool ownsSkeletonData = false, bool ownsAtlas = false);
|
||||
void initWithData(SkeletonData *skeletonData, bool ownsSkeletonData = false);
|
||||
void initWithJsonFile(const std::string &skeletonDataFile, Atlas *atlas, float scale = 1);
|
||||
void initWithJsonFile(const std::string &skeletonDataFile, const std::string &atlasFile, float scale = 1);
|
||||
void initWithBinaryFile(const std::string &skeletonDataFile, Atlas *atlas, float scale = 1);
|
||||
void initWithBinaryFile(const std::string &skeletonDataFile, const std::string &atlasFile, float scale = 1);
|
||||
|
||||
virtual void initialize();
|
||||
|
||||
cc::RenderDrawInfo *requestDrawInfo(int idx);
|
||||
cc::Material *requestMaterial(uint16_t blendSrc, uint16_t blendDst);
|
||||
void setMaterial(cc::Material *material);
|
||||
void setRenderEntity(cc::RenderEntity *entity);
|
||||
void setSlotTexture(const std::string &slotName, cc::Texture2D *tex2d, bool createAttachment);
|
||||
|
||||
protected:
|
||||
void setSkeletonData(SkeletonData *skeletonData, bool ownsSkeletonData);
|
||||
|
||||
bool _ownsSkeletonData = false;
|
||||
bool _ownsSkeleton = false;
|
||||
bool _ownsAtlas = false;
|
||||
Atlas *_atlas = nullptr;
|
||||
AttachmentLoader *_attachmentLoader = nullptr;
|
||||
Skeleton *_skeleton = nullptr;
|
||||
VertexEffectDelegate *_effectDelegate = nullptr;
|
||||
float _timeScale = 1;
|
||||
bool _paused = false;
|
||||
|
||||
bool _useAttach = false;
|
||||
bool _debugMesh = false;
|
||||
bool _debugSlots = false;
|
||||
bool _debugBones = false;
|
||||
cc::middleware::Color4F _nodeColor = cc::middleware::Color4F::WHITE;
|
||||
bool _premultipliedAlpha = false;
|
||||
SkeletonClipping *_clipper = nullptr;
|
||||
bool _useTint = false;
|
||||
bool _enableBatch = false;
|
||||
std::string _uuid;
|
||||
|
||||
int _startSlotIndex = -1;
|
||||
int _endSlotIndex = -1;
|
||||
|
||||
cc::middleware::IOTypedArray *_sharedBufferOffset = nullptr;
|
||||
cc::middleware::IOTypedArray *_debugBuffer = nullptr;
|
||||
|
||||
cc::RenderEntity *_entity = nullptr;
|
||||
cc::Material *_material = nullptr;
|
||||
ccstd::vector<cc::RenderDrawInfo *> _drawInfoArray;
|
||||
ccstd::unordered_map<uint32_t, cc::Material *> _materialCaches;
|
||||
};
|
||||
|
||||
} // namespace spine
|
||||
48
cocos/editor-support/spine-creator-support/Vector2.cpp
Normal file
48
cocos/editor-support/spine-creator-support/Vector2.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "Vector2.h"
|
||||
#include <math.h>
|
||||
namespace spine {
|
||||
|
||||
Vector2::Vector2(): x(0), y(0) {
|
||||
|
||||
}
|
||||
|
||||
Vector2::Vector2(float x, float y) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
Vector2::~Vector2() {}
|
||||
|
||||
void Vector2::setX(float x) {
|
||||
this->x = x;
|
||||
}
|
||||
|
||||
float Vector2::getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
void Vector2::setY(float y) {
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
float Vector2::getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
Vector2& Vector2::set(float x, float y) {
|
||||
this->setX(x);
|
||||
this->setY(y);
|
||||
return *this;
|
||||
}
|
||||
|
||||
float Vector2::length() {
|
||||
return sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
Vector2& Vector2::normalize() {
|
||||
float invLen = 1.F / length();
|
||||
this->setX(x * invLen);
|
||||
this->setY(y * invLen);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
54
cocos/editor-support/spine-creator-support/Vector2.h
Normal file
54
cocos/editor-support/spine-creator-support/Vector2.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "spine/spine.h"
|
||||
|
||||
namespace spine {
|
||||
class Vector2
|
||||
{
|
||||
public:
|
||||
float x, y;
|
||||
public:
|
||||
Vector2();
|
||||
Vector2(float x, float y);
|
||||
~Vector2();
|
||||
|
||||
void setX(float x);
|
||||
float getX();
|
||||
|
||||
void setY(float y);
|
||||
float getY();
|
||||
|
||||
Vector2 &set(float x, float y);
|
||||
float length();
|
||||
Vector2 &normalize();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "VertexEffectDelegate.h"
|
||||
namespace spine {
|
||||
|
||||
VertexEffectDelegate::VertexEffectDelegate() {
|
||||
}
|
||||
|
||||
VertexEffectDelegate::~VertexEffectDelegate() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void VertexEffectDelegate::clear() {
|
||||
if (_interpolation) {
|
||||
delete _interpolation;
|
||||
_interpolation = nullptr;
|
||||
}
|
||||
if (_vertexEffect) {
|
||||
delete _vertexEffect;
|
||||
_vertexEffect = nullptr;
|
||||
}
|
||||
_effectType = "none";
|
||||
}
|
||||
|
||||
JitterVertexEffect *VertexEffectDelegate::initJitter(float jitterX, float jitterY) {
|
||||
clear();
|
||||
_vertexEffect = new JitterVertexEffect(jitterX, jitterY);
|
||||
_effectType = "jitter";
|
||||
return (JitterVertexEffect *)_vertexEffect;
|
||||
}
|
||||
|
||||
SwirlVertexEffect *VertexEffectDelegate::initSwirlWithPow(float radius, int power) {
|
||||
clear();
|
||||
_interpolation = new PowInterpolation(power);
|
||||
_vertexEffect = new SwirlVertexEffect(radius, *_interpolation);
|
||||
_effectType = "swirl";
|
||||
return (SwirlVertexEffect *)_vertexEffect;
|
||||
}
|
||||
|
||||
SwirlVertexEffect *VertexEffectDelegate::initSwirlWithPowOut(float radius, int power) {
|
||||
clear();
|
||||
_interpolation = new PowOutInterpolation(power);
|
||||
_vertexEffect = new SwirlVertexEffect(radius, *_interpolation);
|
||||
_effectType = "swirl";
|
||||
return (SwirlVertexEffect *)_vertexEffect;
|
||||
}
|
||||
|
||||
JitterVertexEffect *VertexEffectDelegate::getJitterVertexEffect() {
|
||||
JitterVertexEffect *jitter = dynamic_cast<JitterVertexEffect *>(_vertexEffect);
|
||||
return jitter;
|
||||
}
|
||||
|
||||
SwirlVertexEffect *VertexEffectDelegate::getSwirlVertexEffect() {
|
||||
SwirlVertexEffect *swirl = dynamic_cast<SwirlVertexEffect *>(_vertexEffect);
|
||||
return swirl;
|
||||
}
|
||||
} // namespace spine
|
||||
@@ -0,0 +1,59 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "base/RefCounted.h"
|
||||
#include "spine/spine.h"
|
||||
|
||||
namespace spine {
|
||||
class VertexEffectDelegate : public cc::RefCounted {
|
||||
public:
|
||||
VertexEffectDelegate();
|
||||
~VertexEffectDelegate() override;
|
||||
JitterVertexEffect *initJitter(float jitterX, float jitterY);
|
||||
SwirlVertexEffect *initSwirlWithPow(float radius, int power);
|
||||
SwirlVertexEffect *initSwirlWithPowOut(float radius, int power);
|
||||
VertexEffect *getVertexEffect() {
|
||||
return _vertexEffect;
|
||||
}
|
||||
JitterVertexEffect *getJitterVertexEffect();
|
||||
SwirlVertexEffect *getSwirlVertexEffect();
|
||||
const std::string &getEffectType() const {
|
||||
return _effectType;
|
||||
}
|
||||
void clear();
|
||||
|
||||
private:
|
||||
VertexEffect *_vertexEffect = nullptr;
|
||||
Interpolation *_interpolation = nullptr;
|
||||
std::string _effectType = "none";
|
||||
};
|
||||
} // namespace spine
|
||||
152
cocos/editor-support/spine-creator-support/spine-cocos2dx.cpp
Normal file
152
cocos/editor-support/spine-creator-support/spine-cocos2dx.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/******************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "spine-creator-support/spine-cocos2dx.h"
|
||||
#include "base/Data.h"
|
||||
#include "middleware-adapter.h"
|
||||
#include "platform/FileUtils.h"
|
||||
#include "spine-creator-support/AttachmentVertices.h"
|
||||
|
||||
namespace spine {
|
||||
static CustomTextureLoader customTextureLoader = nullptr;
|
||||
void spAtlasPage_setCustomTextureLoader(CustomTextureLoader texLoader) {
|
||||
customTextureLoader = texLoader;
|
||||
}
|
||||
|
||||
static SpineObjectDisposeCallback spineObjectDisposeCallback = nullptr;
|
||||
void setSpineObjectDisposeCallback(SpineObjectDisposeCallback callback) {
|
||||
spineObjectDisposeCallback = callback;
|
||||
}
|
||||
} // namespace spine
|
||||
|
||||
USING_NS_MW; // NOLINT(google-build-using-namespace)
|
||||
using namespace cc; // NOLINT(google-build-using-namespace)
|
||||
using namespace spine; // NOLINT(google-build-using-namespace)
|
||||
|
||||
static void deleteAttachmentVertices(void *vertices) {
|
||||
delete static_cast<AttachmentVertices *>(vertices);
|
||||
}
|
||||
|
||||
static uint16_t quadTriangles[6] = {0, 1, 2, 2, 3, 0};
|
||||
|
||||
static void setAttachmentVertices(RegionAttachment *attachment) {
|
||||
auto *region = static_cast<AtlasRegion *>(attachment->getRendererObject());
|
||||
auto *attachmentVertices = new AttachmentVertices(static_cast<middleware::Texture2D *>(region->page->getRendererObject()), 4, quadTriangles, 6);
|
||||
V3F_T2F_C4B *vertices = attachmentVertices->_triangles->verts;
|
||||
for (int i = 0, ii = 0; i < 4; ++i, ii += 2) {
|
||||
vertices[i].texCoord.u = attachment->getUVs()[ii];
|
||||
vertices[i].texCoord.v = attachment->getUVs()[ii + 1];
|
||||
}
|
||||
attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
|
||||
}
|
||||
|
||||
static void setAttachmentVertices(MeshAttachment *attachment) {
|
||||
auto *region = static_cast<AtlasRegion *>(attachment->getRendererObject());
|
||||
auto *attachmentVertices = new AttachmentVertices(static_cast<middleware::Texture2D *>(region->page->getRendererObject()),
|
||||
static_cast<int32_t>(attachment->getWorldVerticesLength() >> 1), attachment->getTriangles().buffer(), static_cast<int32_t>(attachment->getTriangles().size()));
|
||||
V3F_T2F_C4B *vertices = attachmentVertices->_triangles->verts;
|
||||
for (size_t i = 0, ii = 0, nn = attachment->getWorldVerticesLength(); ii < nn; ++i, ii += 2) {
|
||||
vertices[i].texCoord.u = attachment->getUVs()[ii];
|
||||
vertices[i].texCoord.v = attachment->getUVs()[ii + 1];
|
||||
}
|
||||
attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
|
||||
}
|
||||
|
||||
Cocos2dAtlasAttachmentLoader::Cocos2dAtlasAttachmentLoader(Atlas *atlas) : AtlasAttachmentLoader(atlas) {
|
||||
}
|
||||
|
||||
Cocos2dAtlasAttachmentLoader::~Cocos2dAtlasAttachmentLoader() = default;
|
||||
|
||||
void Cocos2dAtlasAttachmentLoader::configureAttachment(Attachment *attachment) {
|
||||
if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) {
|
||||
setAttachmentVertices(dynamic_cast<RegionAttachment *>(attachment));
|
||||
} else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) {
|
||||
setAttachmentVertices(dynamic_cast<MeshAttachment *>(attachment));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t wrap(TextureWrap wrap) {
|
||||
return static_cast<uint32_t>(wrap);
|
||||
}
|
||||
|
||||
uint32_t filter(TextureFilter filter) {
|
||||
return static_cast<uint32_t>(filter);
|
||||
}
|
||||
|
||||
Cocos2dTextureLoader::Cocos2dTextureLoader() = default;
|
||||
Cocos2dTextureLoader::~Cocos2dTextureLoader() = default;
|
||||
|
||||
void Cocos2dTextureLoader::load(AtlasPage &page, const spine::String &path) {
|
||||
middleware::Texture2D *texture = nullptr;
|
||||
if (spine::customTextureLoader) {
|
||||
texture = spine::customTextureLoader(path.buffer());
|
||||
}
|
||||
CC_ASSERT_NOT_NULL(texture);
|
||||
|
||||
if (texture) {
|
||||
texture->addRef();
|
||||
|
||||
middleware::Texture2D::TexParams textureParams = {filter(page.minFilter), filter(page.magFilter), wrap(page.uWrap), wrap(page.vWrap)};
|
||||
texture->setTexParameters(textureParams);
|
||||
|
||||
page.setRendererObject(texture);
|
||||
page.width = texture->getPixelsWide();
|
||||
page.height = texture->getPixelsHigh();
|
||||
}
|
||||
}
|
||||
|
||||
void Cocos2dTextureLoader::unload(void *texture) {
|
||||
if (texture) {
|
||||
(static_cast<middleware::Texture2D *>(texture))->release();
|
||||
}
|
||||
}
|
||||
|
||||
Cocos2dExtension::Cocos2dExtension() = default;
|
||||
|
||||
Cocos2dExtension::~Cocos2dExtension() = default;
|
||||
|
||||
char *Cocos2dExtension::_readFile(const spine::String &path, int *length) {
|
||||
*length = 0;
|
||||
Data data = FileUtils::getInstance()->getDataFromFile(FileUtils::getInstance()->fullPathForFilename(path.buffer()));
|
||||
if (data.isNull()) return nullptr;
|
||||
|
||||
char *ret = static_cast<char *>(malloc(sizeof(unsigned char) * data.getSize()));
|
||||
memcpy(ret, reinterpret_cast<char *>(data.getBytes()), data.getSize());
|
||||
*length = static_cast<int>(data.getSize());
|
||||
return ret;
|
||||
}
|
||||
|
||||
SpineExtension *spine::getDefaultExtension() {
|
||||
return new Cocos2dExtension();
|
||||
}
|
||||
|
||||
void Cocos2dExtension::_free(void *mem, const char *file, int line) {
|
||||
spineObjectDisposeCallback(mem);
|
||||
DefaultSpineExtension::_free(mem, file, line);
|
||||
}
|
||||
77
cocos/editor-support/spine-creator-support/spine-cocos2dx.h
Normal file
77
cocos/editor-support/spine-creator-support/spine-cocos2dx.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, 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.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "middleware-adapter.h"
|
||||
#include "spine-creator-support/SkeletonAnimation.h"
|
||||
#include "spine-creator-support/SkeletonCacheAnimation.h"
|
||||
#include "spine-creator-support/SkeletonCacheMgr.h"
|
||||
#include "spine-creator-support/SkeletonDataMgr.h"
|
||||
#include "spine-creator-support/SkeletonRenderer.h"
|
||||
#include "spine/spine.h"
|
||||
|
||||
namespace spine {
|
||||
typedef cc::middleware::Texture2D *(*CustomTextureLoader)(const char *path);
|
||||
// set custom texture loader for _spAtlasPage_createTexture
|
||||
void spAtlasPage_setCustomTextureLoader(CustomTextureLoader texLoader);
|
||||
|
||||
class Cocos2dAtlasAttachmentLoader : public AtlasAttachmentLoader {
|
||||
public:
|
||||
Cocos2dAtlasAttachmentLoader(Atlas *atlas);
|
||||
virtual ~Cocos2dAtlasAttachmentLoader();
|
||||
virtual void configureAttachment(Attachment *attachment);
|
||||
};
|
||||
|
||||
class Cocos2dTextureLoader : public TextureLoader {
|
||||
public:
|
||||
Cocos2dTextureLoader();
|
||||
|
||||
virtual ~Cocos2dTextureLoader();
|
||||
|
||||
virtual void load(AtlasPage &page, const String &path);
|
||||
|
||||
virtual void unload(void *texture);
|
||||
};
|
||||
|
||||
class Cocos2dExtension : public DefaultSpineExtension {
|
||||
public:
|
||||
Cocos2dExtension();
|
||||
|
||||
virtual ~Cocos2dExtension();
|
||||
|
||||
virtual void _free(void *mem, const char *file, int line);
|
||||
|
||||
protected:
|
||||
virtual char *_readFile(const String &path, int *length);
|
||||
};
|
||||
|
||||
typedef void (*SpineObjectDisposeCallback)(void *);
|
||||
void setSpineObjectDisposeCallback(SpineObjectDisposeCallback callback);
|
||||
} // namespace spine
|
||||
Reference in New Issue
Block a user