Преглед изворни кода

[cpp] More 4.0 porting, Atlas, fixes.

badlogic пре 4 година
родитељ
комит
cf3a28e3a4

+ 4 - 29
spine-cpp/spine-cpp/include/spine/Atlas.h

@@ -74,10 +74,11 @@ public:
 	TextureWrap uWrap;
 	TextureWrap vWrap;
 	int width, height;
+	bool pma;
 
 	explicit AtlasPage(const String &inName) : name(inName), format(Format_RGBA8888), minFilter(TextureFilter_Nearest),
 		magFilter(TextureFilter_Nearest), uWrap(TextureWrap_ClampToEdge),
-		vWrap(TextureWrap_ClampToEdge), width(0), height(0) {
+		vWrap(TextureWrap_ClampToEdge), width(0), height(0), pma(false) {
 	}
 };
 
@@ -94,6 +95,8 @@ public:
 	int degrees;
 	Vector<int> splits;
 	Vector<int> pads;
+	Vector<String> names;
+	Vector<float> values;
 };
 
 class TextureLoader;
@@ -123,34 +126,6 @@ private:
 	TextureLoader *_textureLoader;
 
 	void load(const char *begin, int length, const char *dir, bool createTexture);
-
-	class Str {
-	public:
-		const char *begin;
-		const char *end;
-	};
-
-	static void trim(Str *str);
-
-	/// Tokenize string without modification. Returns 0 on failure
-	static int readLine(const char **begin, const char *end, Str *str);
-
-	/// Moves str->begin past the first occurence of c. Returns 0 on failure
-	static int beginPast(Str *str, char c);
-
-	/// Returns 0 on failure
-	static int readValue(const char **begin, const char *end, Str *str);
-
-	/// Returns the number of tuple values read (1, 2, 4, or 0 for failure)
-	static int readTuple(const char **begin, const char *end, Str tuple[]);
-
-	static char *mallocString(Str *str);
-
-	static int indexOf(const char **array, int count, Str *str);
-
-	static int equals(Str *str, const char *other);
-
-	static int toInt(Str *str);
 };
 }
 

+ 0 - 2
spine-cpp/spine-cpp/include/spine/TransformConstraintTimeline.h

@@ -60,8 +60,6 @@ namespace spine {
 		static const int SCALEX = 4;
         static const int SCALEY = 5;
 		static const int SHEARY = 6;
-
-		Vector<float> _frames;
 	};
 }
 

+ 245 - 225
spine-cpp/spine-cpp/src/spine/Atlas.cpp

@@ -102,232 +102,252 @@ Vector<AtlasRegion*> &Atlas::getRegions() {
     return _regions;
 }
 
