#include #include #include #include #include #include #include #include using std::string; using std::invalid_argument; namespace spine { BaseSkeleton::BaseSkeleton (SkeletonData *data) : data(data), skin(0), r(1), g(1), b(1), a(1), time(0), flipX(false), flipY(false) { if (!data) throw invalid_argument("data cannot be null."); int boneCount = data->bones.size(); bones.reserve(boneCount); for (int i = 0; i < boneCount; i++) { BoneData *boneData = data->bones[i]; Bone *bone = new Bone(boneData); if (boneData->parent) { for (int ii = 0; ii < boneCount; ii++) { if (data->bones[ii] == boneData->parent) { bone->parent = bones[ii]; break; } } } bones.push_back(bone); } int slotCount = data->slots.size(); slots.reserve(slotCount); drawOrder.reserve(slotCount); for (int i = 0; i < slotCount; i++) { SlotData *slotData = data->slots[i]; Bone *bone; for (int ii = 0; ii < boneCount; ii++) { if (data->bones[ii] == slotData->boneData) { bone = bones[ii]; break; } } Slot *slot = new Slot(slotData, this, bone); slots.push_back(slot); drawOrder.push_back(slot); } } BaseSkeleton::~BaseSkeleton () { for (int i = 0, n = bones.size(); i < n; i++) delete bones[i]; for (int i = 0, n = slots.size(); i < n; i++) delete slots[i]; } void BaseSkeleton::updateWorldTransform () { for (int i = 0, n = bones.size(); i < n; i++) bones[i]->updateWorldTransform(flipX, flipY); } void BaseSkeleton::setToBindPose () { setBonesToBindPose(); setSlotsToBindPose(); } void BaseSkeleton::setBonesToBindPose () { for (int i = 0, n = bones.size(); i < n; i++) bones[i]->setToBindPose(); } void BaseSkeleton::setSlotsToBindPose () { for (int i = 0, n = slots.size(); i < n; i++) slots[i]->setToBindPose(i); } Bone* BaseSkeleton::getRootBone () const { if (bones.size() == 0) return 0; return bones[0]; } Bone* BaseSkeleton::findBone (const string &boneName) const { for (int i = 0; i < bones.size(); i++) if (data->bones[i]->name == boneName) return bones[i]; return 0; } int BaseSkeleton::findBoneIndex (const string &boneName) const { for (int i = 0; i < bones.size(); i++) if (data->bones[i]->name == boneName) return i; return -1; } Slot* BaseSkeleton::findSlot (const string &slotName) const { for (int i = 0; i < slots.size(); i++) if (data->slots[i]->name == slotName) return slots[i]; return 0; } int BaseSkeleton::findSlotIndex (const string &slotName) const { for (int i = 0; i < slots.size(); i++) if (data->slots[i]->name == slotName) return i; return -1; } void BaseSkeleton::setSkin (const string &skinName) { Skin *skin = data->findSkin(skinName); if (!skin) throw invalid_argument("Skin not found: " + skinName); setSkin(skin); } void BaseSkeleton::setSkin (Skin *newSkin) { if (skin && newSkin) newSkin->attachAll(this, skin); skin = newSkin; } Attachment* BaseSkeleton::getAttachment (const string &slotName, const string &attachmentName) { return getAttachment(data->findSlotIndex(slotName), attachmentName); } Attachment* BaseSkeleton::getAttachment (int slotIndex, const string &attachmentName) { if (data->defaultSkin) { Attachment *attachment = data->defaultSkin->getAttachment(slotIndex, attachmentName); if (attachment) return attachment; } if (skin) return skin->getAttachment(slotIndex, attachmentName); return 0; } void BaseSkeleton::setAttachment (const string &slotName, const string &attachmentName) { for (int i = 0, n = slots.size(); i < n; i++) { Slot *slot = slots[i]; if (slot->data->name == slotName) { slot->setAttachment(getAttachment(i, attachmentName)); return; } } throw invalid_argument("Slot not found: " + slotName); } } /* namespace spine */