/** * 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; }
static void initBones(const aiScene * scene, const aiMesh * nodeMesh, Mesh * mesh, SubMesh * subMesh) { Armature * armature = mesh->getArmature(); BoneData bdata; map<unsigned int, AssimpSkinData> skinDatas; // bones for(unsigned int i=0; i<nodeMesh->mNumBones; i++) { aiBone * nodeBone = nodeMesh->mBones[i]; unsigned int boneId; if(! armature->getBoneId(nodeBone->mName.data, &boneId)) continue; OBone * bone = armature->getBone(boneId); aiMatrix4x4 offsetMat = nodeBone->mOffsetMatrix; aiTransposeMatrix4(&offsetMat); Matrix4x4 matrix = (*bone->getMatrix()) * Matrix4x4((float*)&offsetMat); // pose skinning Vector3 * vertices = subMesh->getVertices(); Vector3 * normals = subMesh->getNormals(); Vector3 * tangents = subMesh->getTangents(); unsigned int w; for(w=0; w<nodeBone->mNumWeights; w++) { unsigned int vid = nodeBone->mWeights[w].mVertexId; float weight = nodeBone->mWeights[w].mWeight; bdata.id = boneId; bdata.weight = weight; skinDatas[vid].bones.push_back(bdata); if(skinDatas[vid].bones.size() == 1) { if(vertices) vertices[vid] = Vector3(0, 0, 0); if(normals) normals[vid] = Vector3(0, 0, 0); if(tangents) tangents[vid] = Vector3(0, 0, 0); } if(vertices) vertices[vid] += matrix * Vector3(nodeMesh->mVertices[vid].x, nodeMesh->mVertices[vid].y, nodeMesh->mVertices[vid].z) * weight; if(normals) normals[vid] += matrix.getRotatedVector3(Vector3(nodeMesh->mNormals[vid].x, nodeMesh->mNormals[vid].y, nodeMesh->mNormals[vid].z)) * weight; if(tangents) tangents[vid] += matrix.getRotatedVector3(Vector3(nodeMesh->mTangents[vid].x, nodeMesh->mTangents[vid].y, nodeMesh->mTangents[vid].z)) * weight; } } // alloc skin unsigned int skinSize = skinDatas.size(); if(skinSize > 0) { SkinData * skin = subMesh->createSkinData(); SkinPoint * skinPoints = skin->allocPoints(skinSize); map<unsigned int, AssimpSkinData>::iterator mit (skinDatas.begin()), mend(skinDatas.end()); unsigned int p = 0; for(; mit!=mend; ++mit) { unsigned int vertexId = mit->first; AssimpSkinData * sdata = &mit->second; unsigned int b, bSize = sdata->bones.size(); if(skinPoints[p].allocateBonesLinks(bSize)) { skinPoints[p].setVertexId(vertexId); unsigned short * ids = skinPoints[p].getBonesIds(); float * weights = skinPoints[p].getBonesWeights(); for(b=0; b<bSize; b++) { ids[b] = sdata->bones[b].id; weights[b] = sdata->bones[b].weight; } } p++; } } }
// on "init" you need to initialize your instance bool HelloWorld::init() { bool bRet = false; do { ////////////////////////////////////////////////////////////////////////// // super init first ////////////////////////////////////////////////////////////////////////// CC_BREAK_IF(! CCLayerColor::initWithColor(ccc4(200, 200, 200, 255))); // CC_BREAK_IF(! CCLayerColor::initWithColor(ccc4(0, 0, 0, 255))); CCSize size = CCDirector::sharedDirector()->getWinSize(); weaponIndex = 0; BatchNodeManager::sharedBatchNodeManager()->initWithLayer(this, "TEST_ARMATURE"); ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("Zombie_f/Zombie", "", "zombie.png", "zombie.plist", "zombie.xml"); ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("Knight_f/Knight", "", "knight.png", "knight.plist", "knight.xml"); ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("cyborg", "", "cyborg.png", "cyborg.plist", "cyborg.xml"); // if the png, plist, xml is same, you can use param _useExistFileInfo ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("armInside", "cyborg", "", "", ""); ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("armOutside", "cyborg", "", "", ""); ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("circle_in_circle_stage3", "", "loading.png", "loading.plist", "loading.xml"); ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("Cattail", "", "Cattail.png", "Cattail.plist", "Cattail.xml"); ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("Zombie_ladder", "", "zombie_ladder.png", "zombie_ladder.plist", "zombie_ladder.xml"); ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("Zombie_ladder", "", "zombie_ladder.png", "zombie_ladder.plist", "zombie_ladder.xml"); ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("bird", "", "bird.png", "bird.plist", "bird.xml"); ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("weapon", "", "weapon.png", "weapon.plist", "weapon.xml"); armatures = new CCArray(); Armature *armature = NULL; //! use BATCHNODE_VERTEXZ you can change display in different batchnode BatchNodeManager::sharedBatchNodeManager()->getBatchNode("knight.png")->setRenderType(BATCHNODE_VERTEXZ); BatchNodeManager::sharedBatchNodeManager()->getBatchNode("cyborg.png")->setRenderType(BATCHNODE_VERTEXZ); BatchNodeManager::sharedBatchNodeManager()->getBatchNode("zombie.png")->setRenderType(BATCHNODE_VERTEXZ); armature = Armature::create("cyborg"); armature->getAnimation()->play("run"); armature->getDisplay()->setPosition(ccp(size.width/2 + 130, size.height/2)); armature->setZOrder(2); armature->setAnimationCallback(this); armatures->addObject(armature); armature = Armature::create("Zombie_f/Zombie"); armature->getAnimation()->play("run"); armature->getDisplay()->setPosition(ccp(size.width/2 + 100, size.height/2)); armature->setZOrder(1); armatures->addObject(armature); armature = Armature::create("Knight_f/Knight"); armature->getAnimation()->play("run"); armature->getDisplay()->setPosition(ccp(size.width/2 + 50, size.height/2)); armatures->addObject(armature); armature = Armature::create("Knight_f/Knight"); armature->getAnimation()->play("run"); armature->getDisplay()->setPosition(ccp(size.width/2 - 150, size.height/2)); armature->getBone("weapon")->addSpriteDisplay("weapon_f-sword2.png", "weapon.png", 0); armatures->addObject(armature); // armature = Armature::create("circle_in_circle_stage3"); // armature->getAnimation()->play("loading"); // armature->getDisplay()->setPosition(ccp(size.width/2, size.height/2)); // armatures->addObject(armature); armature = Armature::create("Cattail"); armature->getAnimation()->play("anim_shooting"); armature->getDisplay()->setPosition(ccp(size.width/2 + 50, size.height/2 - 100)); armatures->addObject(armature); armature = Armature::create("Zombie_ladder"); armature->getAnimation()->play("anim_placeladder", 0, 50, 1, TWEEN_EASING_MAX); armature->getAnimation()->setAnimationScale(3); armature->getDisplay()->setPosition(ccp(size.width/2 - 230, size.height/2 -100)); armatures->addObject(armature); armature = Armature::create("bird"); armature->getAnimation()->play("changeColor"); armature->getDisplay()->setPosition(ccp(size.width/2 - 230, size.height/2 + 100)); armatures->addObject(armature); // for (int i = 0; i<500; i++) // { // Armature *armature = Armature::create("Knight_f/Knight"); // armature->getAnimation()->play("run"); // armature->getDisplay()->setPosition(ccp(30 + (i%20)*(size.width/21), 30 + (i/20)*20)); // armatures->addObject(armature); // } scheduleUpdate(); bRet = true; } while (0); return bRet; }