-void Atlas::load(const char *begin, int length, const char *dir, bool createTexture) {
-	static const char *formatNames[] = {"", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888"};
-	static const char *textureFilterNames[] = {"", "Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest",
-		"MipMapNearestLinear", "MipMapLinearLinear"};
-
-	int count;
-	const char *end = begin + length;
-	int dirLength = (int) strlen(dir);
-	int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\';
-
-	AtlasPage *page = NULL;
-	Str str;
-	Str tuple[4];
-
-	while (readLine(&begin, end, &str)) {
-		if (str.end - str.begin == 0) {
-			page = 0;
-		} else if (!page) {
-			char *name = mallocString(&str);
-			char *path = SpineExtension::calloc<char>(dirLength + needsSlash + strlen(name) + 1, __FILE__, __LINE__);
-			memcpy(path, dir, dirLength);
-			if (needsSlash) path[dirLength] = '/';
-			strcpy(path + dirLength + needsSlash, name);
-
-			page = new(__FILE__, __LINE__) AtlasPage(String(name, true));
-
-			int tupleVal = readTuple(&begin, end, tuple);
-			assert(tupleVal == 2);
-
-			/* size is only optional for an atlas packed with an old TexturePacker. */
-			page->width = toInt(tuple);
-			page->height = toInt(tuple + 1);
-			readTuple(&begin, end, tuple);
-
-			page->format = (Format) indexOf(formatNames, 8, tuple);
-
-			readTuple(&begin, end, tuple);
-			page->minFilter = (TextureFilter) indexOf(textureFilterNames, 8, tuple);
-			page->magFilter = (TextureFilter) indexOf(textureFilterNames, 8, tuple + 1);
-
-			readValue(&begin, end, &str);
-
-			page->uWrap = TextureWrap_ClampToEdge;
-			page->vWrap = TextureWrap_ClampToEdge;
-			if (!equals(&str, "none")) {
-				if (str.end - str.begin == 1) {
-					if (*str.begin == 'x') {
-						page->uWrap = TextureWrap_Repeat;
-					} else if (*str.begin == 'y') {
-						page->vWrap = TextureWrap_Repeat;
-					}
-				} else if (equals(&str, "xy")) {
-					page->uWrap = TextureWrap_Repeat;
-					page->vWrap = TextureWrap_Repeat;
-				}
-			}
-
-			if (createTexture) {
-				if (_textureLoader) _textureLoader->load(*page, String(path));
-				SpineExtension::free(path, __FILE__, __LINE__);
-			} else
-				page->texturePath = String(path, true);
-
-			_pages.add(page);
-		} else {
-			AtlasRegion *region = new(__FILE__, __LINE__) AtlasRegion();
-
-			region->page = page;
-			region->name = String(mallocString(&str), true);
-
-			readValue(&begin, end, &str);
-			if (equals(&str, "true")) region->degrees = 90;
-			else if (equals(&str, "false")) region->degrees = 0;
-			else region->degrees = toInt(&str);
-			region->rotate = region->degrees == 90;
-
-			readTuple(&begin, end, tuple);
-			region->x = toInt(tuple);
-			region->y = toInt(tuple + 1);
-
-			readTuple(&begin, end, tuple);
-			region->width = toInt(tuple);
-			region->height = toInt(tuple + 1);
-
-			region->u = region->x / (float) page->width;
-			region->v = region->y / (float) page->height;
-			if (region->rotate) {
-				region->u2 = (region->x + region->height) / (float) page->width;
-				region->v2 = (region->y + region->width) / (float) page->height;
-			} else {
-				region->u2 = (region->x + region->width) / (float) page->width;
-				region->v2 = (region->y + region->height) / (float) page->height;
-			}
-
-			count = readTuple(&begin, end, tuple);
-			assert(count);
-
-			if (count == 4) {
-				/* split is optional */
-				region->splits.setSize(4, 0);
-				region->splits[0] = toInt(tuple);
-				region->splits[1] = toInt(tuple + 1);
-				region->splits[2] = toInt(tuple + 2);
-				region->splits[3] = toInt(tuple + 3);
-
-				count = readTuple(&begin, end, tuple);
-				assert(count);
-
-				if (count == 4) {
-					/* pad is optional, but only present with splits */
-					region->pads.setSize(4, 0);
-					region->pads[0] = toInt(tuple);
-					region->pads[1] = toInt(tuple + 1);
-					region->pads[2] = toInt(tuple + 2);
-					region->pads[3] = toInt(tuple + 3);
-
-					readTuple(&begin, end, tuple);
-				}
-			}
-
-			region->originalWidth = toInt(tuple);
-			region->originalHeight = toInt(tuple + 1);
-
-			readTuple(&begin, end, tuple);
-			region->offsetX = (float)toInt(tuple);
-			region->offsetY = (float)toInt(tuple + 1);
-
-			readValue(&begin, end, &str);
-
-			region->index = toInt(&str);
-
-			_regions.add(region);
-		}
-	}
-}
-
-void Atlas::trim(Str *str) {
-	while (isspace((unsigned char) *str->begin) && str->begin < str->end)
-		(str->begin)++;
-
-	if (str->begin == str->end) return;
-
-	str->end--;
-
-	while (((unsigned char)*str->end == '\r') && str->end >= str->begin)
-		str->end--;
-
-	str->end++;
-}
-
-int Atlas::readLine(const char **begin, const char *end, Str *str) {
-	if (*begin == end) return 0;
-
-	str->begin = *begin;
-
-	/* Find next delimiter. */
-	while (*begin != end && **begin != '\n')
-		(*begin)++;
-
-	str->end = *begin;
-	trim(str);
-
-	if (*begin != end) (*begin)++;
-
-	return 1;
+struct SimpleString {
+    char* start;
+    char* end;
+    int length;
+
+    SimpleString trim() {
+        while (isspace((unsigned char) *start) && start < end)
+            start++;
+        if (start == end) return *this;
+        end--;
+        while (((unsigned char)*end == '\r') && end >= start)
+            end--;
+        end++;
+        length = end - start;
+        return *this;
+    }
+
+    int indexOf(char needle) {
+        char *c = start;
+        while (c < end) {
+            if (*c == needle) return c - start;
+            c++;
+        }
+        return -1;
+    }
+
+    int indexOf(char needle, int at) {
+        char *c = start + at;
+        while (c < end) {
+            if (*c == needle) return c - start;
+            c++;
+        }
+        return -1;
+    }
+
+    SimpleString substr(int s, int e) {
+        e = s + e;
+        SimpleString result;
+        result.start = start + s;
+        result.end = start + e;
+        result.length = e - s;
+        return result;
+    }
+
+    SimpleString substr(int s) {
+        SimpleString result;
+        result.start = start + s;
+        result.end = end;
+        result.length = result.end - result.start;
+        return result;
+    }
+
+    bool equals(const char *str) {
+        int otherLen = strlen(str);
+        if (length != otherLen) return false;
+        for (int i = 0; i < length; i++) {
+            if (start[i] != str[i]) return false;
+        }
+        return true;
+    }
+
+    char *copy() {
+        char *string = SpineExtension::calloc<char>(length + 1, __FILE__, __LINE__);
+        memcpy(string, start, length);
+        string[length] = '\0';
+        return string;
+    }
+
+    int toInt() {
+        return (int) strtol(start, &end, 10);
+    }
+};
+
+struct AtlasInput {
+    const char *start;
+    const char *end;
+    char *index;
+    int length;
+    SimpleString line;
+
+    AtlasInput(const char *data, int length) : start(data), end(data + length), index((char*)data), length(length) {}
+
+    SimpleString *readLine() {
+        if (index >= end) return 0;
+        line.start = index;
+        while (index < end && *index != '\n')
+            index++;
+        line.end = index;
+        if (index != end) index++;
+        line = line.trim();
+        line.length = end - start;
+        return &line;
+    }
+
+    static int readEntry(SimpleString entry[5], SimpleString *line) {
+        if (line == NULL) return 0;
+        line->trim();
+        if (line->length == 0) return 0;
+
+        int colon = line->indexOf(':');
+        if (colon == -1) return 0;
+        entry[0] = line->substr(0, colon).trim();
+        for (int i = 1, lastMatch = colon + 1;; i++) {
+            int comma = line->indexOf(',', lastMatch);
+            if (comma == -1) {
+                entry[i] = line->substr(lastMatch).trim();
+                return i;
+            }
+            entry[i] = line->substr(lastMatch, comma - lastMatch).trim();
+            lastMatch = comma + 1;
+            if (i == 4) return 4;
+        }
+    }
+};
+
+int indexOf(const char **array, int count, SimpleString *str) {
+    for (int i = 0; i < count; i++)
+        if (str->equals(array[i])) return i;
+    return 0;
 }
 
-int Atlas::beginPast(Str *str, char c) {
-	const char *begin = str->begin;
-	while (true) {
-		char lastSkippedChar = *begin;
-		if (begin == str->end) return 0;
-		begin++;
-		if (lastSkippedChar == c) break;
-	}
-	str->begin = begin;
-	return 1;
-}
-
-int Atlas::readValue(const char **begin, const char *end, Str *str) {
-	readLine(begin, end, str);
-	if (!beginPast(str, ':')) return 0;
-	trim(str);
-	return 1;
-}
-
-int Atlas::readTuple(const char **begin, const char *end, Str tuple[]) {
-	int i;
-	Str str = {NULL, NULL};
-	readLine(begin, end, &str);
-	if (!beginPast(&str, ':')) return 0;
-
-	for (i = 0; i < 3; ++i) {
-		tuple[i].begin = str.begin;
-		if (!beginPast(&str, ',')) break;
-		tuple[i].end = str.begin - 2;
-		trim(&tuple[i]);
-	}
-
-	tuple[i].begin = str.begin;
-	tuple[i].end = str.end;
-	trim(&tuple[i]);
-
-	return i + 1;
-}
-
-char *Atlas::mallocString(Str *str) {
-	int length = (int) (str->end - str->begin);
-	char *string = SpineExtension::calloc<char>(length + 1, __FILE__, __LINE__);
-	memcpy(string, str->begin, length);
-	string[length] = '\0';
-	return string;
-}
-
-int Atlas::indexOf(const char **array, int count, Str *str) {
-	int length = (int) (str->end - str->begin);
-	int i;
-	for (i = count - 1; i >= 0; i--)
-		if (strncmp(array[i], str->begin, length) == 0) return i;
-	return 0;
-}
-
-int Atlas::equals(Str *str, const char *other) {
-	return strncmp(other, str->begin, str->end - str->begin) == 0;
+void Atlas::load(const char *begin, int length, const char *dir, bool createTexture) {
+    static const char *formatNames[] = {"", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888",
+                                        "RGBA8888"};
+    static const char *textureFilterNames[] = {"", "Nearest", "Linear", "MipMap", "MipMapNearestNearest",
+                                               "MipMapLinearNearest",
+                                               "MipMapNearestLinear", "MipMapLinearLinear"};
+
+    int dirLength = (int) strlen(dir);
+    int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\';
+    AtlasInput reader(begin, length);
+    SimpleString entry[5];
+    AtlasPage *page = NULL;
+
+    SimpleString *line = reader.readLine();
+    while (line != NULL && line->length == 0)
+        line = reader.readLine();
+
+    while (true) {
+        if (line == NULL || line->length == 0) break;
+        if (reader.readEntry(entry, line) == 0) break;
+        line = reader.readLine();
+    }
+
+    while (true) {
+        if (line == NULL) break;
+        if (line->trim().length == 0) {
+            page = NULL;
+            line = reader.readLine();
+        } else if (page == NULL) {
+            char *name = line->copy();
+            char *path = SpineExtension::calloc<char>(dirLength + needsSlash + strlen(name) + 1, __FILE__, __LINE__);
+            memcpy(path, dir, dirLength);
+            if (needsSlash) path[dirLength] = '/';
+            strcpy(path + dirLength + needsSlash, name);
+            page = new(__FILE__, __LINE__) AtlasPage(String(name, true));
+
+            while (true) {
+                line = line = reader.readLine();
+                if (reader.readEntry(entry, line) == 0) break;
+                if (entry[0].equals("size")) {
+                    page->width = entry[1].toInt();
+                    page->height = entry[2].toInt();
+                } else if (entry[0].equals("format")) {
+                    page->format = (Format) indexOf(formatNames, 8, &entry[1]);
+                } else if (entry[0].equals("filter")) {
+                    page->minFilter = (TextureFilter) indexOf(textureFilterNames, 8, &entry[1]);
+                    page->magFilter = (TextureFilter) indexOf(textureFilterNames, 8, &entry[2]);
+                } else if (entry[0].equals("repeat")) {
+                    page->uWrap = TextureWrap_ClampToEdge;
+                    page->vWrap = TextureWrap_ClampToEdge;
+                    if (entry[1].indexOf('x') != -1) page->uWrap = TextureWrap_Repeat;
+                    if (entry[1].indexOf('y') != -1) page->vWrap = TextureWrap_Repeat;
+                } else if (entry[0].equals("pma")) {
+                    page->pma = entry[1].equals("true");
+                }
+            }
+
+            if (createTexture) {
+                if (_textureLoader) _textureLoader->load(*page, String(path));
+                SpineExtension::free(path, __FILE__, __LINE__);
+            } else {
+                page->texturePath = String(path, true);
+            }
+            _pages.add(page);
+        } else {
+            AtlasRegion *region = new(__FILE__, __LINE__) AtlasRegion();
+            region->page = page;
+            region->name = String(line->copy(), true);
+            while (true) {
+                line = line = reader.readLine();
+                int count = reader.readEntry(entry, line);
+                if (count == 0) break;
+                if (entry[0].equals("xy")) {
+                    region->x = entry[1].toInt();
+                    region->y = entry[2].toInt();
+                } else if (entry[0].equals("size")) {
+                    region->width = entry[1].toInt();
+                    region->height = entry[2].toInt();
+                } else if (entry[0].equals("bounds")) {
+                    region->x = entry[1].toInt();
+                    region->y = entry[2].toInt();
+                    region->width = entry[3].toInt();
+                    region->height = entry[4].toInt();
+                } else if (entry[0].equals("offset")) {
+                    region->offsetX = entry[1].toInt();
+                    region->offsetY = entry[2].toInt();
+                } else if (entry[0].equals("orig")) {
+                    region->originalWidth = entry[1].toInt();
+                    region->originalHeight = entry[2].toInt();
+                } else if (entry[0].equals("offsets")) {
+                    region->offsetX = entry[1].toInt();
+                    region->offsetY = entry[2].toInt();
+                    region->originalWidth = entry[3].toInt();
+                    region->originalHeight = entry[4].toInt();
+                } else if (entry[0].equals("rotate")) {
+                    if (entry[1].equals("true")) {
+                        region->degrees = 90;
+                    } else if (!entry[1].equals("false")) {
+                        region->degrees = entry[1].toInt();
+                    }
+                } else if (entry[0].equals("index")) {
+                    region->index = entry[1].toInt();
+                } else {
+                    region->names.add(String(entry[0].copy()));
+                    for (int i = 0; i < count; i++) {
+                        region->values.add(entry[i + 1].toInt());
+                    }
+                }
+            }
+            if (region->originalWidth == 0 && region->originalHeight == 0) {
+                region->originalWidth = region->width;
+                region->originalHeight = region->height;
+            }
+
+            region->u = region->x / page->width;
+            region->v = region->y / page->height;
+            if (region->degrees == 90) {
+                region->u2 = (region->x + region->height) / page->width;
+                region->v2 = (region->y + region->width) / page->height;
+            } else {
+                region->u2 = (region->x + region->width) / page->width;
+                region->v2 = (region->y + region->height) / page->height;
+            }
+            _regions.add(region);
+        }
+    }
 }
 
-int Atlas::toInt(Str *str) {
-	return (int) strtol(str->begin, (char **) &str->end, 10);
-}

+ 15 - 15
spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp

@@ -858,7 +858,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
 				for (frame = 0, bezier = 0;;++frame) {
 					timeline->setFrame(frame, time, color.r, color.g, color.b, color.a);
 					nextMap = keyMap->_next;
-					if (!keyMap) break;
+					if (!nextMap) break;
 					float time2 = Json::getFloat(nextMap, "time", 0);
                     toColor(newColor, Json::getString(nextMap, "color", 0), true);
                     curve = Json::getItem(keyMap, "curve");
@@ -884,7 +884,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
                 for (frame = 0, bezier = 0;;++frame) {
                     timeline->setFrame(frame, time, color.r, color.g, color.b);
                     nextMap = keyMap->_next;
-                    if (!keyMap) break;
+                    if (!nextMap) break;
                     float time2 = Json::getFloat(nextMap, "time", 0);
                     toColor(newColor, Json::getString(nextMap, "color", 0), false);
                     curve = Json::getItem(keyMap, "curve");
@@ -899,7 +899,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
                 }
                 timelines.add(timeline);
             } else if (strcmp(timelineMap->_name, "alpha") == 0) {
-                timelines.add(readTimeline(timelineMap, new (__FILE__, __LINE__) AlphaTimeline(timelineMap->_size, timelineMap->_size, slotIndex), 0, 1));
+                timelines.add(readTimeline(timelineMap->_child, new (__FILE__, __LINE__) AlphaTimeline(timelineMap->_size, timelineMap->_size, slotIndex), 0, 1));
             } else if (strcmp(timelineMap->_name, "rgba2") == 0) {
                 int frameCount = timelineMap->_size;
                 int bezierCount = frameCount * 7;
@@ -912,7 +912,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
                 for (frame = 0, bezier = 0;;++frame) {
                     timeline->setFrame(frame, time, color.r, color.g, color.b, color.a, color2.g, color2.g, color2.b);
                     nextMap = keyMap->_next;
-                    if (!keyMap) break;
+                    if (!nextMap) break;
                     float time2 = Json::getFloat(nextMap, "time", 0);
                     toColor(newColor, Json::getString(nextMap, "light", 0), true);
                     toColor(newColor2, Json::getString(nextMap, "dark", 0), false);
@@ -944,7 +944,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
                 for (frame = 0, bezier = 0;;++frame) {
                     timeline->setFrame(frame, time, color.r, color.g, color.b, color.a, color2.r, color2.g, color2.b);
                     nextMap = keyMap->_next;
-                    if (!keyMap) break;
+                    if (!nextMap) break;
                     float time2 = Json::getFloat(nextMap, "time", 0);
                     toColor(newColor, Json::getString(nextMap, "light", 0), false);
                     toColor(newColor2, Json::getString(nextMap, "dark", 0), false);
@@ -986,34 +986,34 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
 		    if (timelineMap->_size == 0) continue;
 
             if (strcmp(timelineMap->_name, "rotate") == 0) {
-                timelines.add(readTimeline(timelineMap, new RotateTimeline(timelineMap->_size, timelineMap->_size, boneIndex), 0, 1));
+                timelines.add(readTimeline(timelineMap->_child, new RotateTimeline(timelineMap->_size, timelineMap->_size, boneIndex), 0, 1));
             } else if (strcmp(timelineMap->_name, "translate") == 0) {
                 TranslateTimeline *timeline = new TranslateTimeline(timelineMap->_size, timelineMap->_size << 1, boneIndex);
-                timelines.add(readTimeline(timelineMap, timeline, "x", "y", 0, _scale));
+                timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 0, _scale));
             } else if (strcmp(timelineMap->_name, "translatex") == 0) {
                 TranslateXTimeline *timeline = new TranslateXTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap, timeline, 0, _scale));
+                timelines.add(readTimeline(timelineMap->_child, timeline, 0, _scale));
             } else if (strcmp(timelineMap->_name, "translatey") == 0) {
                 TranslateYTimeline *timeline = new TranslateYTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap, timeline, 0, _scale));
+                timelines.add(readTimeline(timelineMap->_child, timeline, 0, _scale));
             } else if (strcmp(timelineMap->_name, "scale") == 0) {
                 ScaleTimeline *timeline = new (__FILE__, __LINE__) ScaleTimeline(timelineMap->_size, timelineMap->_size << 1, boneIndex);
-                timelines.add(readTimeline(timelineMap, timeline, "x", "y", 1, 1));
+                timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 1, 1));
             } else if (strcmp(timelineMap->_name, "scalex") == 0) {
                 ScaleXTimeline *timeline = new (__FILE__, __LINE__) ScaleXTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap, timeline, 1, 1));
