mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
[cpp] Fixed up binary reader, added debug extension for memory profiling, fixed up RTTI usage, fixed update cache sorting.
This commit is contained in:
parent
2d41846b1f
commit
a8fd3e14be
@ -10,7 +10,6 @@ include_directories(../spine-cpp/include teamcity minicppunit tests memory)
|
||||
|
||||
set(SRC
|
||||
src/main.cpp
|
||||
src/TestHarness.cpp
|
||||
)
|
||||
|
||||
add_executable(spine_cpp_unit_test ${SRC})
|
||||
|
||||
@ -1,91 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
||||
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include "TestHarness.h"
|
||||
|
||||
void *Spine::TestSpineExtension::_alloc(size_t size, const char *file, int line) {
|
||||
void* result = DefaultSpineExtension::_alloc(size, file, line);
|
||||
_allocated.push_back(Allocation(result, size, file, line));
|
||||
_allocations++;
|
||||
return result;
|
||||
}
|
||||
|
||||
void *Spine::TestSpineExtension::_calloc(size_t size, const char *file, int line) {
|
||||
void* result = DefaultSpineExtension::_calloc(size, file, line);
|
||||
_allocated.push_back(Allocation(result, size, file, line));
|
||||
_allocations++;
|
||||
return result;
|
||||
}
|
||||
|
||||
void *Spine::TestSpineExtension::_realloc(void *ptr, size_t size, const char *file, int line) {
|
||||
void* result = DefaultSpineExtension::_realloc(ptr, size, file, line);
|
||||
_reallocations++;
|
||||
|
||||
for (std::vector<Allocation>::iterator it = _allocated.begin(); it != _allocated.end(); it++) {
|
||||
if (it->address == ptr) {
|
||||
it->address = result;
|
||||
it->size = size;
|
||||
it->fileName = file;
|
||||
it->line = line;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
_allocated.push_back(Allocation(result, size, file, line));
|
||||
return result;
|
||||
}
|
||||
|
||||
void Spine::TestSpineExtension::_free(void *mem, const char *file, int line) {
|
||||
|
||||
for (std::vector<Allocation>::iterator it = _allocated.begin(); it != _allocated.end(); it++) {
|
||||
if (it->address == mem) {
|
||||
DefaultSpineExtension::_free(mem, file, line);
|
||||
_frees++;
|
||||
_allocated.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s:%i (address %p): Double free or not allocated through SpineExtension\n", file, line, mem);
|
||||
DefaultSpineExtension::_free(mem, file, line);
|
||||
}
|
||||
|
||||
void Spine::TestSpineExtension::reportLeaks() {
|
||||
for (std::vector<Allocation>::iterator it = _allocated.begin(); it != _allocated.end(); it++) {
|
||||
printf("\"%s:%i (%zu bytes at %p)\n", it->fileName, it->line, it->size, it->address);
|
||||
}
|
||||
printf("allocations: %lu, reallocations: %lu, frees: %lu\n", _allocations, _reallocations, _frees);
|
||||
if (_allocated.empty()) printf("No leaks detected");
|
||||
}
|
||||
|
||||
void Spine::TestSpineExtension::clearAllocations() {
|
||||
_allocated.resize(0);
|
||||
}
|
||||
@ -30,8 +30,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <spine/spine.h>
|
||||
|
||||
#include "TestHarness.h"
|
||||
#include <spine/Debug.h>
|
||||
|
||||
using namespace Spine;
|
||||
|
||||
@ -115,7 +114,7 @@ void testLoading() {
|
||||
}
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
TestSpineExtension* ext = new TestSpineExtension();
|
||||
DebugExtension* ext = new DebugExtension();
|
||||
SpineExtension::setInstance(ext);
|
||||
|
||||
testLoading();
|
||||
|
||||
@ -1,7 +1,32 @@
|
||||
//
|
||||
// Created by Mario Zechner on 2/20/18.
|
||||
//
|
||||
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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.
|
||||
*****************************************************************************/
|
||||
#ifndef SPINE_COLOR_H
|
||||
#define SPINE_COLOR_H
|
||||
|
||||
|
||||
@ -28,40 +28,87 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef SPINE_TESTHARNESS_H
|
||||
#define SPINE_TESTHARNESS_H
|
||||
#ifndef SPINE_DEBUG_H
|
||||
#define SPINE_DEBUG_H
|
||||
|
||||
#include <spine/Extension.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Spine {
|
||||
struct Allocation {
|
||||
void* address;
|
||||
size_t size;
|
||||
const char* fileName;
|
||||
int line;
|
||||
class DebugExtension: public DefaultSpineExtension {
|
||||
struct Allocation {
|
||||
void* address;
|
||||
size_t size;
|
||||
const char* fileName;
|
||||
int line;
|
||||
|
||||
Allocation() : address(NULL), size(0), fileName(NULL), line(0) {
|
||||
}
|
||||
Allocation() : address(NULL), size(0), fileName(NULL), line(0) {
|
||||
}
|
||||
|
||||
Allocation(void* a, size_t s, const char* f, int l) : address(a), size(s), fileName(f), line(l) {
|
||||
}
|
||||
};
|
||||
Allocation(void* a, size_t s, const char* f, int l) : address(a), size(s), fileName(f), line(l) {
|
||||
}
|
||||
};
|
||||
|
||||
class TestSpineExtension: public DefaultSpineExtension {
|
||||
public:
|
||||
void reportLeaks ();
|
||||
void clearAllocations();
|
||||
void reportLeaks () {
|
||||
for (std::vector<Allocation>::iterator it = _allocated.begin(); it != _allocated.end(); it++) {
|
||||
printf("\"%s:%i (%zu bytes at %p)\n", it->fileName, it->line, it->size, it->address);
|
||||
}
|
||||
printf("allocations: %lu, reallocations: %lu, frees: %lu\n", _allocations, _reallocations, _frees);
|
||||
if (_allocated.empty()) printf("No leaks detected");
|
||||
}
|
||||
|
||||
void clearAllocations() {
|
||||
_allocated.resize(0);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void* _alloc(size_t size, const char* file, int line);
|
||||
virtual void* _alloc(size_t size, const char* file, int line) {
|
||||
void* result = DefaultSpineExtension::_alloc(size, file, line);
|
||||
_allocated.push_back(Allocation(result, size, file, line));
|
||||
_allocations++;
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void* _calloc(size_t size, const char* file, int line);
|
||||
virtual void* _calloc(size_t size, const char* file, int line) {
|
||||
void* result = DefaultSpineExtension::_calloc(size, file, line);
|
||||
_allocated.push_back(Allocation(result, size, file, line));
|
||||
_allocations++;
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void* _realloc(void* ptr, size_t size, const char* file, int line);
|
||||
virtual void* _realloc(void* ptr, size_t size, const char* file, int line) {
|
||||
void* result = DefaultSpineExtension::_realloc(ptr, size, file, line);
|
||||
_reallocations++;
|
||||
|
||||
virtual void _free(void* mem, const char* file, int line);
|
||||
for (std::vector<Allocation>::iterator it = _allocated.begin(); it != _allocated.end(); it++) {
|
||||
if (it->address == ptr) {
|
||||
it->address = result;
|
||||
it->size = size;
|
||||
it->fileName = file;
|
||||
it->line = line;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
_allocated.push_back(Allocation(result, size, file, line));
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void _free(void* mem, const char* file, int line) {
|
||||
for (std::vector<Allocation>::iterator it = _allocated.begin(); it != _allocated.end(); it++) {
|
||||
if (it->address == mem) {
|
||||
DefaultSpineExtension::_free(mem, file, line);
|
||||
_frees++;
|
||||
_allocated.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s:%i (address %p): Double free or not allocated through SpineExtension\n", file, line, mem);
|
||||
DefaultSpineExtension::_free(mem, file, line);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Allocation> _allocated;
|
||||
@ -72,4 +119,4 @@ namespace Spine {
|
||||
}
|
||||
|
||||
|
||||
#endif //SPINE_TESTHARNESS_H
|
||||
#endif //SPINE_DEBUG_H
|
||||
@ -99,6 +99,19 @@ namespace Spine {
|
||||
|
||||
virtual char* _readFile(const String& path, int* length);
|
||||
};
|
||||
|
||||
struct Allocation {
|
||||
void* address;
|
||||
size_t size;
|
||||
const char* fileName;
|
||||
int line;
|
||||
|
||||
Allocation() : address(NULL), size(0), fileName(NULL), line(0) {
|
||||
}
|
||||
|
||||
Allocation(void* a, size_t s, const char* f, int l) : address(a), size(s), fileName(f), line(l) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_Extension_h */
|
||||
|
||||
@ -45,8 +45,8 @@ namespace Spine {
|
||||
const std::string& getClassName() const;
|
||||
|
||||
bool isExactly(const RTTI& rtti) const;
|
||||
|
||||
bool derivesFrom(const RTTI& rtti) const;
|
||||
|
||||
bool instanceOf(const RTTI &rtti) const;
|
||||
|
||||
private:
|
||||
// Prevent copying
|
||||
|
||||
@ -78,6 +78,8 @@ namespace Spine {
|
||||
/// Caches information about bones and constraints. Must be called if bones, constraints or weighted path attachments are added
|
||||
/// or removed.
|
||||
void updateCache();
|
||||
|
||||
void printUpdateCache ();
|
||||
|
||||
/// Updates the world transform for each bone and applies constraints.
|
||||
void updateWorldTransform();
|
||||
|
||||
@ -113,9 +113,9 @@ namespace Spine {
|
||||
|
||||
int readVarint(DataInput* input, bool optimizePositive);
|
||||
|
||||
Skin* readSkin(DataInput* input, const char* skinName, SkeletonData* skeletonData, bool nonessential);
|
||||
Skin* readSkin(DataInput* input, const String& skinName, SkeletonData* skeletonData, bool nonessential);
|
||||
|
||||
Attachment* readAttachment(DataInput* input, Skin* skin, int slotIndex, const char* attachmentName, SkeletonData* skeletonData, bool nonessential);
|
||||
Attachment* readAttachment(DataInput* input, Skin* skin, int slotIndex, const String& attachmentName, SkeletonData* skeletonData, bool nonessential);
|
||||
|
||||
void readVertices(DataInput* input, VertexAttachment* attachment, int vertexCount);
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ namespace Spine {
|
||||
public:
|
||||
SlotData(int index, const String& name, BoneData& boneData);
|
||||
|
||||
const int getIndex();
|
||||
int getIndex();
|
||||
|
||||
const String& getName();
|
||||
|
||||
|
||||
@ -72,6 +72,10 @@ namespace Spine {
|
||||
return _length;
|
||||
}
|
||||
|
||||
bool isEmpty () const {
|
||||
return _length == 0;
|
||||
}
|
||||
|
||||
const char* buffer () const {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ namespace Spine {
|
||||
deallocate(_buffer);
|
||||
}
|
||||
|
||||
void clear () {
|
||||
inline void clear () {
|
||||
for (size_t i = 0; i < _size; ++i) {
|
||||
destroy(_buffer + (_size - 1 - i));
|
||||
}
|
||||
@ -88,11 +88,11 @@ namespace Spine {
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
inline size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
void setSize(size_t newSize) {
|
||||
inline void setSize(size_t newSize) {
|
||||
assert(newSize >= 0);
|
||||
_size = newSize;
|
||||
if (_capacity < newSize) {
|
||||
@ -102,13 +102,13 @@ namespace Spine {
|
||||
}
|
||||
}
|
||||
|
||||
void ensureCapacity(size_t newCapacity = 0) {
|
||||
inline void ensureCapacity(size_t newCapacity = 0) {
|
||||
if (_capacity >= newCapacity) return;
|
||||
_capacity = newCapacity;
|
||||
_buffer = SpineExtension::realloc<T>(_buffer, newCapacity, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void add(const T &inValue) {
|
||||
inline void add(const T &inValue) {
|
||||
if (_size == _capacity) {
|
||||
_capacity = (int)(_size * 1.75f);
|
||||
if (_capacity < 8) _capacity = 8;
|
||||
@ -117,7 +117,7 @@ namespace Spine {
|
||||
construct(_buffer + _size++, inValue);
|
||||
}
|
||||
|
||||
void removeAt(size_t inIndex) {
|
||||
inline void removeAt(size_t inIndex) {
|
||||
assert(inIndex < _size);
|
||||
|
||||
--_size;
|
||||
@ -131,7 +131,7 @@ namespace Spine {
|
||||
destroy(_buffer + _size);
|
||||
}
|
||||
|
||||
bool contains(const T& inValue) {
|
||||
inline bool contains(const T& inValue) {
|
||||
for (size_t i = 0; i < _size; ++i) {
|
||||
if (_buffer[i] == inValue) {
|
||||
return true;
|
||||
@ -141,7 +141,7 @@ namespace Spine {
|
||||
return false;
|
||||
}
|
||||
|
||||
int indexOf(const T& inValue) {
|
||||
inline int indexOf(const T& inValue) {
|
||||
for (size_t i = 0; i < _size; ++i) {
|
||||
if (_buffer[i] == inValue) {
|
||||
return static_cast<int>(i);
|
||||
@ -151,13 +151,13 @@ namespace Spine {
|
||||
return -1;
|
||||
}
|
||||
|
||||
T& operator[](size_t inIndex) {
|
||||
inline T& operator[](size_t inIndex) {
|
||||
assert(inIndex < _size);
|
||||
|
||||
return _buffer[inIndex];
|
||||
}
|
||||
|
||||
friend bool operator==(Vector<T>& lhs, Vector<T>& rhs) {
|
||||
inline friend bool operator==(Vector<T>& lhs, Vector<T>& rhs) {
|
||||
if (lhs.size() != rhs.size()) {
|
||||
return false;
|
||||
}
|
||||
@ -171,11 +171,11 @@ namespace Spine {
|
||||
return true;
|
||||
}
|
||||
|
||||
friend bool operator!=(Vector<T>& lhs, Vector<T>& rhs) {
|
||||
inline friend bool operator!=(Vector<T>& lhs, Vector<T>& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
T* buffer() {
|
||||
inline T* buffer() {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
|
||||
@ -428,7 +428,7 @@ namespace Spine {
|
||||
MixPose pose = timelineData[ii] >= AnimationState::First ? MixPose_Setup : currentPose;
|
||||
|
||||
RotateTimeline* rotateTimeline = NULL;
|
||||
if (timeline->getRTTI().derivesFrom(RotateTimeline::rtti)) {
|
||||
if (timeline->getRTTI().isExactly(RotateTimeline::rtti)) {
|
||||
rotateTimeline = static_cast<RotateTimeline*>(timeline);
|
||||
}
|
||||
|
||||
@ -784,10 +784,10 @@ namespace Spine {
|
||||
Timeline* timeline = timelines[i];
|
||||
switch (timelineData[i]) {
|
||||
case Subsequent:
|
||||
if (!attachments && timeline->getRTTI().derivesFrom(AttachmentTimeline::rtti)) {
|
||||
if (!attachments && timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) {
|
||||
continue;
|
||||
}
|
||||
if (!drawOrder && timeline->getRTTI().derivesFrom(DrawOrderTimeline::rtti)) {
|
||||
if (!drawOrder && timeline->getRTTI().isExactly(DrawOrderTimeline::rtti)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -811,7 +811,7 @@ namespace Spine {
|
||||
from->_totalAlpha += alpha;
|
||||
|
||||
RotateTimeline* rotateTimeline = NULL;
|
||||
if (timeline->getRTTI().derivesFrom(RotateTimeline::rtti)) {
|
||||
if (timeline->getRTTI().isExactly(RotateTimeline::rtti)) {
|
||||
rotateTimeline = static_cast<RotateTimeline*>(timeline);
|
||||
}
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ namespace Spine {
|
||||
Slot* slotP = skeleton._slots[_slotIndex];
|
||||
Slot& slot = *slotP;
|
||||
|
||||
if (slot._attachment == NULL || !slot._attachment->getRTTI().derivesFrom(VertexAttachment::rtti)) {
|
||||
if (slot._attachment == NULL || !slot._attachment->getRTTI().instanceOf(VertexAttachment::rtti)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -73,7 +73,7 @@ namespace Spine {
|
||||
|
||||
void PathConstraint::update() {
|
||||
Attachment* baseAttachment = _target->getAttachment();
|
||||
if (baseAttachment == NULL || !baseAttachment->getRTTI().derivesFrom(PathAttachment::rtti)) {
|
||||
if (baseAttachment == NULL || !baseAttachment->getRTTI().instanceOf(PathAttachment::rtti)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -45,18 +45,18 @@ namespace Spine {
|
||||
bool RTTI::isExactly(const RTTI& rtti) const {
|
||||
return (this == &rtti);
|
||||
}
|
||||
|
||||
bool RTTI::derivesFrom(const RTTI& rtti) const {
|
||||
|
||||
bool RTTI::instanceOf(const RTTI &rtti) const {
|
||||
const RTTI * pCompare = this;
|
||||
|
||||
|
||||
while (pCompare) {
|
||||
if (pCompare == &rtti) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
pCompare = pCompare->_pBaseRTTI;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,57 +142,57 @@ namespace Spine {
|
||||
int pathCount = static_cast<int>(_pathConstraints.size());
|
||||
|
||||
int constraintCount = ikCount + transformCount + pathCount;
|
||||
|
||||
for (int i = 0; i < constraintCount; ++i) {
|
||||
bool gotoNextConstraintCount = false;
|
||||
|
||||
|
||||
int i = 0;
|
||||
continue_outer:
|
||||
for (; i < constraintCount; ++i) {
|
||||
for (int ii = 0; ii < ikCount; ++ii) {
|
||||
IkConstraint* constraint = _ikConstraints[ii];
|
||||
if (constraint->getData().getOrder() == i) {
|
||||
sortIkConstraint(constraint);
|
||||
|
||||
gotoNextConstraintCount = true;
|
||||
break;
|
||||
i++;
|
||||
goto continue_outer;
|
||||
}
|
||||
}
|
||||
|
||||
if (gotoNextConstraintCount) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < transformCount; ++ii) {
|
||||
TransformConstraint* constraint = _transformConstraints[ii];
|
||||
if (constraint->getData().getOrder() == i) {
|
||||
sortTransformConstraint(constraint);
|
||||
|
||||
gotoNextConstraintCount = true;
|
||||
break;
|
||||
i++;
|
||||
goto continue_outer;
|
||||
}
|
||||
}
|
||||
|
||||
if (gotoNextConstraintCount) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < pathCount; ++ii) {
|
||||
PathConstraint* constraint = _pathConstraints[ii];
|
||||
if (constraint->getData().getOrder() == i) {
|
||||
sortPathConstraint(constraint);
|
||||
|
||||
gotoNextConstraintCount = true;
|
||||
break;
|
||||
i++;
|
||||
goto continue_outer;
|
||||
}
|
||||
}
|
||||
|
||||
if (gotoNextConstraintCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0, n = static_cast<int>(_bones.size()); i < n; ++i) {
|
||||
sortBone(_bones[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::printUpdateCache () {
|
||||
for (size_t i = 0; i < _updateCache.size(); i++) {
|
||||
Updatable* updatable = _updateCache[i];
|
||||
if (updatable->getRTTI().isExactly(Bone::rtti)) {
|
||||
printf("bone %s\n", ((Bone*)updatable)->getData().getName().buffer());
|
||||
} else if (updatable->getRTTI().isExactly(TransformConstraint::rtti)) {
|
||||
printf("transform constraint %s\n", ((TransformConstraint*)updatable)->getData().getName().buffer());
|
||||
} else if (updatable->getRTTI().isExactly(IkConstraint::rtti)) {
|
||||
printf("ik constraint %s\n", ((IkConstraint*)updatable)->getData().getName().buffer());
|
||||
} else if (updatable->getRTTI().isExactly(PathConstraint::rtti)) {
|
||||
printf("path constraint %s\n", ((PathConstraint*)updatable)->getData().getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::updateWorldTransform() {
|
||||
for (int i = 0, n = static_cast<int>(_updateCacheReset.size()); i < n; ++i) {
|
||||
@ -407,7 +407,7 @@ namespace Spine {
|
||||
int verticesLength = 0;
|
||||
Attachment* attachment = slot->getAttachment();
|
||||
|
||||
if (attachment != NULL && attachment->getRTTI().derivesFrom(RegionAttachment::rtti)) {
|
||||
if (attachment != NULL && attachment->getRTTI().instanceOf(RegionAttachment::rtti)) {
|
||||
RegionAttachment* regionAttachment = static_cast<RegionAttachment*>(attachment);
|
||||
|
||||
verticesLength = 8;
|
||||
@ -416,7 +416,7 @@ namespace Spine {
|
||||
}
|
||||
regionAttachment->computeWorldVertices(slot->getBone(), outVertexBuffer, 0);
|
||||
}
|
||||
else if (attachment != NULL && attachment->getRTTI().derivesFrom(MeshAttachment::rtti)) {
|
||||
else if (attachment != NULL && attachment->getRTTI().instanceOf(MeshAttachment::rtti)) {
|
||||
MeshAttachment* mesh = static_cast<MeshAttachment*>(attachment);
|
||||
|
||||
verticesLength = mesh->getWorldVerticesLength();
|
||||
@ -543,9 +543,7 @@ namespace Spine {
|
||||
|
||||
if (constrained.size() > 1) {
|
||||
Bone* child = constrained[constrained.size() - 1];
|
||||
if (!_updateCache.contains(child)) {
|
||||
_updateCacheReset.add(child);
|
||||
}
|
||||
if (!_updateCache.contains(child)) _updateCacheReset.add(child);
|
||||
}
|
||||
|
||||
_updateCache.add(constraint);
|
||||
@ -556,72 +554,55 @@ namespace Spine {
|
||||
|
||||
void Skeleton::sortPathConstraint(PathConstraint* constraint) {
|
||||
Slot* slot = constraint->getTarget();
|
||||
int slotIndex = slot->_data.getIndex();
|
||||
Bone& slotBone = slot->_bone;
|
||||
|
||||
if (_skin != NULL) {
|
||||
sortPathConstraintAttachment(_skin, slotIndex, slotBone);
|
||||
}
|
||||
|
||||
if (_data->_defaultSkin != NULL && _data->_defaultSkin != _skin) {
|
||||
int slotIndex = slot->getData().getIndex();
|
||||
Bone& slotBone = slot->getBone();
|
||||
if (_skin != NULL) sortPathConstraintAttachment(_skin, slotIndex, slotBone);
|
||||
if (_data->_defaultSkin != NULL && _data->_defaultSkin != _skin)
|
||||
sortPathConstraintAttachment(_data->_defaultSkin, slotIndex, slotBone);
|
||||
}
|
||||
|
||||
for (int ii = 0, nn = static_cast<int>(_data->_skins.size()); ii < nn; ++ii) {
|
||||
for (size_t ii = 0, nn = _data->_skins.size(); ii < nn; ii++)
|
||||
sortPathConstraintAttachment(_data->_skins[ii], slotIndex, slotBone);
|
||||
}
|
||||
|
||||
Attachment* attachment = slot->_attachment;
|
||||
if (attachment != NULL && attachment->getRTTI().derivesFrom(PathAttachment::rtti)) {
|
||||
if (attachment != NULL && attachment->getRTTI().instanceOf(PathAttachment::rtti))
|
||||
sortPathConstraintAttachment(attachment, slotBone);
|
||||
}
|
||||
|
||||
Vector<Bone*>& constrained = constraint->getBones();
|
||||
int boneCount = static_cast<int>(constrained.size());
|
||||
for (int i = 0; i < boneCount; ++i) {
|
||||
size_t boneCount = constrained.size();
|
||||
for (size_t i = 0; i < boneCount; ++i) {
|
||||
sortBone(constrained[i]);
|
||||
}
|
||||
|
||||
_updateCache.add(constraint);
|
||||
|
||||
for (int i = 0; i < boneCount; ++i) {
|
||||
for (int i = 0; i < boneCount; i++)
|
||||
sortReset(constrained[i]->getChildren());
|
||||
}
|
||||
|
||||
for (int i = 0; i < boneCount; ++i) {
|
||||
for (int i = 0; i < boneCount; i++)
|
||||
constrained[i]->_sorted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::sortTransformConstraint(TransformConstraint* constraint) {
|
||||
sortBone(constraint->getTarget());
|
||||
|
||||
Vector<Bone*>& constrained = constraint->getBones();
|
||||
int boneCount = static_cast<int>(constrained.size());
|
||||
size_t boneCount = constrained.size();
|
||||
if (constraint->_data.isLocal()) {
|
||||
for (int i = 0; i < boneCount; ++i) {
|
||||
for (size_t i = 0; i < boneCount; i++) {
|
||||
Bone* child = constrained[i];
|
||||
sortBone(child->getParent());
|
||||
if (!_updateCache.contains(child)) {
|
||||
_updateCacheReset.add(child);
|
||||
}
|
||||
if (!_updateCache.contains(child)) _updateCacheReset.add(child);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < boneCount; ++i) {
|
||||
} else {
|
||||
for (size_t i = 0; i < boneCount; ++i) {
|
||||
sortBone(constrained[i]);
|
||||
}
|
||||
}
|
||||
|
||||
_updateCache.add(constraint);
|
||||
|
||||
for (int i = 0; i < boneCount; ++i) {
|
||||
for (size_t i = 0; i < boneCount; ++i)
|
||||
sortReset(constrained[i]->getChildren());
|
||||
}
|
||||
|
||||
for (int i = 0; i < boneCount; ++i) {
|
||||
for (size_t i = 0; i < boneCount; ++i)
|
||||
constrained[i]->_sorted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::sortPathConstraintAttachment(Skin* skin, int slotIndex, Bone& slotBone) {
|
||||
@ -638,18 +619,12 @@ namespace Spine {
|
||||
}
|
||||
|
||||
void Skeleton::sortPathConstraintAttachment(Attachment* attachment, Bone& slotBone) {
|
||||
if (attachment == NULL || attachment->getRTTI().derivesFrom(PathAttachment::rtti)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PathAttachment* pathAttachment = static_cast<PathAttachment*>(attachment);
|
||||
Vector<int>& pathBonesRef = pathAttachment->getBones();
|
||||
Vector<int> pathBones = pathBonesRef;
|
||||
if (pathBones.size() == 0) {
|
||||
if (attachment == NULL || !attachment->getRTTI().instanceOf(PathAttachment::rtti)) return;
|
||||
Vector<int>& pathBones = static_cast<PathAttachment*>(attachment)->getBones();
|
||||
if (pathBones.size() == 0)
|
||||
sortBone(&slotBone);
|
||||
}
|
||||
else {
|
||||
for (int i = 0, n = static_cast<int>(pathBones.size()); i < n;) {
|
||||
for (size_t i = 0, n = pathBones.size(); i < n;) {
|
||||
int nn = pathBones[i++];
|
||||
nn += i;
|
||||
while (i < nn) {
|
||||
@ -660,29 +635,17 @@ namespace Spine {
|
||||
}
|
||||
|
||||
void Skeleton::sortBone(Bone* bone) {
|
||||
assert(bone != NULL);
|
||||
|
||||
if (bone->_sorted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bone->_sorted) return;
|
||||
Bone* parent = bone->_parent;
|
||||
if (parent != NULL) {
|
||||
sortBone(parent);
|
||||
}
|
||||
|
||||
if (parent != NULL) sortBone(parent);
|
||||
bone->_sorted = true;
|
||||
|
||||
_updateCache.add(bone);
|
||||
}
|
||||
|
||||
void Skeleton::sortReset(Vector<Bone*>& bones) {
|
||||
for (size_t i = 0; i < bones.size(); ++i) {
|
||||
for (size_t i = 0, n = bones.size(); i < n; ++i) {
|
||||
Bone* bone = bones[i];
|
||||
if (bone->_sorted) {
|
||||
sortReset(bone->getChildren());
|
||||
}
|
||||
|
||||
if (bone->_sorted) sortReset(bone->getChildren());
|
||||
bone->_sorted = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -492,7 +492,7 @@ namespace Spine {
|
||||
return value;
|
||||
}
|
||||
|
||||
Skin* SkeletonBinary::readSkin(DataInput* input, const char* skinName, SkeletonData* skeletonData, bool nonessential) {
|
||||
Skin* SkeletonBinary::readSkin(DataInput* input, const String& skinName, SkeletonData* skeletonData, bool nonessential) {
|
||||
Skin* skin = NULL;
|
||||
int slotCount = readVarint(input, true);
|
||||
int i, ii, nn;
|
||||
@ -500,7 +500,7 @@ namespace Spine {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
skin = new (__FILE__, __LINE__) Skin(String(skinName));
|
||||
skin = new (__FILE__, __LINE__) Skin(skinName);
|
||||
|
||||
for (i = 0; i < slotCount; ++i) {
|
||||
int slotIndex = readVarint(input, true);
|
||||
@ -517,27 +517,17 @@ namespace Spine {
|
||||
return skin;
|
||||
}
|
||||
|
||||
Attachment* SkeletonBinary::readAttachment(DataInput* input, Skin* skin, int slotIndex, const char* attachmentName, SkeletonData* skeletonData, bool nonessential) {
|
||||
int i;
|
||||
AttachmentType type;
|
||||
const char* name = readString(input);
|
||||
int freeName = name != 0;
|
||||
if (!name) {
|
||||
freeName = 0;
|
||||
name = attachmentName;
|
||||
}
|
||||
|
||||
type = static_cast<AttachmentType>(readByte(input));
|
||||
|
||||
Attachment* SkeletonBinary::readAttachment(DataInput* input, Skin* skin, int slotIndex, const String& attachmentName, SkeletonData* skeletonData, bool nonessential) {
|
||||
String name(readString(input), true);
|
||||
if (name.isEmpty()) name = attachmentName;
|
||||
|
||||
AttachmentType type = static_cast<AttachmentType>(readByte(input));
|
||||
switch (type) {
|
||||
case AttachmentType_Region: {
|
||||
const char* path = readString(input);
|
||||
RegionAttachment* region;
|
||||
if (!path) {
|
||||
path = name;
|
||||
}
|
||||
region = _attachmentLoader->newRegionAttachment(*skin, String(name), String(path));
|
||||
region->_path = String(path);
|
||||
String path(readString(input), true);
|
||||
if (path.isEmpty()) path = name;
|
||||
RegionAttachment *region = _attachmentLoader->newRegionAttachment(*skin, String(name), String(path));
|
||||
region->_path = path;
|
||||
region->_rotation = readFloat(input);
|
||||
region->_x = readFloat(input) * _scale;
|
||||
region->_y = readFloat(input) * _scale;
|
||||
@ -547,68 +537,50 @@ namespace Spine {
|
||||
region->_height = readFloat(input) * _scale;
|
||||
readColor(input, region->getColor());
|
||||
region->updateOffset();
|
||||
|
||||
if (freeName) {
|
||||
SpineExtension::free(name, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
case AttachmentType_Boundingbox: {
|
||||
int vertexCount = readVarint(input, true);
|
||||
BoundingBoxAttachment* box = _attachmentLoader->newBoundingBoxAttachment(*skin, String(name));
|
||||
readVertices(input, static_cast<VertexAttachment*>(box), vertexCount);
|
||||
BoundingBoxAttachment *box = _attachmentLoader->newBoundingBoxAttachment(*skin, String(name));
|
||||
readVertices(input, static_cast<VertexAttachment *>(box), vertexCount);
|
||||
if (nonessential) {
|
||||
/* Skip color. */
|
||||
readInt(input);
|
||||
}
|
||||
if (freeName) {
|
||||
SpineExtension::free(name, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
return box;
|
||||
}
|
||||
case AttachmentType_Mesh: {
|
||||
int vertexCount;
|
||||
MeshAttachment* mesh;
|
||||
const char* path = readString(input);
|
||||
if (!path) {
|
||||
path = name;
|
||||
}
|
||||
MeshAttachment *mesh;
|
||||
String path(readString(input), true);
|
||||
if (path.isEmpty()) path = name;
|
||||
|
||||
mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
|
||||
mesh->_path = String(path);
|
||||
readColor(input, mesh->getColor());
|
||||
vertexCount = readVarint(input, true);
|
||||
readFloatArray(input, vertexCount << 1, 1, mesh->getRegionUVs());
|
||||
readShortArray(input, mesh->getTriangles());
|
||||
readVertices(input, static_cast<VertexAttachment*>(mesh), vertexCount);
|
||||
readVertices(input, static_cast<VertexAttachment *>(mesh), vertexCount);
|
||||
mesh->updateUVs();
|
||||
mesh->_hullLength = readVarint(input, true) << 1;
|
||||
if (nonessential) {
|
||||
readShortArray(input, mesh->getEdges());
|
||||
mesh->_width = readFloat(input) * _scale;
|
||||
mesh->_height = readFloat(input) * _scale;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
mesh->_width = 0;
|
||||
mesh->_height = 0;
|
||||
}
|
||||
|
||||
if (freeName) {
|
||||
SpineExtension::free(name, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
case AttachmentType_Linkedmesh: {
|
||||
const char* skinName;
|
||||
const char* parent;
|
||||
MeshAttachment* mesh;
|
||||
const char* path = readString(input);
|
||||
if (!path) {
|
||||
path = name;
|
||||
}
|
||||
|
||||
const char *skinName;
|
||||
const char *parent;
|
||||
MeshAttachment *mesh;
|
||||
String path(readString(input), true);
|
||||
if (path.isEmpty()) path = name;
|
||||
|
||||
mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
|
||||
mesh->_path = path;
|
||||
readColor(input, mesh->getColor());
|
||||
@ -619,110 +591,91 @@ namespace Spine {
|
||||
mesh->_width = readFloat(input) * _scale;
|
||||
mesh->_height = readFloat(input) * _scale;
|
||||
}
|
||||
|
||||
LinkedMesh* linkedMesh = new (__FILE__, __LINE__) LinkedMesh(mesh, String(skinName), slotIndex, String(parent));
|
||||
_linkedMeshes.add(linkedMesh);
|
||||
|
||||
if (freeName) {
|
||||
SpineExtension::free(name, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
|
||||
LinkedMesh *linkedMesh = new(__FILE__, __LINE__) LinkedMesh(mesh, String(skinName), slotIndex,
|
||||
String(parent));
|
||||
_linkedMeshes.add(linkedMesh);
|
||||
|
||||
SpineExtension::free(skinName, __FILE__, __LINE__);
|
||||
SpineExtension::free(parent, __FILE__, __LINE__);
|
||||
|
||||
|
||||
return mesh;
|
||||
}
|
||||
case AttachmentType_Path: {
|
||||
PathAttachment* path = _attachmentLoader->newPathAttachment(*skin, String(name));
|
||||
PathAttachment *path = _attachmentLoader->newPathAttachment(*skin, String(name));
|
||||
int vertexCount = 0;
|
||||
path->_closed = readBoolean(input);
|
||||
path->_constantSpeed = readBoolean(input);
|
||||
vertexCount = readVarint(input, true);
|
||||
readVertices(input, static_cast<VertexAttachment*>(path), vertexCount);
|
||||
readVertices(input, static_cast<VertexAttachment *>(path), vertexCount);
|
||||
int lengthsLength = vertexCount / 3;
|
||||
path->_lengths.setSize(lengthsLength);
|
||||
for (i = 0; i < lengthsLength; ++i) {
|
||||
for (int i = 0; i < lengthsLength; ++i) {
|
||||
path->_lengths[i] = readFloat(input) * _scale;
|
||||
}
|
||||
|
||||
|
||||
if (nonessential) {
|
||||
/* Skip color. */
|
||||
readInt(input);
|
||||
}
|
||||
|
||||
if (freeName) {
|
||||
SpineExtension::free(name, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
case AttachmentType_Point: {
|
||||
PointAttachment* point = _attachmentLoader->newPointAttachment(*skin, String(name));
|
||||
PointAttachment *point = _attachmentLoader->newPointAttachment(*skin, String(name));
|
||||
point->_rotation = readFloat(input);
|
||||
point->_x = readFloat(input) * _scale;
|
||||
point->_y = readFloat(input) * _scale;
|
||||
|
||||
|
||||
if (nonessential) {
|
||||
/* Skip color. */
|
||||
readInt(input);
|
||||
}
|
||||
|
||||
|
||||
return point;
|
||||
}
|
||||
case AttachmentType_Clipping: {
|
||||
int endSlotIndex = readVarint(input, true);
|
||||
int vertexCount = readVarint(input, true);
|
||||
ClippingAttachment* clip = _attachmentLoader->newClippingAttachment(*skin, name);
|
||||
readVertices(input, static_cast<VertexAttachment*>(clip), vertexCount);
|
||||
|
||||
ClippingAttachment *clip = _attachmentLoader->newClippingAttachment(*skin, name);
|
||||
readVertices(input, static_cast<VertexAttachment *>(clip), vertexCount);
|
||||
|
||||
if (nonessential) {
|
||||
/* Skip color. */
|
||||
readInt(input);
|
||||
}
|
||||
|
||||
|
||||
clip->_endSlot = skeletonData->_slots[endSlotIndex];
|
||||
|
||||
if (freeName) {
|
||||
SpineExtension::free(name, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
return clip;
|
||||
}
|
||||
}
|
||||
|
||||
if (freeName) {
|
||||
SpineExtension::free(name, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SkeletonBinary::readVertices(DataInput* input, VertexAttachment* attachment, int vertexCount) {
|
||||
float scale = _scale;
|
||||
int verticesLength = vertexCount << 1;
|
||||
|
||||
attachment->setWorldVerticesLength(vertexCount << 1);
|
||||
|
||||
if (!readBoolean(input)) {
|
||||
readFloatArray(input, verticesLength, scale, attachment->getVertices());
|
||||
return;
|
||||
}
|
||||
|
||||
Vertices vertices;
|
||||
vertices._bones.ensureCapacity(verticesLength * 3);
|
||||
vertices._vertices.ensureCapacity(verticesLength * 3 * 3);
|
||||
|
||||
Vector<float>& vertices = attachment->getVertices();
|
||||
Vector<int>& bones = attachment->getBones();
|
||||
vertices.ensureCapacity(verticesLength * 3 * 3);
|
||||
bones.ensureCapacity(verticesLength * 3);
|
||||
|
||||
for (int i = 0; i < vertexCount; ++i) {
|
||||
int boneCount = readVarint(input, true);
|
||||
vertices._bones.add(boneCount);
|
||||
bones.add(boneCount);
|
||||
for (int ii = 0; ii < boneCount; ++ii) {
|
||||
vertices._bones.add(readVarint(input, true));
|
||||
vertices._vertices.add(readFloat(input) * scale);
|
||||
vertices._vertices.add(readFloat(input) * scale);
|
||||
vertices._vertices.add(readFloat(input));
|
||||
bones.add(readVarint(input, true));
|
||||
vertices.add(readFloat(input) * scale);
|
||||
vertices.add(readFloat(input) * scale);
|
||||
vertices.add(readFloat(input));
|
||||
}
|
||||
}
|
||||
|
||||
attachment->setVertices(vertices._vertices);
|
||||
attachment->setBones(vertices._bones);
|
||||
}
|
||||
|
||||
void SkeletonBinary::readFloatArray(DataInput *input, int n, float scale, Vector<float>& array) {
|
||||
|
||||
@ -54,7 +54,7 @@ namespace Spine {
|
||||
for (int i = 0; i < slotCount; i++) {
|
||||
Slot* slot = slots[i];
|
||||
Attachment* attachment = slot->_attachment;
|
||||
if (attachment == NULL || !attachment->getRTTI().derivesFrom(BoundingBoxAttachment::rtti)) {
|
||||
if (attachment == NULL || !attachment->getRTTI().instanceOf(BoundingBoxAttachment::rtti)) {
|
||||
continue;
|
||||
}
|
||||
BoundingBoxAttachment* boundingBox = static_cast<BoundingBoxAttachment*>(attachment);
|
||||
|
||||
@ -49,7 +49,6 @@ namespace Spine {
|
||||
|
||||
std::size_t Skin::HashAttachmentKey::operator()(const Spine::Skin::AttachmentKey& val) const {
|
||||
std::size_t h1 = val._slotIndex;
|
||||
|
||||
return h1;
|
||||
}
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ namespace Spine {
|
||||
assert(_name.length() > 0);
|
||||
}
|
||||
|
||||
const int SlotData::getIndex() {
|
||||
int SlotData::getIndex() {
|
||||
return _index;
|
||||
}
|
||||
|
||||
|
||||
@ -208,6 +208,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
||||
}
|
||||
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
skeleton.updateWorldTransform();
|
||||
skeleton.setToSetupPose();
|
||||
skeleton = new Skeleton(skeleton); // Tests copy constructors.
|
||||
skeleton.updateWorldTransform();
|
||||
|
||||
@ -1,5 +1,49 @@
|
||||
cmake_minimum_required(VERSION 2.8.9)
|
||||
|
||||
#
|
||||
# First download and extract SFML 2.3.2 for the respective OS we are on
|
||||
#
|
||||
set(DEPS_DIR "${CMAKE_CURRENT_LIST_DIR}/dependencies/")
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(SFML_URL "http://www.sfml-dev.org/files/SFML-2.4.1-osx-clang.tar.gz")
|
||||
set(SFML_DIR ${DEPS_DIR}/SFML-2.4.1-osx-clang)
|
||||
if (NOT EXISTS "${SFML_DIR}")
|
||||
message("Downloading SFML for Mac OS X")
|
||||
file(DOWNLOAD "${SFML_URL}" "${DEPS_DIR}/sfml.tar.gz")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${DEPS_DIR}/sfml.tar.gz
|
||||
WORKING_DIRECTORY ${DEPS_DIR}
|
||||
)
|
||||
# copy freetype over to Frameworks/ so rpath resoultion works
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${SFML_DIR}/extlibs/freetype.framework ${SFML_DIR}/Frameworks/freetype.framework
|
||||
WORKING_DIRECTORY ${SFML_DIR}
|
||||
)
|
||||
endif()
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(SFML_URL "http://www.sfml-dev.org/files/SFML-2.4.1-linux-gcc-64-bit.tar.gz")
|
||||
set(SFML_DIR ${DEPS_DIR}/SFML-2.4.1)
|
||||
if (NOT EXISTS ${SFML_DIR})
|
||||
message("Downloading SFML for Linux 64-bit")
|
||||
file(DOWNLOAD "${SFML_URL}" "${DEPS_DIR}/sfml.tar.gz")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${DEPS_DIR}/sfml.tar.gz
|
||||
WORKING_DIRECTORY ${DEPS_DIR}
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
set(SFML_URL "http://www.sfml-dev.org/files/SFML-2.4.1-windows-vc14-32-bit.zip")
|
||||
set(SFML_DIR ${DEPS_DIR}/SFML-2.4.1)
|
||||
if (NOT EXISTS ${SFML_DIR})
|
||||
message("Downloading SFML for Windows 32-bit")
|
||||
file(DOWNLOAD "${SFML_URL}" "${DEPS_DIR}/sfml.zip")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar x ${DEPS_DIR}/sfml.zip
|
||||
WORKING_DIRECTORY ${DEPS_DIR}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Define spine-sfml library
|
||||
include_directories(src ${SFML_DIR}/include)
|
||||
file(GLOB INCLUDES "src/**/*.h")
|
||||
|
||||
@ -30,8 +30,8 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#define SPINE_SHORT_NAMES
|
||||
#include <spine/spine-sfml.h>
|
||||
#include <spine/Debug.h>
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/Window/Mouse.hpp>
|
||||
|
||||
@ -94,7 +94,8 @@ SkeletonData* readSkeletonBinaryData (const char* filename, Atlas* atlas, float
|
||||
void testcase (void func(SkeletonData* skeletonData, Atlas* atlas),
|
||||
const char* jsonName, const char* binaryName, const char* atlasName,
|
||||
float scale) {
|
||||
Atlas* atlas = new (__FILE__, __LINE__) Atlas(atlasName, 0);
|
||||
SFMLTextureLoader textureLoader;
|
||||
Atlas* atlas = new (__FILE__, __LINE__) Atlas(atlasName, &textureLoader);
|
||||
|
||||
SkeletonData* skeletonData = readSkeletonJsonData(jsonName, atlas, scale);
|
||||
func(skeletonData, atlas);
|
||||
@ -440,15 +441,17 @@ void test (SkeletonData* skeletonData, Atlas* atlas) {
|
||||
}
|
||||
|
||||
int main () {
|
||||
DebugExtension dbgExtension;
|
||||
SpineExtension::setInstance(&dbgExtension);
|
||||
testcase(test, "data/tank-pro.json", "data/tank-pro.skel", "data/tank.atlas", 1.0f);
|
||||
testcase(spineboy, "data/spineboy-ess.json", "data/spineboy-ess.skel", "data/spineboy.atlas", 0.6f);
|
||||
/*testcase(owl, "data/owl-pro.json", "data/owl-pro.skel", "data/owl.atlas", 0.5f);
|
||||
testcase(owl, "data/owl-pro.json", "data/owl-pro.skel", "data/owl.atlas", 0.5f);
|
||||
testcase(coin, "data/coin-pro.json", "data/coin-pro.skel", "data/coin.atlas", 0.5f);
|
||||
testcase(vine, "data/vine-pro.json", "data/vine-pro.skel", "data/vine.atlas", 0.5f);
|
||||
testcase(tank, "data/tank-pro.json", "data/tank-pro.skel", "data/tank.atlas", 0.2f);
|
||||
testcase(raptor, "data/raptor-pro.json", "data/raptor-pro.skel", "data/raptor.atlas", 0.5f);
|
||||
testcase(spineboy, "data/spineboy-ess.json", "data/spineboy-ess.skel", "data/spineboy.atlas", 0.6f);
|
||||
testcase(goblins, "data/goblins-pro.json", "data/goblins-pro.skel", "data/goblins.atlas", 1.4f);
|
||||
testcase(stretchyman, "data/stretchyman-pro.json", "data/stretchyman-pro.skel", "data/stretchyman.atlas", 0.6f);*/
|
||||
testcase(stretchyman, "data/stretchyman-pro.json", "data/stretchyman-pro.skel", "data/stretchyman.atlas", 0.6f);
|
||||
dbgExtension.reportLeaks();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
||||
int indicesCount = 0;
|
||||
Color* attachmentColor;
|
||||
|
||||
if (attachment->rtti.derivesFrom(RegionAttachment::rtti)) {
|
||||
if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) {
|
||||
RegionAttachment* regionAttachment = (RegionAttachment*)attachment;
|
||||
regionAttachment->computeWorldVertices(slot.getBone(), worldVertices, 0, 2);
|
||||
verticesCount = 4;
|
||||
@ -140,7 +140,7 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
||||
texture = (Texture*)((AtlasRegion*)regionAttachment->getRendererObject())->page->rendererObject;
|
||||
attachmentColor = ®ionAttachment->getColor();
|
||||
|
||||
} else if (attachment->rtti.derivesFrom(MeshAttachment::rtti)) {
|
||||
} else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) {
|
||||
MeshAttachment* mesh = (MeshAttachment*)attachment;
|
||||
if (mesh->getWorldVerticesLength() > worldVertices.size()) worldVertices.setSize(mesh->getWorldVerticesLength());
|
||||
texture = (Texture*)((AtlasRegion*)mesh->getRendererObject())->page->rendererObject;
|
||||
@ -150,7 +150,7 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
||||
indices = &mesh->getTriangles();
|
||||
indicesCount = mesh->getTriangles().size();
|
||||
attachmentColor = &mesh->getColor();
|
||||
} else if (attachment->rtti.derivesFrom(ClippingAttachment::rtti)) {
|
||||
} else if (attachment->getRTTI().isExactly(ClippingAttachment::rtti)) {
|
||||
ClippingAttachment* clip = (ClippingAttachment*)slot.getAttachment();
|
||||
clipper.clipStart(slot, clip);
|
||||
continue;
|
||||
@ -280,4 +280,20 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
||||
// BOZO if (vertexEffect != 0) vertexEffect->end(vertexEffect);
|
||||
}
|
||||
|
||||
void SFMLTextureLoader::load(AtlasPage &page, const String &path) {
|
||||
Texture* texture = new Texture();
|
||||
if (!texture->loadFromFile(path.buffer())) return;
|
||||
|
||||
if (page.magFilter == TextureFilter_Linear) texture->setSmooth(true);
|
||||
if (page.uWrap == TextureWrap_Repeat && page.vWrap == TextureWrap_Repeat) texture->setRepeated(true);
|
||||
|
||||
page.rendererObject = texture;
|
||||
Vector2u size = texture->getSize();
|
||||
page.width = size.x;
|
||||
page.height = size.y;
|
||||
}
|
||||
|
||||
void SFMLTextureLoader::unload(void *texture) {
|
||||
delete (Texture*)texture;
|
||||
}
|
||||
} /* namespace spine */
|
||||
|
||||
@ -66,5 +66,12 @@ private:
|
||||
mutable bool usePremultipliedAlpha;
|
||||
};
|
||||
|
||||
class SFMLTextureLoader: public TextureLoader {
|
||||
public:
|
||||
virtual void load(AtlasPage& page, const String& path);
|
||||
|
||||
virtual void unload(void* texture);
|
||||
};
|
||||
|
||||
} /* namespace spine */
|
||||
#endif /* SPINE_SFML_H_ */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user