cpp, skeleton loading and rendering with SFML.

This commit is contained in:
NathanSweet 2013-02-22 14:52:25 +01:00
parent 5efed09862
commit 268933242f
29 changed files with 819 additions and 365 deletions

View File

@ -19,7 +19,7 @@ org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=-Warning
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
@ -65,4 +65,3 @@ org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
useParentScope=false

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false

View File

@ -41,9 +41,6 @@
],
"skins": {
"default": {
"template": {
"spineboy": { "y": 167.82, "width": 145, "height": 341 }
},
"left shoulder": {
"left-shoulder": { "x": 23.74, "y": 0.11, "rotation": 62.01, "width": 34, "height": 53 }
},

View File

@ -0,0 +1,278 @@
{
"bones": {
"left upper leg": {
"rotate": [
{ "time": 0, "angle": -26.55 },
{ "time": 0.1333, "angle": -8.78 },
{ "time": 0.2666, "angle": 9.51 },
{ "time": 0.4, "angle": 30.74 },
{ "time": 0.5333, "angle": 25.33 },
{ "time": 0.6666, "angle": 26.11 },
{ "time": 0.8, "angle": -7.7 },
{ "time": 0.9333, "angle": -21.19 },
{ "time": 1.0666, "angle": -26.55 }
],
"translate": [
{ "time": 0, "x": -3, "y": -2.25 },
{ "time": 0.4, "x": -2.18, "y": -2.25 },
{ "time": 1.0666, "x": -3, "y": -2.25 }
]
},
"right upper leg": {
"rotate": [
{ "time": 0, "angle": 42.45 },
{ "time": 0.1333, "angle": 52.1 },
{ "time": 0.2666, "angle": 5.96 },
{ "time": 0.5333, "angle": -16.93 },
{ "time": 0.6666, "angle": 1.89 },
{
"time": 0.8,
"angle": 28.06,
"curve": [ 0.462, 0.11, 1, 1 ]
},
{
"time": 0.9333,
"angle": 58.68,
"curve": [ 0.5, 0.02, 1, 1 ]
},
{ "time": 1.0666, "angle": 42.45 }
],
"translate": [
{ "time": 0, "x": 8.11, "y": -2.36 },
{ "time": 0.1333, "x": 10.03, "y": -2.56 },
{ "time": 0.4, "x": 2.76, "y": -2.97 },
{ "time": 0.5333, "x": 2.76, "y": -2.81 },
{ "time": 0.9333, "x": 8.67, "y": -2.54 },
{ "time": 1.0666, "x": 8.11, "y": -2.36 }
]
},
"left lower leg": {
"rotate": [
{ "time": 0, "angle": -10.21 },
{ "time": 0.1333, "angle": -55.64 },
{ "time": 0.2666, "angle": -68.12 },
{ "time": 0.5333, "angle": 5.11 },
{ "time": 0.6666, "angle": -28.29 },
{ "time": 0.8, "angle": 4.08 },
{ "time": 0.9333, "angle": 3.53 },
{ "time": 1.0666, "angle": -10.21 }
]
},
"left foot": {
"rotate": [
{ "time": 0, "angle": -3.69 },
{ "time": 0.1333, "angle": -10.42 },
{ "time": 0.2666, "angle": -17.14 },
{ "time": 0.4, "angle": -2.83 },
{ "time": 0.5333, "angle": -3.87 },
{ "time": 0.6666, "angle": 2.78 },
{ "time": 0.8, "angle": 1.68 },
{ "time": 0.9333, "angle": -8.54 },
{ "time": 1.0666, "angle": -3.69 }
]
},
"right shoulder": {
"rotate": [
{
"time": 0,
"angle": 20.89,
"curve": [ 0.264, 0, 0.75, 1 ]
},
{
"time": 0.1333,
"angle": 3.72,
"curve": [ 0.272, 0, 0.841, 1 ]
},
{ "time": 0.6666, "angle": -278.28 },
{ "time": 1.0666, "angle": 20.89 }
],
"translate": [
{ "time": 0, "x": -7.84, "y": 7.19 },
{ "time": 0.1333, "x": -6.36, "y": 6.42 },
{ "time": 0.6666, "x": -11.07, "y": 5.25 },
{ "time": 1.0666, "x": -7.84, "y": 7.19 }
]
},
"right arm": {
"rotate": [
{
"time": 0,
"angle": -4.02,
"curve": [ 0.267, 0, 0.804, 0.99 ]
},
{
"time": 0.1333,
"angle": -13.99,
"curve": [ 0.341, 0, 1, 1 ]
},
{
"time": 0.6666,
"angle": 36.54,
"curve": [ 0.307, 0, 0.787, 0.99 ]
},
{ "time": 1.0666, "angle": -4.02 }
]
},
"right hand": {
"rotate": [
{ "time": 0, "angle": 22.92 },
{ "time": 0.4, "angle": -8.97 },
{ "time": 0.6666, "angle": 0.51 },
{ "time": 1.0666, "angle": 22.92 }
]
},
"left shoulder": {
"rotate": [
{ "time": 0, "angle": -1.47 },
{ "time": 0.1333, "angle": 13.6 },
{ "time": 0.6666, "angle": 280.74 },
{ "time": 1.0666, "angle": -1.47 }
],
"translate": [
{ "time": 0, "x": -1.76, "y": 0.56 },
{ "time": 0.6666, "x": -2.47, "y": 8.14 },
{ "time": 1.0666, "x": -1.76, "y": 0.56 }
]
},
"left hand": {
"rotate": [
{
"time": 0,
"angle": 11.58,
"curve": [ 0.169, 0.37, 0.632, 1.55 ]
},
{
"time": 0.1333,
"angle": 28.13,
"curve": [ 0.692, 0, 0.692, 0.99 ]
},
{
"time": 0.6666,
"angle": -27.42,
"curve": [ 0.117, 0.41, 0.738, 1.76 ]
},
{ "time": 0.8, "angle": -36.32 },
{ "time": 1.0666, "angle": 11.58 }
]
},
"left arm": {
"rotate": [
{ "time": 0, "angle": -8.27 },
{ "time": 0.1333, "angle": 18.43 },
{ "time": 0.6666, "angle": 0.88 },
{ "time": 1.0666, "angle": -8.27 }
]
},
"torso": {
"rotate": [
{ "time": 0, "angle": -10.28 },
{
"time": 0.1333,
"angle": -15.38,
"curve": [ 0.545, 0, 1, 1 ]
},
{
"time": 0.4,
"angle": -9.78,
"curve": [ 0.58, 0.17, 1, 1 ]
},
{ "time": 0.6666, "angle": -15.75 },
{ "time": 0.9333, "angle": -7.06 },
{ "time": 1.0666, "angle": -10.28 }
],
"translate": [
{ "time": 0, "x": -3.67, "y": 1.68 },
{ "time": 0.1333, "x": -3.67, "y": 0.68 },
{ "time": 0.4, "x": -3.67, "y": 1.97 },
{ "time": 0.6666, "x": -3.67, "y": -0.14 },
{ "time": 1.0666, "x": -3.67, "y": 1.68 }
]
},
"right foot": {
"rotate": [
{ "time": 0, "angle": -5.25 },
{ "time": 0.2666, "angle": -4.08 },
{ "time": 0.4, "angle": -6.45 },
{ "time": 0.5333, "angle": -5.39 },
{ "time": 0.8, "angle": -11.68 },
{ "time": 0.9333, "angle": 0.46 },
{ "time": 1.0666, "angle": -5.25 }
]
},
"right lower leg": {
"rotate": [
{ "time": 0, "angle": -3.39 },
{ "time": 0.1333, "angle": -45.53 },
{ "time": 0.2666, "angle": -2.59 },
{ "time": 0.5333, "angle": -19.53 },
{ "time": 0.6666, "angle": -64.8 },
{
"time": 0.8,
"angle": -82.56,
"curve": [ 0.557, 0.18, 1, 1 ]
},
{ "time": 1.0666, "angle": -3.39 }
]
},
"hip": {
"rotate": [
{ "time": 0, "angle": 0, "curve": "stepped" },
{ "time": 1.0666, "angle": 0 }
],
"translate": [
{ "time": 0, "x": 0, "y": 0 },
{
"time": 0.1333,
"x": 0,
"y": -7.61,
"curve": [ 0.272, 0.86, 1, 1 ]
},
{ "time": 0.4, "x": 0, "y": 8.7 },
{ "time": 0.5333, "x": 0, "y": -0.41 },
{
"time": 0.6666,
"x": 0,
"y": -7.05,
"curve": [ 0.235, 0.89, 1, 1 ]
},
{ "time": 0.8, "x": 0, "y": 2.92 },
{ "time": 0.9333, "x": 0, "y": 6.78 },
{ "time": 1.0666, "x": 0, "y": 0 }
]
},
"neck": {
"rotate": [
{ "time": 0, "angle": 3.6 },
{ "time": 0.1333, "angle": 17.49 },
{ "time": 0.2666, "angle": 6.1 },
{ "time": 0.4, "angle": 3.45 },
{ "time": 0.5333, "angle": 5.17 },
{ "time": 0.6666, "angle": 18.36 },
{ "time": 0.8, "angle": 6.09 },
{ "time": 0.9333, "angle": 2.28 },
{ "time": 1.0666, "angle": 3.6 }
]
},
"head": {
"rotate": [
{
"time": 0,
"angle": 3.6,
"curve": [ 0, 0, 0.704, 1.61 ]
},
{ "time": 0.1666, "angle": -0.2 },
{ "time": 0.2666, "angle": 6.1 },
{ "time": 0.4, "angle": 3.45 },
{
"time": 0.5333,
"angle": 5.17,
"curve": [ 0, 0, 0.704, 1.61 ]
},
{ "time": 0.7, "angle": 1.1 },
{ "time": 0.8, "angle": 6.09 },
{ "time": 0.9333, "angle": 2.28 },
{ "time": 1.0666, "angle": 3.6 }
]
}
}
}

View File

@ -0,0 +1,166 @@
../data/spineboy.png
format: RGBA8888
filter: Nearest,Nearest
repeat: none
head
rotate: false
xy: 1, 122
size: 121, 132
orig: 121, 132
offset: 0, 0
index: -1
torso
rotate: false
xy: 1, 28
size: 68, 92
orig: 68, 92
offset: 0, 0
index: -1
left-pant-bottom
rotate: false
xy: 1, 4
size: 44, 22
orig: 44, 22
offset: 0, 0
index: -1
right-pant-bottom
rotate: false
xy: 47, 8
size: 46, 18
orig: 46, 18
offset: 0, 0
index: -1
right-upper-leg
rotate: false
xy: 71, 50
size: 44, 70
orig: 44, 70
offset: 0, 0
index: -1
pelvis
rotate: false
xy: 95, 1
size: 63, 47
orig: 63, 47
offset: 0, 0
index: -1
left-upper-leg
rotate: false
xy: 117, 53
size: 33, 67
orig: 33, 67
offset: 0, 0
index: -1
right-foot
rotate: false
xy: 160, 224
size: 67, 30
orig: 67, 30
offset: 0, 0
index: -1
left-shoulder
rotate: false
xy: 124, 201
size: 34, 53
orig: 34, 53
offset: 0, 0
index: -1
left-ankle
rotate: false
xy: 229, 222
size: 25, 32
orig: 25, 32
offset: 0, 0
index: -1
left-foot
rotate: false
xy: 160, 192
size: 65, 30
orig: 65, 30
offset: 0, 0
index: -1
neck
rotate: false
xy: 124, 171
size: 34, 28
orig: 34, 28
offset: 0, 0
index: -1
right-arm
rotate: false
xy: 124, 124
size: 21, 45
orig: 21, 45
offset: 0, 0
index: -1
right-ankle
rotate: false
xy: 227, 190
size: 25, 30
orig: 25, 30
offset: 0, 0
index: -1
left-hand
rotate: false
xy: 147, 131
size: 35, 38
orig: 35, 38
offset: 0, 0
index: -1
left-arm
rotate: false
xy: 184, 161
size: 35, 29
orig: 35, 29
offset: 0, 0
index: -1
eyes-closed
rotate: false
xy: 221, 161
size: 34, 27
orig: 34, 27
offset: 0, 0
index: -1
right-lower-leg
rotate: false
xy: 152, 65
size: 51, 64
orig: 51, 64
offset: 0, 0
index: -1
right-foot-idle
rotate: false
xy: 184, 131
size: 53, 28
orig: 53, 28
offset: 0, 0
index: -1
left-lower-leg
rotate: false
xy: 205, 65
size: 49, 64
orig: 49, 64
offset: 0, 0
index: -1
right-shoulder
rotate: false
xy: 160, 12
size: 52, 51
orig: 52, 51
offset: 0, 0
index: -1
eyes
rotate: false
xy: 214, 36
size: 34, 27
orig: 34, 27
offset: 0, 0
index: -1
right-hand
rotate: false
xy: 214, 2
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1

BIN
spine-cpp/data/spineboy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -0,0 +1,38 @@
#ifndef SPINE_ATLAS_H_
#define SPINE_ATLAS_H_
#include <spine/BaseAtlas.h>
#include <SFML/Graphics/Texture.hpp>
namespace spine {
class AtlasPage: public BaseAtlasPage {
public:
sf::Texture *texture;
};
//
class AtlasRegion: public BaseAtlasRegion {
public:
AtlasPage *page;
};
//
class Atlas: public BaseAtlas {
public:
Atlas (std::ifstream &file);
Atlas (std::istream &input);
Atlas (const std::string &text);
Atlas (const char *begin, const char *end);
AtlasRegion* findRegion (const std::string &name);
private:
virtual BaseAtlasPage* newAtlasPage (std::string name);
virtual BaseAtlasRegion* newAtlasRegion (BaseAtlasPage* page);
};
} /* namespace spine */
#endif /* SPINE_ATLAS_H_ */

View File

@ -0,0 +1,21 @@
#ifndef SPINE_ATLASATTACHMENTLOADER_H_
#define SPINE_ATLASATTACHMENTLOADER_H_
#include <spine/BaseAttachmentLoader.h>
namespace spine {
class Atlas;
class AtlasAttachmentLoader: public BaseAttachmentLoader {
public:
Atlas *atlas;
AtlasAttachmentLoader (Atlas *atlas);
virtual Attachment* newAttachment (AttachmentType type, const std::string &name);
}
;
} /* namespace spine */
#endif /* SPINE_ATLASATTACHMENTLOADER_H_ */

View File

@ -3,20 +3,22 @@
#include <spine/BaseRegionAttachment.h>
#include <SFML/Graphics/Vertex.hpp>
#include <SFML/Graphics/Texture.hpp>
namespace spine {
class Bone;
class AtlasRegion;
class RegionAttachment: public BaseRegionAttachment {
public:
sf::Vertex vertices[4];
sf::Texture *texture;
RegionAttachment ();
RegionAttachment (AtlasRegion *region);
virtual void updateWorldVertices (Bone *bone);
virtual void draw (const BaseSkeleton *skeleton);
virtual void draw (Slot *slot);
};
} /* namespace spine */

View File

@ -6,9 +6,10 @@
namespace spine {
class Skeleton: public BaseSkeleton, private sf::Drawable {
class Skeleton: public BaseSkeleton, public sf::Drawable {
public:
sf::VertexArray vertexArray;
sf::Texture *texture;
Skeleton (SkeletonData *skeletonData);

View File

@ -5,9 +5,12 @@
namespace spine {
class Atlas;
class SkeletonJson: public BaseSkeletonJson {
public:
SkeletonJson ();
SkeletonJson (Atlas *atlas);
SkeletonJson (BaseAttachmentLoader *attachmentLoader);
};
} /* namespace spine */

View File

@ -10,7 +10,10 @@
#include <spine/Slot.h>
#include <spine/Bone.h>
#include <spine-sfml/SkeletonJson.h>
#include <spine-sfml/RegionAttachment.h>
#include <spine-sfml/Atlas.h>
#include <spine-sfml/AtlasAttachmentLoader.h>
#include <spine-sfml/SkeletonJson.h>
#include <spine-sfml/Skeleton.h>
#endif /* SF_SPINE_H_ */

View File

@ -1,62 +0,0 @@
#ifndef SPINE_ATLASDATA_H_
#define SPINE_ATLASDATA_H_
#include <istream>
#include <string>
#include <vector>
namespace spine {
class AtlasPage;
class AtlasRegion;
class AtlasData {
public:
std::vector<AtlasPage*> pages;
std::vector<AtlasRegion*> regions;
AtlasData (const char *begin, const char *end);
AtlasData (const std::string &json);
AtlasData (std::istream &file);
~AtlasData ();
private:
void init (const char *begin, const char *end);
};
enum Format {
alpha, intensity, luminanceAlpha, rgb565, rgba4444, rgb888, rgba8888
};
enum TextureFilter {
nearest, linear, mipMap, mipMapNearestNearest, mipMapLinearNearest, mipMapNearestLinear, mipMapLinearLinear
};
enum TextureWrap {
mirroredRepeat, clampToEdge, repeat
};
class AtlasPage {
public:
std::string name;
Format format;
TextureFilter minFilter, magFilter;
TextureWrap uWrap, vWrap;
};
class AtlasRegion {
public:
std::string name;
AtlasPage *page;
int x, y, width, height;
float offsetX, offsetY;
int originalWidth, originalHeight;
int index;
bool rotate;
bool flip;
int *splits;
int *pads;
};
} /* namespace spine */
#endif /* SPINE_ATLASDATA_H_ */

View File

@ -6,6 +6,7 @@
namespace spine {
class BaseSkeleton;
class Slot;
class Attachment {
public:
@ -15,7 +16,7 @@ public:
virtual ~Attachment () {
}
virtual void draw (const BaseSkeleton *skeleton) = 0;
virtual void draw (Slot *slot) = 0;
};
} /* namespace spine */

View File

@ -0,0 +1,78 @@
#ifndef SPINE_BASEATLASDATA_H_
#define SPINE_BASEATLASDATA_H_
#include <istream>
#include <string>
#include <vector>
#include <map>
namespace spine {
class BaseAtlasPage;
class BaseAtlasRegion;
class BaseAtlas {
public:
std::vector<BaseAtlasPage*> pages;
std::vector<BaseAtlasRegion*> regions;
virtual ~BaseAtlas ();
void load (std::ifstream &file);
void load (std::istream &input);
void load (const std::string &text);
void load (const char *begin, const char *end);
virtual BaseAtlasRegion* findRegion (const std::string &name);
private:
virtual BaseAtlasPage* newAtlasPage (std::string name) = 0;
virtual BaseAtlasRegion* newAtlasRegion (BaseAtlasPage*) = 0;
};
//
enum Format {
alpha, intensity, luminanceAlpha, rgb565, rgba4444, rgb888, rgba8888
};
enum TextureFilter {
nearest, linear, mipMap, mipMapNearestNearest, mipMapLinearNearest, mipMapNearestLinear, mipMapLinearLinear
};
enum TextureWrap {
mirroredRepeat, clampToEdge, repeat
};
//
class BaseAtlasPage {
public:
std::string name;
Format format;
TextureFilter minFilter, magFilter;
TextureWrap uWrap, vWrap;
virtual ~BaseAtlasPage () {
}
};
//
class BaseAtlasRegion {
public:
std::string name;
int x, y, width, height;
float offsetX, offsetY;
int originalWidth, originalHeight;
int index;
bool rotate;
bool flip;
int *splits;
int *pads;
virtual ~BaseAtlasRegion ();
};
} /* namespace spine */
#endif /* SPINE_BASEATLASDATA_H_ */

View File

@ -14,7 +14,7 @@ public:
virtual ~BaseAttachmentLoader () {
}
virtual Attachment* newAttachment (AttachmentType type) = 0;
virtual Attachment* newAttachment (AttachmentType type, const std::string &name) = 0;
};
} /* namespace spine */

View File

@ -6,6 +6,7 @@
namespace spine {
class Bone;
class Slot;
class BaseRegionAttachment: public Attachment {
public:

View File

@ -16,9 +16,10 @@ public:
BaseSkeletonJson (BaseAttachmentLoader *attachmentLoader);
virtual ~BaseSkeletonJson ();
SkeletonData* readSkeletonData (const char *begin, const char *end) const;
SkeletonData* readSkeletonData (const std::string &json) const;
SkeletonData* readSkeletonData (std::ifstream &file) const;
SkeletonData* readSkeletonData (std::istream &file) const;
SkeletonData* readSkeletonData (const std::string &json) const;
SkeletonData* readSkeletonData (const char *begin, const char *end) const;
};
} /* namespace spine */

View File

@ -1,7 +1,5 @@
#include <iostream>
#include <fstream>
#include <spine/BaseSkeleton.h>
#include <spine/AtlasData.h>
#include <spine-sfml/spine.h>
#include <SFML/Graphics.hpp>
@ -9,40 +7,30 @@ using namespace std;
using namespace spine;
int main () {
ifstream file("../spineboy-skeleton.json");
ifstream file("../data/spineboy-skeleton.json");
try {
SkeletonJson skeletonJson;
ifstream file2("../data/spineboy.atlas");
Atlas *atlas = new Atlas(file2);
SkeletonJson skeletonJson(atlas);
SkeletonData *skeletonData = skeletonJson.readSkeletonData(file);
cout << skeletonData->bones.size() << " bone datas.\n";
cout << skeletonData->slots.size() << " slot datas.\n";
cout << skeletonData->skins.size() << " skins.\n";
cout << (skeletonData->defaultSkin ? "Has" : "Doesn't have") << " default skin.\n";
Skeleton *skeleton = new Skeleton(skeletonData);
skeleton->setToBindPose();
skeleton->getRootBone()->x = 200;
skeleton->getRootBone()->y = 420;
skeleton->updateWorldTransform();
BaseSkeleton *skeleton = new BaseSkeleton(skeletonData);
cout << skeleton->bones.size() << " bones.\n";
sf::RenderWindow window(sf::VideoMode(640, 480), "Spine SFML");
window.setFramerateLimit(60);
sf::Event event;
while (window.isOpen()) {
while (window.pollEvent(event))
if (event.type == sf::Event::Closed) window.close();
window.clear();
window.draw(*skeleton);
window.display();
}
} catch (exception &ex) {
cout << ex.what() << endl;
cout << ex.what() << endl << flush;
}
cout << flush;
ifstream file2("../uiskin.atlas");
new AtlasData(file2);
sf::RenderWindow window(sf::VideoMode(640, 480), "Spine SFML");
window.setFramerateLimit(60);
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
sf::Event event;
while (window.isOpen() && false) {
while (window.pollEvent(event))
if (event.type == sf::Event::Closed) window.close();
window.clear();
window.draw(shape);
window.display();
}
return 0;
}

View File

@ -0,0 +1,39 @@
#include <SFML/Graphics/Texture.hpp>
#include <spine-sfml/Atlas.h>
namespace spine {
Atlas::Atlas (std::ifstream &file) {
load(file);
}
Atlas::Atlas (std::istream &input) {
load(input);
}
Atlas::Atlas (const std::string &text) {
load(text);
}
Atlas::Atlas (const char *begin, const char *end) {
load(begin, end);
}
BaseAtlasPage* Atlas::newAtlasPage (std::string name) {
AtlasPage *page = new AtlasPage();
page->texture = new sf::Texture();
page->texture->loadFromFile(name);
return page;
}
BaseAtlasRegion* Atlas::newAtlasRegion (BaseAtlasPage* page) {
AtlasRegion *region = new AtlasRegion();
region->page = reinterpret_cast<AtlasPage*>(page);
return region;
}
AtlasRegion* Atlas::findRegion (const std::string &name) {
return reinterpret_cast<AtlasRegion*>(BaseAtlas::findRegion(name));
}
} /* namespace spine */

View File

@ -0,0 +1,24 @@
#include <stdexcept>
#include <spine-sfml/AtlasAttachmentLoader.h>
#include <spine-sfml/Atlas.h>
#include <spine-sfml/RegionAttachment.h>
namespace spine {
AtlasAttachmentLoader::AtlasAttachmentLoader (Atlas *atlas) :
atlas(atlas) {
}
Attachment* AtlasAttachmentLoader::newAttachment (AttachmentType type, const std::string &name) {
switch (type) {
case region: {
AtlasRegion *region = atlas->findRegion(name);
if (!region) throw std::runtime_error("Atlas region not found: " + name);
return new RegionAttachment(region);
}
default:
throw std::runtime_error("Unknown attachment type: " + type);
}
}
} /* namespace spine */

View File

@ -1,23 +0,0 @@
#ifndef ATTACHMENTLOADER_H_
#define ATTACHMENTLOADER_H_
#include <stdexcept>
#include <spine/BaseAttachmentLoader.h>
#include <spine-sfml/RegionAttachment.h>
namespace spine {
class AttachmentLoader: public BaseAttachmentLoader {
public:
virtual Attachment* newAttachment (AttachmentType type) {
switch (type) {
case region:
return new RegionAttachment();
default:
throw std::runtime_error("Unknown attachment type: " + type);
}
}
};
} /* namespace spine */
#endif /* ATTACHMENTLOADER_H_ */

View File

@ -1,14 +1,73 @@
#include <iostream>
#include <SFML/System/Vector2.hpp>
#include <spine-sfml/RegionAttachment.h>
#include <spine-sfml/Atlas.h>
#include <spine-sfml/Skeleton.h>
#include <spine/Bone.h>
#include <spine/Slot.h>
namespace spine {
RegionAttachment::RegionAttachment () {
RegionAttachment::RegionAttachment (AtlasRegion *region) {
texture = region->page->texture;
sf::Vector2u size = texture->getSize();
int u = region->x;
int u2 = u + region->width;
int v = region->y;
int v2 = v + region->height;
if (region->rotate) {
vertices[1].texCoords.x = u;
vertices[1].texCoords.y = v2;
vertices[2].texCoords.x = u;
vertices[2].texCoords.y = v;
vertices[3].texCoords.x = u2;
vertices[3].texCoords.y = v;
vertices[0].texCoords.x = u2;
vertices[0].texCoords.y = v2;
} else {
vertices[0].texCoords.x = u;
vertices[0].texCoords.y = v2;
vertices[1].texCoords.x = u;
vertices[1].texCoords.y = v;
vertices[2].texCoords.x = u2;
vertices[2].texCoords.y = v;
vertices[3].texCoords.x = u2;
vertices[3].texCoords.y = v2;
}
}
void RegionAttachment::draw (const BaseSkeleton *skeleton) {
((Skeleton*)skeleton)->vertexArray.append(vertices[0]);
void RegionAttachment::draw (Slot *slot) {
Skeleton* skeleton = (Skeleton*)slot->skeleton;
sf::Uint8 r = skeleton->r * slot->r * 255;
sf::Uint8 g = skeleton->g * slot->g * 255;
sf::Uint8 b = skeleton->b * slot->b * 255;
sf::Uint8 a = skeleton->a * slot->a * 255;
vertices[0].color.r = r;
vertices[0].color.g = g;
vertices[0].color.b = b;
vertices[0].color.a = a;
vertices[1].color.r = r;
vertices[1].color.g = g;
vertices[1].color.b = b;
vertices[1].color.a = a;
vertices[2].color.r = r;
vertices[2].color.g = g;
vertices[2].color.b = b;
vertices[2].color.a = a;
vertices[3].color.r = r;
vertices[3].color.g = g;
vertices[3].color.b = b;
vertices[3].color.a = a;
updateOffset(); // BOZO - Move to resolve()?
updateWorldVertices(slot->bone);
skeleton->texture = texture;
skeleton->vertexArray.append(vertices[0]);
skeleton->vertexArray.append(vertices[1]);
skeleton->vertexArray.append(vertices[2]);
skeleton->vertexArray.append(vertices[3]);
}
void RegionAttachment::updateWorldVertices (spine::Bone *bone) {

View File

@ -1,23 +1,30 @@
#include <iostream>
#include <spine-sfml/Skeleton.h>
#include <spine/SkeletonData.h>
#include <spine/Slot.h>
#include <spine/Attachment.h>
#include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/RenderStates.hpp>
#include <SFML/Graphics/Texture.hpp>
using namespace sf;
using sf::Quads;
using sf::RenderTarget;
using sf::RenderStates;
namespace spine {
Skeleton::Skeleton (SkeletonData *skeletonData) :
BaseSkeleton(skeletonData),
vertexArray(Quads, skeletonData->bones.size() * 4) {
vertexArray(Quads, skeletonData->bones.size() * 4),
texture(0) {
flipY = true; // BOZO - Flip in loader for animation?
}
void Skeleton::draw (RenderTarget& target, RenderStates states) const {
const_cast<Skeleton*>(this)->vertexArray.clear();
for (int i = 0, n = slots.size(); i < n; i++)
if (slots[i]->attachment) slots[i]->attachment->draw(this);
target.draw(vertexArray, states);
if (slots[i]->attachment) slots[i]->attachment->draw(slots[i]);
target.draw(vertexArray, texture);
}
} /* namespace spine */

View File

@ -1,9 +1,14 @@
#include <spine-sfml/SkeletonJson.h>
#include "AttachmentLoader.h"
#include <spine-sfml/AtlasAttachmentLoader.h>
namespace spine {
SkeletonJson::SkeletonJson () : BaseSkeletonJson(new AttachmentLoader()) {
SkeletonJson::SkeletonJson (BaseAttachmentLoader *attachmentLoader) :
BaseSkeletonJson(attachmentLoader) {
}
SkeletonJson::SkeletonJson (Atlas *atlas) :
BaseSkeletonJson(new AtlasAttachmentLoader(atlas)) {
}
} /* namespace spine */

View File

@ -1,9 +1,9 @@
#include <cstdio>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cctype>
#include <stdexcept>
#include <spine/AtlasData.h>
#include <spine/BaseAtlas.h>
using std::string;
using std::runtime_error;
@ -65,35 +65,45 @@ static string formatNames[] = {"Alpha", "Intensity", "LuminanceAlpha", "RGB565",
static string textureFilterNames[] = {"Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest",
"MipMapNearestLinear", "MipMapLinearLinear"};
AtlasData::AtlasData (std::istream &file) {
//
BaseAtlas::~BaseAtlas () {
for (int i = 0, n = pages.size(); i < n; i++)
delete pages[i];
for (int i = 0, n = regions.size(); i < n; i++)
delete regions[i];
}
void BaseAtlas::load (std::ifstream &file) {
if (!file.is_open()) throw runtime_error("Atlas file is not open.");
load((std::istream&)file);
}
void BaseAtlas::load (std::istream &input) {
string text;
std::getline(file, text, (char)EOF);
std::getline(input, text, (char)EOF);
const char *begin = text.c_str();
const char *end = begin + text.length();
init(begin, end);
load(begin, end);
}
AtlasData::AtlasData (const string &text) {
void BaseAtlas::load (const string &text) {
const char *begin = text.c_str();
const char *end = begin + text.length();
init(begin, end);
load(begin, end);
}
AtlasData::AtlasData (const char *begin, const char *end) {
init(begin, end);
}
void AtlasData::init (const char *current, const char *end) {
void BaseAtlas::load (const char *current, const char *end) {
string value;
string tuple[4];
AtlasPage *page;
BaseAtlasPage *page;
while (current != end) {
readLine(current, end, value);
trim(value);
if (value.length() == 0) {
page = 0;
} else if (!page) {
page = new AtlasPage();
page = newAtlasPage(value);
pages.push_back(page);
page->name = value;
page->format = static_cast<Format>(indexOf(formatNames, 7, readValue(current, end, value)));
@ -114,10 +124,9 @@ void AtlasData::init (const char *current, const char *end) {
page->vWrap = repeat;
}
} else {
AtlasRegion *region = new AtlasRegion();
BaseAtlasRegion *region = newAtlasRegion(page);
regions.push_back(region);
region->name = value;
region->page = page;
region->rotate = readValue(current, end, value) == "true";
@ -159,11 +168,17 @@ void AtlasData::init (const char *current, const char *end) {
}
}
AtlasData::~AtlasData () {
for (int i = 0, n = pages.size(); i < n; i++)
delete pages[i];
BaseAtlasRegion* BaseAtlas::findRegion (const std::string &name) {
for (int i = 0, n = regions.size(); i < n; i++)
delete regions[i];
if (regions[i]->name == name) return regions[i];
return 0;
}
//
BaseAtlasRegion::~BaseAtlasRegion () {
if (splits) delete splits;
if (pads) delete pads;
}
} /* namespace spine */

View File

@ -1,3 +1,4 @@
#include <iostream>
#include <spine/BaseSkeleton.h>
#include <spine/SkeletonData.h>
#include <spine/SlotData.h>
@ -17,7 +18,10 @@ BaseSkeleton::BaseSkeleton (SkeletonData *data) :
r(1),
g(1),
b(1),
a(1) {
a(1),
time(0),
flipX(false),
flipY(false) {
if (!data) throw invalid_argument("data cannot be null.");
int boneCount = data->bones.size();

View File

@ -1,5 +1,5 @@
#include <cstdlib>
#include <cstdio>
#include <fstream>
#include <stdexcept>
#include <json/json.h>
#include <spine/BaseSkeletonJson.h>
@ -31,9 +31,14 @@ float toColor (const string &value, int index) {
return color / (float)255;
}
SkeletonData* BaseSkeletonJson::readSkeletonData (std::istream &file) const {
SkeletonData* BaseSkeletonJson::readSkeletonData (std::ifstream &file) const {
if (!file.is_open()) throw runtime_error("Skeleton file is not open.");
return readSkeletonData((std::istream&)file);
}
SkeletonData* BaseSkeletonJson::readSkeletonData (std::istream &input) const {
string json;
std::getline(file, json, (char)EOF);
std::getline(input, json, (char)EOF);
return readSkeletonData(json);
}
@ -133,8 +138,8 @@ SkeletonData* BaseSkeletonJson::readSkeletonData (const char *begin, const char
else
throw runtime_error("Unknown attachment type: " + typeString + " (" + attachmentName + ")");
Attachment* attachment = attachmentLoader->newAttachment(type);
attachment->name = attachmentMap.get("name", attachmentName).asString();
Attachment* attachment = attachmentLoader->newAttachment(type,
attachmentMap.get("name", attachmentName).asString());
attachment->x = attachmentMap.get("x", 0).asDouble() * scale;
attachment->y = attachmentMap.get("y", 0).asDouble() * scale;
attachment->scaleX = attachmentMap.get("scaleX", 1).asDouble();

View File

@ -1,198 +0,0 @@
uiskin.png
format: RGBA8888
filter: Nearest,Nearest
repeat: none
default
rotate: false
xy: 1, 50
size: 254, 77
orig: 254, 77
offset: 0, 0
index: -1
default-window
rotate: false
xy: 1, 20
size: 27, 29
split: 4, 3, 20, 3
orig: 27, 29
offset: 0, 0
index: -1
default-select
rotate: false
xy: 29, 29
size: 27, 20
split: 4, 14, 4, 4
orig: 27, 20
offset: 0, 0
index: -1
default-round-large
rotate: false
xy: 57, 29
size: 20, 20
split: 5, 5, 5, 4
orig: 20, 20
offset: 0, 0
index: -1
default-scroll
rotate: false
xy: 78, 29
size: 20, 20
split: 2, 2, 2, 2
orig: 20, 20
offset: 0, 0
index: -1
default-slider-knob
rotate: false
xy: 1, 1
size: 9, 18
orig: 9, 18
offset: 0, 0
index: -1
default-round-down
rotate: false
xy: 99, 29
size: 12, 20
split: 5, 5, 5, 4
orig: 12, 20
offset: 0, 0
index: -1
default-round
rotate: false
xy: 112, 29
size: 12, 20
split: 5, 5, 5, 4
pad: 4, 4, 1, 1
orig: 12, 20
offset: 0, 0
index: -1
check-off
rotate: false
xy: 11, 5
size: 14, 14
orig: 14, 14
offset: 0, 0
index: -1
textfield
rotate: false
xy: 11, 5
size: 14, 14
split: 3, 3, 3, 3
orig: 14, 14
offset: 0, 0
index: -1
check-on
rotate: false
xy: 125, 35
size: 14, 14
orig: 14, 14
offset: 0, 0
index: -1
tree-minus
rotate: false
xy: 140, 35
size: 14, 14
orig: 14, 14
offset: 0, 0
index: -1
tree-plus
rotate: false
xy: 155, 35
size: 14, 14
orig: 14, 14
offset: 0, 0
index: -1
default-slider
rotate: false
xy: 29, 20
size: 8, 8
split: 2, 2, 2, 2
orig: 8, 8
offset: 0, 0
index: -1
default-pane
rotate: false
xy: 11, 1
size: 5, 3
split: 1, 1, 1, 1
orig: 5, 3
offset: 0, 0
index: -1
default-rect-pad
rotate: false
xy: 11, 1
size: 5, 3
split: 1, 1, 1, 1
orig: 5, 3
offset: 0, 0
index: -1
default-splitpane
rotate: false
xy: 17, 1
size: 5, 3
split: 0, 5, 0, 0
orig: 5, 3
offset: 0, 0
index: -1
cursor
rotate: false
xy: 23, 1
size: 3, 3
split: 1, 1, 1, 1
orig: 3, 3
offset: 0, 0
index: -1
default-splitpane-vertical
rotate: false
xy: 125, 29
size: 3, 5
split: 0, 0, 0, 5
orig: 3, 5
offset: 0, 0
index: -1
default-rect-down
rotate: false
xy: 170, 46
size: 3, 3
split: 1, 1, 1, 1
orig: 3, 3
offset: 0, 0
index: -1
default-rect
rotate: false
xy: 38, 25
size: 3, 3
split: 1, 1, 1, 1
orig: 3, 3
offset: 0, 0
index: -1
default-select-selection
rotate: false
xy: 26, 16
size: 3, 3
split: 1, 1, 1, 1
orig: 3, 3
offset: 0, 0
index: -1
default-pane-noborder
rotate: false
xy: 129, 33
size: 1, 1
split: 0, 0, 0, 0
orig: 1, 1
offset: 0, 0
index: -1
selection
rotate: false
xy: 170, 44
size: 1, 1
orig: 1, 1
offset: 0, 0
index: -1
white
rotate: false
xy: 174, 48
size: 1, 1
orig: 1, 1
offset: 0, 0
index: -1