+                timelines.add(readTimeline(timelineMap->_child, timeline, 1, 1));
             } else if (strcmp(timelineMap->_name, "scaley") == 0) {
                 ScaleYTimeline *timeline = new (__FILE__, __LINE__) ScaleYTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap, timeline, 1, 1));
+                timelines.add(readTimeline(timelineMap->_child, timeline, 1, 1));
             } else if (strcmp(timelineMap->_name, "shear") == 0) {
                 ShearTimeline *timeline = new (__FILE__, __LINE__) ShearTimeline(timelineMap->_size, timelineMap->_size << 1, boneIndex);
-                timelines.add(readTimeline(timelineMap, timeline, "x", "y", 0, 1));
+                timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 0, 1));
             } else if (strcmp(timelineMap->_name, "shearx") == 0) {
                 ShearXTimeline *timeline = new (__FILE__, __LINE__) ShearXTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap, timeline, 0, 1));
+                timelines.add(readTimeline(timelineMap->_child, timeline, 0, 1));
             } else if (strcmp(timelineMap->_name, "sheary") == 0) {
                 ShearYTimeline *timeline = new (__FILE__, __LINE__) ShearYTimeline(timelineMap->_size, timelineMap->_size, boneIndex);
-                timelines.add(readTimeline(timelineMap, timeline, 0, 1));
+                timelines.add(readTimeline(timelineMap->_child, timeline, 0, 1));
             } else {
                 ContainerUtil::cleanUpVectorOfPointers(timelines);
                 setError(NULL, "Invalid timeline type for a bone: ", timelineMap->_name);