Преглед на файлове

cpp, skeleton loading and rendering with SFML.

NathanSweet преди 12 години
родител
ревизия
268933242f
променени са 29 файла, в които са добавени 820 реда и са изтрити 366 реда
  1. 1 2
      spine-cpp/.settings/org.eclipse.cdt.codan.core.prefs
  2. 2 0
      spine-cpp/.settings/org.eclipse.ltk.core.refactoring.prefs
  3. 0 3
      spine-cpp/data/spineboy-skeleton.json
  4. 278 0
      spine-cpp/data/spineboy-walk.json
  5. 166 0
      spine-cpp/data/spineboy.atlas
  6. BIN
      spine-cpp/data/spineboy.png
  7. 38 0
      spine-cpp/includes/spine-sfml/Atlas.h
  8. 21 0
      spine-cpp/includes/spine-sfml/AtlasAttachmentLoader.h
  9. 5 3
      spine-cpp/includes/spine-sfml/RegionAttachment.h
  10. 2 1
      spine-cpp/includes/spine-sfml/Skeleton.h
  11. 4 1
      spine-cpp/includes/spine-sfml/SkeletonJson.h
  12. 4 1
      spine-cpp/includes/spine-sfml/spine.h
  13. 0 62
      spine-cpp/includes/spine/AtlasData.h
  14. 2 1
      spine-cpp/includes/spine/Attachment.h
  15. 78 0
      spine-cpp/includes/spine/BaseAtlas.h
  16. 1 1
      spine-cpp/includes/spine/BaseAttachmentLoader.h
  17. 1 0
      spine-cpp/includes/spine/BaseRegionAttachment.h
  18. 3 2
      spine-cpp/includes/spine/BaseSkeletonJson.h
  19. 21 33
      spine-cpp/src/main.cpp
  20. 39 0
      spine-cpp/src/spine-sfml/Atlas.cpp
  21. 24 0
      spine-cpp/src/spine-sfml/AtlasAttachmentLoader.cpp
  22. 0 23
      spine-cpp/src/spine-sfml/AttachmentLoader.h
  23. 62 3
      spine-cpp/src/spine-sfml/RegionAttachment.cpp
  24. 11 4
      spine-cpp/src/spine-sfml/Skeleton.cpp
  25. 7 2
      spine-cpp/src/spine-sfml/SkeletonJson.cpp
  26. 35 20
      spine-cpp/src/spine/BaseAtlas.cpp
  27. 5 1
      spine-cpp/src/spine/BaseSkeleton.cpp
  28. 10 5
      spine-cpp/src/spine/BaseSkeletonJson.cpp
  29. 0 198
      spine-cpp/uiskin.atlas

+ 1 - 2
spine-cpp/.settings/org.eclipse.cdt.codan.core.prefs

@@ -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

+ 2 - 0
spine-cpp/.settings/org.eclipse.ltk.core.refactoring.prefs

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

+ 0 - 3
spine-cpp/spineboy-skeleton.json → spine-cpp/data/spineboy-skeleton.json

@@ -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 }
 		},

+ 278 - 0
spine-cpp/data/spineboy-walk.json

@@ -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 }
+		]
+	}
+}
+}

+ 166 - 0
spine-cpp/data/spineboy.atlas

@@ -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


+ 38 - 0
spine-cpp/includes/spine-sfml/Atlas.h

@@ -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_ */

+ 21 - 0
spine-cpp/includes/spine-sfml/AtlasAttachmentLoader.h

@@ -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_ */

+ 5 - 3
spine-cpp/includes/spine-sfml/RegionAttachment.h

@@ -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 */

+ 2 - 1
spine-cpp/includes/spine-sfml/Skeleton.h

@@ -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);
 

+ 4 - 1
spine-cpp/includes/spine-sfml/SkeletonJson.h

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

+ 4 - 1
spine-cpp/includes/spine-sfml/spine.h

@@ -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_ */

+ 0 - 62
spine-cpp/includes/spine/AtlasData.h

@@ -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_ */

+ 2 - 1
spine-cpp/includes/spine/Attachment.h

@@ -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 */

+ 78 - 0
spine-cpp/includes/spine/BaseAtlas.h

@@ -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_ */

+ 1 - 1
spine-cpp/includes/spine/BaseAttachmentLoader.h

@@ -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 */

+ 1 - 0
spine-cpp/includes/spine/BaseRegionAttachment.h

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

+ 3 - 2
spine-cpp/includes/spine/BaseSkeletonJson.h

@@ -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 */

+ 21 - 33
spine-cpp/src/main.cpp

@@ -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";
-
-		BaseSkeleton *skeleton = new BaseSkeleton(skeletonData);
-		cout << skeleton->bones.size() << " bones.\n";
+		Skeleton *skeleton = new Skeleton(skeletonData);
+		skeleton->setToBindPose();
+		skeleton->getRootBone()->x = 200;
+		skeleton->getRootBone()->y = 420;
+		skeleton->updateWorldTransform();
+
+		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;
 }

+ 39 - 0
spine-cpp/src/spine-sfml/Atlas.cpp

@@ -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 */

+ 24 - 0
spine-cpp/src/spine-sfml/AtlasAttachmentLoader.cpp

@@ -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 */

+ 0 - 23
spine-cpp/src/spine-sfml/AttachmentLoader.h

@@ -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_ */

+ 62 - 3
spine-cpp/src/spine-sfml/RegionAttachment.cpp

@@ -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) {

+ 11 - 4
spine-cpp/src/spine-sfml/Skeleton.cpp

@@ -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 */

+ 7 - 2
spine-cpp/src/spine-sfml/SkeletonJson.cpp

@@ -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 */

+ 35 - 20
spine-cpp/src/spine/AtlasData.cpp → spine-cpp/src/spine/BaseAtlas.cpp

@@ -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 */

+ 5 - 1
spine-cpp/src/spine/BaseSkeleton.cpp

@@ -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();

+ 10 - 5
spine-cpp/src/spine/BaseSkeletonJson.cpp

@@ -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();

+ 0 - 198
spine-cpp/uiskin.atlas

@@ -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