[v4] spine v3.8
|
@ -49,7 +49,7 @@ include(audio/CMakeLists.txt)
|
||||||
|
|
||||||
# default value for cocos2dx extensions modules build
|
# default value for cocos2dx extensions modules build
|
||||||
option(BUILD_EDITOR_COCOSTUDIO "Build editor support for cocostudio" ON)
|
option(BUILD_EDITOR_COCOSTUDIO "Build editor support for cocostudio" ON)
|
||||||
option(BUILD_EDITOR_SPINE "Build editor support for spine" OFF)
|
option(BUILD_EDITOR_SPINE "Build editor support for spine" ON)
|
||||||
option(BUILD_EXTENSIONS "Build extension library" ON)
|
option(BUILD_EXTENSIONS "Build extension library" ON)
|
||||||
|
|
||||||
if(BUILD_EDITOR_COCOSTUDIO)
|
if(BUILD_EDITOR_COCOSTUDIO)
|
||||||
|
@ -58,7 +58,11 @@ if(BUILD_EDITOR_COCOSTUDIO)
|
||||||
endif(BUILD_EDITOR_COCOSTUDIO)
|
endif(BUILD_EDITOR_COCOSTUDIO)
|
||||||
|
|
||||||
if(BUILD_EDITOR_SPINE)
|
if(BUILD_EDITOR_SPINE)
|
||||||
include(editor-support/spine/CMakeLists.txt)
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/editor-support/spine/CMakeLists.txt")
|
||||||
|
include(editor-support/spine/CMakeLists.txt)
|
||||||
|
else()
|
||||||
|
message(WARNING "${CMAKE_CURRENT_SOURCE_DIR}/editor-support/spine/CMakeLists.txt not found!")
|
||||||
|
endif()
|
||||||
set(COCOS_EDITOR_SUPPORT_SRC ${COCOS_EDITOR_SUPPORT_SRC} ${COCOS_SPINE_SRC} ${COCOS_SPINE_HEADER})
|
set(COCOS_EDITOR_SUPPORT_SRC ${COCOS_EDITOR_SUPPORT_SRC} ${COCOS_SPINE_SRC} ${COCOS_SPINE_HEADER})
|
||||||
endif(BUILD_EDITOR_SPINE)
|
endif(BUILD_EDITOR_SPINE)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes License Agreement
|
* Spine Runtimes License Agreement
|
||||||
* Last updated May 1, 2019. Replaces all prior versions.
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||||
*
|
*
|
||||||
* Integration of the Spine Runtimes into software or otherwise creating
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
@ -15,16 +15,16 @@
|
||||||
* Spine Editor license and redistribution of the Products in any form must
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
* include this license and copyright notice.
|
* include this license and copyright notice.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <spine/AttachmentVertices.h>
|
#include <spine/AttachmentVertices.h>
|
||||||
|
@ -35,6 +35,7 @@ namespace spine {
|
||||||
|
|
||||||
AttachmentVertices::AttachmentVertices (Texture2D* texture, int verticesCount, unsigned short* triangles, int trianglesCount) {
|
AttachmentVertices::AttachmentVertices (Texture2D* texture, int verticesCount, unsigned short* triangles, int trianglesCount) {
|
||||||
_texture = texture;
|
_texture = texture;
|
||||||
|
if (_texture) _texture->retain();
|
||||||
|
|
||||||
_triangles = new TrianglesCommand::Triangles();
|
_triangles = new TrianglesCommand::Triangles();
|
||||||
_triangles->verts = new V3F_C4B_T2F[verticesCount];
|
_triangles->verts = new V3F_C4B_T2F[verticesCount];
|
||||||
|
@ -46,6 +47,7 @@ AttachmentVertices::AttachmentVertices (Texture2D* texture, int verticesCount, u
|
||||||
AttachmentVertices::~AttachmentVertices () {
|
AttachmentVertices::~AttachmentVertices () {
|
||||||
delete [] _triangles->verts;
|
delete [] _triangles->verts;
|
||||||
delete _triangles;
|
delete _triangles;
|
||||||
|
if (_texture) _texture->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes License Agreement
|
* Spine Runtimes License Agreement
|
||||||
* Last updated May 1, 2019. Replaces all prior versions.
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||||
*
|
*
|
||||||
* Integration of the Spine Runtimes into software or otherwise creating
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
@ -15,16 +15,16 @@
|
||||||
* Spine Editor license and redistribution of the Products in any form must
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
* include this license and copyright notice.
|
* include this license and copyright notice.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifndef SPINE_ATTACHMENTVERTICES_H_
|
#ifndef SPINE_ATTACHMENTVERTICES_H_
|
||||||
|
|
|
@ -1,17 +1,10 @@
|
||||||
set(COCOS_SPINE_HEADER
|
|
||||||
editor-support/spine/AttachmentVertices.h
|
|
||||||
editor-support/spine/SkeletonAnimation.h
|
|
||||||
editor-support/spine/SkeletonBatch.h
|
|
||||||
editor-support/spine/SkeletonRenderer.h
|
|
||||||
editor-support/spine/SkeletonTwoColorBatch.h
|
|
||||||
editor-support/spine/spine-cocos2dx.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(COCOS_SPINE_SRC
|
file(GLOB_RECURSE COCOS_SPINE_SRC
|
||||||
editor-support/spine/AttachmentVertices.cpp
|
${CMAKE_CURRENT_LIST_DIR}/*.cpp
|
||||||
editor-support/spine/SkeletonAnimation.cpp
|
${CMAKE_CURRENT_LIST_DIR}/**/*.cpp
|
||||||
editor-support/spine/SkeletonBatch.cpp
|
)
|
||||||
editor-support/spine/SkeletonRenderer.cpp
|
|
||||||
editor-support/spine/SkeletonTwoColorBatch.cpp
|
file(GLOB_RECURSE COCOS_SPINE_HEADER
|
||||||
editor-support/spine/spine-cocos2dx.cpp
|
${CMAKE_CURRENT_LIST_DIR}/*.h
|
||||||
)
|
${CMAKE_CURRENT_LIST_DIR}/**/*.h
|
||||||
|
)
|
|
@ -1,8 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes License Agreement
|
* Spine Runtimes License Agreement
|
||||||
* Last updated May 1, 2019. Replaces all prior versions.
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||||
*
|
*
|
||||||
* Integration of the Spine Runtimes into software or otherwise creating
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
@ -15,16 +15,16 @@
|
||||||
* Spine Editor license and redistribution of the Products in any form must
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
* include this license and copyright notice.
|
* include this license and copyright notice.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <spine/SkeletonAnimation.h>
|
#include <spine/SkeletonAnimation.h>
|
||||||
|
@ -40,25 +40,26 @@ using std::vector;
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
typedef struct _TrackEntryListeners {
|
typedef struct _TrackEntryListeners {
|
||||||
StartListener startListener;
|
StartListener startListener;
|
||||||
InterruptListener interruptListener;
|
InterruptListener interruptListener;
|
||||||
EndListener endListener;
|
EndListener endListener;
|
||||||
DisposeListener disposeListener;
|
DisposeListener disposeListener;
|
||||||
CompleteListener completeListener;
|
CompleteListener completeListener;
|
||||||
EventListener eventListener;
|
EventListener eventListener;
|
||||||
} _TrackEntryListeners;
|
} _TrackEntryListeners;
|
||||||
|
|
||||||
void animationCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
|
void animationCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
|
||||||
((SkeletonAnimation*)state->getRendererObject())->onAnimationStateEvent(entry, type, event);
|
((SkeletonAnimation*)state->getRendererObject())->onAnimationStateEvent(entry, type, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void trackEntryCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
|
void trackEntryCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
|
||||||
((SkeletonAnimation*)state->getRendererObject())->onTrackEntryEvent(entry, type, event);
|
((SkeletonAnimation*)state->getRendererObject())->onTrackEntryEvent(entry, type, event);
|
||||||
if (type == EventType_Dispose)
|
if (type == EventType_Dispose) {
|
||||||
if (entry->getRendererObject()) {
|
if (entry->getRendererObject()) {
|
||||||
delete (spine::_TrackEntryListeners*)entry->getRendererObject();
|
delete (spine::_TrackEntryListeners*)entry->getRendererObject();
|
||||||
entry->setRendererObject(NULL);
|
entry->setRendererObject(NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static _TrackEntryListeners* getListeners (TrackEntry* entry) {
|
static _TrackEntryListeners* getListeners (TrackEntry* entry) {
|
||||||
|
@ -68,7 +69,7 @@ static _TrackEntryListeners* getListeners (TrackEntry* entry) {
|
||||||
}
|
}
|
||||||
return (_TrackEntryListeners*)entry->getRendererObject();
|
return (_TrackEntryListeners*)entry->getRendererObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
SkeletonAnimation* SkeletonAnimation::createWithData (SkeletonData* skeletonData, bool ownsSkeletonData) {
|
SkeletonAnimation* SkeletonAnimation::createWithData (SkeletonData* skeletonData, bool ownsSkeletonData) {
|
||||||
|
@ -111,6 +112,7 @@ void SkeletonAnimation::initialize () {
|
||||||
super::initialize();
|
super::initialize();
|
||||||
|
|
||||||
_ownsAnimationStateData = true;
|
_ownsAnimationStateData = true;
|
||||||
|
_updateOnlyIfVisible = false;
|
||||||
_state = new (__FILE__, __LINE__) AnimationState(new (__FILE__, __LINE__) AnimationStateData(_skeleton->getData()));
|
_state = new (__FILE__, __LINE__) AnimationState(new (__FILE__, __LINE__) AnimationStateData(_skeleton->getData()));
|
||||||
_state->setRendererObject(this);
|
_state->setRendererObject(this);
|
||||||
_state->setListener(animationCallback);
|
_state->setListener(animationCallback);
|
||||||
|
@ -128,12 +130,16 @@ SkeletonAnimation::~SkeletonAnimation () {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::update (float deltaTime) {
|
void SkeletonAnimation::update (float deltaTime) {
|
||||||
|
if (_updateOnlyIfVisible && !isVisible()) return;
|
||||||
|
|
||||||
super::update(deltaTime);
|
super::update(deltaTime);
|
||||||
|
|
||||||
deltaTime *= _timeScale;
|
deltaTime *= _timeScale;
|
||||||
|
if (_preUpdateListener) _preUpdateListener(this);
|
||||||
_state->update(deltaTime);
|
_state->update(deltaTime);
|
||||||
_state->apply(*_skeleton);
|
_state->apply(*_skeleton);
|
||||||
_skeleton->updateWorldTransform();
|
_skeleton->updateWorldTransform();
|
||||||
|
if (_postUpdateListener) _postUpdateListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t transformFlags) {
|
void SkeletonAnimation::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t transformFlags) {
|
||||||
|
@ -147,7 +153,7 @@ void SkeletonAnimation::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &t
|
||||||
void SkeletonAnimation::setAnimationStateData (AnimationStateData* stateData) {
|
void SkeletonAnimation::setAnimationStateData (AnimationStateData* stateData) {
|
||||||
CCASSERT(stateData, "stateData cannot be null.");
|
CCASSERT(stateData, "stateData cannot be null.");
|
||||||
|
|
||||||
if (_ownsAnimationStateData) delete _state->getData();
|
if (_ownsAnimationStateData) delete _state->getData();
|
||||||
delete _state;
|
delete _state;
|
||||||
|
|
||||||
_ownsAnimationStateData = false;
|
_ownsAnimationStateData = false;
|
||||||
|
@ -177,7 +183,7 @@ TrackEntry* SkeletonAnimation::addAnimation (int trackIndex, const std::string&
|
||||||
}
|
}
|
||||||
return _state->addAnimation(trackIndex, animation, loop, delay);
|
return _state->addAnimation(trackIndex, animation, loop, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackEntry* SkeletonAnimation::setEmptyAnimation (int trackIndex, float mixDuration) {
|
TrackEntry* SkeletonAnimation::setEmptyAnimation (int trackIndex, float mixDuration) {
|
||||||
return _state->setEmptyAnimation(trackIndex, mixDuration);
|
return _state->setEmptyAnimation(trackIndex, mixDuration);
|
||||||
}
|
}
|
||||||
|
@ -211,15 +217,15 @@ void SkeletonAnimation::onAnimationStateEvent (TrackEntry* entry, EventType type
|
||||||
case EventType_Start:
|
case EventType_Start:
|
||||||
if (_startListener) _startListener(entry);
|
if (_startListener) _startListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Interrupt:
|
case EventType_Interrupt:
|
||||||
if (_interruptListener) _interruptListener(entry);
|
if (_interruptListener) _interruptListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_End:
|
case EventType_End:
|
||||||
if (_endListener) _endListener(entry);
|
if (_endListener) _endListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Dispose:
|
case EventType_Dispose:
|
||||||
if (_disposeListener) _disposeListener(entry);
|
if (_disposeListener) _disposeListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Complete:
|
case EventType_Complete:
|
||||||
if (_completeListener) _completeListener(entry);
|
if (_completeListener) _completeListener(entry);
|
||||||
break;
|
break;
|
||||||
|
@ -236,15 +242,15 @@ void SkeletonAnimation::onTrackEntryEvent (TrackEntry* entry, EventType type, Ev
|
||||||
case EventType_Start:
|
case EventType_Start:
|
||||||
if (listeners->startListener) listeners->startListener(entry);
|
if (listeners->startListener) listeners->startListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Interrupt:
|
case EventType_Interrupt:
|
||||||
if (listeners->interruptListener) listeners->interruptListener(entry);
|
if (listeners->interruptListener) listeners->interruptListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_End:
|
case EventType_End:
|
||||||
if (listeners->endListener) listeners->endListener(entry);
|
if (listeners->endListener) listeners->endListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Dispose:
|
case EventType_Dispose:
|
||||||
if (listeners->disposeListener) listeners->disposeListener(entry);
|
if (listeners->disposeListener) listeners->disposeListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Complete:
|
case EventType_Complete:
|
||||||
if (listeners->completeListener) listeners->completeListener(entry);
|
if (listeners->completeListener) listeners->completeListener(entry);
|
||||||
break;
|
break;
|
||||||
|
@ -257,17 +263,17 @@ void SkeletonAnimation::onTrackEntryEvent (TrackEntry* entry, EventType type, Ev
|
||||||
void SkeletonAnimation::setStartListener (const StartListener& listener) {
|
void SkeletonAnimation::setStartListener (const StartListener& listener) {
|
||||||
_startListener = listener;
|
_startListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setInterruptListener (const InterruptListener& listener) {
|
void SkeletonAnimation::setInterruptListener (const InterruptListener& listener) {
|
||||||
_interruptListener = listener;
|
_interruptListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setEndListener (const EndListener& listener) {
|
void SkeletonAnimation::setEndListener (const EndListener& listener) {
|
||||||
_endListener = listener;
|
_endListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setDisposeListener (const DisposeListener& listener) {
|
void SkeletonAnimation::setDisposeListener (const DisposeListener& listener) {
|
||||||
_disposeListener = listener;
|
_disposeListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setCompleteListener (const CompleteListener& listener) {
|
void SkeletonAnimation::setCompleteListener (const CompleteListener& listener) {
|
||||||
|
@ -278,20 +284,28 @@ void SkeletonAnimation::setEventListener (const EventListener& listener) {
|
||||||
_eventListener = listener;
|
_eventListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkeletonAnimation::setPreUpdateWorldTransformsListener(const UpdateWorldTransformsListener &listener) {
|
||||||
|
_preUpdateListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonAnimation::setPostUpdateWorldTransformsListener(const UpdateWorldTransformsListener &listener) {
|
||||||
|
_postUpdateListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setTrackStartListener (TrackEntry* entry, const StartListener& listener) {
|
void SkeletonAnimation::setTrackStartListener (TrackEntry* entry, const StartListener& listener) {
|
||||||
getListeners(entry)->startListener = listener;
|
getListeners(entry)->startListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setTrackInterruptListener (TrackEntry* entry, const InterruptListener& listener) {
|
void SkeletonAnimation::setTrackInterruptListener (TrackEntry* entry, const InterruptListener& listener) {
|
||||||
getListeners(entry)->interruptListener = listener;
|
getListeners(entry)->interruptListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setTrackEndListener (TrackEntry* entry, const EndListener& listener) {
|
void SkeletonAnimation::setTrackEndListener (TrackEntry* entry, const EndListener& listener) {
|
||||||
getListeners(entry)->endListener = listener;
|
getListeners(entry)->endListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setTrackDisposeListener (TrackEntry* entry, const DisposeListener& listener) {
|
void SkeletonAnimation::setTrackDisposeListener (TrackEntry* entry, const DisposeListener& listener) {
|
||||||
getListeners(entry)->disposeListener = listener;
|
getListeners(entry)->disposeListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setTrackCompleteListener (TrackEntry* entry, const CompleteListener& listener) {
|
void SkeletonAnimation::setTrackCompleteListener (TrackEntry* entry, const CompleteListener& listener) {
|
||||||
|
@ -306,4 +320,8 @@ AnimationState* SkeletonAnimation::getState() const {
|
||||||
return _state;
|
return _state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkeletonAnimation::setUpdateOnlyIfVisible(bool status) {
|
||||||
|
_updateOnlyIfVisible = status;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes License Agreement
|
* Spine Runtimes License Agreement
|
||||||
* Last updated May 1, 2019. Replaces all prior versions.
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||||
*
|
*
|
||||||
* Integration of the Spine Runtimes into software or otherwise creating
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
@ -15,33 +15,36 @@
|
||||||
* Spine Editor license and redistribution of the Products in any form must
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
* include this license and copyright notice.
|
* include this license and copyright notice.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifndef SPINE_SKELETONANIMATION_H_
|
#ifndef SPINE_SKELETONANIMATION_H_
|
||||||
#define SPINE_SKELETONANIMATION_H_
|
#define SPINE_SKELETONANIMATION_H_
|
||||||
#define SPINE_SHORT_NAMES
|
|
||||||
#include <spine/spine.h>
|
#include <spine/spine.h>
|
||||||
#include <spine/SkeletonRenderer.h>
|
#include <spine/spine-cocos2dx.h>
|
||||||
#include "cocos2d.h"
|
#include "cocos2d.h"
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
|
class SkeletonAnimation;
|
||||||
|
|
||||||
typedef std::function<void(TrackEntry* entry)> StartListener;
|
typedef std::function<void(TrackEntry* entry)> StartListener;
|
||||||
typedef std::function<void(TrackEntry* entry)> InterruptListener;
|
typedef std::function<void(TrackEntry* entry)> InterruptListener;
|
||||||
typedef std::function<void(TrackEntry* entry)> EndListener;
|
typedef std::function<void(TrackEntry* entry)> EndListener;
|
||||||
typedef std::function<void(TrackEntry* entry)> DisposeListener;
|
typedef std::function<void(TrackEntry* entry)> DisposeListener;
|
||||||
typedef std::function<void(TrackEntry* entry)> CompleteListener;
|
typedef std::function<void(TrackEntry* entry)> CompleteListener;
|
||||||
typedef std::function<void(TrackEntry* entry, Event* event)> EventListener;
|
typedef std::function<void(TrackEntry* entry, Event* event)> EventListener;
|
||||||
|
typedef std::function<void(SkeletonAnimation* node)> UpdateWorldTransformsListener;
|
||||||
|
|
||||||
/** Draws an animated skeleton, providing an AnimationState for applying one or more animations and queuing animations to be
|
/** Draws an animated skeleton, providing an AnimationState for applying one or more animations and queuing animations to be
|
||||||
* played later. */
|
* played later. */
|
||||||
|
@ -82,16 +85,18 @@ public:
|
||||||
void clearTrack (int trackIndex = 0);
|
void clearTrack (int trackIndex = 0);
|
||||||
|
|
||||||
void setStartListener (const StartListener& listener);
|
void setStartListener (const StartListener& listener);
|
||||||
void setInterruptListener (const InterruptListener& listener);
|
void setInterruptListener (const InterruptListener& listener);
|
||||||
void setEndListener (const EndListener& listener);
|
void setEndListener (const EndListener& listener);
|
||||||
void setDisposeListener (const DisposeListener& listener);
|
void setDisposeListener (const DisposeListener& listener);
|
||||||
void setCompleteListener (const CompleteListener& listener);
|
void setCompleteListener (const CompleteListener& listener);
|
||||||
void setEventListener (const EventListener& listener);
|
void setEventListener (const EventListener& listener);
|
||||||
|
void setPreUpdateWorldTransformsListener(const UpdateWorldTransformsListener& listener);
|
||||||
|
void setPostUpdateWorldTransformsListener(const UpdateWorldTransformsListener& listener);
|
||||||
|
|
||||||
void setTrackStartListener (TrackEntry* entry, const StartListener& listener);
|
void setTrackStartListener (TrackEntry* entry, const StartListener& listener);
|
||||||
void setTrackInterruptListener (TrackEntry* entry, const InterruptListener& listener);
|
void setTrackInterruptListener (TrackEntry* entry, const InterruptListener& listener);
|
||||||
void setTrackEndListener (TrackEntry* entry, const EndListener& listener);
|
void setTrackEndListener (TrackEntry* entry, const EndListener& listener);
|
||||||
void setTrackDisposeListener (TrackEntry* entry, const DisposeListener& listener);
|
void setTrackDisposeListener (TrackEntry* entry, const DisposeListener& listener);
|
||||||
void setTrackCompleteListener (TrackEntry* entry, const CompleteListener& listener);
|
void setTrackCompleteListener (TrackEntry* entry, const CompleteListener& listener);
|
||||||
void setTrackEventListener (TrackEntry* entry, const EventListener& listener);
|
void setTrackEventListener (TrackEntry* entry, const EventListener& listener);
|
||||||
|
|
||||||
|
@ -99,6 +104,7 @@ public:
|
||||||
virtual void onTrackEntryEvent (TrackEntry* entry, EventType type, Event* event);
|
virtual void onTrackEntryEvent (TrackEntry* entry, EventType type, Event* event);
|
||||||
|
|
||||||
AnimationState* getState() const;
|
AnimationState* getState() const;
|
||||||
|
void setUpdateOnlyIfVisible(bool status);
|
||||||
|
|
||||||
CC_CONSTRUCTOR_ACCESS:
|
CC_CONSTRUCTOR_ACCESS:
|
||||||
SkeletonAnimation ();
|
SkeletonAnimation ();
|
||||||
|
@ -109,14 +115,17 @@ protected:
|
||||||
AnimationState* _state;
|
AnimationState* _state;
|
||||||
|
|
||||||
bool _ownsAnimationStateData;
|
bool _ownsAnimationStateData;
|
||||||
|
bool _updateOnlyIfVisible;
|
||||||
bool _firstDraw;
|
bool _firstDraw;
|
||||||
|
|
||||||
StartListener _startListener;
|
StartListener _startListener;
|
||||||
InterruptListener _interruptListener;
|
InterruptListener _interruptListener;
|
||||||
EndListener _endListener;
|
EndListener _endListener;
|
||||||
DisposeListener _disposeListener;
|
DisposeListener _disposeListener;
|
||||||
CompleteListener _completeListener;
|
CompleteListener _completeListener;
|
||||||
EventListener _eventListener;
|
EventListener _eventListener;
|
||||||
|
UpdateWorldTransformsListener _preUpdateListener;
|
||||||
|
UpdateWorldTransformsListener _postUpdateListener;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef SkeletonRenderer super;
|
typedef SkeletonRenderer super;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes License Agreement
|
* Spine Runtimes License Agreement
|
||||||
* Last updated May 1, 2019. Replaces all prior versions.
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||||
*
|
*
|
||||||
* Integration of the Spine Runtimes into software or otherwise creating
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
@ -15,28 +15,28 @@
|
||||||
* Spine Editor license and redistribution of the Products in any form must
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
* include this license and copyright notice.
|
* include this license and copyright notice.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifndef SPINE_SKELETONRENDERER_H_
|
#ifndef SPINE_SKELETONRENDERER_H_
|
||||||
#define SPINE_SKELETONRENDERER_H_
|
#define SPINE_SKELETONRENDERER_H_
|
||||||
|
|
||||||
#include <spine/spine.h>
|
|
||||||
#include "cocos2d.h"
|
#include "cocos2d.h"
|
||||||
|
#include <spine/spine.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
class AttachmentVertices;
|
class AttachmentVertices;
|
||||||
|
|
||||||
/* Draws a skeleton. */
|
/* Draws a skeleton. */
|
||||||
class SkeletonRenderer: public cocos2d::Node, public cocos2d::BlendProtocol {
|
class SkeletonRenderer: public cocos2d::Node, public cocos2d::BlendProtocol {
|
||||||
public:
|
public:
|
||||||
|
@ -45,48 +45,50 @@ namespace spine {
|
||||||
static SkeletonRenderer* createWithData (SkeletonData* skeletonData, bool ownsSkeletonData = false);
|
static SkeletonRenderer* createWithData (SkeletonData* skeletonData, bool ownsSkeletonData = false);
|
||||||
static SkeletonRenderer* createWithFile (const std::string& skeletonDataFile, Atlas* atlas, float scale = 1);
|
static SkeletonRenderer* createWithFile (const std::string& skeletonDataFile, Atlas* atlas, float scale = 1);
|
||||||
static SkeletonRenderer* createWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);
|
static SkeletonRenderer* createWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);
|
||||||
|
|
||||||
virtual void update (float deltaTime) override;
|
void update (float deltaTime) override;
|
||||||
virtual void draw (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags) override;
|
void draw (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags) override;
|
||||||
virtual void drawDebug (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags);
|
cocos2d::Rect getBoundingBox () const override;
|
||||||
virtual cocos2d::Rect getBoundingBox () const override;
|
void onEnter () override;
|
||||||
virtual void onEnter () override;
|
void onExit () override;
|
||||||
virtual void onExit () override;
|
|
||||||
|
Skeleton* getSkeleton() const;
|
||||||
Skeleton* getSkeleton();
|
|
||||||
|
|
||||||
void setTimeScale(float scale);
|
void setTimeScale(float scale);
|
||||||
float getTimeScale() const;
|
float getTimeScale() const;
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
void setDebugSlotsEnabled(bool enabled);
|
void setDebugSlotsEnabled(bool enabled);
|
||||||
bool getDebugSlotsEnabled() const;
|
bool getDebugSlotsEnabled() const;
|
||||||
|
|
||||||
void setDebugBonesEnabled(bool enabled);
|
void setDebugBonesEnabled(bool enabled);
|
||||||
bool getDebugBonesEnabled() const;
|
bool getDebugBonesEnabled() const;
|
||||||
|
|
||||||
void setDebugMeshesEnabled(bool enabled);
|
void setDebugMeshesEnabled(bool enabled);
|
||||||
bool getDebugMeshesEnabled() const;
|
bool getDebugMeshesEnabled() const;
|
||||||
|
|
||||||
|
void setDebugBoundingRectEnabled(bool enabled);
|
||||||
|
bool getDebugBoundingRectEnabled() const;
|
||||||
|
|
||||||
// --- Convenience methods for common Skeleton_* functions.
|
// --- Convenience methods for common Skeleton_* functions.
|
||||||
void updateWorldTransform ();
|
void updateWorldTransform ();
|
||||||
|
|
||||||
void setToSetupPose ();
|
void setToSetupPose ();
|
||||||
void setBonesToSetupPose ();
|
void setBonesToSetupPose ();
|
||||||
void setSlotsToSetupPose ();
|
void setSlotsToSetupPose ();
|
||||||
|
|
||||||
/* Returns 0 if the bone was not found. */
|
/* Returns 0 if the bone was not found. */
|
||||||
Bone* findBone (const std::string& boneName) const;
|
Bone* findBone (const std::string& boneName) const;
|
||||||
/* Returns 0 if the slot was not found. */
|
/* Returns 0 if the slot was not found. */
|
||||||
Slot* findSlot (const std::string& slotName) const;
|
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
|
/* 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.
|
* attached if the corresponding attachment from the old skin was attached.
|
||||||
* @param skin May be empty string ("") for no skin.*/
|
* @param skin May be empty string ("") for no skin.*/
|
||||||
void setSkin (const std::string& skinName);
|
void setSkin (const std::string& skinName);
|
||||||
/** @param skin May be 0 for no skin.*/
|
/** @param skin May be 0 for no skin.*/
|
||||||
void setSkin (const char* skinName);
|
void setSkin (const char* skinName);
|
||||||
|
|
||||||
/* Returns 0 if the slot or attachment was not found. */
|
/* Returns 0 if the slot or attachment was not found. */
|
||||||
Attachment* getAttachment (const std::string& slotName, const std::string& attachmentName) const;
|
Attachment* getAttachment (const std::string& slotName, const std::string& attachmentName) const;
|
||||||
/* Returns false if the slot or attachment was not found.
|
/* Returns false if the slot or attachment was not found.
|
||||||
|
@ -94,55 +96,53 @@ namespace spine {
|
||||||
bool setAttachment (const std::string& slotName, const std::string& attachmentName);
|
bool setAttachment (const std::string& slotName, const std::string& attachmentName);
|
||||||
/* @param attachmentName May be 0 for no attachment. */
|
/* @param attachmentName May be 0 for no attachment. */
|
||||||
bool setAttachment (const std::string& slotName, const char* attachmentName);
|
bool setAttachment (const std::string& slotName, const char* attachmentName);
|
||||||
|
|
||||||
/* Enables/disables two color tinting for this instance. May break batching */
|
/* Enables/disables two color tinting for this instance. May break batching */
|
||||||
void setTwoColorTint(bool enabled);
|
void setTwoColorTint(bool enabled);
|
||||||
/* Whether two color tinting is enabled */
|
/* Whether two color tinting is enabled */
|
||||||
bool isTwoColorTint();
|
bool isTwoColorTint();
|
||||||
|
|
||||||
/* Sets the vertex effect to be used, set to 0 to disable vertex effects */
|
/* Sets the vertex effect to be used, set to 0 to disable vertex effects */
|
||||||
void setVertexEffect(VertexEffect* effect);
|
void setVertexEffect(VertexEffect* effect);
|
||||||
|
|
||||||
/* Sets the range of slots that should be rendered. Use -1, -1 to clear the range */
|
/* Sets the range of slots that should be rendered. Use -1, -1 to clear the range */
|
||||||
void setSlotsRange(int startSlotIndex, int endSlotIndex);
|
void setSlotsRange(int startSlotIndex, int endSlotIndex);
|
||||||
|
|
||||||
// --- BlendProtocol
|
// --- BlendProtocol
|
||||||
virtual void setBlendFunc (const cocos2d::BlendFunc& blendFunc)override;
|
void setBlendFunc (const cocos2d::BlendFunc& blendFunc)override;
|
||||||
virtual const cocos2d::BlendFunc& getBlendFunc () const override;
|
const cocos2d::BlendFunc& getBlendFunc () const override;
|
||||||
virtual void setOpacityModifyRGB (bool value) override;
|
void setOpacityModifyRGB (bool value) override;
|
||||||
virtual bool isOpacityModifyRGB () const override;
|
bool isOpacityModifyRGB () const override;
|
||||||
|
|
||||||
// Frees global memory used for temporay vertex transformations.
|
|
||||||
static void destroyScratchBuffers();
|
|
||||||
|
|
||||||
CC_CONSTRUCTOR_ACCESS:
|
CC_CONSTRUCTOR_ACCESS:
|
||||||
SkeletonRenderer ();
|
SkeletonRenderer ();
|
||||||
SkeletonRenderer(Skeleton* skeleton, bool ownsSkeleton = false, bool ownsSkeletonData = false, bool ownsAtlas = false);
|
SkeletonRenderer(Skeleton* skeleton, bool ownsSkeleton = false, bool ownsSkeletonData = false, bool ownsAtlas = false);
|
||||||
SkeletonRenderer (SkeletonData* skeletonData, bool ownsSkeletonData = false);
|
SkeletonRenderer (SkeletonData* skeletonData, bool ownsSkeletonData = false);
|
||||||
SkeletonRenderer (const std::string& skeletonDataFile, Atlas* atlas, float scale = 1);
|
SkeletonRenderer (const std::string& skeletonDataFile, Atlas* atlas, float scale = 1);
|
||||||
SkeletonRenderer (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);
|
SkeletonRenderer (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);
|
||||||
|
|
||||||
virtual ~SkeletonRenderer ();
|
virtual ~SkeletonRenderer ();
|
||||||
|
|
||||||
void initWithSkeleton(Skeleton* skeleton, bool ownsSkeleton = false, bool ownsSkeletonData = false, bool ownsAtlas = false);
|
void initWithSkeleton(Skeleton* skeleton, bool ownsSkeleton = false, bool ownsSkeletonData = false, bool ownsAtlas = false);
|
||||||
void initWithData (SkeletonData* skeletonData, bool ownsSkeletonData = 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, Atlas* atlas, float scale = 1);
|
||||||
void initWithJsonFile (const std::string& skeletonDataFile, const std::string& atlasFile, 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, Atlas* atlas, float scale = 1);
|
||||||
void initWithBinaryFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);
|
void initWithBinaryFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);
|
||||||
|
|
||||||
virtual void initialize ();
|
virtual void initialize ();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setSkeletonData (SkeletonData* skeletonData, bool ownsSkeletonData);
|
void setSkeletonData (SkeletonData* skeletonData, bool ownsSkeletonData);
|
||||||
void setupGLProgramState(bool twoColorTintEnabled);
|
void setupGLProgramState(bool twoColorTintEnabled);
|
||||||
|
virtual void drawDebug (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags);
|
||||||
|
|
||||||
bool _ownsSkeletonData;
|
bool _ownsSkeletonData;
|
||||||
bool _ownsSkeleton;
|
bool _ownsSkeleton;
|
||||||
bool _ownsAtlas;
|
bool _ownsAtlas = false;
|
||||||
Atlas* _atlas;
|
Atlas* _atlas;
|
||||||
AttachmentLoader* _attachmentLoader;
|
AttachmentLoader* _attachmentLoader;
|
||||||
|
cocos2d::CustomCommand _debugCommand;
|
||||||
cocos2d::BlendFunc _blendFunc;
|
cocos2d::BlendFunc _blendFunc;
|
||||||
bool _premultipliedAlpha;
|
bool _premultipliedAlpha;
|
||||||
Skeleton* _skeleton;
|
Skeleton* _skeleton;
|
||||||
|
@ -150,13 +150,16 @@ namespace spine {
|
||||||
bool _debugSlots;
|
bool _debugSlots;
|
||||||
bool _debugBones;
|
bool _debugBones;
|
||||||
bool _debugMeshes;
|
bool _debugMeshes;
|
||||||
|
bool _debugBoundingRect;
|
||||||
SkeletonClipping* _clipper;
|
SkeletonClipping* _clipper;
|
||||||
VertexEffect* _effect;
|
VertexEffect* _effect;
|
||||||
bool _twoColorTintEnabled = false;
|
cocos2d::Rect _boundingRect;
|
||||||
|
|
||||||
int _startSlotIndex;
|
int _startSlotIndex;
|
||||||
int _endSlotIndex;
|
int _endSlotIndex;
|
||||||
|
bool _twoColorTint;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SPINE_SKELETONRENDERER_H_ */
|
#endif /* SPINE_SKELETONRENDERER_H_ */
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes License Agreement
|
* Spine Runtimes License Agreement
|
||||||
* Last updated May 1, 2019. Replaces all prior versions.
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||||
*
|
*
|
||||||
* Integration of the Spine Runtimes into software or otherwise creating
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
@ -15,16 +15,16 @@
|
||||||
* Spine Editor license and redistribution of the Products in any form must
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
* include this license and copyright notice.
|
* include this license and copyright notice.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <spine/spine-cocos2dx.h>
|
#include <spine/spine-cocos2dx.h>
|
||||||
|
@ -48,7 +48,7 @@ static void setAttachmentVertices(RegionAttachment* attachment) {
|
||||||
vertices[i].texCoords.u = attachment->getUVs()[ii];
|
vertices[i].texCoords.u = attachment->getUVs()[ii];
|
||||||
vertices[i].texCoords.v = attachment->getUVs()[ii + 1];
|
vertices[i].texCoords.v = attachment->getUVs()[ii + 1];
|
||||||
}
|
}
|
||||||
attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
|
attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setAttachmentVertices(MeshAttachment* attachment) {
|
static void setAttachmentVertices(MeshAttachment* attachment) {
|
||||||
|
@ -63,7 +63,7 @@ static void setAttachmentVertices(MeshAttachment* attachment) {
|
||||||
attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
|
attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cocos2dAtlasAttachmentLoader::Cocos2dAtlasAttachmentLoader(Atlas* atlas): AtlasAttachmentLoader(atlas) {
|
Cocos2dAtlasAttachmentLoader::Cocos2dAtlasAttachmentLoader(Atlas* atlas): AtlasAttachmentLoader(atlas) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Cocos2dAtlasAttachmentLoader::~Cocos2dAtlasAttachmentLoader() { }
|
Cocos2dAtlasAttachmentLoader::~Cocos2dAtlasAttachmentLoader() { }
|
||||||
|
@ -107,29 +107,29 @@ backend::SamplerFilter filter (TextureFilter filter) {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
GLuint wrap (TextureWrap wrap) {
|
GLuint wrap (TextureWrap wrap) {
|
||||||
return wrap == TextureWrap_ClampToEdge ? GL_CLAMP_TO_EDGE : GL_REPEAT;
|
return wrap == TextureWrap_ClampToEdge ? GL_CLAMP_TO_EDGE : GL_REPEAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint filter (TextureFilter filter) {
|
GLuint filter (TextureFilter filter) {
|
||||||
switch (filter) {
|
switch (filter) {
|
||||||
case TextureFilter_Unknown:
|
case TextureFilter_Unknown:
|
||||||
break;
|
break;
|
||||||
case TextureFilter_Nearest:
|
case TextureFilter_Nearest:
|
||||||
return GL_NEAREST;
|
return GL_NEAREST;
|
||||||
case TextureFilter_Linear:
|
case TextureFilter_Linear:
|
||||||
return GL_LINEAR;
|
return GL_LINEAR;
|
||||||
case TextureFilter_MipMap:
|
case TextureFilter_MipMap:
|
||||||
return GL_LINEAR_MIPMAP_LINEAR;
|
return GL_LINEAR_MIPMAP_LINEAR;
|
||||||
case TextureFilter_MipMapNearestNearest:
|
case TextureFilter_MipMapNearestNearest:
|
||||||
return GL_NEAREST_MIPMAP_NEAREST;
|
return GL_NEAREST_MIPMAP_NEAREST;
|
||||||
case TextureFilter_MipMapLinearNearest:
|
case TextureFilter_MipMapLinearNearest:
|
||||||
return GL_LINEAR_MIPMAP_NEAREST;
|
return GL_LINEAR_MIPMAP_NEAREST;
|
||||||
case TextureFilter_MipMapNearestLinear:
|
case TextureFilter_MipMapNearestLinear:
|
||||||
return GL_NEAREST_MIPMAP_LINEAR;
|
return GL_NEAREST_MIPMAP_LINEAR;
|
||||||
case TextureFilter_MipMapLinearLinear:
|
case TextureFilter_MipMapLinearLinear:
|
||||||
return GL_LINEAR_MIPMAP_LINEAR;
|
return GL_LINEAR_MIPMAP_LINEAR;
|
||||||
}
|
}
|
||||||
return GL_LINEAR;
|
return GL_LINEAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -140,32 +140,36 @@ Cocos2dTextureLoader::~Cocos2dTextureLoader() { }
|
||||||
void Cocos2dTextureLoader::load(AtlasPage& page, const spine::String& path) {
|
void Cocos2dTextureLoader::load(AtlasPage& page, const spine::String& path) {
|
||||||
Texture2D* texture = Director::getInstance()->getTextureCache()->addImage(path.buffer());
|
Texture2D* texture = Director::getInstance()->getTextureCache()->addImage(path.buffer());
|
||||||
CCASSERT(texture != nullptr, "Invalid image");
|
CCASSERT(texture != nullptr, "Invalid image");
|
||||||
texture->retain();
|
if (texture) {
|
||||||
|
texture->retain();
|
||||||
#if COCOS2D_VERSION >= 0x0040000
|
#if COCOS2D_VERSION >= 0x0040000
|
||||||
Texture2D::TexParams textureParams(filter(page.minFilter), filter(page.magFilter), wrap(page.uWrap), wrap(page.vWrap));
|
Texture2D::TexParams textureParams(filter(page.minFilter), filter(page.magFilter), wrap(page.uWrap), wrap(page.vWrap));
|
||||||
#else
|
#else
|
||||||
Texture2D::TexParams textureParams = {filter(page.minFilter), filter(page.magFilter), wrap(page.uWrap), wrap(page.vWrap)};
|
Texture2D::TexParams textureParams = {filter(page.minFilter), filter(page.magFilter), wrap(page.uWrap), wrap(page.vWrap)};
|
||||||
#endif
|
#endif
|
||||||
texture->setTexParameters(textureParams);
|
texture->setTexParameters(textureParams);
|
||||||
|
|
||||||
page.setRendererObject(texture);
|
page.setRendererObject(texture);
|
||||||
page.width = texture->getPixelsWide();
|
page.width = texture->getPixelsWide();
|
||||||
page.height = texture->getPixelsHigh();
|
page.height = texture->getPixelsHigh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cocos2dTextureLoader::unload(void* texture) {
|
void Cocos2dTextureLoader::unload(void* texture) {
|
||||||
((Texture2D*)texture)->release();
|
if (texture) {
|
||||||
|
((Texture2D*)texture)->release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Cocos2dExtension::Cocos2dExtension() : DefaultSpineExtension() { }
|
Cocos2dExtension::Cocos2dExtension() : DefaultSpineExtension() { }
|
||||||
|
|
||||||
Cocos2dExtension::~Cocos2dExtension() { }
|
Cocos2dExtension::~Cocos2dExtension() { }
|
||||||
|
|
||||||
char *Cocos2dExtension::_readFile(const spine::String &path, int *length) {
|
char *Cocos2dExtension::_readFile(const spine::String &path, int *length) {
|
||||||
Data data = FileUtils::getInstance()->getDataFromFile(FileUtils::getInstance()->fullPathForFilename(path.buffer()));
|
Data data = FileUtils::getInstance()->getDataFromFile(FileUtils::getInstance()->fullPathForFilename(path.buffer()));
|
||||||
if (data.isNull()) return 0;
|
if (data.isNull()) return nullptr;
|
||||||
|
|
||||||
// avoid buffer overflow (int is shorter than ssize_t in certain platforms)
|
// avoid buffer overflow (int is shorter than ssize_t in certain platforms)
|
||||||
#if COCOS2D_VERSION >= 0x00031200
|
#if COCOS2D_VERSION >= 0x00031200
|
||||||
ssize_t tmpLen;
|
ssize_t tmpLen;
|
||||||
|
@ -180,8 +184,6 @@ char *Cocos2dExtension::_readFile(const spine::String &path, int *length) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//SpineExtension *spine::getDefaultExtension () {
|
SpineExtension *spine::getDefaultExtension () {
|
||||||
// return new Cocos2dExtension();
|
return new Cocos2dExtension();
|
||||||
//}
|
}
|
||||||
|
|
||||||
static int __preinit_spine_extension = (spine::SpineExtension::setInstance(new Cocos2dExtension()), 0);
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes License Agreement
|
* Spine Runtimes License Agreement
|
||||||
* Last updated May 1, 2019. Replaces all prior versions.
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||||
*
|
*
|
||||||
* Integration of the Spine Runtimes into software or otherwise creating
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
@ -15,27 +15,35 @@
|
||||||
* Spine Editor license and redistribution of the Products in any form must
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
* include this license and copyright notice.
|
* include this license and copyright notice.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifndef SPINE_COCOS2DX_H_
|
#ifndef SPINE_COCOS2DX_H_
|
||||||
#define SPINE_COCOS2DX_H_
|
#define SPINE_COCOS2DX_H_
|
||||||
#define SPINE_SHORT_NAMES
|
|
||||||
#include <spine/spine.h>
|
#include <spine/spine.h>
|
||||||
#include "cocos2d.h"
|
#include "cocos2d.h"
|
||||||
|
|
||||||
#include <spine/SkeletonRenderer.h>
|
#include <spine/SkeletonRenderer.h>
|
||||||
|
|
||||||
|
#if COCOS2D_VERSION < 0x00040000
|
||||||
|
#include <spine/v3/SkeletonBatch.h>
|
||||||
|
#include <spine/v3/SkeletonTwoColorBatch.h>
|
||||||
|
#else
|
||||||
|
#include <spine/v4/SkeletonBatch.h>
|
||||||
|
#include <spine/v4/SkeletonTwoColorBatch.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <spine/SkeletonAnimation.h>
|
#include <spine/SkeletonAnimation.h>
|
||||||
#include <spine/SkeletonBatch.h>
|
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class Cocos2dAtlasAttachmentLoader: public AtlasAttachmentLoader {
|
class Cocos2dAtlasAttachmentLoader: public AtlasAttachmentLoader {
|
||||||
|
@ -44,7 +52,7 @@ namespace spine {
|
||||||
virtual ~Cocos2dAtlasAttachmentLoader();
|
virtual ~Cocos2dAtlasAttachmentLoader();
|
||||||
virtual void configureAttachment(Attachment* attachment);
|
virtual void configureAttachment(Attachment* attachment);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Cocos2dTextureLoader: public TextureLoader {
|
class Cocos2dTextureLoader: public TextureLoader {
|
||||||
public:
|
public:
|
||||||
Cocos2dTextureLoader();
|
Cocos2dTextureLoader();
|
||||||
|
@ -52,10 +60,10 @@ namespace spine {
|
||||||
virtual ~Cocos2dTextureLoader();
|
virtual ~Cocos2dTextureLoader();
|
||||||
|
|
||||||
virtual void load(AtlasPage& page, const String& path);
|
virtual void load(AtlasPage& page, const String& path);
|
||||||
|
|
||||||
virtual void unload(void* texture);
|
virtual void unload(void* texture);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Cocos2dExtension: public DefaultSpineExtension {
|
class Cocos2dExtension: public DefaultSpineExtension {
|
||||||
public:
|
public:
|
||||||
Cocos2dExtension();
|
Cocos2dExtension();
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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/spine-cocos2dx.h>
|
||||||
|
#if COCOS2D_VERSION < 0x00040000
|
||||||
|
|
||||||
|
#include <spine/Extension.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
USING_NS_CC;
|
||||||
|
#define EVENT_AFTER_DRAW_RESET_POSITION "director_after_draw"
|
||||||
|
using std::max;
|
||||||
|
#define INITIAL_SIZE (10000)
|
||||||
|
|
||||||
|
namespace spine {
|
||||||
|
|
||||||
|
static SkeletonBatch* instance = nullptr;
|
||||||
|
|
||||||
|
SkeletonBatch* SkeletonBatch::getInstance () {
|
||||||
|
if (!instance) instance = new SkeletonBatch();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonBatch::destroyInstance () {
|
||||||
|
if (instance) {
|
||||||
|
delete instance;
|
||||||
|
instance = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SkeletonBatch::SkeletonBatch () {
|
||||||
|
for (unsigned int i = 0; i < INITIAL_SIZE; i++) {
|
||||||
|
_commandsPool.push_back(new TrianglesCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
reset ();
|
||||||
|
|
||||||
|
// callback after drawing is finished so we can clear out the batch state
|
||||||
|
// for the next frame
|
||||||
|
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom){
|
||||||
|
this->update(0);
|
||||||
|
});;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkeletonBatch::~SkeletonBatch () {
|
||||||
|
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
||||||
|
delete _commandsPool[i];
|
||||||
|
_commandsPool[i] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonBatch::update (float delta) {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
cocos2d::V3F_C4B_T2F* SkeletonBatch::allocateVertices(uint32_t numVertices) {
|
||||||
|
if (_vertices.size() - _numVertices < numVertices) {
|
||||||
|
cocos2d::V3F_C4B_T2F* oldData = _vertices.data();
|
||||||
|
_vertices.resize((_vertices.size() + numVertices) * 2 + 1);
|
||||||
|
cocos2d::V3F_C4B_T2F* newData = _vertices.data();
|
||||||
|
for (uint32_t i = 0; i < this->_nextFreeCommand; i++) {
|
||||||
|
TrianglesCommand* command = _commandsPool[i];
|
||||||
|
cocos2d::TrianglesCommand::Triangles& triangles = (cocos2d::TrianglesCommand::Triangles&)command->getTriangles();
|
||||||
|
triangles.verts = newData + (triangles.verts - oldData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cocos2d::V3F_C4B_T2F* vertices = _vertices.data() + _numVertices;
|
||||||
|
_numVertices += numVertices;
|
||||||
|
return vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonBatch::deallocateVertices(uint32_t numVertices) {
|
||||||
|
_numVertices -= numVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned short* SkeletonBatch::allocateIndices(uint32_t numIndices) {
|
||||||
|
if (_indices.getCapacity() - _indices.size() < numIndices) {
|
||||||
|
unsigned short* oldData = _indices.buffer();
|
||||||
|
int oldSize = _indices.size();
|
||||||
|
_indices.ensureCapacity(_indices.size() + numIndices);
|
||||||
|
unsigned short* newData = _indices.buffer();
|
||||||
|
for (uint32_t i = 0; i < this->_nextFreeCommand; i++) {
|
||||||
|
TrianglesCommand* command = _commandsPool[i];
|
||||||
|
cocos2d::TrianglesCommand::Triangles& triangles = (cocos2d::TrianglesCommand::Triangles&)command->getTriangles();
|
||||||
|
if (triangles.indices >= oldData && triangles.indices < oldData + oldSize) {
|
||||||
|
triangles.indices = newData + (triangles.indices - oldData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short* indices = _indices.buffer() + _indices.size();
|
||||||
|
_indices.setSize(_indices.size() + numIndices, 0);
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonBatch::deallocateIndices(uint32_t numIndices) {
|
||||||
|
_indices.setSize(_indices.size() - numIndices, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cocos2d::TrianglesCommand* SkeletonBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) {
|
||||||
|
TrianglesCommand* command = nextFreeCommand();
|
||||||
|
command->init(globalOrder, texture, glProgramState, blendType, triangles, mv, flags);
|
||||||
|
renderer->addCommand(command);
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonBatch::reset() {
|
||||||
|
_nextFreeCommand = 0;
|
||||||
|
_numVertices = 0;
|
||||||
|
_indices.setSize(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cocos2d::TrianglesCommand* SkeletonBatch::nextFreeCommand() {
|
||||||
|
if (_commandsPool.size() <= _nextFreeCommand) {
|
||||||
|
unsigned int newSize = _commandsPool.size() * 2 + 1;
|
||||||
|
for (int i = _commandsPool.size(); i < newSize; i++) {
|
||||||
|
_commandsPool.push_back(new TrianglesCommand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _commandsPool[_nextFreeCommand++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,79 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef SPINE_SKELETONBATCH_H_
|
||||||
|
#define SPINE_SKELETONBATCH_H_
|
||||||
|
|
||||||
|
#include "cocos2d.h"
|
||||||
|
#if COCOS2D_VERSION < 0x00040000
|
||||||
|
|
||||||
|
#include <spine/spine.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace spine {
|
||||||
|
|
||||||
|
class SkeletonBatch {
|
||||||
|
public:
|
||||||
|
static SkeletonBatch* getInstance ();
|
||||||
|
|
||||||
|
static void destroyInstance ();
|
||||||
|
|
||||||
|
void update (float delta);
|
||||||
|
|
||||||
|
cocos2d::V3F_C4B_T2F* allocateVertices(uint32_t numVertices);
|
||||||
|
void deallocateVertices(uint32_t numVertices);
|
||||||
|
unsigned short* allocateIndices(uint32_t numIndices);
|
||||||
|
void deallocateIndices(uint32_t numVertices);
|
||||||
|
cocos2d::TrianglesCommand* addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SkeletonBatch ();
|
||||||
|
virtual ~SkeletonBatch ();
|
||||||
|
|
||||||
|
void reset ();
|
||||||
|
|
||||||
|
cocos2d::TrianglesCommand* nextFreeCommand ();
|
||||||
|
|
||||||
|
// pool of commands
|
||||||
|
std::vector<cocos2d::TrianglesCommand*> _commandsPool;
|
||||||
|
uint32_t _nextFreeCommand;
|
||||||
|
|
||||||
|
// pool of vertices
|
||||||
|
std::vector<cocos2d::V3F_C4B_T2F> _vertices;
|
||||||
|
uint32_t _numVertices;
|
||||||
|
|
||||||
|
// pool of indices
|
||||||
|
Vector<unsigned short> _indices;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SPINE_SKELETONBATCH_H_
|
|
@ -0,0 +1,351 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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/spine-cocos2dx.h>
|
||||||
|
#if COCOS2D_VERSION < 0x00040000
|
||||||
|
|
||||||
|
#include <spine/Extension.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
USING_NS_CC;
|
||||||
|
#define EVENT_AFTER_DRAW_RESET_POSITION "director_after_draw"
|
||||||
|
using std::max;
|
||||||
|
#define INITIAL_SIZE (10000)
|
||||||
|
#define MAX_VERTICES 64000
|
||||||
|
#define MAX_INDICES 64000
|
||||||
|
|
||||||
|
#define STRINGIFY(A) #A
|
||||||
|
|
||||||
|
namespace spine {
|
||||||
|
|
||||||
|
TwoColorTrianglesCommand::TwoColorTrianglesCommand() :_materialID(0), _textureID(0), _glProgramState(nullptr), _glProgram(nullptr), _blendType(BlendFunc::DISABLE), _alphaTextureID(0) {
|
||||||
|
_type = RenderCommand::Type::CUSTOM_COMMAND;
|
||||||
|
func = [this]() { draw(); };
|
||||||
|
}
|
||||||
|
|
||||||
|
void TwoColorTrianglesCommand::init(float globalOrder, GLuint textureID, GLProgramState* glProgramState, BlendFunc blendType, const TwoColorTriangles& triangles, const Mat4& mv, uint32_t flags) {
|
||||||
|
CCASSERT(glProgramState, "Invalid GLProgramState");
|
||||||
|
CCASSERT(glProgramState->getVertexAttribsFlags() == 0, "No custom attributes are supported in QuadCommand");
|
||||||
|
|
||||||
|
RenderCommand::init(globalOrder, mv, flags);
|
||||||
|
|
||||||
|
_triangles = triangles;
|
||||||
|
if(_triangles.indexCount % 3 != 0) {
|
||||||
|
int count = _triangles.indexCount;
|
||||||
|
_triangles.indexCount = count / 3 * 3;
|
||||||
|
CCLOGERROR("Resize indexCount from %d to %d, size must be multiple times of 3", count, _triangles.indexCount);
|
||||||
|
}
|
||||||
|
_mv = mv;
|
||||||
|
|
||||||
|
if( _textureID != textureID || _blendType.src != blendType.src || _blendType.dst != blendType.dst ||
|
||||||
|
_glProgramState != glProgramState ||
|
||||||
|
_glProgram != glProgramState->getGLProgram()) {
|
||||||
|
_textureID = textureID;
|
||||||
|
_blendType = blendType;
|
||||||
|
_glProgramState = glProgramState;
|
||||||
|
_glProgram = glProgramState->getGLProgram();
|
||||||
|
|
||||||
|
generateMaterialID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TwoColorTrianglesCommand::~TwoColorTrianglesCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void TwoColorTrianglesCommand::generateMaterialID() {
|
||||||
|
// do not batch if using custom uniforms (since we cannot batch) it
|
||||||
|
if(_glProgramState->getUniformCount() > 0) {
|
||||||
|
_materialID = Renderer::MATERIAL_ID_DO_NOT_BATCH;
|
||||||
|
setSkipBatching(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int glProgram = (int)_glProgram->getProgram();
|
||||||
|
_materialID = glProgram + (int)_textureID + (int)_blendType.src + (int)_blendType.dst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TwoColorTrianglesCommand::useMaterial() const {
|
||||||
|
//Set texture
|
||||||
|
GL::bindTexture2D(_textureID);
|
||||||
|
|
||||||
|
if (_alphaTextureID > 0) {
|
||||||
|
// ANDROID ETC1 ALPHA supports.
|
||||||
|
GL::bindTexture2DN(1, _alphaTextureID);
|
||||||
|
}
|
||||||
|
//set blend mode
|
||||||
|
GL::blendFunc(_blendType.src, _blendType.dst);
|
||||||
|
|
||||||
|
_glProgramState->apply(_mv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TwoColorTrianglesCommand::draw() {
|
||||||
|
SkeletonTwoColorBatch::getInstance()->batch(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* TWO_COLOR_TINT_VERTEX_SHADER = STRINGIFY(
|
||||||
|
attribute vec4 a_position;
|
||||||
|
attribute vec4 a_color;
|
||||||
|
attribute vec4 a_color2;
|
||||||
|
attribute vec2 a_texCoords;
|
||||||
|
|
||||||
|
\n#ifdef GL_ES\n
|
||||||
|
varying lowp vec4 v_light;
|
||||||
|
varying lowp vec4 v_dark;
|
||||||
|
varying mediump vec2 v_texCoord;
|
||||||
|
\n#else\n
|
||||||
|
varying vec4 v_light;
|
||||||
|
varying vec4 v_dark;
|
||||||
|
varying vec2 v_texCoord;
|
||||||
|
|
||||||
|
\n#endif\n
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
v_light = a_color;
|
||||||
|
v_dark = a_color2;
|
||||||
|
v_texCoord = a_texCoords;
|
||||||
|
gl_Position = CC_PMatrix * a_position;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const char* TWO_COLOR_TINT_FRAGMENT_SHADER = STRINGIFY(
|
||||||
|
\n#ifdef GL_ES\n
|
||||||
|
precision lowp float;
|
||||||
|
\n#endif\n
|
||||||
|
|
||||||
|
varying vec4 v_light;
|
||||||
|
varying vec4 v_dark;
|
||||||
|
varying vec2 v_texCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texColor = texture2D(CC_Texture0, v_texCoord);
|
||||||
|
float alpha = texColor.a * v_light.a;
|
||||||
|
gl_FragColor.a = alpha;
|
||||||
|
gl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
static SkeletonTwoColorBatch* instance = nullptr;
|
||||||
|
|
||||||
|
SkeletonTwoColorBatch* SkeletonTwoColorBatch::getInstance () {
|
||||||
|
if (!instance) instance = new SkeletonTwoColorBatch();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonTwoColorBatch::destroyInstance () {
|
||||||
|
if (instance) {
|
||||||
|
delete instance;
|
||||||
|
instance = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SkeletonTwoColorBatch::SkeletonTwoColorBatch () : _vertexBuffer(0), _indexBuffer(0) {
|
||||||
|
for (unsigned int i = 0; i < INITIAL_SIZE; i++) {
|
||||||
|
_commandsPool.push_back(new TwoColorTrianglesCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
reset ();
|
||||||
|
|
||||||
|
// callback after drawing is finished so we can clear out the batch state
|
||||||
|
// for the next frame
|
||||||
|
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom){
|
||||||
|
this->update(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
_twoColorTintShader = cocos2d::GLProgram::createWithByteArrays(TWO_COLOR_TINT_VERTEX_SHADER, TWO_COLOR_TINT_FRAGMENT_SHADER);
|
||||||
|
_twoColorTintShaderState = GLProgramState::getOrCreateWithGLProgram(_twoColorTintShader);
|
||||||
|
_twoColorTintShaderState->retain();
|
||||||
|
|
||||||
|
glGenBuffers(1, &_vertexBufferHandle);
|
||||||
|
_vertexBuffer = new V3F_C4B_C4B_T2F[MAX_VERTICES];
|
||||||
|
glGenBuffers(1, &_indexBufferHandle);
|
||||||
|
_indexBuffer = new unsigned short[MAX_INDICES];
|
||||||
|
_positionAttributeLocation = _twoColorTintShader->getAttribLocation("a_position");
|
||||||
|
_colorAttributeLocation = _twoColorTintShader->getAttribLocation("a_color");
|
||||||
|
_color2AttributeLocation = _twoColorTintShader->getAttribLocation("a_color2");
|
||||||
|
_texCoordsAttributeLocation = _twoColorTintShader->getAttribLocation("a_texCoords");
|
||||||
|
}
|
||||||
|
|
||||||
|
SkeletonTwoColorBatch::~SkeletonTwoColorBatch () {
|
||||||
|
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
||||||
|
delete _commandsPool[i];
|
||||||
|
_commandsPool[i] = nullptr;
|
||||||
|
}
|
||||||
|
_twoColorTintShader->release();
|
||||||
|
delete[] _vertexBuffer;
|
||||||
|
delete[] _indexBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonTwoColorBatch::update (float delta) {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
V3F_C4B_C4B_T2F* SkeletonTwoColorBatch::allocateVertices(uint32_t numVertices) {
|
||||||
|
if (_vertices.size() - _numVertices < numVertices) {
|
||||||
|
V3F_C4B_C4B_T2F* oldData = _vertices.data();
|
||||||
|
_vertices.resize((_vertices.size() + numVertices) * 2 + 1);
|
||||||
|
V3F_C4B_C4B_T2F* newData = _vertices.data();
|
||||||
|
for (uint32_t i = 0; i < this->_nextFreeCommand; i++) {
|
||||||
|
TwoColorTrianglesCommand* command = _commandsPool[i];
|
||||||
|
TwoColorTriangles& triangles = (TwoColorTriangles&)command->getTriangles();
|
||||||
|
triangles.verts = newData + (triangles.verts - oldData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
V3F_C4B_C4B_T2F* vertices = _vertices.data() + _numVertices;
|
||||||
|
_numVertices += numVertices;
|
||||||
|
return vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SkeletonTwoColorBatch::deallocateVertices(uint32_t numVertices) {
|
||||||
|
_numVertices -= numVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned short* SkeletonTwoColorBatch::allocateIndices(uint32_t numIndices) {
|
||||||
|
if (_indices.getCapacity() - _indices.size() < numIndices) {
|
||||||
|
unsigned short* oldData = _indices.buffer();
|
||||||
|
int oldSize =_indices.size();
|
||||||
|
_indices.ensureCapacity(_indices.size() + numIndices);
|
||||||
|
unsigned short* newData = _indices.buffer();
|
||||||
|
for (uint32_t i = 0; i < this->_nextFreeCommand; i++) {
|
||||||
|
TwoColorTrianglesCommand* command = _commandsPool[i];
|
||||||
|
TwoColorTriangles& triangles = (TwoColorTriangles&)command->getTriangles();
|
||||||
|
if (triangles.indices >= oldData && triangles.indices < oldData + oldSize) {
|
||||||
|
triangles.indices = newData + (triangles.indices - oldData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short* indices = _indices.buffer() + _indices.size();
|
||||||
|
_indices.setSize(_indices.size() + numIndices, 0);
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonTwoColorBatch::deallocateIndices(uint32_t numIndices) {
|
||||||
|
_indices.setSize(_indices.size() - numIndices, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TwoColorTrianglesCommand* SkeletonTwoColorBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const TwoColorTriangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) {
|
||||||
|
TwoColorTrianglesCommand* command = nextFreeCommand();
|
||||||
|
command->init(globalOrder, textureID, glProgramState, blendType, triangles, mv, flags);
|
||||||
|
renderer->addCommand(command);
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonTwoColorBatch::batch (TwoColorTrianglesCommand* command) {
|
||||||
|
if (_numVerticesBuffer + command->getTriangles().vertCount >= MAX_VERTICES || _numIndicesBuffer + command->getTriangles().indexCount >= MAX_INDICES) {
|
||||||
|
flush(_lastCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t materialID = command->getMaterialID();
|
||||||
|
if (_lastCommand && _lastCommand->getMaterialID() != materialID) {
|
||||||
|
flush(_lastCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(_vertexBuffer + _numVerticesBuffer, command->getTriangles().verts, sizeof(V3F_C4B_C4B_T2F) * command->getTriangles().vertCount);
|
||||||
|
const Mat4& modelView = command->getModelView();
|
||||||
|
for (int i = _numVerticesBuffer; i < _numVerticesBuffer + command->getTriangles().vertCount; i++) {
|
||||||
|
modelView.transformPoint(&_vertexBuffer[i].position);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short vertexOffset = (unsigned short)_numVerticesBuffer;
|
||||||
|
unsigned short* indices = command->getTriangles().indices;
|
||||||
|
for (int i = 0, j = _numIndicesBuffer; i < command->getTriangles().indexCount; i++, j++) {
|
||||||
|
_indexBuffer[j] = indices[i] + vertexOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
_numVerticesBuffer += command->getTriangles().vertCount;
|
||||||
|
_numIndicesBuffer += command->getTriangles().indexCount;
|
||||||
|
|
||||||
|
if (command->isForceFlush()) {
|
||||||
|
flush(command);
|
||||||
|
}
|
||||||
|
_lastCommand = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonTwoColorBatch::flush (TwoColorTrianglesCommand* materialCommand) {
|
||||||
|
if (!materialCommand)
|
||||||
|
return;
|
||||||
|
|
||||||
|
materialCommand->useMaterial();
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferHandle);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_C4B_T2F) * _numVerticesBuffer , _vertexBuffer, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(_positionAttributeLocation);
|
||||||
|
glEnableVertexAttribArray(_colorAttributeLocation);
|
||||||
|
glEnableVertexAttribArray(_color2AttributeLocation);
|
||||||
|
glEnableVertexAttribArray(_texCoordsAttributeLocation);
|
||||||
|
|
||||||
|
glVertexAttribPointer(_positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, position));
|
||||||
|
glVertexAttribPointer(_colorAttributeLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, color));
|
||||||
|
glVertexAttribPointer(_color2AttributeLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, color2));
|
||||||
|
glVertexAttribPointer(_texCoordsAttributeLocation, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, texCoords));
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferHandle);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * _numIndicesBuffer, _indexBuffer, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES, (GLsizei)_numIndicesBuffer, GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
_numVerticesBuffer = 0;
|
||||||
|
_numIndicesBuffer = 0;
|
||||||
|
_numBatches++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonTwoColorBatch::reset() {
|
||||||
|
_nextFreeCommand = 0;
|
||||||
|
_numVertices = 0;
|
||||||
|
_indices.setSize(0, 0);
|
||||||
|
_numVerticesBuffer = 0;
|
||||||
|
_numIndicesBuffer = 0;
|
||||||
|
_lastCommand = nullptr;
|
||||||
|
_numBatches = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TwoColorTrianglesCommand* SkeletonTwoColorBatch::nextFreeCommand() {
|
||||||
|
if (_commandsPool.size() <= _nextFreeCommand) {
|
||||||
|
unsigned int newSize = _commandsPool.size() * 2 + 1;
|
||||||
|
for (int i = _commandsPool.size(); i < newSize; i++) {
|
||||||
|
_commandsPool.push_back(new TwoColorTrianglesCommand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TwoColorTrianglesCommand* command = _commandsPool[_nextFreeCommand++];
|
||||||
|
command->setForceFlush(false);
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,172 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef SPINE_SKELETONTWOCOLORBATCH_H_
|
||||||
|
#define SPINE_SKELETONTWOCOLORBATCH_H_
|
||||||
|
|
||||||
|
#include "cocos2d.h"
|
||||||
|
#if COCOS2D_VERSION < 0x00040000
|
||||||
|
|
||||||
|
#include <spine/spine.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace spine {
|
||||||
|
struct V3F_C4B_C4B_T2F {
|
||||||
|
cocos2d::Vec3 position;
|
||||||
|
cocos2d::Color4B color;
|
||||||
|
cocos2d::Color4B color2;
|
||||||
|
cocos2d::Tex2F texCoords;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TwoColorTriangles {
|
||||||
|
V3F_C4B_C4B_T2F* verts;
|
||||||
|
unsigned short* indices;
|
||||||
|
int vertCount;
|
||||||
|
int indexCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TwoColorTrianglesCommand : public cocos2d::CustomCommand {
|
||||||
|
public:
|
||||||
|
TwoColorTrianglesCommand();
|
||||||
|
|
||||||
|
~TwoColorTrianglesCommand();
|
||||||
|
|
||||||
|
void init(float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const TwoColorTriangles& triangles, const cocos2d::Mat4& mv, uint32_t flags);
|
||||||
|
|
||||||
|
void useMaterial() const;
|
||||||
|
|
||||||
|
inline uint32_t getMaterialID() const { return _materialID; }
|
||||||
|
|
||||||
|
inline GLuint getTextureID() const { return _textureID; }
|
||||||
|
|
||||||
|
inline const TwoColorTriangles& getTriangles() const { return _triangles; }
|
||||||
|
|
||||||
|
inline ssize_t getVertexCount() const { return _triangles.vertCount; }
|
||||||
|
|
||||||
|
inline ssize_t getIndexCount() const { return _triangles.indexCount; }
|
||||||
|
|
||||||
|
inline const V3F_C4B_C4B_T2F* getVertices() const { return _triangles.verts; }
|
||||||
|
|
||||||
|
inline const unsigned short* getIndices() const { return _triangles.indices; }
|
||||||
|
|
||||||
|
inline cocos2d::GLProgramState* getGLProgramState() const { return _glProgramState; }
|
||||||
|
|
||||||
|
inline cocos2d::BlendFunc getBlendType() const { return _blendType; }
|
||||||
|
|
||||||
|
inline const cocos2d::Mat4& getModelView() const { return _mv; }
|
||||||
|
|
||||||
|
void draw ();
|
||||||
|
|
||||||
|
void setForceFlush (bool forceFlush) { _forceFlush = forceFlush; }
|
||||||
|
|
||||||
|
bool isForceFlush () { return _forceFlush; };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void generateMaterialID();
|
||||||
|
uint32_t _materialID;
|
||||||
|
GLuint _textureID;
|
||||||
|
cocos2d::GLProgramState* _glProgramState;
|
||||||
|
cocos2d::GLProgram* _glProgram;
|
||||||
|
cocos2d::BlendFunc _blendType;
|
||||||
|
TwoColorTriangles _triangles;
|
||||||
|
cocos2d::Mat4 _mv;
|
||||||
|
GLuint _alphaTextureID;
|
||||||
|
bool _forceFlush;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SkeletonTwoColorBatch {
|
||||||
|
public:
|
||||||
|
static SkeletonTwoColorBatch* getInstance ();
|
||||||
|
|
||||||
|
static void destroyInstance ();
|
||||||
|
|
||||||
|
void update (float delta);
|
||||||
|
|
||||||
|
V3F_C4B_C4B_T2F* allocateVertices(uint32_t numVertices);
|
||||||
|
void deallocateVertices(uint32_t numVertices);
|
||||||
|
|
||||||
|
unsigned short* allocateIndices(uint32_t numIndices);
|
||||||
|
void deallocateIndices(uint32_t numIndices);
|
||||||
|
|
||||||
|
TwoColorTrianglesCommand* addCommand(cocos2d::Renderer* renderer, float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const TwoColorTriangles& triangles, const cocos2d::Mat4& mv, uint32_t flags);
|
||||||
|
|
||||||
|
cocos2d::GLProgramState* getTwoColorTintProgramState () { return _twoColorTintShaderState; }
|
||||||
|
|
||||||
|
void batch (TwoColorTrianglesCommand* command);
|
||||||
|
|
||||||
|
void flush (TwoColorTrianglesCommand* materialCommand);
|
||||||
|
|
||||||
|
uint32_t getNumBatches () { return _numBatches; };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SkeletonTwoColorBatch ();
|
||||||
|
virtual ~SkeletonTwoColorBatch ();
|
||||||
|
|
||||||
|
void reset ();
|
||||||
|
|
||||||
|
TwoColorTrianglesCommand* nextFreeCommand ();
|
||||||
|
|
||||||
|
// pool of commands
|
||||||
|
std::vector<TwoColorTrianglesCommand*> _commandsPool;
|
||||||
|
uint32_t _nextFreeCommand;
|
||||||
|
|
||||||
|
// pool of vertices
|
||||||
|
std::vector<V3F_C4B_C4B_T2F> _vertices;
|
||||||
|
uint32_t _numVertices;
|
||||||
|
|
||||||
|
// pool of indices
|
||||||
|
Vector<unsigned short> _indices;
|
||||||
|
|
||||||
|
// two color tint shader and state
|
||||||
|
cocos2d::GLProgram* _twoColorTintShader;
|
||||||
|
cocos2d::GLProgramState* _twoColorTintShaderState;
|
||||||
|
|
||||||
|
// VBO handles & attribute locations
|
||||||
|
GLuint _vertexBufferHandle;
|
||||||
|
V3F_C4B_C4B_T2F* _vertexBuffer;
|
||||||
|
uint32_t _numVerticesBuffer;
|
||||||
|
GLuint _indexBufferHandle;
|
||||||
|
uint32_t _numIndicesBuffer;
|
||||||
|
unsigned short* _indexBuffer;
|
||||||
|
GLint _positionAttributeLocation;
|
||||||
|
GLint _colorAttributeLocation;
|
||||||
|
GLint _color2AttributeLocation;
|
||||||
|
GLint _texCoordsAttributeLocation;
|
||||||
|
|
||||||
|
// last batched command, needed for flushing to set material
|
||||||
|
TwoColorTrianglesCommand* _lastCommand;
|
||||||
|
|
||||||
|
// number of batches in the last frame
|
||||||
|
uint32_t _numBatches;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SPINE_SKELETONTWOCOLORBATCH_H_
|
|
@ -1,8 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes License Agreement
|
* Spine Runtimes License Agreement
|
||||||
* Last updated May 1, 2019. Replaces all prior versions.
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||||
*
|
*
|
||||||
* Integration of the Spine Runtimes into software or otherwise creating
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
@ -15,19 +15,21 @@
|
||||||
* Spine Editor license and redistribution of the Products in any form must
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
* include this license and copyright notice.
|
* include this license and copyright notice.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <spine/SkeletonBatch.h>
|
#include <spine/spine-cocos2dx.h>
|
||||||
|
#if COCOS2D_VERSION >= 0x00040000
|
||||||
|
|
||||||
#include <spine/Extension.h>
|
#include <spine/Extension.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -56,36 +58,38 @@ void SkeletonBatch::destroyInstance () {
|
||||||
}
|
}
|
||||||
|
|
||||||
SkeletonBatch::SkeletonBatch () {
|
SkeletonBatch::SkeletonBatch () {
|
||||||
|
|
||||||
auto program = backend::Device::getInstance()->newProgram(positionTextureColor_vert, positionTextureColor_frag);
|
|
||||||
_programState = std::make_shared<backend::ProgramState>(program);
|
|
||||||
program->autorelease();
|
|
||||||
|
|
||||||
|
auto program = backend::Program::getBuiltinProgram(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||||
|
_programState = std::make_shared<backend::ProgramState>(program);
|
||||||
|
|
||||||
auto vertexLayout = _programState->getVertexLayout();
|
auto vertexLayout = _programState->getVertexLayout();
|
||||||
|
|
||||||
vertexLayout->setAttribute("a_position", 0, backend::VertexFormat::FLOAT3, offsetof(V3F_C4B_T2F, vertices), false);
|
auto locPosition = _programState->getAttributeLocation("a_position");
|
||||||
vertexLayout->setAttribute("a_color", 2, backend::VertexFormat::UBYTE4, offsetof(V3F_C4B_T2F, colors), true);
|
auto locTexcoord = _programState->getAttributeLocation("a_texCoord");
|
||||||
vertexLayout->setAttribute("a_texCoord", 1, backend::VertexFormat::FLOAT2, offsetof(V3F_C4B_T2F, texCoords), false);
|
auto locColor = _programState->getAttributeLocation("a_color");
|
||||||
|
vertexLayout->setAttribute("a_position", locPosition, backend::VertexFormat::FLOAT3, offsetof(V3F_C4B_T2F, vertices), false);
|
||||||
|
vertexLayout->setAttribute("a_color", locColor, backend::VertexFormat::UBYTE4, offsetof(V3F_C4B_T2F, colors), true);
|
||||||
|
vertexLayout->setAttribute("a_texCoord", locTexcoord, backend::VertexFormat::FLOAT2, offsetof(V3F_C4B_T2F, texCoords), false);
|
||||||
vertexLayout->setLayout(sizeof(_vertices[0]));
|
vertexLayout->setLayout(sizeof(_vertices[0]));
|
||||||
|
|
||||||
|
|
||||||
_locMVP = _programState->getUniformLocation("u_MVPMatrix");
|
_locMVP = _programState->getUniformLocation("u_MVPMatrix");
|
||||||
_locTexture = _programState->getUniformLocation("u_texture");
|
_locTexture = _programState->getUniformLocation("u_texture");
|
||||||
|
|
||||||
for (unsigned int i = 0; i < INITIAL_SIZE; i++) {
|
for (unsigned int i = 0; i < INITIAL_SIZE; i++) {
|
||||||
_commandsPool.push_back(createNewTrianglesCommand());
|
_commandsPool.push_back(createNewTrianglesCommand());
|
||||||
}
|
}
|
||||||
reset ();
|
reset();
|
||||||
// callback after drawing is finished so we can clear out the batch state
|
// callback after drawing is finished so we can clear out the batch state
|
||||||
// for the next frame
|
// for the next frame
|
||||||
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom){
|
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom) {
|
||||||
this->update(0);
|
this->update(0);
|
||||||
});;
|
});;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkeletonBatch::~SkeletonBatch () {
|
SkeletonBatch::~SkeletonBatch () {
|
||||||
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
||||||
CC_SAFE_RELEASE(_commandsPool[i]->getPipelineDescriptor().programState);
|
CC_SAFE_RELEASE(_commandsPool[i]->getPipelineDescriptor().programState);
|
||||||
delete _commandsPool[i];
|
delete _commandsPool[i];
|
||||||
|
@ -96,7 +100,7 @@ SkeletonBatch::~SkeletonBatch () {
|
||||||
void SkeletonBatch::update (float delta) {
|
void SkeletonBatch::update (float delta) {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
cocos2d::V3F_C4B_T2F* SkeletonBatch::allocateVertices(uint32_t numVertices) {
|
cocos2d::V3F_C4B_T2F* SkeletonBatch::allocateVertices(uint32_t numVertices) {
|
||||||
if (_vertices.size() - _numVertices < numVertices) {
|
if (_vertices.size() - _numVertices < numVertices) {
|
||||||
cocos2d::V3F_C4B_T2F* oldData = _vertices.data();
|
cocos2d::V3F_C4B_T2F* oldData = _vertices.data();
|
||||||
|
@ -108,18 +112,18 @@ cocos2d::V3F_C4B_T2F* SkeletonBatch::allocateVertices(uint32_t numVertices) {
|
||||||
triangles.verts = newData + (triangles.verts - oldData);
|
triangles.verts = newData + (triangles.verts - oldData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cocos2d::V3F_C4B_T2F* vertices = _vertices.data() + _numVertices;
|
cocos2d::V3F_C4B_T2F* vertices = _vertices.data() + _numVertices;
|
||||||
_numVertices += numVertices;
|
_numVertices += numVertices;
|
||||||
return vertices;
|
return vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonBatch::deallocateVertices(uint32_t numVertices) {
|
void SkeletonBatch::deallocateVertices(uint32_t numVertices) {
|
||||||
_numVertices -= numVertices;
|
_numVertices -= numVertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned short* SkeletonBatch::allocateIndices(uint32_t numIndices) {
|
unsigned short* SkeletonBatch::allocateIndices(uint32_t numIndices) {
|
||||||
if (_indices.getCapacity() - _indices.size() < numIndices) {
|
if (_indices.getCapacity() - _indices.size() < numIndices) {
|
||||||
unsigned short* oldData = _indices.buffer();
|
unsigned short* oldData = _indices.buffer();
|
||||||
int oldSize = _indices.size();
|
int oldSize = _indices.size();
|
||||||
|
@ -133,7 +137,7 @@ unsigned short* SkeletonBatch::allocateIndices(uint32_t numIndices) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short* indices = _indices.buffer() + _indices.size();
|
unsigned short* indices = _indices.buffer() + _indices.size();
|
||||||
_indices.setSize(_indices.size() + numIndices, 0);
|
_indices.setSize(_indices.size() + numIndices, 0);
|
||||||
return indices;
|
return indices;
|
||||||
|
@ -143,11 +147,10 @@ void SkeletonBatch::deallocateIndices(uint32_t numIndices) {
|
||||||
_indices.setSize(_indices.size() - numIndices, 0);
|
_indices.setSize(_indices.size() - numIndices, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cocos2d::TrianglesCommand* SkeletonBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) {
|
cocos2d::TrianglesCommand* SkeletonBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) {
|
||||||
TrianglesCommand* command = nextFreeCommand();
|
TrianglesCommand* command = nextFreeCommand();
|
||||||
const cocos2d::Mat4& projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
const cocos2d::Mat4& projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||||
auto &pipelineDescriptor = command->getPipelineDescriptor();
|
|
||||||
|
|
||||||
auto programState = command->getPipelineDescriptor().programState;
|
auto programState = command->getPipelineDescriptor().programState;
|
||||||
CCASSERT(programState, "programState should not be null");
|
CCASSERT(programState, "programState should not be null");
|
||||||
|
@ -167,13 +170,13 @@ void SkeletonBatch::reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
cocos2d::TrianglesCommand* SkeletonBatch::nextFreeCommand() {
|
cocos2d::TrianglesCommand* SkeletonBatch::nextFreeCommand() {
|
||||||
if (_commandsPool.size() <= _nextFreeCommand) {
|
if (_commandsPool.size() <= _nextFreeCommand) {
|
||||||
unsigned int newSize = _commandsPool.size() * 2 + 1;
|
unsigned int newSize = _commandsPool.size() * 2 + 1;
|
||||||
for (int i = _commandsPool.size(); i < newSize; i++) {
|
for (int i = _commandsPool.size(); i < newSize; i++) {
|
||||||
_commandsPool.push_back(createNewTrianglesCommand());
|
_commandsPool.push_back(createNewTrianglesCommand());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto *command = _commandsPool[_nextFreeCommand++];
|
auto* command = _commandsPool[_nextFreeCommand++];
|
||||||
auto& pipelineDescriptor = command->getPipelineDescriptor();
|
auto& pipelineDescriptor = command->getPipelineDescriptor();
|
||||||
if (pipelineDescriptor.programState == nullptr)
|
if (pipelineDescriptor.programState == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -188,3 +191,5 @@ cocos2d::TrianglesCommand *SkeletonBatch::createNewTrianglesCommand() {
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,8 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes License Agreement
|
* Spine Runtimes License Agreement
|
||||||
* Last updated May 1, 2019. Replaces all prior versions.
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||||
*
|
*
|
||||||
* Integration of the Spine Runtimes into software or otherwise creating
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
@ -15,23 +15,25 @@
|
||||||
* Spine Editor license and redistribution of the Products in any form must
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
* include this license and copyright notice.
|
* include this license and copyright notice.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifndef SPINE_SKELETONBATCH_H_
|
#ifndef SPINE_SKELETONBATCH_H_
|
||||||
#define SPINE_SKELETONBATCH_H_
|
#define SPINE_SKELETONBATCH_H_
|
||||||
#define SPINE_SHORT_NAMES
|
|
||||||
#include <spine/spine.h>
|
|
||||||
#include "cocos2d.h"
|
#include "cocos2d.h"
|
||||||
|
#if COCOS2D_VERSION >= 0x00040000
|
||||||
|
|
||||||
|
#include <spine/spine.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
@ -77,4 +79,6 @@ namespace spine {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // SPINE_SKELETONBATCH_H_
|
#endif // SPINE_SKELETONBATCH_H_
|
|
@ -1,8 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes License Agreement
|
* Spine Runtimes License Agreement
|
||||||
* Last updated May 1, 2019. Replaces all prior versions.
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||||
*
|
*
|
||||||
* Integration of the Spine Runtimes into software or otherwise creating
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
@ -15,18 +15,21 @@
|
||||||
* Spine Editor license and redistribution of the Products in any form must
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
* include this license and copyright notice.
|
* include this license and copyright notice.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#include <spine/SkeletonTwoColorBatch.h>
|
|
||||||
|
#include <spine/spine-cocos2dx.h>
|
||||||
|
#if COCOS2D_VERSION >= 0x00040000
|
||||||
|
|
||||||
#include <spine/Extension.h>
|
#include <spine/Extension.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stddef.h> // offsetof
|
#include <stddef.h> // offsetof
|
||||||
|
@ -103,7 +106,7 @@ namespace {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto program = backend::Device::getInstance()->newProgram(TWO_COLOR_TINT_VERTEX_SHADER, TWO_COLOR_TINT_FRAGMENT_SHADER);
|
auto program = backend::Device::getInstance()->newProgram(TWO_COLOR_TINT_VERTEX_SHADER, TWO_COLOR_TINT_FRAGMENT_SHADER);
|
||||||
auto *programState = new backend::ProgramState(program);
|
auto* programState = new backend::ProgramState(program);
|
||||||
program->autorelease();
|
program->autorelease();
|
||||||
|
|
||||||
__locPMatrix = programState->getUniformLocation("u_PMatrix");
|
__locPMatrix = programState->getUniformLocation("u_PMatrix");
|
||||||
|
@ -111,10 +114,15 @@ namespace {
|
||||||
|
|
||||||
auto layout = programState->getVertexLayout();
|
auto layout = programState->getVertexLayout();
|
||||||
|
|
||||||
layout->setAttribute("a_position", 0, backend::VertexFormat::FLOAT3, offsetof(spine::V3F_C4B_C4B_T2F, position), false);
|
auto locPosition = programState->getAttributeLocation("a_position");
|
||||||
layout->setAttribute("a_color", 1, backend::VertexFormat::UBYTE4, offsetof(spine::V3F_C4B_C4B_T2F, color), true);
|
auto locTexcoord = programState->getAttributeLocation("a_texCoords");
|
||||||
layout->setAttribute("a_color2", 2, backend::VertexFormat::UBYTE4, offsetof(spine::V3F_C4B_C4B_T2F, color2), true);
|
auto locColor = programState->getAttributeLocation("a_color");
|
||||||
layout->setAttribute("a_texCoords", 3, backend::VertexFormat::FLOAT2, offsetof(spine::V3F_C4B_C4B_T2F, texCoords), false);
|
auto locColor2 = programState->getAttributeLocation("a_color2");
|
||||||
|
|
||||||
|
layout->setAttribute("a_position", locPosition, backend::VertexFormat::FLOAT3, offsetof(spine::V3F_C4B_C4B_T2F, position), false);
|
||||||
|
layout->setAttribute("a_color", locColor, backend::VertexFormat::UBYTE4, offsetof(spine::V3F_C4B_C4B_T2F, color), true);
|
||||||
|
layout->setAttribute("a_color2", locColor2, backend::VertexFormat::UBYTE4, offsetof(spine::V3F_C4B_C4B_T2F, color2), true);
|
||||||
|
layout->setAttribute("a_texCoords", locTexcoord, backend::VertexFormat::FLOAT2, offsetof(spine::V3F_C4B_C4B_T2F, texCoords), false);
|
||||||
layout->setLayout(sizeof(spine::V3F_C4B_C4B_T2F));
|
layout->setLayout(sizeof(spine::V3F_C4B_C4B_T2F));
|
||||||
|
|
||||||
__twoColorProgramState = std::shared_ptr<backend::ProgramState>(programState);
|
__twoColorProgramState = std::shared_ptr<backend::ProgramState>(programState);
|
||||||
|
@ -124,7 +132,7 @@ namespace {
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
TwoColorTrianglesCommand::TwoColorTrianglesCommand() :_materialID(0), _texture(nullptr), _blendType(BlendFunc::DISABLE), _alphaTextureID(0) {
|
TwoColorTrianglesCommand::TwoColorTrianglesCommand() :_materialID(0), _texture(nullptr), _blendType(BlendFunc::DISABLE) {
|
||||||
_type = RenderCommand::Type::CUSTOM_COMMAND;
|
_type = RenderCommand::Type::CUSTOM_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +140,7 @@ void TwoColorTrianglesCommand::init(float globalOrder, cocos2d::Texture2D *textu
|
||||||
|
|
||||||
updateCommandPipelineDescriptor();
|
updateCommandPipelineDescriptor();
|
||||||
const cocos2d::Mat4& projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
const cocos2d::Mat4& projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||||
|
|
||||||
auto finalMatrix = projectionMat * mv;
|
auto finalMatrix = projectionMat * mv;
|
||||||
|
|
||||||
_programState->setUniform(_locPMatrix, finalMatrix.m, sizeof(finalMatrix.m));
|
_programState->setUniform(_locPMatrix, finalMatrix.m, sizeof(finalMatrix.m));
|
||||||
|
@ -151,11 +159,11 @@ void TwoColorTrianglesCommand::init(float globalOrder, cocos2d::Texture2D *textu
|
||||||
_mv = mv;
|
_mv = mv;
|
||||||
|
|
||||||
if (_blendType.src != blendType.src || _blendType.dst != blendType.dst ||
|
if (_blendType.src != blendType.src || _blendType.dst != blendType.dst ||
|
||||||
_texture != texture->getBackendTexture() || _pipelineDescriptor.programState != _programState)
|
_texture != texture->getBackendTexture() || _pipelineDescriptor.programState != _programState)
|
||||||
{
|
{
|
||||||
_texture = texture->getBackendTexture();
|
_texture = texture->getBackendTexture();
|
||||||
_blendType = blendType;
|
_blendType = blendType;
|
||||||
|
|
||||||
_prog = _programState->getProgram();
|
_prog = _programState->getProgram();
|
||||||
|
|
||||||
auto& blendDescriptor = _pipelineDescriptor.blendDescriptor;
|
auto& blendDescriptor = _pipelineDescriptor.blendDescriptor;
|
||||||
|
@ -177,13 +185,13 @@ void TwoColorTrianglesCommand::updateCommandPipelineDescriptor()
|
||||||
}
|
}
|
||||||
|
|
||||||
CC_SAFE_RELEASE_NULL(_programState);
|
CC_SAFE_RELEASE_NULL(_programState);
|
||||||
_programState = __twoColorProgramState->clone();
|
_programState = __twoColorProgramState->clone();
|
||||||
_locPMatrix = __locPMatrix;
|
_locPMatrix = __locPMatrix;
|
||||||
_locTexture = __locTexture;
|
_locTexture = __locTexture;
|
||||||
_pipelineDescriptor.programState = _programState;
|
_pipelineDescriptor.programState = _programState;
|
||||||
}
|
}
|
||||||
|
|
||||||
TwoColorTrianglesCommand::~TwoColorTrianglesCommand()
|
TwoColorTrianglesCommand::~TwoColorTrianglesCommand()
|
||||||
{
|
{
|
||||||
CC_SAFE_RELEASE_NULL(_programState);
|
CC_SAFE_RELEASE_NULL(_programState);
|
||||||
}
|
}
|
||||||
|
@ -223,7 +231,7 @@ void TwoColorTrianglesCommand::updateVertexAndIndexBuffer(Renderer *r, V3F_C4B_C
|
||||||
createVertexBuffer(sizeof(V3F_C4B_C4B_T2F), verticesSize, CustomCommand::BufferUsage::DYNAMIC);
|
createVertexBuffer(sizeof(V3F_C4B_C4B_T2F), verticesSize, CustomCommand::BufferUsage::DYNAMIC);
|
||||||
if(indicesSize != _indexCapacity)
|
if(indicesSize != _indexCapacity)
|
||||||
createIndexBuffer(CustomCommand::IndexFormat::U_SHORT, indicesSize, CustomCommand::BufferUsage::DYNAMIC);
|
createIndexBuffer(CustomCommand::IndexFormat::U_SHORT, indicesSize, CustomCommand::BufferUsage::DYNAMIC);
|
||||||
|
|
||||||
updateVertexBuffer(vertices, sizeof(V3F_C4B_C4B_T2F) * verticesSize);
|
updateVertexBuffer(vertices, sizeof(V3F_C4B_C4B_T2F) * verticesSize);
|
||||||
updateIndexBuffer(indices, sizeof(uint16_t) * indicesSize);
|
updateIndexBuffer(indices, sizeof(uint16_t) * indicesSize);
|
||||||
}
|
}
|
||||||
|
@ -248,20 +256,20 @@ SkeletonTwoColorBatch::SkeletonTwoColorBatch () : _vertexBuffer(0), _indexBuffer
|
||||||
for (unsigned int i = 0; i < INITIAL_SIZE; i++) {
|
for (unsigned int i = 0; i < INITIAL_SIZE; i++) {
|
||||||
_commandsPool.push_back(new TwoColorTrianglesCommand());
|
_commandsPool.push_back(new TwoColorTrianglesCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
reset ();
|
reset ();
|
||||||
|
|
||||||
// callback after drawing is finished so we can clear out the batch state
|
// callback after drawing is finished so we can clear out the batch state
|
||||||
// for the next frame
|
// for the next frame
|
||||||
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom){
|
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom){
|
||||||
this->update(0);
|
this->update(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SkeletonTwoColorBatch::~SkeletonTwoColorBatch () {
|
SkeletonTwoColorBatch::~SkeletonTwoColorBatch () {
|
||||||
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
||||||
delete _commandsPool[i];
|
delete _commandsPool[i];
|
||||||
_commandsPool[i] = nullptr;
|
_commandsPool[i] = nullptr;
|
||||||
|
@ -271,7 +279,7 @@ SkeletonTwoColorBatch::~SkeletonTwoColorBatch () {
|
||||||
delete[] _indexBuffer;
|
delete[] _indexBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonTwoColorBatch::update (float delta) {
|
void SkeletonTwoColorBatch::update (float delta) {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,13 +294,13 @@ V3F_C4B_C4B_T2F* SkeletonTwoColorBatch::allocateVertices(uint32_t numVertices) {
|
||||||
triangles.verts = newData + (triangles.verts - oldData);
|
triangles.verts = newData + (triangles.verts - oldData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
V3F_C4B_C4B_T2F* vertices = _vertices.data() + _numVertices;
|
V3F_C4B_C4B_T2F* vertices = _vertices.data() + _numVertices;
|
||||||
_numVertices += numVertices;
|
_numVertices += numVertices;
|
||||||
return vertices;
|
return vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SkeletonTwoColorBatch::deallocateVertices(uint32_t numVertices) {
|
void SkeletonTwoColorBatch::deallocateVertices(uint32_t numVertices) {
|
||||||
_numVertices -= numVertices;
|
_numVertices -= numVertices;
|
||||||
}
|
}
|
||||||
|
@ -312,7 +320,7 @@ unsigned short* SkeletonTwoColorBatch::allocateIndices(uint32_t numIndices) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short* indices = _indices.buffer() + _indices.size();
|
unsigned short* indices = _indices.buffer() + _indices.size();
|
||||||
_indices.setSize(_indices.size() + numIndices, 0);
|
_indices.setSize(_indices.size() + numIndices, 0);
|
||||||
return indices;
|
return indices;
|
||||||
|
@ -326,45 +334,45 @@ TwoColorTrianglesCommand* SkeletonTwoColorBatch::addCommand(cocos2d::Renderer* r
|
||||||
TwoColorTrianglesCommand* command = nextFreeCommand();
|
TwoColorTrianglesCommand* command = nextFreeCommand();
|
||||||
command->init(globalOrder, texture, blendType, triangles, mv, flags);
|
command->init(globalOrder, texture, blendType, triangles, mv, flags);
|
||||||
command->updateVertexAndIndexBuffer(renderer, triangles.verts, triangles.vertCount, triangles.indices, triangles.indexCount);
|
command->updateVertexAndIndexBuffer(renderer, triangles.verts, triangles.vertCount, triangles.indices, triangles.indexCount);
|
||||||
renderer->addCommand(command);
|
renderer->addCommand(command);
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonTwoColorBatch::batch (cocos2d::Renderer *renderer, TwoColorTrianglesCommand* command) {
|
void SkeletonTwoColorBatch::batch (cocos2d::Renderer *renderer, TwoColorTrianglesCommand* command) {
|
||||||
if (_numVerticesBuffer + command->getTriangles().vertCount >= MAX_VERTICES || _numIndicesBuffer + command->getTriangles().indexCount >= MAX_INDICES) {
|
if (_numVerticesBuffer + command->getTriangles().vertCount >= MAX_VERTICES || _numIndicesBuffer + command->getTriangles().indexCount >= MAX_INDICES) {
|
||||||
flush(renderer, _lastCommand);
|
flush(renderer, _lastCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t materialID = command->getMaterialID();
|
uint32_t materialID = command->getMaterialID();
|
||||||
if (_lastCommand && _lastCommand->getMaterialID() != materialID) {
|
if (_lastCommand && _lastCommand->getMaterialID() != materialID) {
|
||||||
flush(renderer, _lastCommand);
|
flush(renderer, _lastCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(_vertexBuffer + _numVerticesBuffer, command->getTriangles().verts, sizeof(V3F_C4B_C4B_T2F) * command->getTriangles().vertCount);
|
memcpy(_vertexBuffer + _numVerticesBuffer, command->getTriangles().verts, sizeof(V3F_C4B_C4B_T2F) * command->getTriangles().vertCount);
|
||||||
const Mat4& modelView = command->getModelView();
|
const Mat4& modelView = command->getModelView();
|
||||||
for (int i = _numVerticesBuffer; i < _numVerticesBuffer + command->getTriangles().vertCount; i++) {
|
for (int i = _numVerticesBuffer; i < _numVerticesBuffer + command->getTriangles().vertCount; i++) {
|
||||||
modelView.transformPoint(&_vertexBuffer[i].position);
|
modelView.transformPoint(&_vertexBuffer[i].position);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short vertexOffset = (unsigned short)_numVerticesBuffer;
|
unsigned short vertexOffset = (unsigned short)_numVerticesBuffer;
|
||||||
unsigned short* indices = command->getTriangles().indices;
|
unsigned short* indices = command->getTriangles().indices;
|
||||||
for (int i = 0, j = _numIndicesBuffer; i < command->getTriangles().indexCount; i++, j++) {
|
for (int i = 0, j = _numIndicesBuffer; i < command->getTriangles().indexCount; i++, j++) {
|
||||||
_indexBuffer[j] = indices[i] + vertexOffset;
|
_indexBuffer[j] = indices[i] + vertexOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
_numVerticesBuffer += command->getTriangles().vertCount;
|
_numVerticesBuffer += command->getTriangles().vertCount;
|
||||||
_numIndicesBuffer += command->getTriangles().indexCount;
|
_numIndicesBuffer += command->getTriangles().indexCount;
|
||||||
|
|
||||||
if (command->isForceFlush()) {
|
if (command->isForceFlush()) {
|
||||||
flush(renderer, command);
|
flush(renderer, command);
|
||||||
}
|
}
|
||||||
_lastCommand = command;
|
_lastCommand = command;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonTwoColorBatch::flush (cocos2d::Renderer *renderer, TwoColorTrianglesCommand* materialCommand) {
|
void SkeletonTwoColorBatch::flush (cocos2d::Renderer *renderer, TwoColorTrianglesCommand* materialCommand) {
|
||||||
if (!materialCommand)
|
if (!materialCommand)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
materialCommand->updateVertexAndIndexBuffer(renderer, _vertexBuffer, _numVerticesBuffer, _indexBuffer, _numIndicesBuffer);
|
materialCommand->updateVertexAndIndexBuffer(renderer, _vertexBuffer, _numVerticesBuffer, _indexBuffer, _numIndicesBuffer);
|
||||||
|
|
||||||
renderer->addCommand(materialCommand);
|
renderer->addCommand(materialCommand);
|
||||||
|
@ -396,3 +404,5 @@ TwoColorTrianglesCommand* SkeletonTwoColorBatch::nextFreeCommand() {
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,8 +1,8 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Spine Runtimes License Agreement
|
* Spine Runtimes License Agreement
|
||||||
* Last updated May 1, 2019. Replaces all prior versions.
|
* Last updated January 1, 2020. Replaces all prior versions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||||
*
|
*
|
||||||
* Integration of the Spine Runtimes into software or otherwise creating
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
@ -15,23 +15,25 @@
|
||||||
* Spine Editor license and redistribution of the Products in any form must
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
* include this license and copyright notice.
|
* include this license and copyright notice.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifndef SPINE_SKELETONTWOCOLORBATCH_H_
|
#ifndef SPINE_SKELETONTWOCOLORBATCH_H_
|
||||||
#define SPINE_SKELETONTWOCOLORBATCH_H_
|
#define SPINE_SKELETONTWOCOLORBATCH_H_
|
||||||
#define SPINE_SHORT_NAMES
|
|
||||||
#include <spine/spine.h>
|
|
||||||
#include "cocos2d.h"
|
#include "cocos2d.h"
|
||||||
|
#if COCOS2D_VERSION >= 0x00040000
|
||||||
|
|
||||||
|
#include <spine/spine.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
@ -99,7 +101,6 @@ namespace spine {
|
||||||
cocos2d::BlendFunc _blendType;
|
cocos2d::BlendFunc _blendType;
|
||||||
TwoColorTriangles _triangles;
|
TwoColorTriangles _triangles;
|
||||||
cocos2d::Mat4 _mv;
|
cocos2d::Mat4 _mv;
|
||||||
GLuint _alphaTextureID;
|
|
||||||
bool _forceFlush;
|
bool _forceFlush;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -146,7 +147,6 @@ namespace spine {
|
||||||
|
|
||||||
|
|
||||||
// VBO handles & attribute locations
|
// VBO handles & attribute locations
|
||||||
GLuint _vertexBufferHandle;
|
|
||||||
V3F_C4B_C4B_T2F* _vertexBuffer;
|
V3F_C4B_C4B_T2F* _vertexBuffer;
|
||||||
uint32_t _numVerticesBuffer;
|
uint32_t _numVerticesBuffer;
|
||||||
uint32_t _numIndicesBuffer;
|
uint32_t _numIndicesBuffer;
|
||||||
|
@ -160,4 +160,6 @@ namespace spine {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // SPINE_SKELETONTWOCOLORBATCH_H_
|
#endif // SPINE_SKELETONTWOCOLORBATCH_H_
|
|
@ -43,12 +43,12 @@ namespace cocos2d { namespace network {
|
||||||
|
|
||||||
DownloadTask::DownloadTask(const std::string& srcUrl,
|
DownloadTask::DownloadTask(const std::string& srcUrl,
|
||||||
const std::string& storagePath,
|
const std::string& storagePath,
|
||||||
const std::string& md5checksum,
|
const std::string& checksum,
|
||||||
const std::string& identifier)
|
const std::string& identifier)
|
||||||
{
|
{
|
||||||
this->requestURL = srcUrl;
|
this->requestURL = srcUrl;
|
||||||
this->storagePath = storagePath;
|
this->storagePath = storagePath;
|
||||||
this->md5checksum = md5checksum;
|
this->checksum = checksum;
|
||||||
this->identifier = identifier;
|
this->identifier = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,14 @@ int register_all_cocos2dx_spine(lua_State* tolua_S);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,7 @@ LuaSkeletonAnimation::~LuaSkeletonAnimation()
|
||||||
LuaSkeletonAnimation* LuaSkeletonAnimation::createWithFile (const char* skeletonDataFile, const char* atlasFile, float scale)
|
LuaSkeletonAnimation* LuaSkeletonAnimation::createWithFile (const char* skeletonDataFile, const char* atlasFile, float scale)
|
||||||
{
|
{
|
||||||
LuaSkeletonAnimation* node = new (std::nothrow) LuaSkeletonAnimation();
|
LuaSkeletonAnimation* node = new (std::nothrow) LuaSkeletonAnimation();
|
||||||
static spine::Cocos2dTextureLoader s_loader;
|
spine::Atlas* atlas = new spine::Atlas(atlasFile, nullptr);
|
||||||
spine::Atlas* atlas = new spine::Atlas(atlasFile, &s_loader);
|
|
||||||
node->initWithJsonFile(skeletonDataFile, atlas, scale);
|
node->initWithJsonFile(skeletonDataFile, atlas, scale);
|
||||||
node->autorelease();
|
node->autorelease();
|
||||||
return node;
|
return node;
|
||||||
|
|
|
@ -153,8 +153,8 @@ list(APPEND GAME_HEADER
|
||||||
Classes/SceneTest/SceneTest.h
|
Classes/SceneTest/SceneTest.h
|
||||||
Classes/ReleasePoolTest/ReleasePoolTest.h
|
Classes/ReleasePoolTest/ReleasePoolTest.h
|
||||||
Classes/InputTest/MouseTest.h
|
Classes/InputTest/MouseTest.h
|
||||||
# Classes/SpineTest/SpineTest.h
|
Classes/SpineTest/SpineTest.h
|
||||||
# Classes/Scene3DTest/Scene3DTest.h
|
# Classes/Scene3DTest/Scene3DTest.h
|
||||||
Classes/ParticleTest/ParticleTest.h
|
Classes/ParticleTest/ParticleTest.h
|
||||||
Classes/EffectsTest/EffectsTest.h
|
Classes/EffectsTest/EffectsTest.h
|
||||||
Classes/UITest/UITest.h
|
Classes/UITest/UITest.h
|
||||||
|
@ -278,8 +278,8 @@ list(APPEND GAME_SOURCE
|
||||||
Classes/SchedulerTest/SchedulerTest.cpp
|
Classes/SchedulerTest/SchedulerTest.cpp
|
||||||
Classes/ShaderTest/ShaderTest.cpp
|
Classes/ShaderTest/ShaderTest.cpp
|
||||||
Classes/ShaderTest/ShaderTest2.cpp
|
Classes/ShaderTest/ShaderTest2.cpp
|
||||||
#Classes/SpineTest/SpineTest.cpp
|
Classes/SpineTest/SpineTest.cpp
|
||||||
# Classes/Scene3DTest/Scene3DTest.cpp
|
# Classes/Scene3DTest/Scene3DTest.cpp
|
||||||
Classes/Sprite3DTest/DrawNode3D.cpp
|
Classes/Sprite3DTest/DrawNode3D.cpp
|
||||||
Classes/Sprite3DTest/Sprite3DTest.cpp
|
Classes/Sprite3DTest/Sprite3DTest.cpp
|
||||||
Classes/SpritePolygonTest/SpritePolygonTest.cpp
|
Classes/SpritePolygonTest/SpritePolygonTest.cpp
|
||||||
|
|
|
@ -33,204 +33,452 @@ using namespace cocos2d;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace spine;
|
using namespace spine;
|
||||||
|
|
||||||
|
|
||||||
|
#define NUM_SKELETONS 50
|
||||||
|
#define SPINE_NODE_SCALE_FACTOR 0.4
|
||||||
|
|
||||||
|
static Cocos2dTextureLoader textureLoader;
|
||||||
|
|
||||||
|
PowInterpolation pow2(2);
|
||||||
|
PowOutInterpolation powOut2(2);
|
||||||
|
SwirlVertexEffect effect(400, powOut2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define SCALE_SKELETON_NODE(node) do { if(node) node->setScale(SPINE_NODE_SCALE_FACTOR); } while(false)
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// SpineTestScene
|
// SpineTestScene
|
||||||
//
|
//
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
SpineTests::SpineTests()
|
SpineTests::SpineTests()
|
||||||
{
|
{
|
||||||
|
auto fu = FileUtils::getInstance();
|
||||||
|
_searchPaths = fu->getSearchPaths();
|
||||||
|
fu->addSearchPath("spine", true);
|
||||||
|
|
||||||
ADD_TEST_CASE(BatchingExample);
|
ADD_TEST_CASE(BatchingExample);
|
||||||
ADD_TEST_CASE(CoinExample);
|
ADD_TEST_CASE(CoinExample);
|
||||||
ADD_TEST_CASE(GoblinsExample);
|
ADD_TEST_CASE(GoblinsExample);
|
||||||
|
ADD_TEST_CASE(IKExample);
|
||||||
|
ADD_TEST_CASE(MixAndMatchExample);
|
||||||
ADD_TEST_CASE(RaptorExample);
|
ADD_TEST_CASE(RaptorExample);
|
||||||
|
ADD_TEST_CASE(SkeletonRendererSeparatorExample);
|
||||||
ADD_TEST_CASE(SpineboyExample);
|
ADD_TEST_CASE(SpineboyExample);
|
||||||
ADD_TEST_CASE(TankExample);
|
ADD_TEST_CASE(TankExample);
|
||||||
|
|
||||||
|
#ifdef COCOS2D_DEBUG
|
||||||
|
debugExtension = new DebugExtension(SpineExtension::getInstance());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SpineTests::~SpineTests()
|
||||||
|
{
|
||||||
|
FileUtils::getInstance()->setSearchPaths(_searchPaths);
|
||||||
|
SkeletonBatch::destroyInstance();
|
||||||
|
SkeletonTwoColorBatch::destroyInstance();
|
||||||
|
#ifdef COCOS2D_DEBUG
|
||||||
|
debugExtension->reportLeaks();
|
||||||
|
delete debugExtension;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SpineTestLayer::SpineTestLayer()
|
SpineTestLayer::SpineTestLayer()
|
||||||
: _title("")
|
: _title("")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
SpineTestLayer::~SpineTestLayer()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
std::string SpineTestLayer::title() const
|
std::string SpineTestLayer::title() const
|
||||||
{
|
{
|
||||||
return _title;
|
return _title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SpineTestLayer::init()
|
||||||
|
{
|
||||||
|
if (!TestCase::init()) return false;
|
||||||
|
|
||||||
|
EventListenerTouchOneByOne* listener = EventListenerTouchOneByOne::create();
|
||||||
|
listener->onTouchBegan = [this](Touch* touch, cocos2d::Event* event) -> bool {
|
||||||
|
if (!skeletonNode) return true;
|
||||||
|
_touchIndex = (_touchIndex + 1) % 3;
|
||||||
|
if (_touchIndex == 0)
|
||||||
|
{
|
||||||
|
skeletonNode->setDebugBonesEnabled(false);
|
||||||
|
skeletonNode->setTimeScale(1.0f);
|
||||||
|
}
|
||||||
|
else if (_touchIndex == 1)
|
||||||
|
{
|
||||||
|
skeletonNode->setDebugBonesEnabled(true);
|
||||||
|
skeletonNode->setTimeScale(1.0f);
|
||||||
|
}
|
||||||
|
else if (_touchIndex == 2)
|
||||||
|
{
|
||||||
|
skeletonNode->setDebugBonesEnabled(true);
|
||||||
|
skeletonNode->setTimeScale(0.3f);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
||||||
|
|
||||||
|
SCALE_SKELETON_NODE(skeletonNode);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// BatchingExample
|
// BatchingExample
|
||||||
bool BatchingExample::init () {
|
bool BatchingExample::init () {
|
||||||
if (!SpineTestLayer::init()) return false;
|
if (!SpineTestLayer::init()) return false;
|
||||||
|
|
||||||
_title = "BatchingExample";
|
_title = "Batching";
|
||||||
|
|
||||||
// Load the texture atlas.
|
_atlas = new (__FILE__, __LINE__) Atlas("spineboy.atlas", &textureLoader, true);
|
||||||
_atlas = spAtlas_createFromFile("spine/spineboy.atlas", 0);
|
|
||||||
CCASSERT(_atlas, "Error reading atlas file.");
|
CCASSERT(_atlas, "Error reading atlas file.");
|
||||||
|
|
||||||
// This attachment loader configures attachments with data needed for cocos2d-x rendering.
|
// This attachment loader configures attachments with data needed for cocos2d-x rendering.
|
||||||
// Do not dispose the attachment loader until the skeleton data is disposed!
|
// Do not dispose the attachment loader until the skeleton data is disposed!
|
||||||
_attachmentLoader = (spAttachmentLoader*)Cocos2dAttachmentLoader_create(_atlas);
|
_attachmentLoader = new (__FILE__, __LINE__) Cocos2dAtlasAttachmentLoader(_atlas);
|
||||||
|
|
||||||
// Load the skeleton data.
|
// Load the skeleton data.
|
||||||
spSkeletonJson* json = spSkeletonJson_createWithLoader(_attachmentLoader);
|
SkeletonJson* json = new (__FILE__, __LINE__) SkeletonJson(_attachmentLoader);
|
||||||
json->scale = 0.6f; // Resizes skeleton data to 60% of the size it was in Spine.
|
json->setScale(0.6f); // Resizes skeleton data to 60% of the size it was in Spine.
|
||||||
_skeletonData = spSkeletonJson_readSkeletonDataFile(json, "spine/spineboy-ess.json");
|
_skeletonData = json->readSkeletonDataFile("spineboy-pro.json");
|
||||||
CCASSERT(_skeletonData, json->error ? json->error : "Error reading skeleton data file.");
|
CCASSERT(_skeletonData, json->getError().isEmpty() ? json->getError().buffer() : "Error reading skeleton data file.");
|
||||||
spSkeletonJson_dispose(json);
|
delete json;
|
||||||
|
|
||||||
// Setup mix times.
|
// Setup mix times.
|
||||||
_stateData = spAnimationStateData_create(_skeletonData);
|
_stateData = new (__FILE__, __LINE__) AnimationStateData(_skeletonData);
|
||||||
spAnimationStateData_setMixByName(_stateData, "walk", "jump", 0.2f);
|
_stateData->setMix("walk", "jump", 0.2f);
|
||||||
spAnimationStateData_setMixByName(_stateData, "jump", "run", 0.2f);
|
_stateData->setMix("jump", "run", 0.2f);
|
||||||
|
|
||||||
int xMin = _contentSize.width * 0.10f, xMax = _contentSize.width * 0.90f;
|
int xMin = _contentSize.width * 0.10f, xMax = _contentSize.width * 0.90f;
|
||||||
int yMin = 0, yMax = _contentSize.height * 0.7f;
|
int yMin = 0, yMax = _contentSize.height * 0.7f;
|
||||||
for (int i = 0; i < 50; i++) {
|
for (int i = 0; i < NUM_SKELETONS; i++) {
|
||||||
// Each skeleton node shares the same atlas, skeleton data, and mix times.
|
// Each skeleton node shares the same atlas, skeleton data, and mix times.
|
||||||
SkeletonAnimation* skeletonNode = SkeletonAnimation::createWithData(_skeletonData, false);
|
SkeletonAnimation* skeletonNode = SkeletonAnimation::createWithData(_skeletonData, false);
|
||||||
skeletonNode->setAnimationStateData(_stateData);
|
skeletonNode->setAnimationStateData(_stateData);
|
||||||
|
|
||||||
skeletonNode->setAnimation(0, "walk", true);
|
skeletonNode->setAnimation(0, "walk", true);
|
||||||
skeletonNode->addAnimation(0, "jump", false, 3);
|
skeletonNode->addAnimation(0, "jump", true, RandomHelper::random_int(0, 300) / 100.0f);
|
||||||
skeletonNode->addAnimation(0, "run", true);
|
skeletonNode->addAnimation(0, "run", true);
|
||||||
|
|
||||||
|
// alternative setting two color tint for groups of 10 skeletons
|
||||||
|
// should end up with #skeletons / 10 batches
|
||||||
|
// if (j++ < 10)
|
||||||
|
// skeletonNode->setTwoColorTint(true);
|
||||||
|
// if (j == 20) j = 0;
|
||||||
|
// skeletonNode->setTwoColorTint(true);
|
||||||
|
|
||||||
skeletonNode->setPosition(Vec2(
|
skeletonNode->setPosition(Vec2(
|
||||||
RandomHelper::random_int(xMin, xMax),
|
RandomHelper::random_int(xMin, xMax),
|
||||||
RandomHelper::random_int(yMin, yMax)
|
RandomHelper::random_int(yMin, yMax)
|
||||||
));
|
));
|
||||||
skeletonNode->setScale(0.8);
|
|
||||||
addChild(skeletonNode);
|
addChild(skeletonNode);
|
||||||
}
|
}
|
||||||
|
SCALE_SKELETON_NODE(skeletonNode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BatchingExample::~BatchingExample () {
|
|
||||||
|
BatchingExample::~BatchingExample() {
|
||||||
// SkeletonAnimation instances are cocos2d-x nodes and are disposed of automatically as normal, but the data created
|
// SkeletonAnimation instances are cocos2d-x nodes and are disposed of automatically as normal, but the data created
|
||||||
// manually to be shared across multiple SkeletonAnimations needs to be disposed of manually.
|
// manually to be shared across multiple SkeletonAnimations needs to be disposed of manually.
|
||||||
spSkeletonData_dispose(_skeletonData);
|
|
||||||
spAnimationStateData_dispose(_stateData);
|
delete _skeletonData;
|
||||||
spAttachmentLoader_dispose(_attachmentLoader);
|
delete _stateData;
|
||||||
spAtlas_dispose(_atlas);
|
delete _attachmentLoader;
|
||||||
|
delete _atlas;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CoinExample
|
|
||||||
|
|
||||||
bool CoinExample::init () {
|
bool CoinExample::init() {
|
||||||
|
|
||||||
if (!SpineTestLayer::init()) return false;
|
if (!SpineTestLayer::init()) return false;
|
||||||
|
|
||||||
_title = "CoinExample";
|
_title = "Coin";
|
||||||
|
|
||||||
skeletonNode = SkeletonAnimation::createWithJsonFile("spine/coin-pro.json", "spine/coin.atlas", 1.f);
|
|
||||||
skeletonNode->setAnimation(0, "rotate", true);
|
skeletonNode = SkeletonAnimation::createWithBinaryFile("coin-pro.skel", "coin.atlas", 1);
|
||||||
|
skeletonNode->setAnimation(0, "animation", true);
|
||||||
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 100));
|
|
||||||
|
skeletonNode->setPosition(Vec2(_contentSize.width / 2, _contentSize.height / 2));
|
||||||
addChild(skeletonNode);
|
addChild(skeletonNode);
|
||||||
|
|
||||||
|
scheduleUpdate();
|
||||||
|
SCALE_SKELETON_NODE(skeletonNode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GoblinsExample
|
|
||||||
|
|
||||||
bool GoblinsExample::init () {
|
|
||||||
|
bool GoblinsExample::init() {
|
||||||
if (!SpineTestLayer::init()) return false;
|
if (!SpineTestLayer::init()) return false;
|
||||||
|
|
||||||
_title = "GoblinsExample";
|
_title = "Goblins";
|
||||||
|
skeletonNode = SkeletonAnimation::createWithJsonFile("goblins-pro.json", "goblins.atlas", 1.5f);
|
||||||
skeletonNode = SkeletonAnimation::createWithJsonFile("spine/goblins-pro.json", "spine/goblins.atlas", 1.5f);
|
|
||||||
skeletonNode->setAnimation(0, "walk", true);
|
skeletonNode->setAnimation(0, "walk", true);
|
||||||
skeletonNode->setSkin("goblin");
|
skeletonNode->setSkin("goblin");
|
||||||
|
|
||||||
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
||||||
skeletonNode->setScale(0.6);
|
|
||||||
addChild(skeletonNode);
|
addChild(skeletonNode);
|
||||||
|
SCALE_SKELETON_NODE(skeletonNode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RaptorExample
|
|
||||||
|
|
||||||
bool RaptorExample::init () {
|
bool IKExample::init() {
|
||||||
if (!SpineTestLayer::init()) return false;
|
if (!SpineTestLayer::init()) return false;
|
||||||
|
|
||||||
_title = "RaptorExample";
|
_title = "IKExample";
|
||||||
skeletonNode = SkeletonAnimation::createWithJsonFile("spine/raptor-pro.json", "spine/raptor.atlas", 0.5f);
|
|
||||||
|
// Load the Spineboy skeleton and create a SkeletonAnimation node from it
|
||||||
skeletonNode->setAnimation(0, "walk", true);
|
// centered on the screen.
|
||||||
skeletonNode->setAnimation(1, "empty", false);
|
skeletonNode = SkeletonAnimation::createWithJsonFile("spineboy-pro.json", "spineboy.atlas", 0.6f);
|
||||||
skeletonNode->addAnimation(1, "gungrab", false, 2);
|
|
||||||
|
|
||||||
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
||||||
skeletonNode->setScale(0.6);
|
|
||||||
addChild(skeletonNode);
|
addChild(skeletonNode);
|
||||||
|
|
||||||
|
// Queue the "walk" animation on the first track.
|
||||||
|
skeletonNode->setAnimation(0, "walk", true);
|
||||||
|
|
||||||
|
// Queue the "aim" animation on a higher track.
|
||||||
|
// It consists of a single frame that positions
|
||||||
|
// the back arm and gun such that they point at
|
||||||
|
// the "crosshair" bone. By setting this
|
||||||
|
// animation on a higher track, it overrides
|
||||||
|
// any changes to the back arm and gun made
|
||||||
|
// by the walk animation, allowing us to
|
||||||
|
// mix the two. The mouse position following
|
||||||
|
// is performed in the lambda below.
|
||||||
|
skeletonNode->setAnimation(1, "aim", true);
|
||||||
|
|
||||||
|
// Next we setup a listener that receives and stores
|
||||||
|
// the current mouse location. The location is converted
|
||||||
|
// to the skeleton's coordinate system.
|
||||||
|
EventListenerMouse* mouseListener = EventListenerMouse::create();
|
||||||
|
mouseListener->onMouseMove = [this](cocos2d::Event* event) -> void {
|
||||||
|
// convert the mosue location to the skeleton's coordinate space
|
||||||
|
// and store it.
|
||||||
|
EventMouse* mouseEvent = dynamic_cast<EventMouse*>(event);
|
||||||
|
position = skeletonNode->convertToNodeSpace(mouseEvent->getLocationInView());
|
||||||
|
};
|
||||||
|
_eventDispatcher->addEventListenerWithSceneGraphPriority(mouseListener, this);
|
||||||
|
|
||||||
|
// Position the "crosshair" bone at the mouse
|
||||||
|
// location.
|
||||||
|
//
|
||||||
|
// When setting the crosshair bone position
|
||||||
|
// to the mouse position, we need to translate
|
||||||
|
// from "skeleton space" to "local bone space".
|
||||||
|
// Note that the local bone space is calculated
|
||||||
|
// using the bone's parent worldToLocal() function!
|
||||||
|
//
|
||||||
|
// After updating the bone position based on the
|
||||||
|
// converted mouse location, we call updateWorldTransforms()
|
||||||
|
// again so the change of the IK target position is
|
||||||
|
// applied to the rest of the skeleton.
|
||||||
|
skeletonNode->setPostUpdateWorldTransformsListener([this](SkeletonAnimation* node) -> void {
|
||||||
|
Bone* crosshair = node->findBone("crosshair"); // The bone should be cached
|
||||||
|
float localX = 0, localY = 0;
|
||||||
|
crosshair->getParent()->worldToLocal(position.x, position.y, localX, localY);
|
||||||
|
crosshair->setX(localX);
|
||||||
|
crosshair->setY(localY);
|
||||||
|
crosshair->setAppliedValid(false);
|
||||||
|
|
||||||
|
node->getSkeleton()->updateWorldTransform();
|
||||||
|
});
|
||||||
|
|
||||||
|
SCALE_SKELETON_NODE(skeletonNode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SpineboyExample
|
|
||||||
|
|
||||||
bool SpineboyExample::init () {
|
|
||||||
|
MixAndMatchExample::~MixAndMatchExample() {
|
||||||
|
delete skin;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MixAndMatchExample::init() {
|
||||||
if (!SpineTestLayer::init()) return false;
|
if (!SpineTestLayer::init()) return false;
|
||||||
|
|
||||||
_title = "SpineboyExample";
|
_title = "Mix and Match";
|
||||||
skeletonNode = SkeletonAnimation::createWithJsonFile("spine/spineboy-ess.json", "spine/spineboy.atlas", 0.6f);
|
|
||||||
skeletonNode->setStartListener( [] (spTrackEntry* entry) {
|
skeletonNode = SkeletonAnimation::createWithBinaryFile("mix-and-match-pro.skel", "mix-and-match.atlas", 0.5);
|
||||||
log("%d start: %s", entry->trackIndex, entry->animation->name);
|
skeletonNode->setAnimation(0, "dance", true);
|
||||||
});
|
|
||||||
skeletonNode->setInterruptListener( [] (spTrackEntry* entry) {
|
// Create a new skin, by mixing and matching other skins
|
||||||
log("%d interrupt", entry->trackIndex);
|
// that fit together. Items making up the girl are individual
|
||||||
});
|
// skins. Using the skin API, a new skin is created which is
|
||||||
skeletonNode->setEndListener( [] (spTrackEntry* entry) {
|
// a combination of all these individual item skins.
|
||||||
log("%d end", entry->trackIndex);
|
SkeletonData* skeletonData = skeletonNode->getSkeleton()->getData();
|
||||||
});
|
skin = new (__FILE__, __LINE__) Skin("mix-and-match");
|
||||||
skeletonNode->setCompleteListener( [] (spTrackEntry* entry) {
|
skin->addSkin(skeletonData->findSkin("skin-base"));
|
||||||
log("%d complete", entry->trackIndex);
|
skin->addSkin(skeletonData->findSkin("nose/short"));
|
||||||
});
|
skin->addSkin(skeletonData->findSkin("eyelids/girly"));
|
||||||
skeletonNode->setDisposeListener( [] (spTrackEntry* entry) {
|
skin->addSkin(skeletonData->findSkin("eyes/violet"));
|
||||||
log("%d dispose", entry->trackIndex);
|
skin->addSkin(skeletonData->findSkin("hair/brown"));
|
||||||
});
|
skin->addSkin(skeletonData->findSkin("clothes/hoodie-orange"));
|
||||||
skeletonNode->setEventListener( [] (spTrackEntry* entry, spEvent* event) {
|
skin->addSkin(skeletonData->findSkin("legs/pants-jeans"));
|
||||||
log("%d event: %s, %d, %f, %s", entry->trackIndex, event->data->name, event->intValue, event->floatValue, event->stringValue);
|
skin->addSkin(skeletonData->findSkin("accessories/bag"));
|
||||||
});
|
skin->addSkin(skeletonData->findSkin("accessories/hat-red-yellow"));
|
||||||
|
skeletonNode->getSkeleton()->setSkin(skin);
|
||||||
skeletonNode->setMix("walk", "jump", 0.4);
|
|
||||||
skeletonNode->setMix("jump", "run", 0.4);
|
skeletonNode->setPosition(Vec2(_contentSize.width / 2, _contentSize.height / 2 - 100 ));
|
||||||
skeletonNode->setAnimation(0, "walk", true);
|
|
||||||
spTrackEntry* jumpEntry = skeletonNode->addAnimation(0, "jump", false, 1);
|
|
||||||
skeletonNode->addAnimation(0, "run", true);
|
|
||||||
|
|
||||||
skeletonNode->setTrackStartListener(jumpEntry, [] (spTrackEntry* entry) {
|
|
||||||
log("jumped!");
|
|
||||||
});
|
|
||||||
|
|
||||||
// skeletonNode->addAnimation(1, "test", true);
|
|
||||||
// skeletonNode->runAction(RepeatForever::create(Sequence::create(FadeOut::create(1), FadeIn::create(1), DelayTime::create(5), NULL)));
|
|
||||||
|
|
||||||
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
|
||||||
skeletonNode->setScale(0.8);
|
|
||||||
addChild(skeletonNode);
|
addChild(skeletonNode);
|
||||||
|
|
||||||
|
SCALE_SKELETON_NODE(skeletonNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool RaptorExample::init() {
|
||||||
|
if (!SpineTestLayer::init()) return false;
|
||||||
|
|
||||||
|
_title = "Raptor";
|
||||||
|
skeletonNode = SkeletonAnimation::createWithJsonFile("raptor-pro.json", "raptor.atlas", 0.5f);
|
||||||
|
skeletonNode->setAnimation(0, "walk", true);
|
||||||
|
skeletonNode->addAnimation(1, "gun-grab", false, 2);
|
||||||
|
skeletonNode->setTwoColorTint(true);
|
||||||
|
|
||||||
|
effect.setCenterY(200);
|
||||||
|
swirlTime = 0;
|
||||||
|
|
||||||
|
skeletonNode->setVertexEffect(&effect);
|
||||||
|
|
||||||
|
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
||||||
|
addChild(skeletonNode);
|
||||||
|
|
||||||
scheduleUpdate();
|
scheduleUpdate();
|
||||||
|
|
||||||
|
SCALE_SKELETON_NODE(skeletonNode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpineboyExample::update (float deltaTime) {
|
void RaptorExample::update(float fDelta) {
|
||||||
|
swirlTime += fDelta;
|
||||||
|
float percent = spine::MathUtil::fmod(swirlTime, 2);
|
||||||
|
if (percent > 1) percent = 1 - (percent - 1);
|
||||||
|
effect.setAngle(pow2.interpolate(-60.0f, 60.0f, percent));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool SkeletonRendererSeparatorExample::init() {
|
||||||
|
if (!SpineTestLayer::init()) return false;
|
||||||
|
|
||||||
|
_title = "Seperator";
|
||||||
|
|
||||||
|
// Spineboy's back, which will manage the animation and GPU resources
|
||||||
|
// will render only the front slots of Spineboy
|
||||||
|
skeletonNode = SkeletonAnimation::createWithJsonFile("spineboy-pro.json", "spineboy.atlas", 0.6f);
|
||||||
|
skeletonNode->setMix("walk", "jump", 0.4);
|
||||||
|
skeletonNode->setAnimation(0, "walk", true);
|
||||||
|
skeletonNode->setSlotsRange(skeletonNode->findSlot("rear-upper-arm")->getData().getIndex(), skeletonNode->findSlot("rear-shin")->getData().getIndex());
|
||||||
|
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
||||||
|
|
||||||
|
// A simple rectangle to go between the front and back slots of Spineboy
|
||||||
|
betweenNode = DrawNode::create();
|
||||||
|
Vec2 rect[4];
|
||||||
|
rect[0] = Vec2(0, 0);
|
||||||
|
rect[1] = Vec2(40, 0);
|
||||||
|
rect[2] = Vec2(40, 200);
|
||||||
|
rect[3] = Vec2(0, 200);
|
||||||
|
betweenNode->drawPolygon(rect, 4, Color4F(1, 0, 0, 1), 1, Color4F(1, 0, 0, 1));
|
||||||
|
betweenNode->setPosition(Vec2(_contentSize.width / 2 + 30, 20));
|
||||||
|
// Spineboy's front, doesn't manage any skeleton, animation or GPU resources, but simply
|
||||||
|
// renders the back slots of Spineboy. The skeleton, animatio state and GPU resources
|
||||||
|
// are shared with the front node!
|
||||||
|
frontNode = SkeletonRenderer::createWithSkeleton(skeletonNode->getSkeleton());
|
||||||
|
frontNode->setSlotsRange(frontNode->findSlot("neck")->getData().getIndex(), -1);
|
||||||
|
frontNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
||||||
|
|
||||||
|
// Add the front, between and back node in the correct order to this scene
|
||||||
|
addChild(skeletonNode);
|
||||||
|
addChild(betweenNode);
|
||||||
|
addChild(frontNode);
|
||||||
|
|
||||||
|
scheduleUpdate();
|
||||||
|
|
||||||
|
SCALE_SKELETON_NODE(skeletonNode);
|
||||||
|
SCALE_SKELETON_NODE(frontNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonRendererSeparatorExample::update(float deltaTime) {
|
||||||
// Test releasing memory.
|
// Test releasing memory.
|
||||||
// Director::getInstance()->replaceScene(SpineboyExample::scene());
|
// Director::getInstance()->replaceScene(SpineboyExample::scene());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TankExample
|
|
||||||
|
|
||||||
bool TankExample::init () {
|
bool SpineboyExample::init() {
|
||||||
if (!SpineTestLayer::init()) return false;
|
if (!SpineTestLayer::init()) return false;
|
||||||
|
|
||||||
_title = "TankExample";
|
_title = "Spineboy";
|
||||||
skeletonNode = SkeletonAnimation::createWithJsonFile("spine/tank-pro.json", "spine/tank.atlas", 0.5f);
|
|
||||||
skeletonNode->setAnimation(0, "drive", true);
|
skeletonNode = SkeletonAnimation::createWithJsonFile("spineboy-pro.json", "spineboy.atlas", 0.6f);
|
||||||
|
|
||||||
skeletonNode->setPosition(Vec2(_contentSize.width / 2 + 400, 20));
|
skeletonNode->setStartListener([](TrackEntry* entry) {
|
||||||
skeletonNode->setScale(0.8);
|
log("%d start: %s", entry->getTrackIndex(), entry->getAnimation()->getName().buffer());
|
||||||
|
});
|
||||||
|
skeletonNode->setInterruptListener([](TrackEntry* entry) {
|
||||||
|
log("%d interrupt", entry->getTrackIndex());
|
||||||
|
});
|
||||||
|
skeletonNode->setEndListener([](TrackEntry* entry) {
|
||||||
|
log("%d end", entry->getTrackIndex());
|
||||||
|
});
|
||||||
|
skeletonNode->setCompleteListener([](TrackEntry* entry) {
|
||||||
|
log("%d complete", entry->getTrackIndex());
|
||||||
|
});
|
||||||
|
skeletonNode->setDisposeListener([](TrackEntry* entry) {
|
||||||
|
log("%d dispose", entry->getTrackIndex());
|
||||||
|
});
|
||||||
|
skeletonNode->setEventListener([](TrackEntry* entry, spine::Event* event) {
|
||||||
|
log("%d event: %s, %d, %f, %s", entry->getTrackIndex(), event->getData().getName().buffer(), event->getIntValue(), event->getFloatValue(), event->getStringValue().buffer());
|
||||||
|
});
|
||||||
|
|
||||||
|
skeletonNode->setMix("walk", "jump", 0.4);
|
||||||
|
skeletonNode->setMix("jump", "run", 0.4);
|
||||||
|
skeletonNode->setAnimation(0, "walk", true);
|
||||||
|
TrackEntry* jumpEntry = skeletonNode->addAnimation(0, "jump", false, 1);
|
||||||
|
skeletonNode->addAnimation(0, "run", true);
|
||||||
|
|
||||||
|
skeletonNode->setTrackStartListener(jumpEntry, [](TrackEntry* entry) {
|
||||||
|
log("jumped!");
|
||||||
|
});
|
||||||
|
|
||||||
|
// skeletonNode->addAnimation(1, "test", true);
|
||||||
|
// skeletonNode->runAction(RepeatForever::create(Sequence::create(FadeOut::create(1), FadeIn::create(1), DelayTime::create(5), NULL)));
|
||||||
|
|
||||||
|
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
||||||
addChild(skeletonNode);
|
addChild(skeletonNode);
|
||||||
|
|
||||||
|
scheduleUpdate();
|
||||||
|
|
||||||
|
SCALE_SKELETON_NODE(skeletonNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpineboyExample::update(float deltaTime) {
|
||||||
|
// Test releasing memory.
|
||||||
|
// Director::getInstance()->replaceScene(SpineboyExample::scene());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TankExample::init() {
|
||||||
|
if (!SpineTestLayer::init()) return false;
|
||||||
|
|
||||||
|
_title = "Tank";
|
||||||
|
skeletonNode = SkeletonAnimation::createWithBinaryFile("tank-pro.skel", "tank.atlas", 0.5f);
|
||||||
|
skeletonNode->setAnimation(0, "shoot", true);
|
||||||
|
|
||||||
|
skeletonNode->setPosition(Vec2(_contentSize.width / 2 + 400, 20));
|
||||||
|
addChild(skeletonNode);
|
||||||
|
|
||||||
|
SCALE_SKELETON_NODE(skeletonNode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,83 +30,138 @@
|
||||||
#include "../BaseTest.h"
|
#include "../BaseTest.h"
|
||||||
#include <spine/spine-cocos2dx.h>
|
#include <spine/spine-cocos2dx.h>
|
||||||
|
|
||||||
DEFINE_TEST_SUITE(SpineTests);
|
#ifdef COCOS2D_DEBUG
|
||||||
|
#include <spine/Debug.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//DEFINE_TEST_SUITE(SpineTests);
|
||||||
|
|
||||||
|
class SpineTests : public TestSuite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SpineTests();
|
||||||
|
|
||||||
|
virtual ~SpineTests();
|
||||||
|
private:
|
||||||
|
std::vector<std::string> _searchPaths;
|
||||||
|
#ifdef COCOS2D_DEBUG
|
||||||
|
spine::DebugExtension* debugExtension = nullptr;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
class SpineTestLayer : public TestCase
|
class SpineTestLayer : public TestCase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpineTestLayer();
|
SpineTestLayer();
|
||||||
|
virtual ~SpineTestLayer();
|
||||||
virtual std::string title() const;
|
|
||||||
|
virtual bool init();
|
||||||
|
virtual std::string title() const override;
|
||||||
protected:
|
protected:
|
||||||
std::string _title;
|
std::string _title;
|
||||||
|
spine::SkeletonAnimation* skeletonNode = nullptr;
|
||||||
|
int _touchIndex = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BatchingExample: public SpineTestLayer {
|
|
||||||
|
class BatchingExample : public SpineTestLayer {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CREATE_FUNC(BatchingExample);
|
CREATE_FUNC(BatchingExample);
|
||||||
~BatchingExample ();
|
~BatchingExample();
|
||||||
|
|
||||||
virtual bool init ();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
spAtlas* _atlas;
|
|
||||||
spAttachmentLoader* _attachmentLoader;
|
|
||||||
spSkeletonData* _skeletonData;
|
|
||||||
spAnimationStateData* _stateData;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CoinExample: public SpineTestLayer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CREATE_FUNC(CoinExample);
|
|
||||||
|
|
||||||
virtual bool init();
|
virtual bool init();
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
spine::SkeletonAnimation* skeletonNode;
|
spine::Atlas* _atlas;
|
||||||
|
spine::AttachmentLoader* _attachmentLoader;
|
||||||
|
spine::SkeletonData* _skeletonData;
|
||||||
|
spine::AnimationStateData* _stateData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CoinExample : public SpineTestLayer {
|
||||||
|
public:
|
||||||
|
|
||||||
|
CREATE_FUNC(CoinExample);
|
||||||
|
|
||||||
|
virtual bool init();
|
||||||
|
|
||||||
|
};
|
||||||
class GoblinsExample : public SpineTestLayer {
|
class GoblinsExample : public SpineTestLayer {
|
||||||
public:
|
public:
|
||||||
CREATE_FUNC(GoblinsExample);
|
CREATE_FUNC(GoblinsExample);
|
||||||
|
|
||||||
virtual bool init ();
|
virtual bool init ();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class IKExample : public SpineTestLayer {
|
||||||
|
public:
|
||||||
|
|
||||||
|
CREATE_FUNC(IKExample);
|
||||||
|
|
||||||
|
virtual bool init();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
spine::SkeletonAnimation* skeletonNode;
|
cocos2d::Vec2 position;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MixAndMatchExample : public SpineTestLayer {
|
||||||
|
public:
|
||||||
|
|
||||||
|
CREATE_FUNC(MixAndMatchExample);
|
||||||
|
|
||||||
|
virtual bool init();
|
||||||
|
|
||||||
|
virtual ~MixAndMatchExample();
|
||||||
|
|
||||||
|
private:
|
||||||
|
spine::Skin* skin;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RaptorExample : public SpineTestLayer {
|
class RaptorExample : public SpineTestLayer {
|
||||||
public:
|
public:
|
||||||
CREATE_FUNC(RaptorExample);
|
CREATE_FUNC(RaptorExample);
|
||||||
|
|
||||||
virtual bool init ();
|
virtual bool init();
|
||||||
|
|
||||||
|
virtual void update(float fDelta);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
spine::SkeletonAnimation* skeletonNode;
|
float swirlTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SkeletonRendererSeparatorExample : public SpineTestLayer {
|
||||||
|
public:
|
||||||
|
CREATE_FUNC(SkeletonRendererSeparatorExample);
|
||||||
|
|
||||||
|
virtual bool init();
|
||||||
|
|
||||||
|
virtual void update(float deltaTime);
|
||||||
|
|
||||||
|
private:
|
||||||
|
spine::SkeletonRenderer* frontNode;
|
||||||
|
cocos2d::DrawNode* betweenNode;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpineboyExample : public SpineTestLayer {
|
class SpineboyExample : public SpineTestLayer {
|
||||||
public:
|
public:
|
||||||
CREATE_FUNC (SpineboyExample);
|
CREATE_FUNC(SpineboyExample);
|
||||||
|
|
||||||
virtual bool init ();
|
virtual bool init();
|
||||||
|
|
||||||
virtual void update (float deltaTime);
|
virtual void update(float deltaTime);
|
||||||
|
|
||||||
private:
|
|
||||||
spine::SkeletonAnimation* skeletonNode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TankExample : public SpineTestLayer {
|
class TankExample : public SpineTestLayer {
|
||||||
public:
|
public:
|
||||||
CREATE_FUNC(TankExample);
|
CREATE_FUNC(TankExample);
|
||||||
|
|
||||||
virtual bool init ();
|
virtual bool init();
|
||||||
|
|
||||||
private:
|
|
||||||
spine::SkeletonAnimation* skeletonNode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _EXAMPLELAYER_H_
|
#endif // _EXAMPLELAYER_H_
|
||||||
|
|
|
@ -93,7 +93,7 @@ public:
|
||||||
addTest("Node: Physics3D", []() { return new Physics3DTests(); } );
|
addTest("Node: Physics3D", []() { return new Physics3DTests(); } );
|
||||||
addTest("Node: RenderTexture", [](){return new RenderTextureTests(); });
|
addTest("Node: RenderTexture", [](){return new RenderTextureTests(); });
|
||||||
addTest("Node: Scene", [](){return new SceneTests(); });
|
addTest("Node: Scene", [](){return new SceneTests(); });
|
||||||
// addTest("Node: Spine", [](){return new SpineTests(); });
|
addTest("Node: Spine", [](){return new SpineTests(); });
|
||||||
addTest("Node: Sprite", [](){return new SpriteTests(); });
|
addTest("Node: Sprite", [](){return new SpriteTests(); });
|
||||||
addTest("Node: Sprite3D", [](){ return new Sprite3DTests(); });
|
addTest("Node: Sprite3D", [](){ return new Sprite3DTests(); });
|
||||||
addTest("Node: SpritePolygon", [](){return new (std::nothrow) SpritePolygonTest(); });
|
addTest("Node: SpritePolygon", [](){return new (std::nothrow) SpritePolygonTest(); });
|
||||||
|
|
|
@ -1,26 +1,54 @@
|
||||||
|
|
||||||
coin.png
|
coin.png
|
||||||
size: 1024,256
|
size: 1024,1024
|
||||||
format: RGBA8888
|
format: RGBA8888
|
||||||
filter: Linear,Linear
|
filter: Linear,Linear
|
||||||
repeat: none
|
repeat: none
|
||||||
coin
|
coin-front-logo
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 2, 2
|
xy: 2, 609
|
||||||
size: 259, 245
|
size: 305, 302
|
||||||
orig: 259, 245
|
orig: 305, 302
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
coin-invert
|
coin-front-shine-logo
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 263, 2
|
xy: 309, 629
|
||||||
size: 259, 245
|
size: 282, 282
|
||||||
orig: 259, 245
|
orig: 282, 282
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
coin-front-shine-spineboy
|
||||||
|
rotate: false
|
||||||
|
xy: 2, 21
|
||||||
|
size: 282, 282
|
||||||
|
orig: 282, 282
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
coin-front-spineboy
|
||||||
|
rotate: false
|
||||||
|
xy: 2, 305
|
||||||
|
size: 305, 302
|
||||||
|
orig: 305, 302
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
coin-side-round
|
||||||
|
rotate: false
|
||||||
|
xy: 309, 345
|
||||||
|
size: 144, 282
|
||||||
|
orig: 144, 282
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
coin-side-straight
|
||||||
|
rotate: true
|
||||||
|
xy: 2, 2
|
||||||
|
size: 17, 282
|
||||||
|
orig: 17, 282
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
shine
|
shine
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 524, 2
|
xy: 593, 666
|
||||||
size: 72, 245
|
size: 72, 245
|
||||||
orig: 72, 245
|
orig: 72, 245
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
|
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 393 KiB |
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 208 KiB |
After Width: | Height: | Size: 370 KiB |
|
@ -1,299 +1,271 @@
|
||||||
|
|
||||||
raptor.png
|
raptor.png
|
||||||
size: 1024,1024
|
size: 1024,512
|
||||||
format: RGBA8888
|
format: RGBA8888
|
||||||
filter: Linear,Linear
|
filter: Linear,Linear
|
||||||
repeat: none
|
repeat: none
|
||||||
back-arm
|
back-arm
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 274, 394
|
xy: 895, 295
|
||||||
size: 46, 29
|
size: 46, 25
|
||||||
orig: 46, 29
|
orig: 46, 25
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
back-bracer
|
back-bracer
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 140, 247
|
xy: 992, 216
|
||||||
size: 39, 28
|
size: 39, 28
|
||||||
orig: 39, 28
|
orig: 39, 28
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
back-hand
|
back-hand
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 824, 699
|
xy: 594, 58
|
||||||
size: 36, 34
|
size: 36, 34
|
||||||
orig: 36, 34
|
orig: 36, 34
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
back-knee
|
back-knee
|
||||||
rotate: false
|
rotate: true
|
||||||
xy: 360, 507
|
xy: 729, 86
|
||||||
size: 49, 67
|
size: 49, 67
|
||||||
orig: 49, 67
|
orig: 49, 67
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
back-thigh
|
back-thigh
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 140, 206
|
xy: 379, 2
|
||||||
size: 39, 24
|
size: 39, 24
|
||||||
orig: 39, 24
|
orig: 39, 24
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
dust01
|
|
||||||
rotate: false
|
|
||||||
xy: 219, 299
|
|
||||||
size: 48, 37
|
|
||||||
orig: 48, 37
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
dust02
|
|
||||||
rotate: false
|
|
||||||
xy: 895, 833
|
|
||||||
size: 43, 44
|
|
||||||
orig: 43, 44
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
dust03
|
|
||||||
rotate: true
|
|
||||||
xy: 167, 445
|
|
||||||
size: 31, 26
|
|
||||||
orig: 31, 26
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
eyes-open
|
eyes-open
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 2, 2
|
xy: 902, 194
|
||||||
size: 47, 45
|
size: 47, 45
|
||||||
orig: 47, 45
|
orig: 47, 45
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-arm
|
front-arm
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 470, 544
|
xy: 945, 306
|
||||||
size: 48, 30
|
size: 48, 26
|
||||||
orig: 48, 30
|
orig: 48, 26
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-bracer
|
front-bracer
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 274, 351
|
xy: 949, 197
|
||||||
size: 41, 29
|
size: 41, 29
|
||||||
orig: 41, 29
|
orig: 41, 29
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-hand
|
front-hand
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 827, 773
|
xy: 949, 266
|
||||||
size: 41, 38
|
size: 41, 38
|
||||||
orig: 41, 38
|
orig: 41, 38
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-open-hand
|
front-open-hand
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 360, 461
|
xy: 875, 148
|
||||||
size: 43, 44
|
size: 43, 44
|
||||||
orig: 43, 44
|
orig: 43, 44
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-thigh
|
front-thigh
|
||||||
rotate: false
|
rotate: true
|
||||||
xy: 411, 545
|
xy: 793, 171
|
||||||
size: 57, 29
|
size: 57, 29
|
||||||
orig: 57, 29
|
orig: 57, 29
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
gun
|
gun
|
||||||
rotate: false
|
rotate: true
|
||||||
xy: 195, 442
|
xy: 379, 28
|
||||||
size: 107, 103
|
size: 107, 103
|
||||||
orig: 107, 103
|
orig: 107, 103
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
gun-nohand
|
gun-nohand
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 167, 338
|
xy: 487, 87
|
||||||
size: 105, 102
|
size: 105, 102
|
||||||
orig: 105, 102
|
orig: 105, 102
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
head
|
head
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 2, 137
|
xy: 807, 361
|
||||||
size: 136, 149
|
size: 136, 149
|
||||||
orig: 136, 149
|
orig: 136, 149
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
lower-leg
|
lower-leg
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 648, 667
|
xy: 827, 195
|
||||||
size: 73, 98
|
size: 73, 98
|
||||||
orig: 73, 98
|
orig: 73, 98
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
mouth-grind
|
mouth-grind
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 49, 2
|
xy: 920, 145
|
||||||
size: 47, 30
|
size: 47, 30
|
||||||
orig: 47, 30
|
orig: 47, 30
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
mouth-smile
|
mouth-smile
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 81, 2
|
xy: 992, 257
|
||||||
size: 47, 30
|
size: 47, 30
|
||||||
orig: 47, 30
|
orig: 47, 30
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
neck
|
neck
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 626, 631
|
xy: 359, 114
|
||||||
size: 18, 21
|
size: 18, 21
|
||||||
orig: 18, 21
|
orig: 18, 21
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-arm-back
|
raptor-back-arm
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 538, 570
|
xy: 653, 142
|
||||||
size: 82, 86
|
size: 82, 86
|
||||||
orig: 82, 86
|
orig: 82, 86
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-body
|
raptor-body
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 2, 737
|
xy: 2, 277
|
||||||
size: 632, 285
|
size: 632, 233
|
||||||
orig: 632, 285
|
orig: 632, 233
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-front-arm
|
raptor-front-arm
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 544, 654
|
xy: 484, 4
|
||||||
size: 81, 102
|
size: 81, 102
|
||||||
orig: 81, 102
|
orig: 81, 102
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-front-leg
|
raptor-front-leg
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 2, 478
|
xy: 2, 18
|
||||||
size: 191, 257
|
size: 191, 257
|
||||||
orig: 191, 257
|
orig: 191, 257
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-hindleg-back
|
raptor-hindleg-back
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 636, 807
|
xy: 636, 295
|
||||||
size: 169, 215
|
size: 169, 215
|
||||||
orig: 169, 215
|
orig: 169, 215
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-horn
|
raptor-horn
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 360, 655
|
xy: 195, 22
|
||||||
size: 182, 80
|
size: 182, 80
|
||||||
orig: 182, 80
|
orig: 182, 80
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-horn-back
|
raptor-horn-back
|
||||||
rotate: false
|
rotate: true
|
||||||
xy: 360, 576
|
xy: 945, 334
|
||||||
size: 176, 77
|
size: 176, 77
|
||||||
orig: 176, 77
|
orig: 176, 77
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-jaw
|
raptor-jaw
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 807, 879
|
xy: 359, 137
|
||||||
size: 153, 143
|
size: 126, 138
|
||||||
orig: 153, 143
|
orig: 126, 138
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-jaw-tooth
|
raptor-jaw-tooth
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 940, 840
|
xy: 895, 322
|
||||||
size: 37, 48
|
size: 37, 48
|
||||||
orig: 37, 48
|
orig: 37, 48
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-mouth-inside
|
raptor-mouth-inside
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 827, 735
|
xy: 949, 228
|
||||||
size: 36, 41
|
size: 36, 41
|
||||||
orig: 36, 41
|
orig: 36, 41
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-saddle-noshadow
|
raptor-saddle-strap-back
|
||||||
rotate: false
|
|
||||||
xy: 2, 288
|
|
||||||
size: 163, 188
|
|
||||||
orig: 163, 188
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
raptor-saddle-strap-front
|
|
||||||
rotate: false
|
|
||||||
xy: 962, 927
|
|
||||||
size: 57, 95
|
|
||||||
orig: 57, 95
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
raptor-saddle-strap-rear
|
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 748, 686
|
xy: 653, 86
|
||||||
size: 54, 74
|
size: 54, 74
|
||||||
orig: 54, 74
|
orig: 54, 74
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
|
raptor-saddle-strap-front
|
||||||
|
rotate: false
|
||||||
|
xy: 594, 94
|
||||||
|
size: 57, 95
|
||||||
|
orig: 57, 95
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
raptor-saddle-w-shadow
|
raptor-saddle-w-shadow
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 195, 547
|
xy: 195, 104
|
||||||
size: 163, 188
|
size: 162, 171
|
||||||
orig: 163, 188
|
orig: 162, 171
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-tail-shadow
|
raptor-tail-shadow
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 636, 742
|
xy: 636, 230
|
||||||
size: 189, 63
|
size: 189, 63
|
||||||
orig: 189, 63
|
orig: 189, 63
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
raptor-tongue
|
raptor-tongue
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 807, 813
|
xy: 807, 295
|
||||||
size: 86, 64
|
size: 86, 64
|
||||||
orig: 86, 64
|
orig: 86, 64
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
stirrup-back
|
stirrup-back
|
||||||
rotate: false
|
rotate: true
|
||||||
xy: 411, 508
|
xy: 952, 151
|
||||||
size: 44, 35
|
size: 44, 35
|
||||||
orig: 44, 35
|
orig: 44, 35
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
stirrup-front
|
stirrup-front
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 167, 291
|
xy: 902, 243
|
||||||
size: 45, 50
|
size: 45, 50
|
||||||
orig: 45, 50
|
orig: 45, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
stirrup-strap
|
stirrup-strap
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 962, 879
|
xy: 824, 147
|
||||||
size: 49, 46
|
size: 49, 46
|
||||||
orig: 49, 46
|
orig: 49, 46
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
torso
|
torso
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 304, 454
|
xy: 737, 137
|
||||||
size: 54, 91
|
size: 54, 91
|
||||||
orig: 54, 91
|
orig: 54, 91
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
visor
|
visor
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 2, 51
|
xy: 487, 191
|
||||||
size: 131, 84
|
size: 131, 84
|
||||||
orig: 131, 84
|
orig: 131, 84
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
|
|
Before Width: | Height: | Size: 510 KiB After Width: | Height: | Size: 469 KiB |
|
@ -1,306 +1,285 @@
|
||||||
|
|
||||||
spineboy.png
|
spineboy.png
|
||||||
size: 1024,512
|
size: 1024,256
|
||||||
format: RGBA8888
|
format: RGBA8888
|
||||||
filter: Linear,Linear
|
filter: Linear,Linear
|
||||||
repeat: none
|
repeat: none
|
||||||
crosshair
|
crosshair
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 794, 167
|
xy: 352, 7
|
||||||
size: 45, 45
|
size: 45, 45
|
||||||
orig: 45, 45
|
orig: 45, 45
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
dust01
|
|
||||||
rotate: false
|
|
||||||
xy: 960, 190
|
|
||||||
size: 48, 37
|
|
||||||
orig: 48, 37
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
dust02
|
|
||||||
rotate: false
|
|
||||||
xy: 392, 2
|
|
||||||
size: 43, 44
|
|
||||||
orig: 43, 44
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
dust03
|
|
||||||
rotate: false
|
|
||||||
xy: 841, 163
|
|
||||||
size: 31, 26
|
|
||||||
orig: 31, 26
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
eye-indifferent
|
eye-indifferent
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 960, 229
|
xy: 862, 105
|
||||||
size: 47, 45
|
size: 47, 45
|
||||||
orig: 47, 45
|
orig: 47, 45
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
eye-surprised
|
eye-surprised
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 745, 167
|
xy: 505, 79
|
||||||
size: 47, 45
|
size: 47, 45
|
||||||
orig: 47, 45
|
orig: 47, 45
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-bracer
|
front-bracer
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 547, 2
|
xy: 826, 66
|
||||||
size: 29, 40
|
size: 29, 40
|
||||||
orig: 29, 40
|
orig: 29, 40
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-fist-closed
|
front-fist-closed
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 920, 190
|
xy: 786, 65
|
||||||
size: 38, 41
|
size: 38, 41
|
||||||
orig: 38, 41
|
orig: 38, 41
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-fist-open
|
front-fist-open
|
||||||
rotate: false
|
rotate: true
|
||||||
xy: 437, 2
|
xy: 710, 51
|
||||||
size: 43, 44
|
size: 43, 44
|
||||||
orig: 43, 44
|
orig: 43, 44
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-foot
|
front-foot
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 482, 11
|
xy: 210, 6
|
||||||
size: 63, 35
|
size: 63, 35
|
||||||
orig: 63, 35
|
orig: 63, 35
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-shin
|
front-shin
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 866, 233
|
xy: 665, 128
|
||||||
size: 41, 92
|
size: 41, 92
|
||||||
orig: 41, 92
|
orig: 41, 92
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-thigh
|
front-thigh
|
||||||
rotate: false
|
rotate: true
|
||||||
xy: 719, 155
|
xy: 2, 2
|
||||||
size: 24, 56
|
size: 23, 56
|
||||||
orig: 24, 56
|
orig: 23, 56
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
front-upper-arm
|
front-upper-arm
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 719, 104
|
xy: 250, 205
|
||||||
size: 27, 49
|
size: 23, 49
|
||||||
orig: 27, 49
|
orig: 23, 49
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
goggles
|
goggles
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 881, 276
|
xy: 665, 171
|
||||||
size: 131, 83
|
size: 131, 83
|
||||||
orig: 131, 83
|
orig: 131, 83
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
gun
|
gun
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 612, 109
|
xy: 798, 152
|
||||||
size: 105, 102
|
size: 105, 102
|
||||||
orig: 105, 102
|
orig: 105, 102
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
head
|
head
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 881, 361
|
xy: 2, 27
|
||||||
size: 136, 149
|
size: 136, 149
|
||||||
orig: 136, 149
|
orig: 136, 149
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
hoverboard-board
|
hoverboard-board
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 2, 38
|
xy: 2, 178
|
||||||
size: 246, 76
|
size: 246, 76
|
||||||
orig: 246, 76
|
orig: 246, 76
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
hoverboard-thruster
|
hoverboard-thruster
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 578, 12
|
xy: 722, 96
|
||||||
size: 30, 32
|
size: 30, 32
|
||||||
orig: 30, 32
|
orig: 30, 32
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
hoverglow-small
|
hoverglow-small
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 572, 44
|
xy: 275, 81
|
||||||
size: 137, 38
|
size: 137, 38
|
||||||
orig: 137, 38
|
orig: 137, 38
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
mouth-grind
|
mouth-grind
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 713, 55
|
xy: 614, 97
|
||||||
size: 47, 30
|
size: 47, 30
|
||||||
orig: 47, 30
|
orig: 47, 30
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
mouth-oooo
|
mouth-oooo
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 713, 6
|
xy: 612, 65
|
||||||
size: 47, 30
|
size: 47, 30
|
||||||
orig: 47, 30
|
orig: 47, 30
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
mouth-smile
|
mouth-smile
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 748, 135
|
xy: 661, 64
|
||||||
size: 47, 30
|
size: 47, 30
|
||||||
orig: 47, 30
|
orig: 47, 30
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
muzzle-glow
|
muzzle-glow
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 612, 8
|
xy: 382, 54
|
||||||
size: 99, 99
|
size: 25, 25
|
||||||
orig: 99, 99
|
orig: 25, 25
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
muzzle-ring
|
muzzle-ring
|
||||||
rotate: false
|
rotate: true
|
||||||
xy: 302, 190
|
xy: 275, 54
|
||||||
size: 25, 105
|
size: 25, 105
|
||||||
orig: 25, 105
|
orig: 25, 105
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
muzzle01
|
muzzle01
|
||||||
rotate: false
|
rotate: true
|
||||||
xy: 336, 335
|
xy: 911, 95
|
||||||
size: 271, 175
|
size: 67, 40
|
||||||
orig: 271, 175
|
orig: 67, 40
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
muzzle02
|
muzzle02
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 609, 341
|
xy: 792, 108
|
||||||
size: 270, 169
|
size: 68, 42
|
||||||
orig: 270, 169
|
orig: 68, 42
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
muzzle03
|
muzzle03
|
||||||
rotate: false
|
rotate: true
|
||||||
xy: 2, 297
|
xy: 956, 171
|
||||||
size: 332, 213
|
size: 83, 53
|
||||||
orig: 332, 213
|
orig: 83, 53
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
muzzle04
|
muzzle04
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 2, 116
|
xy: 275, 7
|
||||||
size: 298, 179
|
size: 75, 45
|
||||||
orig: 298, 179
|
orig: 75, 45
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
muzzle05
|
muzzle05
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 336, 183
|
xy: 140, 3
|
||||||
size: 269, 150
|
size: 68, 38
|
||||||
orig: 269, 150
|
orig: 68, 38
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
neck
|
neck
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 841, 191
|
xy: 250, 182
|
||||||
size: 18, 21
|
size: 18, 21
|
||||||
orig: 18, 21
|
orig: 18, 21
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
portal-bg
|
portal-bg
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 302, 48
|
xy: 140, 43
|
||||||
size: 133, 133
|
size: 133, 133
|
||||||
orig: 133, 133
|
orig: 133, 133
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
portal-flare1
|
portal-flare1
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 180, 6
|
xy: 554, 65
|
||||||
size: 56, 30
|
size: 56, 30
|
||||||
orig: 56, 30
|
orig: 56, 30
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
portal-flare2
|
portal-flare2
|
||||||
rotate: false
|
rotate: true
|
||||||
xy: 2, 5
|
xy: 759, 112
|
||||||
size: 57, 31
|
size: 57, 31
|
||||||
orig: 57, 31
|
orig: 57, 31
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
portal-flare3
|
portal-flare3
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 61, 6
|
xy: 554, 97
|
||||||
size: 58, 30
|
size: 58, 30
|
||||||
orig: 58, 30
|
orig: 58, 30
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
portal-shade
|
portal-shade
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 437, 48
|
xy: 275, 121
|
||||||
size: 133, 133
|
size: 133, 133
|
||||||
orig: 133, 133
|
orig: 133, 133
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
portal-streaks1
|
portal-streaks1
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 609, 213
|
xy: 410, 126
|
||||||
size: 126, 128
|
size: 126, 128
|
||||||
orig: 126, 128
|
orig: 126, 128
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
portsl-streaks2
|
portal-streaks2
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 739, 214
|
xy: 538, 129
|
||||||
size: 125, 125
|
size: 125, 125
|
||||||
orig: 125, 125
|
orig: 125, 125
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
rear-bracer
|
rear-bracer
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 797, 137
|
xy: 857, 67
|
||||||
size: 28, 36
|
size: 28, 36
|
||||||
orig: 28, 36
|
orig: 28, 36
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
rear-foot
|
rear-foot
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 121, 6
|
xy: 663, 96
|
||||||
size: 57, 30
|
size: 57, 30
|
||||||
orig: 57, 30
|
orig: 57, 30
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
rear-shin
|
rear-shin
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 301, 8
|
xy: 414, 86
|
||||||
size: 38, 89
|
size: 38, 89
|
||||||
orig: 38, 89
|
orig: 38, 89
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
rear-thigh
|
rear-thigh
|
||||||
rotate: true
|
rotate: false
|
||||||
xy: 866, 198
|
xy: 756, 63
|
||||||
size: 33, 52
|
size: 28, 47
|
||||||
orig: 33, 52
|
orig: 28, 47
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
rear-upper-arm
|
rear-upper-arm
|
||||||
rotate: true
|
rotate: true
|
||||||
xy: 748, 109
|
xy: 60, 5
|
||||||
size: 24, 44
|
size: 20, 44
|
||||||
orig: 24, 44
|
orig: 20, 44
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
torso
|
torso
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 250, 24
|
xy: 905, 164
|
||||||
size: 49, 90
|
size: 49, 90
|
||||||
orig: 49, 90
|
orig: 49, 90
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
|
|
Before Width: | Height: | Size: 572 KiB After Width: | Height: | Size: 255 KiB |
Before Width: | Height: | Size: 580 KiB After Width: | Height: | Size: 597 KiB |