[v4] spine v3.8
|
@ -49,7 +49,7 @@ include(audio/CMakeLists.txt)
|
|||
|
||||
# default value for cocos2dx extensions modules build
|
||||
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)
|
||||
|
||||
if(BUILD_EDITOR_COCOSTUDIO)
|
||||
|
@ -58,7 +58,11 @@ if(BUILD_EDITOR_COCOSTUDIO)
|
|||
endif(BUILD_EDITOR_COCOSTUDIO)
|
||||
|
||||
if(BUILD_EDITOR_SPINE)
|
||||
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})
|
||||
endif(BUILD_EDITOR_SPINE)
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
* 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
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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/AttachmentVertices.h>
|
||||
|
@ -35,6 +35,7 @@ namespace spine {
|
|||
|
||||
AttachmentVertices::AttachmentVertices (Texture2D* texture, int verticesCount, unsigned short* triangles, int trianglesCount) {
|
||||
_texture = texture;
|
||||
if (_texture) _texture->retain();
|
||||
|
||||
_triangles = new TrianglesCommand::Triangles();
|
||||
_triangles->verts = new V3F_C4B_T2F[verticesCount];
|
||||
|
@ -46,6 +47,7 @@ AttachmentVertices::AttachmentVertices (Texture2D* texture, int verticesCount, u
|
|||
AttachmentVertices::~AttachmentVertices () {
|
||||
delete [] _triangles->verts;
|
||||
delete _triangles;
|
||||
if (_texture) _texture->release();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
* 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
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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_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
|
||||
|
||||
file(GLOB_RECURSE COCOS_SPINE_SRC
|
||||
${CMAKE_CURRENT_LIST_DIR}/*.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/**/*.cpp
|
||||
)
|
||||
|
||||
set(COCOS_SPINE_SRC
|
||||
editor-support/spine/AttachmentVertices.cpp
|
||||
editor-support/spine/SkeletonAnimation.cpp
|
||||
editor-support/spine/SkeletonBatch.cpp
|
||||
editor-support/spine/SkeletonRenderer.cpp
|
||||
editor-support/spine/SkeletonTwoColorBatch.cpp
|
||||
editor-support/spine/spine-cocos2dx.cpp
|
||||
file(GLOB_RECURSE COCOS_SPINE_HEADER
|
||||
${CMAKE_CURRENT_LIST_DIR}/*.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/**/*.h
|
||||
)
|
|
@ -1,8 +1,8 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
* 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
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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/SkeletonAnimation.h>
|
||||
|
@ -54,12 +54,13 @@ void animationCallback (AnimationState* state, EventType type, TrackEntry* entry
|
|||
|
||||
void trackEntryCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
|
||||
((SkeletonAnimation*)state->getRendererObject())->onTrackEntryEvent(entry, type, event);
|
||||
if (type == EventType_Dispose)
|
||||
if (type == EventType_Dispose) {
|
||||
if (entry->getRendererObject()) {
|
||||
delete (spine::_TrackEntryListeners*)entry->getRendererObject();
|
||||
entry->setRendererObject(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static _TrackEntryListeners* getListeners (TrackEntry* entry) {
|
||||
if (!entry->getRendererObject()) {
|
||||
|
@ -111,6 +112,7 @@ void SkeletonAnimation::initialize () {
|
|||
super::initialize();
|
||||
|
||||
_ownsAnimationStateData = true;
|
||||
_updateOnlyIfVisible = false;
|
||||
_state = new (__FILE__, __LINE__) AnimationState(new (__FILE__, __LINE__) AnimationStateData(_skeleton->getData()));
|
||||
_state->setRendererObject(this);
|
||||
_state->setListener(animationCallback);
|
||||
|
@ -128,12 +130,16 @@ SkeletonAnimation::~SkeletonAnimation () {
|
|||
}
|
||||
|
||||
void SkeletonAnimation::update (float deltaTime) {
|
||||
if (_updateOnlyIfVisible && !isVisible()) return;
|
||||
|
||||
super::update(deltaTime);
|
||||
|
||||
deltaTime *= _timeScale;
|
||||
if (_preUpdateListener) _preUpdateListener(this);
|
||||
_state->update(deltaTime);
|
||||
_state->apply(*_skeleton);
|
||||
_skeleton->updateWorldTransform();
|
||||
if (_postUpdateListener) _postUpdateListener(this);
|
||||
}
|
||||
|
||||
void SkeletonAnimation::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t transformFlags) {
|
||||
|
@ -278,6 +284,14 @@ void SkeletonAnimation::setEventListener (const 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) {
|
||||
getListeners(entry)->startListener = listener;
|
||||
}
|
||||
|
@ -306,4 +320,8 @@ AnimationState* SkeletonAnimation::getState() const {
|
|||
return _state;
|
||||
}
|
||||
|
||||
void SkeletonAnimation::setUpdateOnlyIfVisible(bool status) {
|
||||
_updateOnlyIfVisible = status;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
* 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
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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_SKELETONANIMATION_H_
|
||||
#define SPINE_SKELETONANIMATION_H_
|
||||
#define SPINE_SHORT_NAMES
|
||||
|
||||
#include <spine/spine.h>
|
||||
#include <spine/SkeletonRenderer.h>
|
||||
#include <spine/spine-cocos2dx.h>
|
||||
#include "cocos2d.h"
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SkeletonAnimation;
|
||||
|
||||
typedef std::function<void(TrackEntry* entry)> StartListener;
|
||||
typedef std::function<void(TrackEntry* entry)> InterruptListener;
|
||||
typedef std::function<void(TrackEntry* entry)> EndListener;
|
||||
typedef std::function<void(TrackEntry* entry)> DisposeListener;
|
||||
typedef std::function<void(TrackEntry* entry)> CompleteListener;
|
||||
typedef std::function<void(TrackEntry* entry, Event* event)> EventListener;
|
||||
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
|
||||
* played later. */
|
||||
|
@ -87,6 +90,8 @@ public:
|
|||
void setDisposeListener (const DisposeListener& listener);
|
||||
void setCompleteListener (const CompleteListener& listener);
|
||||
void setEventListener (const EventListener& listener);
|
||||
void setPreUpdateWorldTransformsListener(const UpdateWorldTransformsListener& listener);
|
||||
void setPostUpdateWorldTransformsListener(const UpdateWorldTransformsListener& listener);
|
||||
|
||||
void setTrackStartListener (TrackEntry* entry, const StartListener& listener);
|
||||
void setTrackInterruptListener (TrackEntry* entry, const InterruptListener& listener);
|
||||
|
@ -99,6 +104,7 @@ public:
|
|||
virtual void onTrackEntryEvent (TrackEntry* entry, EventType type, Event* event);
|
||||
|
||||
AnimationState* getState() const;
|
||||
void setUpdateOnlyIfVisible(bool status);
|
||||
|
||||
CC_CONSTRUCTOR_ACCESS:
|
||||
SkeletonAnimation ();
|
||||
|
@ -109,6 +115,7 @@ protected:
|
|||
AnimationState* _state;
|
||||
|
||||
bool _ownsAnimationStateData;
|
||||
bool _updateOnlyIfVisible;
|
||||
bool _firstDraw;
|
||||
|
||||
StartListener _startListener;
|
||||
|
@ -117,6 +124,8 @@ protected:
|
|||
DisposeListener _disposeListener;
|
||||
CompleteListener _completeListener;
|
||||
EventListener _eventListener;
|
||||
UpdateWorldTransformsListener _preUpdateListener;
|
||||
UpdateWorldTransformsListener _postUpdateListener;
|
||||
|
||||
private:
|
||||
typedef SkeletonRenderer super;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
|
@ -15,23 +15,23 @@
|
|||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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_SKELETONRENDERER_H_
|
||||
#define SPINE_SKELETONRENDERER_H_
|
||||
|
||||
#include <spine/spine.h>
|
||||
#include "cocos2d.h"
|
||||
#include <spine/spine.h>
|
||||
|
||||
namespace spine {
|
||||
|
||||
|
@ -46,14 +46,13 @@ namespace spine {
|
|||
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);
|
||||
|
||||
virtual void update (float deltaTime) override;
|
||||
virtual 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);
|
||||
virtual cocos2d::Rect getBoundingBox () const override;
|
||||
virtual void onEnter () override;
|
||||
virtual void onExit () override;
|
||||
void update (float deltaTime) override;
|
||||
void draw (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags) override;
|
||||
cocos2d::Rect getBoundingBox () const override;
|
||||
void onEnter () override;
|
||||
void onExit () override;
|
||||
|
||||
Skeleton* getSkeleton();
|
||||
Skeleton* getSkeleton() const;
|
||||
|
||||
void setTimeScale(float scale);
|
||||
float getTimeScale() const;
|
||||
|
@ -68,6 +67,9 @@ namespace spine {
|
|||
void setDebugMeshesEnabled(bool enabled);
|
||||
bool getDebugMeshesEnabled() const;
|
||||
|
||||
void setDebugBoundingRectEnabled(bool enabled);
|
||||
bool getDebugBoundingRectEnabled() const;
|
||||
|
||||
// --- Convenience methods for common Skeleton_* functions.
|
||||
void updateWorldTransform ();
|
||||
|
||||
|
@ -107,13 +109,10 @@ namespace spine {
|
|||
void setSlotsRange(int startSlotIndex, int endSlotIndex);
|
||||
|
||||
// --- BlendProtocol
|
||||
virtual void setBlendFunc (const cocos2d::BlendFunc& blendFunc)override;
|
||||
virtual const cocos2d::BlendFunc& getBlendFunc () const override;
|
||||
virtual void setOpacityModifyRGB (bool value) override;
|
||||
virtual bool isOpacityModifyRGB () const override;
|
||||
|
||||
// Frees global memory used for temporay vertex transformations.
|
||||
static void destroyScratchBuffers();
|
||||
void setBlendFunc (const cocos2d::BlendFunc& blendFunc)override;
|
||||
const cocos2d::BlendFunc& getBlendFunc () const override;
|
||||
void setOpacityModifyRGB (bool value) override;
|
||||
bool isOpacityModifyRGB () const override;
|
||||
|
||||
CC_CONSTRUCTOR_ACCESS:
|
||||
SkeletonRenderer ();
|
||||
|
@ -136,13 +135,14 @@ namespace spine {
|
|||
protected:
|
||||
void setSkeletonData (SkeletonData* skeletonData, bool ownsSkeletonData);
|
||||
void setupGLProgramState(bool twoColorTintEnabled);
|
||||
virtual void drawDebug (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags);
|
||||
|
||||
bool _ownsSkeletonData;
|
||||
bool _ownsSkeleton;
|
||||
bool _ownsAtlas;
|
||||
bool _ownsAtlas = false;
|
||||
Atlas* _atlas;
|
||||
AttachmentLoader* _attachmentLoader;
|
||||
|
||||
cocos2d::CustomCommand _debugCommand;
|
||||
cocos2d::BlendFunc _blendFunc;
|
||||
bool _premultipliedAlpha;
|
||||
Skeleton* _skeleton;
|
||||
|
@ -150,11 +150,14 @@ namespace spine {
|
|||
bool _debugSlots;
|
||||
bool _debugBones;
|
||||
bool _debugMeshes;
|
||||
bool _debugBoundingRect;
|
||||
SkeletonClipping* _clipper;
|
||||
VertexEffect* _effect;
|
||||
bool _twoColorTintEnabled = false;
|
||||
cocos2d::Rect _boundingRect;
|
||||
|
||||
int _startSlotIndex;
|
||||
int _endSlotIndex;
|
||||
bool _twoColorTint;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
* 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
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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>
|
||||
|
@ -140,6 +140,7 @@ Cocos2dTextureLoader::~Cocos2dTextureLoader() { }
|
|||
void Cocos2dTextureLoader::load(AtlasPage& page, const spine::String& path) {
|
||||
Texture2D* texture = Director::getInstance()->getTextureCache()->addImage(path.buffer());
|
||||
CCASSERT(texture != nullptr, "Invalid image");
|
||||
if (texture) {
|
||||
texture->retain();
|
||||
#if COCOS2D_VERSION >= 0x0040000
|
||||
Texture2D::TexParams textureParams(filter(page.minFilter), filter(page.magFilter), wrap(page.uWrap), wrap(page.vWrap));
|
||||
|
@ -152,10 +153,13 @@ void Cocos2dTextureLoader::load(AtlasPage& page, const spine::String& path) {
|
|||
page.width = texture->getPixelsWide();
|
||||
page.height = texture->getPixelsHigh();
|
||||
}
|
||||
}
|
||||
|
||||
void Cocos2dTextureLoader::unload(void* texture) {
|
||||
if (texture) {
|
||||
((Texture2D*)texture)->release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Cocos2dExtension::Cocos2dExtension() : DefaultSpineExtension() { }
|
||||
|
@ -164,7 +168,7 @@ Cocos2dExtension::~Cocos2dExtension() { }
|
|||
|
||||
char *Cocos2dExtension::_readFile(const spine::String &path, int *length) {
|
||||
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)
|
||||
#if COCOS2D_VERSION >= 0x00031200
|
||||
|
@ -180,8 +184,6 @@ char *Cocos2dExtension::_readFile(const spine::String &path, int *length) {
|
|||
#endif
|
||||
}
|
||||
|
||||
//SpineExtension *spine::getDefaultExtension () {
|
||||
// return new Cocos2dExtension();
|
||||
//}
|
||||
|
||||
static int __preinit_spine_extension = (spine::SpineExtension::setInstance(new Cocos2dExtension()), 0);
|
||||
SpineExtension *spine::getDefaultExtension () {
|
||||
return new Cocos2dExtension();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
* 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
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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_COCOS2DX_H_
|
||||
#define SPINE_COCOS2DX_H_
|
||||
#define SPINE_SHORT_NAMES
|
||||
|
||||
#include <spine/spine.h>
|
||||
#include "cocos2d.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/SkeletonBatch.h>
|
||||
|
||||
namespace spine {
|
||||
class Cocos2dAtlasAttachmentLoader: public AtlasAttachmentLoader {
|
||||
|
|
|
@ -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
|
||||
* 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
|
||||
* 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
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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/SkeletonBatch.h>
|
||||
#include <spine/spine-cocos2dx.h>
|
||||
#if COCOS2D_VERSION >= 0x00040000
|
||||
|
||||
#include <spine/Extension.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -57,15 +59,17 @@ void SkeletonBatch::destroyInstance () {
|
|||
|
||||
SkeletonBatch::SkeletonBatch () {
|
||||
|
||||
auto program = backend::Device::getInstance()->newProgram(positionTextureColor_vert, positionTextureColor_frag);
|
||||
auto program = backend::Program::getBuiltinProgram(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
_programState = std::make_shared<backend::ProgramState>(program);
|
||||
program->autorelease();
|
||||
|
||||
auto vertexLayout = _programState->getVertexLayout();
|
||||
|
||||
vertexLayout->setAttribute("a_position", 0, backend::VertexFormat::FLOAT3, offsetof(V3F_C4B_T2F, vertices), false);
|
||||
vertexLayout->setAttribute("a_color", 2, backend::VertexFormat::UBYTE4, offsetof(V3F_C4B_T2F, colors), true);
|
||||
vertexLayout->setAttribute("a_texCoord", 1, backend::VertexFormat::FLOAT2, offsetof(V3F_C4B_T2F, texCoords), false);
|
||||
auto locPosition = _programState->getAttributeLocation("a_position");
|
||||
auto locTexcoord = _programState->getAttributeLocation("a_texCoord");
|
||||
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]));
|
||||
|
||||
|
||||
|
@ -147,7 +151,6 @@ void SkeletonBatch::deallocateIndices(uint32_t numIndices) {
|
|||
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();
|
||||
const cocos2d::Mat4& projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||
auto &pipelineDescriptor = command->getPipelineDescriptor();
|
||||
|
||||
auto programState = command->getPipelineDescriptor().programState;
|
||||
CCASSERT(programState, "programState should not be null");
|
||||
|
@ -188,3 +191,5 @@ cocos2d::TrianglesCommand *SkeletonBatch::createNewTrianglesCommand() {
|
|||
return command;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,8 +1,8 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
* 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
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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_
|
||||
#define SPINE_SHORT_NAMES
|
||||
#include <spine/spine.h>
|
||||
|
||||
#include "cocos2d.h"
|
||||
#if COCOS2D_VERSION >= 0x00040000
|
||||
|
||||
#include <spine/spine.h>
|
||||
#include <vector>
|
||||
|
||||
namespace spine {
|
||||
|
@ -77,4 +79,6 @@ namespace spine {
|
|||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SPINE_SKELETONBATCH_H_
|
|
@ -1,8 +1,8 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
* 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
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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/SkeletonTwoColorBatch.h>
|
||||
|
||||
#include <spine/spine-cocos2dx.h>
|
||||
#if COCOS2D_VERSION >= 0x00040000
|
||||
|
||||
#include <spine/Extension.h>
|
||||
#include <algorithm>
|
||||
#include <stddef.h> // offsetof
|
||||
|
@ -111,10 +114,15 @@ namespace {
|
|||
|
||||
auto layout = programState->getVertexLayout();
|
||||
|
||||
layout->setAttribute("a_position", 0, backend::VertexFormat::FLOAT3, offsetof(spine::V3F_C4B_C4B_T2F, position), false);
|
||||
layout->setAttribute("a_color", 1, backend::VertexFormat::UBYTE4, offsetof(spine::V3F_C4B_C4B_T2F, color), true);
|
||||
layout->setAttribute("a_color2", 2, backend::VertexFormat::UBYTE4, offsetof(spine::V3F_C4B_C4B_T2F, color2), true);
|
||||
layout->setAttribute("a_texCoords", 3, backend::VertexFormat::FLOAT2, offsetof(spine::V3F_C4B_C4B_T2F, texCoords), false);
|
||||
auto locPosition = programState->getAttributeLocation("a_position");
|
||||
auto locTexcoord = programState->getAttributeLocation("a_texCoords");
|
||||
auto locColor = programState->getAttributeLocation("a_color");
|
||||
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));
|
||||
|
||||
__twoColorProgramState = std::shared_ptr<backend::ProgramState>(programState);
|
||||
|
@ -124,7 +132,7 @@ namespace {
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -396,3 +404,5 @@ TwoColorTrianglesCommand* SkeletonTwoColorBatch::nextFreeCommand() {
|
|||
return command;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,8 +1,8 @@
|
|||
/******************************************************************************
|
||||
* 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
|
||||
* 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
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* 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_
|
||||
#define SPINE_SHORT_NAMES
|
||||
#include <spine/spine.h>
|
||||
|
||||
#include "cocos2d.h"
|
||||
#if COCOS2D_VERSION >= 0x00040000
|
||||
|
||||
#include <spine/spine.h>
|
||||
#include <vector>
|
||||
|
||||
namespace spine {
|
||||
|
@ -99,7 +101,6 @@ namespace spine {
|
|||
cocos2d::BlendFunc _blendType;
|
||||
TwoColorTriangles _triangles;
|
||||
cocos2d::Mat4 _mv;
|
||||
GLuint _alphaTextureID;
|
||||
bool _forceFlush;
|
||||
};
|
||||
|
||||
|
@ -146,7 +147,6 @@ namespace spine {
|
|||
|
||||
|
||||
// VBO handles & attribute locations
|
||||
GLuint _vertexBufferHandle;
|
||||
V3F_C4B_C4B_T2F* _vertexBuffer;
|
||||
uint32_t _numVerticesBuffer;
|
||||
uint32_t _numIndicesBuffer;
|
||||
|
@ -160,4 +160,6 @@ namespace spine {
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SPINE_SKELETONTWOCOLORBATCH_H_
|
|
@ -43,12 +43,12 @@ namespace cocos2d { namespace network {
|
|||
|
||||
DownloadTask::DownloadTask(const std::string& srcUrl,
|
||||
const std::string& storagePath,
|
||||
const std::string& md5checksum,
|
||||
const std::string& checksum,
|
||||
const std::string& identifier)
|
||||
{
|
||||
this->requestURL = srcUrl;
|
||||
this->storagePath = storagePath;
|
||||
this->md5checksum = md5checksum;
|
||||
this->checksum = checksum;
|
||||
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* node = new (std::nothrow) LuaSkeletonAnimation();
|
||||
static spine::Cocos2dTextureLoader s_loader;
|
||||
spine::Atlas* atlas = new spine::Atlas(atlasFile, &s_loader);
|
||||
spine::Atlas* atlas = new spine::Atlas(atlasFile, nullptr);
|
||||
node->initWithJsonFile(skeletonDataFile, atlas, scale);
|
||||
node->autorelease();
|
||||
return node;
|
||||
|
|
|
@ -153,7 +153,7 @@ list(APPEND GAME_HEADER
|
|||
Classes/SceneTest/SceneTest.h
|
||||
Classes/ReleasePoolTest/ReleasePoolTest.h
|
||||
Classes/InputTest/MouseTest.h
|
||||
# Classes/SpineTest/SpineTest.h
|
||||
Classes/SpineTest/SpineTest.h
|
||||
# Classes/Scene3DTest/Scene3DTest.h
|
||||
Classes/ParticleTest/ParticleTest.h
|
||||
Classes/EffectsTest/EffectsTest.h
|
||||
|
@ -278,7 +278,7 @@ list(APPEND GAME_SOURCE
|
|||
Classes/SchedulerTest/SchedulerTest.cpp
|
||||
Classes/ShaderTest/ShaderTest.cpp
|
||||
Classes/ShaderTest/ShaderTest2.cpp
|
||||
#Classes/SpineTest/SpineTest.cpp
|
||||
Classes/SpineTest/SpineTest.cpp
|
||||
# Classes/Scene3DTest/Scene3DTest.cpp
|
||||
Classes/Sprite3DTest/DrawNode3D.cpp
|
||||
Classes/Sprite3DTest/Sprite3DTest.cpp
|
||||
|
|
|
@ -33,172 +33,421 @@ using namespace cocos2d;
|
|||
using namespace std;
|
||||
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
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
|
||||
|
||||
SpineTests::SpineTests()
|
||||
{
|
||||
auto fu = FileUtils::getInstance();
|
||||
_searchPaths = fu->getSearchPaths();
|
||||
fu->addSearchPath("spine", true);
|
||||
|
||||
ADD_TEST_CASE(BatchingExample);
|
||||
ADD_TEST_CASE(CoinExample);
|
||||
ADD_TEST_CASE(GoblinsExample);
|
||||
ADD_TEST_CASE(IKExample);
|
||||
ADD_TEST_CASE(MixAndMatchExample);
|
||||
ADD_TEST_CASE(RaptorExample);
|
||||
ADD_TEST_CASE(SkeletonRendererSeparatorExample);
|
||||
ADD_TEST_CASE(SpineboyExample);
|
||||
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()
|
||||
: _title("")
|
||||
{}
|
||||
|
||||
SpineTestLayer::~SpineTestLayer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string SpineTestLayer::title() const
|
||||
{
|
||||
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
|
||||
bool BatchingExample::init () {
|
||||
if (!SpineTestLayer::init()) return false;
|
||||
|
||||
_title = "BatchingExample";
|
||||
_title = "Batching";
|
||||
|
||||
// Load the texture atlas.
|
||||
_atlas = spAtlas_createFromFile("spine/spineboy.atlas", 0);
|
||||
_atlas = new (__FILE__, __LINE__) Atlas("spineboy.atlas", &textureLoader, true);
|
||||
CCASSERT(_atlas, "Error reading atlas file.");
|
||||
|
||||
// This attachment loader configures attachments with data needed for cocos2d-x rendering.
|
||||
// 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.
|
||||
spSkeletonJson* json = spSkeletonJson_createWithLoader(_attachmentLoader);
|
||||
json->scale = 0.6f; // Resizes skeleton data to 60% of the size it was in Spine.
|
||||
_skeletonData = spSkeletonJson_readSkeletonDataFile(json, "spine/spineboy-ess.json");
|
||||
CCASSERT(_skeletonData, json->error ? json->error : "Error reading skeleton data file.");
|
||||
spSkeletonJson_dispose(json);
|
||||
SkeletonJson* json = new (__FILE__, __LINE__) SkeletonJson(_attachmentLoader);
|
||||
json->setScale(0.6f); // Resizes skeleton data to 60% of the size it was in Spine.
|
||||
_skeletonData = json->readSkeletonDataFile("spineboy-pro.json");
|
||||
CCASSERT(_skeletonData, json->getError().isEmpty() ? json->getError().buffer() : "Error reading skeleton data file.");
|
||||
delete json;
|
||||
|
||||
// Setup mix times.
|
||||
_stateData = spAnimationStateData_create(_skeletonData);
|
||||
spAnimationStateData_setMixByName(_stateData, "walk", "jump", 0.2f);
|
||||
spAnimationStateData_setMixByName(_stateData, "jump", "run", 0.2f);
|
||||
_stateData = new (__FILE__, __LINE__) AnimationStateData(_skeletonData);
|
||||
_stateData->setMix("walk", "jump", 0.2f);
|
||||
_stateData->setMix("jump", "run", 0.2f);
|
||||
|
||||
int xMin = _contentSize.width * 0.10f, xMax = _contentSize.width * 0.90f;
|
||||
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.
|
||||
SkeletonAnimation* skeletonNode = SkeletonAnimation::createWithData(_skeletonData, false);
|
||||
skeletonNode->setAnimationStateData(_stateData);
|
||||
|
||||
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);
|
||||
|
||||
// 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(
|
||||
RandomHelper::random_int(xMin, xMax),
|
||||
RandomHelper::random_int(yMin, yMax)
|
||||
));
|
||||
skeletonNode->setScale(0.8);
|
||||
addChild(skeletonNode);
|
||||
}
|
||||
|
||||
SCALE_SKELETON_NODE(skeletonNode);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
BatchingExample::~BatchingExample() {
|
||||
// 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.
|
||||
spSkeletonData_dispose(_skeletonData);
|
||||
spAnimationStateData_dispose(_stateData);
|
||||
spAttachmentLoader_dispose(_attachmentLoader);
|
||||
spAtlas_dispose(_atlas);
|
||||
|
||||
delete _skeletonData;
|
||||
delete _stateData;
|
||||
delete _attachmentLoader;
|
||||
delete _atlas;
|
||||
}
|
||||
|
||||
// CoinExample
|
||||
|
||||
bool CoinExample::init() {
|
||||
|
||||
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->setPosition(Vec2(_contentSize.width / 2, 100));
|
||||
skeletonNode = SkeletonAnimation::createWithBinaryFile("coin-pro.skel", "coin.atlas", 1);
|
||||
skeletonNode->setAnimation(0, "animation", true);
|
||||
|
||||
skeletonNode->setPosition(Vec2(_contentSize.width / 2, _contentSize.height / 2));
|
||||
addChild(skeletonNode);
|
||||
|
||||
scheduleUpdate();
|
||||
SCALE_SKELETON_NODE(skeletonNode);
|
||||
return true;
|
||||
}
|
||||
|
||||
// GoblinsExample
|
||||
|
||||
|
||||
bool GoblinsExample::init() {
|
||||
if (!SpineTestLayer::init()) return false;
|
||||
|
||||
_title = "GoblinsExample";
|
||||
|
||||
skeletonNode = SkeletonAnimation::createWithJsonFile("spine/goblins-pro.json", "spine/goblins.atlas", 1.5f);
|
||||
_title = "Goblins";
|
||||
skeletonNode = SkeletonAnimation::createWithJsonFile("goblins-pro.json", "goblins.atlas", 1.5f);
|
||||
skeletonNode->setAnimation(0, "walk", true);
|
||||
skeletonNode->setSkin("goblin");
|
||||
|
||||
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
||||
skeletonNode->setScale(0.6);
|
||||
addChild(skeletonNode);
|
||||
SCALE_SKELETON_NODE(skeletonNode);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool IKExample::init() {
|
||||
if (!SpineTestLayer::init()) return false;
|
||||
|
||||
_title = "IKExample";
|
||||
|
||||
// Load the Spineboy skeleton and create a SkeletonAnimation node from it
|
||||
// centered on the screen.
|
||||
skeletonNode = SkeletonAnimation::createWithJsonFile("spineboy-pro.json", "spineboy.atlas", 0.6f);
|
||||
skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MixAndMatchExample::~MixAndMatchExample() {
|
||||
delete skin;
|
||||
}
|
||||
|
||||
bool MixAndMatchExample::init() {
|
||||
if (!SpineTestLayer::init()) return false;
|
||||
|
||||
_title = "Mix and Match";
|
||||
|
||||
skeletonNode = SkeletonAnimation::createWithBinaryFile("mix-and-match-pro.skel", "mix-and-match.atlas", 0.5);
|
||||
skeletonNode->setAnimation(0, "dance", true);
|
||||
|
||||
// Create a new skin, by mixing and matching other skins
|
||||
// that fit together. Items making up the girl are individual
|
||||
// skins. Using the skin API, a new skin is created which is
|
||||
// a combination of all these individual item skins.
|
||||
SkeletonData* skeletonData = skeletonNode->getSkeleton()->getData();
|
||||
skin = new (__FILE__, __LINE__) Skin("mix-and-match");
|
||||
skin->addSkin(skeletonData->findSkin("skin-base"));
|
||||
skin->addSkin(skeletonData->findSkin("nose/short"));
|
||||
skin->addSkin(skeletonData->findSkin("eyelids/girly"));
|
||||
skin->addSkin(skeletonData->findSkin("eyes/violet"));
|
||||
skin->addSkin(skeletonData->findSkin("hair/brown"));
|
||||
skin->addSkin(skeletonData->findSkin("clothes/hoodie-orange"));
|
||||
skin->addSkin(skeletonData->findSkin("legs/pants-jeans"));
|
||||
skin->addSkin(skeletonData->findSkin("accessories/bag"));
|
||||
skin->addSkin(skeletonData->findSkin("accessories/hat-red-yellow"));
|
||||
skeletonNode->getSkeleton()->setSkin(skin);
|
||||
|
||||
skeletonNode->setPosition(Vec2(_contentSize.width / 2, _contentSize.height / 2 - 100 ));
|
||||
addChild(skeletonNode);
|
||||
|
||||
SCALE_SKELETON_NODE(skeletonNode);
|
||||
return true;
|
||||
}
|
||||
|
||||
// RaptorExample
|
||||
|
||||
bool RaptorExample::init() {
|
||||
if (!SpineTestLayer::init()) return false;
|
||||
|
||||
_title = "RaptorExample";
|
||||
skeletonNode = SkeletonAnimation::createWithJsonFile("spine/raptor-pro.json", "spine/raptor.atlas", 0.5f);
|
||||
|
||||
_title = "Raptor";
|
||||
skeletonNode = SkeletonAnimation::createWithJsonFile("raptor-pro.json", "raptor.atlas", 0.5f);
|
||||
skeletonNode->setAnimation(0, "walk", true);
|
||||
skeletonNode->setAnimation(1, "empty", false);
|
||||
skeletonNode->addAnimation(1, "gungrab", false, 2);
|
||||
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));
|
||||
skeletonNode->setScale(0.6);
|
||||
addChild(skeletonNode);
|
||||
|
||||
scheduleUpdate();
|
||||
|
||||
SCALE_SKELETON_NODE(skeletonNode);
|
||||
return true;
|
||||
}
|
||||
|
||||
// SpineboyExample
|
||||
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.
|
||||
// Director::getInstance()->replaceScene(SpineboyExample::scene());
|
||||
}
|
||||
|
||||
|
||||
bool SpineboyExample::init() {
|
||||
if (!SpineTestLayer::init()) return false;
|
||||
|
||||
_title = "SpineboyExample";
|
||||
skeletonNode = SkeletonAnimation::createWithJsonFile("spine/spineboy-ess.json", "spine/spineboy.atlas", 0.6f);
|
||||
skeletonNode->setStartListener( [] (spTrackEntry* entry) {
|
||||
log("%d start: %s", entry->trackIndex, entry->animation->name);
|
||||
_title = "Spineboy";
|
||||
|
||||
skeletonNode = SkeletonAnimation::createWithJsonFile("spineboy-pro.json", "spineboy.atlas", 0.6f);
|
||||
|
||||
skeletonNode->setStartListener([](TrackEntry* entry) {
|
||||
log("%d start: %s", entry->getTrackIndex(), entry->getAnimation()->getName().buffer());
|
||||
});
|
||||
skeletonNode->setInterruptListener( [] (spTrackEntry* entry) {
|
||||
log("%d interrupt", entry->trackIndex);
|
||||
skeletonNode->setInterruptListener([](TrackEntry* entry) {
|
||||
log("%d interrupt", entry->getTrackIndex());
|
||||
});
|
||||
skeletonNode->setEndListener( [] (spTrackEntry* entry) {
|
||||
log("%d end", entry->trackIndex);
|
||||
skeletonNode->setEndListener([](TrackEntry* entry) {
|
||||
log("%d end", entry->getTrackIndex());
|
||||
});
|
||||
skeletonNode->setCompleteListener( [] (spTrackEntry* entry) {
|
||||
log("%d complete", entry->trackIndex);
|
||||
skeletonNode->setCompleteListener([](TrackEntry* entry) {
|
||||
log("%d complete", entry->getTrackIndex());
|
||||
});
|
||||
skeletonNode->setDisposeListener( [] (spTrackEntry* entry) {
|
||||
log("%d dispose", entry->trackIndex);
|
||||
skeletonNode->setDisposeListener([](TrackEntry* entry) {
|
||||
log("%d dispose", entry->getTrackIndex());
|
||||
});
|
||||
skeletonNode->setEventListener( [] (spTrackEntry* entry, spEvent* event) {
|
||||
log("%d event: %s, %d, %f, %s", entry->trackIndex, event->data->name, event->intValue, event->floatValue, event->stringValue);
|
||||
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);
|
||||
spTrackEntry* jumpEntry = skeletonNode->addAnimation(0, "jump", false, 1);
|
||||
TrackEntry* jumpEntry = skeletonNode->addAnimation(0, "jump", false, 1);
|
||||
skeletonNode->addAnimation(0, "run", true);
|
||||
|
||||
skeletonNode->setTrackStartListener(jumpEntry, [] (spTrackEntry* entry) {
|
||||
skeletonNode->setTrackStartListener(jumpEntry, [](TrackEntry* entry) {
|
||||
log("jumped!");
|
||||
});
|
||||
|
||||
|
@ -206,11 +455,11 @@ bool SpineboyExample::init () {
|
|||
// 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);
|
||||
|
||||
scheduleUpdate();
|
||||
|
||||
SCALE_SKELETON_NODE(skeletonNode);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -219,18 +468,17 @@ void SpineboyExample::update (float deltaTime) {
|
|||
// Director::getInstance()->replaceScene(SpineboyExample::scene());
|
||||
}
|
||||
|
||||
// TankExample
|
||||
|
||||
bool TankExample::init() {
|
||||
if (!SpineTestLayer::init()) return false;
|
||||
|
||||
_title = "TankExample";
|
||||
skeletonNode = SkeletonAnimation::createWithJsonFile("spine/tank-pro.json", "spine/tank.atlas", 0.5f);
|
||||
skeletonNode->setAnimation(0, "drive", true);
|
||||
_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));
|
||||
skeletonNode->setScale(0.8);
|
||||
addChild(skeletonNode);
|
||||
|
||||
SCALE_SKELETON_NODE(skeletonNode);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -30,51 +30,94 @@
|
|||
#include "../BaseTest.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
|
||||
{
|
||||
public:
|
||||
SpineTestLayer();
|
||||
virtual ~SpineTestLayer();
|
||||
|
||||
virtual std::string title() const;
|
||||
virtual bool init();
|
||||
virtual std::string title() const override;
|
||||
protected:
|
||||
std::string _title;
|
||||
spine::SkeletonAnimation* skeletonNode = nullptr;
|
||||
int _touchIndex = 0;
|
||||
};
|
||||
|
||||
|
||||
class BatchingExample : public SpineTestLayer {
|
||||
public:
|
||||
|
||||
CREATE_FUNC(BatchingExample);
|
||||
~BatchingExample();
|
||||
|
||||
virtual bool init();
|
||||
|
||||
protected:
|
||||
spAtlas* _atlas;
|
||||
spAttachmentLoader* _attachmentLoader;
|
||||
spSkeletonData* _skeletonData;
|
||||
spAnimationStateData* _stateData;
|
||||
spine::Atlas* _atlas;
|
||||
spine::AttachmentLoader* _attachmentLoader;
|
||||
spine::SkeletonData* _skeletonData;
|
||||
spine::AnimationStateData* _stateData;
|
||||
};
|
||||
|
||||
class CoinExample: public SpineTestLayer
|
||||
{
|
||||
|
||||
class CoinExample : public SpineTestLayer {
|
||||
public:
|
||||
|
||||
CREATE_FUNC(CoinExample);
|
||||
|
||||
virtual bool init();
|
||||
|
||||
private:
|
||||
spine::SkeletonAnimation* skeletonNode;
|
||||
};
|
||||
|
||||
class GoblinsExample : public SpineTestLayer {
|
||||
public:
|
||||
CREATE_FUNC(GoblinsExample);
|
||||
|
||||
virtual bool init ();
|
||||
|
||||
};
|
||||
|
||||
class IKExample : public SpineTestLayer {
|
||||
public:
|
||||
|
||||
CREATE_FUNC(IKExample);
|
||||
|
||||
virtual bool init();
|
||||
|
||||
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 {
|
||||
|
@ -83,8 +126,24 @@ public:
|
|||
|
||||
virtual bool init();
|
||||
|
||||
virtual void update(float fDelta);
|
||||
|
||||
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 {
|
||||
|
@ -95,8 +154,6 @@ public:
|
|||
|
||||
virtual void update(float deltaTime);
|
||||
|
||||
private:
|
||||
spine::SkeletonAnimation* skeletonNode;
|
||||
};
|
||||
|
||||
class TankExample : public SpineTestLayer {
|
||||
|
@ -105,8 +162,6 @@ public:
|
|||
|
||||
virtual bool init();
|
||||
|
||||
private:
|
||||
spine::SkeletonAnimation* skeletonNode;
|
||||
};
|
||||
|
||||
#endif // _EXAMPLELAYER_H_
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
addTest("Node: Physics3D", []() { return new Physics3DTests(); } );
|
||||
addTest("Node: RenderTexture", [](){return new RenderTextureTests(); });
|
||||
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: Sprite3D", [](){ return new Sprite3DTests(); });
|
||||
addTest("Node: SpritePolygon", [](){return new (std::nothrow) SpritePolygonTest(); });
|
||||
|
|
|
@ -1,26 +1,54 @@
|
|||
|
||||
coin.png
|
||||
size: 1024,256
|
||||
size: 1024,1024
|
||||
format: RGBA8888
|
||||
filter: Linear,Linear
|
||||
repeat: none
|
||||
coin
|
||||
coin-front-logo
|
||||
rotate: false
|
||||
xy: 2, 2
|
||||
size: 259, 245
|
||||
orig: 259, 245
|
||||
xy: 2, 609
|
||||
size: 305, 302
|
||||
orig: 305, 302
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
coin-invert
|
||||
coin-front-shine-logo
|
||||
rotate: false
|
||||
xy: 263, 2
|
||||
size: 259, 245
|
||||
orig: 259, 245
|
||||
xy: 309, 629
|
||||
size: 282, 282
|
||||
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
|
||||
index: -1
|
||||
shine
|
||||
rotate: false
|
||||
xy: 524, 2
|
||||
xy: 593, 666
|
||||
size: 72, 245
|
||||
orig: 72, 245
|
||||
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
|
||||
size: 1024,1024
|
||||
size: 1024,512
|
||||
format: RGBA8888
|
||||
filter: Linear,Linear
|
||||
repeat: none
|
||||
back-arm
|
||||
rotate: true
|
||||
xy: 274, 394
|
||||
size: 46, 29
|
||||
orig: 46, 29
|
||||
rotate: false
|
||||
xy: 895, 295
|
||||
size: 46, 25
|
||||
orig: 46, 25
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
back-bracer
|
||||
rotate: true
|
||||
xy: 140, 247
|
||||
xy: 992, 216
|
||||
size: 39, 28
|
||||
orig: 39, 28
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
back-hand
|
||||
rotate: false
|
||||
xy: 824, 699
|
||||
xy: 594, 58
|
||||
size: 36, 34
|
||||
orig: 36, 34
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
back-knee
|
||||
rotate: false
|
||||
xy: 360, 507
|
||||
rotate: true
|
||||
xy: 729, 86
|
||||
size: 49, 67
|
||||
orig: 49, 67
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
back-thigh
|
||||
rotate: true
|
||||
xy: 140, 206
|
||||
rotate: false
|
||||
xy: 379, 2
|
||||
size: 39, 24
|
||||
orig: 39, 24
|
||||
offset: 0, 0
|
||||
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
|
||||
rotate: true
|
||||
xy: 2, 2
|
||||
xy: 902, 194
|
||||
size: 47, 45
|
||||
orig: 47, 45
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-arm
|
||||
rotate: false
|
||||
xy: 470, 544
|
||||
size: 48, 30
|
||||
orig: 48, 30
|
||||
xy: 945, 306
|
||||
size: 48, 26
|
||||
orig: 48, 26
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-bracer
|
||||
rotate: true
|
||||
xy: 274, 351
|
||||
rotate: false
|
||||
xy: 949, 197
|
||||
size: 41, 29
|
||||
orig: 41, 29
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-hand
|
||||
rotate: false
|
||||
xy: 827, 773
|
||||
xy: 949, 266
|
||||
size: 41, 38
|
||||
orig: 41, 38
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-open-hand
|
||||
rotate: false
|
||||
xy: 360, 461
|
||||
xy: 875, 148
|
||||
size: 43, 44
|
||||
orig: 43, 44
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-thigh
|
||||
rotate: false
|
||||
xy: 411, 545
|
||||
rotate: true
|
||||
xy: 793, 171
|
||||
size: 57, 29
|
||||
orig: 57, 29
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
gun
|
||||
rotate: false
|
||||
xy: 195, 442
|
||||
rotate: true
|
||||
xy: 379, 28
|
||||
size: 107, 103
|
||||
orig: 107, 103
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
gun-nohand
|
||||
rotate: false
|
||||
xy: 167, 338
|
||||
xy: 487, 87
|
||||
size: 105, 102
|
||||
orig: 105, 102
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
head
|
||||
rotate: false
|
||||
xy: 2, 137
|
||||
xy: 807, 361
|
||||
size: 136, 149
|
||||
orig: 136, 149
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
lower-leg
|
||||
rotate: true
|
||||
xy: 648, 667
|
||||
rotate: false
|
||||
xy: 827, 195
|
||||
size: 73, 98
|
||||
orig: 73, 98
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth-grind
|
||||
rotate: true
|
||||
xy: 49, 2
|
||||
xy: 920, 145
|
||||
size: 47, 30
|
||||
orig: 47, 30
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth-smile
|
||||
rotate: true
|
||||
xy: 81, 2
|
||||
xy: 992, 257
|
||||
size: 47, 30
|
||||
orig: 47, 30
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
neck
|
||||
rotate: false
|
||||
xy: 626, 631
|
||||
xy: 359, 114
|
||||
size: 18, 21
|
||||
orig: 18, 21
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-arm-back
|
||||
rotate: true
|
||||
xy: 538, 570
|
||||
raptor-back-arm
|
||||
rotate: false
|
||||
xy: 653, 142
|
||||
size: 82, 86
|
||||
orig: 82, 86
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-body
|
||||
rotate: false
|
||||
xy: 2, 737
|
||||
size: 632, 285
|
||||
orig: 632, 285
|
||||
xy: 2, 277
|
||||
size: 632, 233
|
||||
orig: 632, 233
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-front-arm
|
||||
rotate: true
|
||||
xy: 544, 654
|
||||
xy: 484, 4
|
||||
size: 81, 102
|
||||
orig: 81, 102
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-front-leg
|
||||
rotate: false
|
||||
xy: 2, 478
|
||||
xy: 2, 18
|
||||
size: 191, 257
|
||||
orig: 191, 257
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-hindleg-back
|
||||
rotate: false
|
||||
xy: 636, 807
|
||||
xy: 636, 295
|
||||
size: 169, 215
|
||||
orig: 169, 215
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-horn
|
||||
rotate: false
|
||||
xy: 360, 655
|
||||
xy: 195, 22
|
||||
size: 182, 80
|
||||
orig: 182, 80
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-horn-back
|
||||
rotate: false
|
||||
xy: 360, 576
|
||||
rotate: true
|
||||
xy: 945, 334
|
||||
size: 176, 77
|
||||
orig: 176, 77
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-jaw
|
||||
rotate: false
|
||||
xy: 807, 879
|
||||
size: 153, 143
|
||||
orig: 153, 143
|
||||
xy: 359, 137
|
||||
size: 126, 138
|
||||
orig: 126, 138
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-jaw-tooth
|
||||
rotate: true
|
||||
xy: 940, 840
|
||||
xy: 895, 322
|
||||
size: 37, 48
|
||||
orig: 37, 48
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-mouth-inside
|
||||
rotate: true
|
||||
xy: 827, 735
|
||||
xy: 949, 228
|
||||
size: 36, 41
|
||||
orig: 36, 41
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-saddle-noshadow
|
||||
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
|
||||
raptor-saddle-strap-back
|
||||
rotate: true
|
||||
xy: 748, 686
|
||||
xy: 653, 86
|
||||
size: 54, 74
|
||||
orig: 54, 74
|
||||
offset: 0, 0
|
||||
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
|
||||
rotate: false
|
||||
xy: 195, 547
|
||||
size: 163, 188
|
||||
orig: 163, 188
|
||||
xy: 195, 104
|
||||
size: 162, 171
|
||||
orig: 162, 171
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-tail-shadow
|
||||
rotate: false
|
||||
xy: 636, 742
|
||||
xy: 636, 230
|
||||
size: 189, 63
|
||||
orig: 189, 63
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
raptor-tongue
|
||||
rotate: false
|
||||
xy: 807, 813
|
||||
xy: 807, 295
|
||||
size: 86, 64
|
||||
orig: 86, 64
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
stirrup-back
|
||||
rotate: false
|
||||
xy: 411, 508
|
||||
rotate: true
|
||||
xy: 952, 151
|
||||
size: 44, 35
|
||||
orig: 44, 35
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
stirrup-front
|
||||
rotate: true
|
||||
xy: 167, 291
|
||||
rotate: false
|
||||
xy: 902, 243
|
||||
size: 45, 50
|
||||
orig: 45, 50
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
stirrup-strap
|
||||
rotate: false
|
||||
xy: 962, 879
|
||||
xy: 824, 147
|
||||
size: 49, 46
|
||||
orig: 49, 46
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
torso
|
||||
rotate: false
|
||||
xy: 304, 454
|
||||
xy: 737, 137
|
||||
size: 54, 91
|
||||
orig: 54, 91
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
visor
|
||||
rotate: false
|
||||
xy: 2, 51
|
||||
xy: 487, 191
|
||||
size: 131, 84
|
||||
orig: 131, 84
|
||||
offset: 0, 0
|
||||
|
|
Before Width: | Height: | Size: 510 KiB After Width: | Height: | Size: 469 KiB |
|
@ -1,306 +1,285 @@
|
|||
|
||||
spineboy.png
|
||||
size: 1024,512
|
||||
size: 1024,256
|
||||
format: RGBA8888
|
||||
filter: Linear,Linear
|
||||
repeat: none
|
||||
crosshair
|
||||
rotate: false
|
||||
xy: 794, 167
|
||||
xy: 352, 7
|
||||
size: 45, 45
|
||||
orig: 45, 45
|
||||
offset: 0, 0
|
||||
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
|
||||
rotate: false
|
||||
xy: 960, 229
|
||||
xy: 862, 105
|
||||
size: 47, 45
|
||||
orig: 47, 45
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
eye-surprised
|
||||
rotate: false
|
||||
xy: 745, 167
|
||||
xy: 505, 79
|
||||
size: 47, 45
|
||||
orig: 47, 45
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-bracer
|
||||
rotate: false
|
||||
xy: 547, 2
|
||||
xy: 826, 66
|
||||
size: 29, 40
|
||||
orig: 29, 40
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-fist-closed
|
||||
rotate: false
|
||||
xy: 920, 190
|
||||
xy: 786, 65
|
||||
size: 38, 41
|
||||
orig: 38, 41
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-fist-open
|
||||
rotate: false
|
||||
xy: 437, 2
|
||||
rotate: true
|
||||
xy: 710, 51
|
||||
size: 43, 44
|
||||
orig: 43, 44
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-foot
|
||||
rotate: false
|
||||
xy: 482, 11
|
||||
xy: 210, 6
|
||||
size: 63, 35
|
||||
orig: 63, 35
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-shin
|
||||
rotate: true
|
||||
xy: 866, 233
|
||||
xy: 665, 128
|
||||
size: 41, 92
|
||||
orig: 41, 92
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-thigh
|
||||
rotate: false
|
||||
xy: 719, 155
|
||||
size: 24, 56
|
||||
orig: 24, 56
|
||||
rotate: true
|
||||
xy: 2, 2
|
||||
size: 23, 56
|
||||
orig: 23, 56
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
front-upper-arm
|
||||
rotate: false
|
||||
xy: 719, 104
|
||||
size: 27, 49
|
||||
orig: 27, 49
|
||||
xy: 250, 205
|
||||
size: 23, 49
|
||||
orig: 23, 49
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
goggles
|
||||
rotate: false
|
||||
xy: 881, 276
|
||||
xy: 665, 171
|
||||
size: 131, 83
|
||||
orig: 131, 83
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
gun
|
||||
rotate: false
|
||||
xy: 612, 109
|
||||
xy: 798, 152
|
||||
size: 105, 102
|
||||
orig: 105, 102
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
head
|
||||
rotate: false
|
||||
xy: 881, 361
|
||||
xy: 2, 27
|
||||
size: 136, 149
|
||||
orig: 136, 149
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hoverboard-board
|
||||
rotate: false
|
||||
xy: 2, 38
|
||||
xy: 2, 178
|
||||
size: 246, 76
|
||||
orig: 246, 76
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hoverboard-thruster
|
||||
rotate: true
|
||||
xy: 578, 12
|
||||
xy: 722, 96
|
||||
size: 30, 32
|
||||
orig: 30, 32
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
hoverglow-small
|
||||
rotate: true
|
||||
xy: 572, 44
|
||||
rotate: false
|
||||
xy: 275, 81
|
||||
size: 137, 38
|
||||
orig: 137, 38
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth-grind
|
||||
rotate: true
|
||||
xy: 713, 55
|
||||
rotate: false
|
||||
xy: 614, 97
|
||||
size: 47, 30
|
||||
orig: 47, 30
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth-oooo
|
||||
rotate: true
|
||||
xy: 713, 6
|
||||
rotate: false
|
||||
xy: 612, 65
|
||||
size: 47, 30
|
||||
orig: 47, 30
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
mouth-smile
|
||||
rotate: false
|
||||
xy: 748, 135
|
||||
xy: 661, 64
|
||||
size: 47, 30
|
||||
orig: 47, 30
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
muzzle-glow
|
||||
rotate: false
|
||||
xy: 612, 8
|
||||
size: 99, 99
|
||||
orig: 99, 99
|
||||
xy: 382, 54
|
||||
size: 25, 25
|
||||
orig: 25, 25
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
muzzle-ring
|
||||
rotate: false
|
||||
xy: 302, 190
|
||||
rotate: true
|
||||
xy: 275, 54
|
||||
size: 25, 105
|
||||
orig: 25, 105
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
muzzle01
|
||||
rotate: false
|
||||
xy: 336, 335
|
||||
size: 271, 175
|
||||
orig: 271, 175
|
||||
rotate: true
|
||||
xy: 911, 95
|
||||
size: 67, 40
|
||||
orig: 67, 40
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
muzzle02
|
||||
rotate: false
|
||||
xy: 609, 341
|
||||
size: 270, 169
|
||||
orig: 270, 169
|
||||
xy: 792, 108
|
||||
size: 68, 42
|
||||
orig: 68, 42
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
muzzle03
|
||||
rotate: false
|
||||
xy: 2, 297
|
||||
size: 332, 213
|
||||
orig: 332, 213
|
||||
rotate: true
|
||||
xy: 956, 171
|
||||
size: 83, 53
|
||||
orig: 83, 53
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
muzzle04
|
||||
rotate: false
|
||||
xy: 2, 116
|
||||
size: 298, 179
|
||||
orig: 298, 179
|
||||
xy: 275, 7
|
||||
size: 75, 45
|
||||
orig: 75, 45
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
muzzle05
|
||||
rotate: false
|
||||
xy: 336, 183
|
||||
size: 269, 150
|
||||
orig: 269, 150
|
||||
xy: 140, 3
|
||||
size: 68, 38
|
||||
orig: 68, 38
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
neck
|
||||
rotate: false
|
||||
xy: 841, 191
|
||||
xy: 250, 182
|
||||
size: 18, 21
|
||||
orig: 18, 21
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
portal-bg
|
||||
rotate: false
|
||||
xy: 302, 48
|
||||
xy: 140, 43
|
||||
size: 133, 133
|
||||
orig: 133, 133
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
portal-flare1
|
||||
rotate: false
|
||||
xy: 180, 6
|
||||
xy: 554, 65
|
||||
size: 56, 30
|
||||
orig: 56, 30
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
portal-flare2
|
||||
rotate: false
|
||||
xy: 2, 5
|
||||
rotate: true
|
||||
xy: 759, 112
|
||||
size: 57, 31
|
||||
orig: 57, 31
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
portal-flare3
|
||||
rotate: false
|
||||
xy: 61, 6
|
||||
xy: 554, 97
|
||||
size: 58, 30
|
||||
orig: 58, 30
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
portal-shade
|
||||
rotate: false
|
||||
xy: 437, 48
|
||||
xy: 275, 121
|
||||
size: 133, 133
|
||||
orig: 133, 133
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
portal-streaks1
|
||||
rotate: true
|
||||
xy: 609, 213
|
||||
rotate: false
|
||||
xy: 410, 126
|
||||
size: 126, 128
|
||||
orig: 126, 128
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
portsl-streaks2
|
||||
portal-streaks2
|
||||
rotate: false
|
||||
xy: 739, 214
|
||||
xy: 538, 129
|
||||
size: 125, 125
|
||||
orig: 125, 125
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear-bracer
|
||||
rotate: true
|
||||
xy: 797, 137
|
||||
rotate: false
|
||||
xy: 857, 67
|
||||
size: 28, 36
|
||||
orig: 28, 36
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear-foot
|
||||
rotate: false
|
||||
xy: 121, 6
|
||||
xy: 663, 96
|
||||
size: 57, 30
|
||||
orig: 57, 30
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear-shin
|
||||
rotate: true
|
||||
xy: 301, 8
|
||||
xy: 414, 86
|
||||
size: 38, 89
|
||||
orig: 38, 89
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear-thigh
|
||||
rotate: true
|
||||
xy: 866, 198
|
||||
size: 33, 52
|
||||
orig: 33, 52
|
||||
rotate: false
|
||||
xy: 756, 63
|
||||
size: 28, 47
|
||||
orig: 28, 47
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
rear-upper-arm
|
||||
rotate: true
|
||||
xy: 748, 109
|
||||
size: 24, 44
|
||||
orig: 24, 44
|
||||
xy: 60, 5
|
||||
size: 20, 44
|
||||
orig: 20, 44
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
torso
|
||||
rotate: false
|
||||
xy: 250, 24
|
||||
xy: 905, 164
|
||||
size: 49, 90
|
||||
orig: 49, 90
|
||||
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 |