bool EC_Mesh::AttachMeshToBone(QObject* targetMesh, const QString& boneName) { if (!entity_) return false; // First make sure that the target mesh is valid, and the bone can be found EC_Mesh* targetMeshPtr = dynamic_cast<EC_Mesh*>(targetMesh); if (!targetMeshPtr) return false; Ogre::Entity* targetEntity = targetMeshPtr->GetEntity(); if (!targetEntity) return false; std::string boneNameStd = boneName.toStdString(); Ogre::SkeletonInstance* skeleton = targetEntity->getSkeleton(); if (!skeleton) return false; if (!skeleton->hasBone(boneNameStd)) return false; // We are ready to go. Detach the entity from its normal scene node first DetachMeshFromBone(); DetachEntity(); bone_tagpoint_ = targetEntity->attachObjectToBone(boneNameStd, entity_); bone_parent_mesh_ = targetMeshPtr; bone_parent_mesh_->bone_attached_mesh_ = this; attached_to_bone_ = true; // Force the adjustment for the tagpoint now OnAttributeUpdated(&nodeTransformation); return true; }
void gkSkeletonLoader::makeManual(gkEntity* ent) { Ogre::Entity* oent = ent->getEntity(); if (!oent || !oent->hasSkeleton()) return; Ogre::SkeletonInstance* inst = oent->getSkeleton(); gkBone::BoneList::Iterator it = m_skeleton->getBoneList().iterator(); while (it.hasMoreElements()) { gkBone* bone = it.getNext(); if (inst->hasBone(bone->getName())) { Ogre::Bone* obone = inst->getBone(bone->getName()); bone->_setOgreBone(obone); obone->setManuallyControlled(true); } } }
void CreatureWeaponAnimation::updatePart(NifOgre::ObjectScenePtr& scene, int slot) { MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); MWWorld::ContainerStoreIterator it = inv.getSlot(slot); if (it == inv.end()) { scene.setNull(); return; } MWWorld::Ptr item = *it; std::string bonename; if (slot == MWWorld::InventoryStore::Slot_CarriedRight) bonename = "Weapon Bone"; else bonename = "Shield Bone"; scene = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, item.getClass().getModel(item)); Ogre::Vector3 glowColor = getEnchantmentColor(item); setRenderProperties(scene, RV_Actors, RQG_Main, RQG_Alpha, 0, !item.getClass().getEnchantment(item).empty(), &glowColor); if(scene->mSkelBase) { Ogre::SkeletonInstance *skel = scene->mSkelBase->getSkeleton(); if(scene->mSkelBase->isParentTagPoint()) { Ogre::Node *root = scene->mSkelBase->getParentNode(); if(skel->hasBone("BoneOffset")) { Ogre::Bone *offset = skel->getBone("BoneOffset"); root->translate(offset->getPosition()); // It appears that the BoneOffset rotation is completely bogus, at least for light models. //root->rotate(offset->getOrientation()); root->pitch(Ogre::Degree(-90.0f)); root->scale(offset->getScale()); root->setInitialState(); } } updateSkeletonInstance(mSkelBase->getSkeleton(), skel); } // TODO: // type == ESM::PRT_Weapon should get an animation source based on the current offset // of the weapon attack animation (from its beginning, or start marker?) std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(scene->mControllers.begin()); for(;ctrl != scene->mControllers.end();ctrl++) { if(ctrl->getSource().isNull()) ctrl->setSource(Ogre::SharedPtr<NullAnimationTime>(new NullAnimationTime())); } }
Ogre::Node *Animation::getNode(const std::string &name) { if(mSkelBase) { Ogre::SkeletonInstance *skel = mSkelBase->getSkeleton(); if(skel->hasBone(name)) return skel->getBone(name); } return NULL; }
Ogre::TagPoint *Animation::attachObjectToBone(const Ogre::String &bonename, Ogre::MovableObject *obj) { Ogre::TagPoint *tag = NULL; Ogre::SkeletonInstance *skel = (mSkelBase ? mSkelBase->getSkeleton() : NULL); if(skel && skel->hasBone(bonename)) { tag = mSkelBase->attachObjectToBone(bonename, obj); mAttachedObjects[obj] = bonename; } return tag; }
void Animation::handleAnimationTransforms(){ Ogre::SkeletonInstance* skel = base->getSkeleton(); Ogre::Bone* b = skel->getRootBone(); b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3)); //This is a trick skel->_updateTransforms(); //skel->_notifyManualBonesDirty(); base->getAllAnimationStates()->_notifyDirty(); //base->_updateAnimation(); //base->_notifyMoved(); std::vector<Nif::NiKeyframeData>::iterator iter; int slot = 0; if(transformations){ for(iter = transformations->begin(); iter != transformations->end(); iter++){ if(time < iter->getStartTime() || time < startTime || time > iter->getStopTime()) { slot++; continue; } float x; float x2; const std::vector<Ogre::Quaternion> & quats = iter->getQuat(); const std::vector<float> & ttime = iter->gettTime(); const std::vector<float> & rtime = iter->getrTime(); int rindexJ = rindexI[slot]; timeIndex(time, rtime, rindexI[slot], rindexJ, x2); int tindexJ = tindexI[slot]; const std::vector<Ogre::Vector3> & translist1 = iter->getTranslist1(); timeIndex(time, ttime, tindexI[slot], tindexJ, x); Ogre::Vector3 t; Ogre::Quaternion r; bool bTrans = translist1.size() > 0; bool bQuats = quats.size() > 0; if(skel->hasBone(iter->getBonename())){ Ogre::Bone* bone = skel->getBone(iter->getBonename()); if(bTrans){ Ogre::Vector3 v1 = translist1[tindexI[slot]]; Ogre::Vector3 v2 = translist1[tindexJ]; t = (v1 + (v2 - v1) * x); bone->setPosition(t); } if(bQuats){ r = Ogre::Quaternion::Slerp(x2, quats[rindexI[slot]], quats[rindexJ], true); bone->setOrientation(r); } } slot++; } skel->_updateTransforms(); base->getAllAnimationStates()->_notifyDirty(); } }
void Animation::setObjectRoot(const std::string &model, bool baseonly) { OgreAssert(mAnimSources.empty(), "Setting object root while animation sources are set!"); mSkelBase = NULL; mObjectRoot.setNull(); if(model.empty()) return; std::string mdlname = Misc::StringUtils::lowerCase(model); std::string::size_type p = mdlname.rfind('\\'); if(p == std::string::npos) p = mdlname.rfind('/'); if(p != std::string::npos) mdlname.insert(mdlname.begin()+p+1, 'x'); else mdlname.insert(mdlname.begin(), 'x'); if(!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(mdlname)) { mdlname = model; Misc::StringUtils::toLower(mdlname); } mObjectRoot = (!baseonly ? NifOgre::Loader::createObjects(mInsert, mdlname) : NifOgre::Loader::createObjectBase(mInsert, mdlname)); if(mObjectRoot->mSkelBase) { mSkelBase = mObjectRoot->mSkelBase; Ogre::AnimationStateSet *aset = mObjectRoot->mSkelBase->getAllAnimationStates(); Ogre::AnimationStateIterator asiter = aset->getAnimationStateIterator(); while(asiter.hasMoreElements()) { Ogre::AnimationState *state = asiter.getNext(); state->setEnabled(false); state->setLoop(false); } // Set the bones as manually controlled since we're applying the // transformations manually Ogre::SkeletonInstance *skelinst = mObjectRoot->mSkelBase->getSkeleton(); Ogre::Skeleton::BoneIterator boneiter = skelinst->getBoneIterator(); while(boneiter.hasMoreElements()) boneiter.getNext()->setManuallyControlled(true); // Reattach any objects that have been attached to this one ObjectAttachMap::iterator iter = mAttachedObjects.begin(); while(iter != mAttachedObjects.end()) { if(!skelinst->hasBone(iter->second)) mAttachedObjects.erase(iter++); else { mSkelBase->attachObjectToBone(iter->second, iter->first); ++iter; } } } else mAttachedObjects.clear(); for(size_t i = 0;i < mObjectRoot->mControllers.size();i++) { if(mObjectRoot->mControllers[i].getSource().isNull()) mObjectRoot->mControllers[i].setSource(mAnimationTimePtr[0]); } }