ArmatureData *XMLDataParser::parseArmatureData(const dragonBones::XMLElement *armatureXML, SkeletonData *data, uint frameRate) { ArmatureData *armatureData = new ArmatureData(); armatureData->name = armatureXML->Attribute(ConstValues::A_NAME.c_str()); for(const dragonBones::XMLElement* boneXML = armatureXML->FirstChildElement(ConstValues::BONE.c_str()) ; boneXML ; boneXML = boneXML->NextSiblingElement(ConstValues::BONE.c_str())) { armatureData->addBoneData(parseBoneData(boneXML)); } for(const dragonBones::XMLElement* skinXML = armatureXML->FirstChildElement(ConstValues::SKIN.c_str()) ; skinXML ; skinXML = skinXML->NextSiblingElement(ConstValues::SKIN.c_str())) { armatureData->addSkinData(parseSkinData(skinXML, data)); } DBDataUtil::transformArmatureData(armatureData); armatureData->sortBoneDataList(); for(const dragonBones::XMLElement* animationXML = armatureXML->FirstChildElement(ConstValues::ANIMATION.c_str()) ; animationXML ; animationXML = animationXML->NextSiblingElement(ConstValues::ANIMATION.c_str())) { armatureData->addAnimationData(parseAnimationData(animationXML, armatureData, frameRate)); } return armatureData; }
ArmatureData* ObjectDataParser::parseArmatureData(Json::Value & armatureObject, SkeletonData* data, unsigned int frameRate) { ArmatureData* armatureData = new ArmatureData(); armatureData->name = armatureObject[ConstValues::A_NAME].asCString(); Json::Value & bones = armatureObject[ConstValues::BONE]; for (unsigned int i = 0; i < bones.size(); i++) { Json::Value & boneObject = bones[i]; armatureData->addBoneData(parseBoneData(boneObject)); } Json::Value & skins = armatureObject[ConstValues::SKIN]; for (unsigned int i = 0; i < skins.size(); i++) { Json::Value & skinObject = skins[i]; armatureData->addSkinData(parseSkinData(skinObject, data)); } DBDataUtil::transformArmatureData(armatureData); armatureData->sortBoneDataList(); Json::Value & animitions = armatureObject[ConstValues::ANIMATION]; for (unsigned int i = 0; i < animitions.size(); i++) { Json::Value & animationObject = animitions[i]; armatureData->addAnimationData(parseAnimationData(animationObject, armatureData, frameRate)); } return armatureData; }
/** * Build and returns a new Armature instance. * @example * <listing> * var armature:Armature = factory.buildArmature('dragon'); * </listing> * @param armatureName The name of this Armature instance. * @param The name of this animation * @param The name of this SkeletonData. * @param The name of this textureAtlas. * @param The name of this skin. * @return A Armature instance. */ Armature* BaseFactory::buildArmature(const String &armatureName, const String &animationName, const String &skeletonName, const String &textureAtlasName, const String &skinName) { ArmatureData* armatureData = 0; SkeletonData *data = 0; if(!skeletonName.empty()) { std::map<String , SkeletonData*>::iterator iter = _dataDic.find(skeletonName); if(iter != _dataDic.end()) { data = iter->second; armatureData = data->getArmatureData(armatureName); } } //else //{ // for(skeletonName in _dataDic) // { // data = _dataDic[skeletonName]; // armatureData = data->getArmatureData(armatureName); // if(armatureData) // { // break; // } // } //} if(!armatureData) { return nullptr; } _currentDataName = skeletonName; _currentTextureAtlasName = textureAtlasName.empty() ? skeletonName : textureAtlasName; Armature* armature = generateArmature(); armature->name = armatureName; Bone* bone; for(size_t i = 0 ; i < armatureData->boneDataList.size() ; i ++) { BoneData* boneData = armatureData->boneDataList[i]; bone = new Bone(); bone->name = boneData->name; bone->fixedRotation = boneData->fixedRotation; bone->scaleMode = boneData->scaleMode; bone->origin = boneData->transform; if(armatureData->getBoneData(boneData->parent)) { armature->addBone(bone, boneData->parent); } else { armature->addBone(bone); } } ArmatureData* animationArmatureData = 0; SkinData *skinDataCopy = 0; if(!animationName.empty() && animationName != armatureName) { //ArmatureData* animationArmatureData = data->getArmatureData(animationName); // Get the default animation //if(!animationArmatureData) //{ // for (skeletonName in _dataDic) // { // data = _dataDic[skeletonName]; // animationArmatureData = data->getArmatureData(animationName); // if(animationArmatureData) // { // break; // } // } //} ArmatureData* armatureDataCopy = data->getArmatureData(animationName); if(armatureDataCopy) { skinDataCopy = armatureDataCopy->getSkinData(""); } } if(animationArmatureData) { armature->getAnimation()->setAnimationDataList(animationArmatureData->animationDataList); } else { armature->getAnimation()->setAnimationDataList(armatureData->animationDataList); } SkinData* skinData = armatureData->getSkinData(skinName); if(!skinData) { return nullptr; //throw new ArgumentError(); } Slot* slot; DisplayData* displayData; Armature* childArmature; size_t i; //var helpArray:Array = []; for(size_t j = 0 ; j < skinData->slotDataList.size() ; j ++) { SlotData* slotData = skinData->slotDataList[j]; bone = armature->getBone(slotData->parent); if(!bone) { continue; } slot = generateSlot(); slot->name = slotData->name; slot->setBlendMode(slotData->blendMode); slot->_originZOrder = slotData->zOrder; slot->_dislayDataList = slotData->displayDataList; std::vector<Object*> helpArray; i = slotData->displayDataList.size(); helpArray.resize(i); while(i --) { displayData = slotData->displayDataList[i]; if(displayData->type == DisplayData::ARMATURE) { DisplayData* displayDataCopy = 0; if(skinDataCopy) { SlotData* slotDataCopy = skinDataCopy->getSlotData(slotData->name); if(slotDataCopy) { displayDataCopy = slotDataCopy->displayDataList[i]; } } else { displayDataCopy = 0; } childArmature = buildArmature(displayData->name, displayDataCopy?displayDataCopy->name:"", _currentDataName, _currentTextureAtlasName); if(childArmature) { helpArray[i] = childArmature; } //fix by Wayne Dimart: // break; we don't use break here, or will crach the program due to incomplete helpArray. continue; } else { helpArray[i] = generateDisplay(getTextureAtlas(_currentTextureAtlasName), displayData->name, displayData->pivot.x, displayData->pivot.y); } } slot->setDisplayList(helpArray); slot->changeDisplay(0); bone->addChild(slot); } // i = armature->_boneList.size(); while(i --) { armature->_boneList[i]->update(); } i = armature->_slotList.size(); while(i --) { slot = armature->_slotList[i]; slot->update(); } armature->updateSlotsZOrder(); return armature; }
// 解析出DB骨骼数据 DragonBonesData* DotaAnimParser::parseDragonBonesData( Dota_Skeleton_Data& dotaSkeletonData, ITextureAtlas& textureAtlas, float scale/* = 1.f*/) { _armatureScale = scale; _frameRate = 24; DragonBonesData *dragonBonesData = new DragonBonesData(); dragonBonesData->name = dotaSkeletonData.name; ArmatureData *armatureData = new ArmatureData(); armatureData->name = dotaSkeletonData.name; for (int i = 0; i < (int)dotaSkeletonData.boneDataList.size(); i++) { Dota_Bone_Data * dotaBoneData = dotaSkeletonData.boneDataList[i]; BoneData *boneData = new BoneData(); boneData->name = dotaBoneData->name; boneData->length = 0; boneData->inheritRotation = true; boneData->inheritScale = false; Dota_Slot_Data * slotData = nullptr; Dota_First_Frame_Data::iterator iter; iter = dotaSkeletonData.firstFrameOfBoneMap.find(dotaBoneData->name); if (iter != dotaSkeletonData.firstFrameOfBoneMap.end()) slotData = iter->second; if (slotData != nullptr) setTransform(boneData->global, slotData->x, slotData->y, slotData->skX, slotData->skY, slotData->scX, slotData->scY); else setTransform(boneData->global, 0, 0, 0, 0, 1, 1); boneData->transform = boneData->global; armatureData->boneDataList.push_back(boneData); } SkinData *skinData = new SkinData(); skinData->name = "default"; for (int i = 0; i < (int)dotaSkeletonData.boneDataList.size(); i++) { Dota_Bone_Data * dotaBoneData = dotaSkeletonData.boneDataList[i]; SlotData *slotData = new SlotData(); slotData->name = dotaBoneData->name; slotData->parent = dotaBoneData->name; slotData->zOrder = dotaBoneData->index; DisplayData *displayData = new DisplayData(); displayData->name = dotaBoneData->textureName + ".png"; displayData->type = DisplayType::DT_IMAGE; displayData->scalingGrid = false; setTransform(displayData->transform, 0, 0, 0, 0, 1, 1); TextureData * textureData = getTextureData(textureAtlas, displayData->name); if (textureData->rotated) { displayData->pivot.x = textureData->region.height / 2 / _armatureScale; displayData->pivot.y = textureData->region.width / 2 / _armatureScale; } else { displayData->pivot.x = textureData->region.width / 2 / _armatureScale; displayData->pivot.y = textureData->region.height / 2 / _armatureScale; } slotData->displayDataList.push_back(displayData); skinData->slotDataList.push_back(slotData); } armatureData->skinDataList.push_back(skinData); transformArmatureData(armatureData); armatureData->sortBoneDataList(); for (int i = 0; i < (int)dotaSkeletonData.animDataList.size(); i++) { Dota_Anim_Data * dotaAnimData = dotaSkeletonData.animDataList[i]; AnimationData *animationData = new AnimationData(); animationData->name = dotaAnimData->name; animationData->frameRate = _frameRate; animationData->duration = (int)(round((int)dotaAnimData->frameDataList.size() * 1000.f / _frameRate)); animationData->playTimes = 0; animationData->fadeTime = 0.f; //0.3f; animationData->scale = 1; // use frame tweenEase, NaN // overwrite frame tweenEase, [-1, 0):ease in, 0:line easing, (0, 1]:ease out, (1, 2]:ease in out animationData->tweenEasing = USE_FRAME_TWEEN_EASING; animationData->autoTween = true; parseTimeline(*animationData); std::map<std::string, Dota_Anim_Data2 *>::iterator iter; iter = dotaSkeletonData.animDataMap.find(dotaAnimData->name); if (iter == dotaSkeletonData.animDataMap.end()) continue; Dota_Anim_Data2 * dotaAnimData2 = iter->second; Dota_Anim_Data2::iterator iter2; for (iter2 = dotaAnimData2->begin(); iter2 != dotaAnimData2->end(); iter2++) { Dota_Timeline_Data * dataTimelineData2 = iter2->second; TransformTimeline *timeline = new TransformTimeline(); timeline->name = iter2->first; timeline->scale = 1; timeline->offset = 0; timeline->duration = animationData->duration; int nBlankKeyframes = 0; for (int j = 0; j < (int)dotaAnimData->frameDataList.size(); j++) { Dota_Timeline_Data::iterator iter3 = dataTimelineData2->find(toString(j)); if (iter3 != dataTimelineData2->end()) { Dota_Slot_Data * slotData = iter3->second; if (nBlankKeyframes > 0) { TransformFrame *frame = newBlankKeyframes(nBlankKeyframes, slotData->soundName); timeline->frameList.push_back(frame); nBlankKeyframes = 0; } TransformFrame *frame = newKeyframes(slotData->zOrder, slotData->opacity, slotData->x, slotData->y, slotData->skX, slotData->skY, slotData->scX, slotData->scY, slotData->soundName); timeline->frameList.push_back(frame); } else { nBlankKeyframes++; } } if (nBlankKeyframes > 0) { TransformFrame *frame = newBlankKeyframes(nBlankKeyframes, ""); timeline->frameList.push_back(frame); nBlankKeyframes = 0; } parseTimeline(*timeline); animationData->timelineList.push_back(timeline); } addHideTimeline(animationData, armatureData); transformAnimationData(animationData, armatureData); armatureData->animationDataList.push_back(animationData); } dragonBonesData->armatureDataList.push_back(armatureData); return dragonBonesData; }
Armature* BaseFactory::buildArmature(const std::string &armatureName, const std::string &skinName, const std::string &animationName, const std::string &dragonBonesName, const std::string &textureAtlasName) const { DragonBonesData *dragonBonesData = nullptr; ArmatureData *armatureData = nullptr; ArmatureData *animationArmatureData = nullptr; SkinData *skinData = nullptr; SkinData *skinDataCopy = nullptr; if (!dragonBonesName.empty()) { auto iterator = _dragonBonesDataMap.find(dragonBonesName); if (iterator != _dragonBonesDataMap.end()) { dragonBonesData = iterator->second; armatureData = dragonBonesData->getArmatureData(armatureName); _currentDragonBonesDataName = dragonBonesName; _currentTextureAtlasName = textureAtlasName.empty() ? _currentDragonBonesDataName : textureAtlasName; } } if (!armatureData) { AutoSearchType searchType = (dragonBonesName.empty() ? AutoSearchType::AST_ALL : (autoSearchDragonBonesData ? AutoSearchType::AST_AUTO : AutoSearchType::AST_NONE)); if (searchType != AutoSearchType::AST_NONE) { for (auto iterator = _dragonBonesDataMap.begin(); iterator != _dragonBonesDataMap.end(); ++iterator) { dragonBonesData = iterator->second; if (searchType == AutoSearchType::AST_ALL || dragonBonesData->autoSearch) { armatureData = dragonBonesData->getArmatureData(armatureName); if (armatureData) { _currentDragonBonesDataName = iterator->first; _currentTextureAtlasName = _currentDragonBonesDataName; break; } } } } } if (!armatureData) { return nullptr; } if (!animationName.empty() && animationName != armatureName) { animationArmatureData = dragonBonesData->getArmatureData(animationName); if (!animationArmatureData) { for (auto iterator = _dragonBonesDataMap.begin(); iterator != _dragonBonesDataMap.end(); ++iterator) { dragonBonesData = iterator->second; animationArmatureData = dragonBonesData->getArmatureData(animationName); if (animationArmatureData) { break; } } } if (animationArmatureData) { skinDataCopy = animationArmatureData->getSkinData(""); } } skinData = armatureData->getSkinData(skinName); Armature *armature = generateArmature(armatureData); armature->name = armatureName; if (animationArmatureData) { armature->getAnimation()->setAnimationDataList(animationArmatureData->animationDataList); } else { armature->getAnimation()->setAnimationDataList(armatureData->animationDataList); } // buildBones(armature, armatureData); // if (skinData) { buildSlots(armature, armatureData, skinData, skinDataCopy); } // update armature pose armature->getAnimation()->play(); armature->advanceTime(0); armature->getAnimation()->stop(); return armature; }