bool EC_Mesh::SetAttachmentMesh(uint index, const std::string& mesh_name, const std::string& attach_point, bool share_skeleton) { if (!ViewEnabled()) return false; OgreWorldPtr world = world_.lock(); if (!entity_) { LogError("EC_Mesh::SetAttachmentMesh: No mesh entity created yet, can not create attachments!"); return false; } Ogre::SceneManager* sceneMgr = world->OgreSceneManager(); size_t oldsize = attachment_entities_.size(); size_t newsize = index + 1; if (oldsize < newsize) { attachment_entities_.resize(newsize); attachment_nodes_.resize(newsize); for(uint i = oldsize; i < newsize; ++i) { attachment_entities_[i] = 0; attachment_nodes_[i] = 0; } } RemoveAttachmentMesh(index); Ogre::Mesh* mesh = PrepareMesh(mesh_name, false); if (!mesh) return false; if (share_skeleton) { // If sharing a skeleton, force the attachment mesh to use the same skeleton // This is theoretically quite a scary operation, for there is possibility for things to go wrong Ogre::SkeletonPtr entity_skel = entity_->getMesh()->getSkeleton(); if (entity_skel.isNull()) { LogError("EC_Mesh::SetAttachmentMesh: Cannot share skeleton for attachment, not found"); return false; } try { mesh->_notifySkeleton(entity_skel); } catch(const Ogre::Exception &/*e*/) { LogError("EC_Mesh::SetAttachmentMesh: Could not set shared skeleton for attachment"); return false; } } try { QString entityName = QString("EC_Mesh_attach") + QString::number(index); attachment_entities_[index] = sceneMgr->createEntity(world->GetUniqueObjectName(entityName.toStdString()), mesh->getName()); if (!attachment_entities_[index]) { LogError("EC_Mesh::SetAttachmentMesh: Could not set attachment mesh " + mesh_name); return false; } attachment_entities_[index]->setRenderingDistance(drawDistance.Get()); attachment_entities_[index]->setCastShadows(castShadows.Get()); attachment_entities_[index]->setUserAny(entity_->getUserAny()); // Set UserAny also on subentities for(uint i = 0; i < attachment_entities_[index]->getNumSubEntities(); ++i) attachment_entities_[index]->getSubEntity(i)->setUserAny(entity_->getUserAny()); Ogre::Bone* attach_bone = 0; if (!attach_point.empty()) { Ogre::Skeleton* skel = entity_->getSkeleton(); if (skel && skel->hasBone(attach_point)) attach_bone = skel->getBone(attach_point); } if (attach_bone) { Ogre::TagPoint* tag = entity_->attachObjectToBone(attach_point, attachment_entities_[index]); attachment_nodes_[index] = tag; } else { QString nodeName = QString("EC_Mesh_attachment_") + QString::number(index); Ogre::SceneNode* node = sceneMgr->createSceneNode(world->GetUniqueObjectName(nodeName.toStdString())); node->attachObject(attachment_entities_[index]); adjustment_node_->addChild(node); attachment_nodes_[index] = node; } if (share_skeleton && entity_->hasSkeleton() && attachment_entities_[index]->hasSkeleton()) { attachment_entities_[index]->shareSkeletonInstanceWith(entity_); } } catch(Ogre::Exception& e) { LogError("EC_Mesh::SetAttachmentMesh: Could not set attachment mesh " + mesh_name + ": " + std::string(e.what())); return false; } return true; }
bool EC_Mesh::SetMeshWithSkeleton(const std::string& mesh_name, const std::string& skeleton_name, bool clone) { if (!ViewEnabled()) return false; OgreWorldPtr world = world_.lock(); Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(AssetAPI::SanitateAssetRef(skeleton_name)); if (skel.isNull()) { LogError("EC_Mesh::SetMeshWithSkeleton: Could not set skeleton " + skeleton_name + " to mesh " + mesh_name + ": not found"); return false; } RemoveMesh(); Ogre::SceneManager* sceneMgr = world->OgreSceneManager(); Ogre::Mesh* mesh = PrepareMesh(mesh_name, clone); if (!mesh) return false; try { mesh->_notifySkeleton(skel); // LogDebug("Set skeleton " + skeleton_name + " to mesh " + mesh_name); } catch(Ogre::Exception& e) { LogError("EC_Mesh::SetMeshWithSkeleton: Could not set skeleton " + skeleton_name + " to mesh " + mesh_name + ": " + std::string(e.what())); return false; } try { entity_ = sceneMgr->createEntity(world->GetUniqueObjectName("EC_Mesh_entwithskel"), mesh->getName()); if (!entity_) { LogError("EC_Mesh::SetMeshWithSkeleton: Could not set mesh " + mesh_name); return false; } entity_->setRenderingDistance(drawDistance.Get()); entity_->setCastShadows(castShadows.Get()); entity_->setUserAny(Ogre::Any(static_cast<IComponent *>(this))); // Set UserAny also on subentities for(uint i = 0; i < entity_->getNumSubEntities(); ++i) entity_->getSubEntity(i)->setUserAny(entity_->getUserAny()); if (entity_->hasSkeleton()) { Ogre::SkeletonInstance* skel = entity_->getSkeleton(); // Enable cumulative mode on skeletal animations if (skel) skel->setBlendMode(Ogre::ANIMBLEND_CUMULATIVE); } } catch(Ogre::Exception& e) { LogError("EC_Mesh::SetMeshWithSkeleton: Could not set mesh " + mesh_name + ": " + std::string(e.what())); return false; } AttachEntity(); emit MeshChanged(); return true; }