void EC_Mesh::RemoveMesh() { OgreWorldPtr world = world_.lock(); if (entity_) { emit MeshAboutToBeDestroyed(); RemoveAllAttachments(); DetachEntity(); Ogre::SceneManager* sceneMgr = world->OgreSceneManager(); sceneMgr->destroyEntity(entity_); entity_ = 0; } if (!cloned_mesh_name_.empty()) { try { Ogre::MeshManager::getSingleton().remove(cloned_mesh_name_); } catch(Ogre::Exception& e) { LogWarning("EC_Mesh::RemoveMesh: Could not remove cloned mesh:" + std::string(e.what())); } cloned_mesh_name_ = std::string(); } }
EC_Mesh::EC_Mesh(Scene* scene) : IComponent(scene), nodeTransformation(this, "Transform", Transform(float3(0,0,0),float3(0,0,0),float3(1,1,1))), meshRef(this, "Mesh ref", AssetReference("", "OgreMesh")), skeletonRef(this, "Skeleton ref", AssetReference("", "OgreSkeleton")), meshMaterial(this, "Mesh materials", AssetReferenceList("OgreMaterial")), drawDistance(this, "Draw distance", 0.0f), castShadows(this, "Cast shadows", false), entity_(0), attached_(false) { if (scene) world_ = scene->GetWorld<OgreWorld>(); static AttributeMetadata drawDistanceData("", "0", "10000"); drawDistance.SetMetadata(&drawDistanceData); static AttributeMetadata materialMetadata; materialMetadata.elementType = "assetreference"; meshMaterial.SetMetadata(&materialMetadata); meshAsset = AssetRefListenerPtr(new AssetRefListener()); skeletonAsset = AssetRefListenerPtr(new AssetRefListener()); OgreWorldPtr world = world_.lock(); if (world) { Ogre::SceneManager* sceneMgr = world->OgreSceneManager(); adjustment_node_ = sceneMgr->createSceneNode(world->GetUniqueObjectName("EC_Mesh_adjustment_node")); connect(this, SIGNAL(ParentEntitySet()), SLOT(UpdateSignals())); connect(meshAsset.get(), SIGNAL(Loaded(AssetPtr)), this, SLOT(OnMeshAssetLoaded(AssetPtr)), Qt::UniqueConnection); connect(skeletonAsset.get(), SIGNAL(Loaded(AssetPtr)), this, SLOT(OnSkeletonAssetLoaded(AssetPtr)), Qt::UniqueConnection); } }
void EC_Hydrax::Create() { PROFILE(EC_Hydrax_Create); SAFE_DELETE(impl); if (!framework || framework->IsHeadless()) return; try { if (!ParentScene()) { LogError("EC_Hydrax: no parent scene. Cannot be created."); return; } OgreWorldPtr w = ParentScene()->Subsystem<OgreWorld>(); assert(w); connect(w->Renderer(), SIGNAL(MainCameraChanged(Entity *)), SLOT(OnActiveCameraChanged(Entity *)), Qt::UniqueConnection); Entity *mainCamera = w->Renderer()->MainCamera(); if (!mainCamera) { // Can't create Hydrax just yet, no main camera set (Hydrax needs a valid camera to initialize). // This error is benign, and Hydrax will now postpone its initialization to until a camera is set. // (see OnActiveCameraChanged()). LogDebug("Cannot create EC_Hydrax: No main camera set!"); return; } Ogre::Camera *cam = mainCamera->GetComponent<EC_Camera>()->GetCamera(); impl = new EC_HydraxImpl(); impl->hydrax = new Hydrax::Hydrax(w->OgreSceneManager(), cam, w->Renderer()->MainViewport()); // Using projected grid module by default Hydrax::Module::ProjectedGrid *module = new Hydrax::Module::ProjectedGrid(impl->hydrax, new Hydrax::Noise::Perlin(), Ogre::Plane(Ogre::Vector3::UNIT_Y, Ogre::Vector3::ZERO), Hydrax::MaterialManager::NM_VERTEX); impl->hydrax->setModule(module); impl->module = module; // Load all parameters from config file, but position attribute is always authoritative for the position. RequestConfigAsset(); connect(framework->Frame(), SIGNAL(PostFrameUpdate(float)), SLOT(Update(float)), Qt::UniqueConnection); } catch(const Ogre::Exception &e) { // Currently if we try to create more than one Hydrax component we end up here due to Ogre internal name collision. LogError("Could not create EC_Hydrax: " + std::string(e.what())); } }
void EC_HoveringText::ShowMessage(const QString &text) { if (!ViewEnabled()) return; if (world_.expired()) return; OgreWorldPtr world = world_.lock(); Ogre::SceneManager *scene = world->OgreSceneManager(); assert(scene); if (!scene) return; Entity* entity = ParentEntity(); assert(entity); if (!entity) return; EC_Placeable *node = entity->GetComponent<EC_Placeable>().get(); if (!node) return; Ogre::SceneNode *sceneNode = node->GetSceneNode(); assert(sceneNode); if (!sceneNode) return; // Create billboard if it doesn't exist. if (!billboardSet_) { billboardSet_ = scene->createBillboardSet(world->GetUniqueObjectName("EC_HoveringText"), 1); assert(billboardSet_); billboardSet_->Ogre::MovableObject::setUserAny(Ogre::Any(static_cast<IComponent *>(this))); billboardSet_->Ogre::Renderable::setUserAny(Ogre::Any(static_cast<IComponent *>(this))); sceneNode->attachObject(billboardSet_); } if (billboardSet_ && !billboard_) { billboard_ = billboardSet_->createBillboard(Ogre::Vector3(0, 0, 0.7f)); SetBillboardSize(width.Get(), height.Get()); SetPosition(position.Get()); } Redraw(); }
EC_Mesh::~EC_Mesh() { if (world_.expired()) { // Log error only if there was an Ogre object to be destroyed if (entity_) LogError("EC_Mesh: World has expired, skipping uninitialization!"); return; } OgreWorldPtr world = world_.lock(); RemoveMesh(); if (adjustment_node_) { Ogre::SceneManager* sceneMgr = world->OgreSceneManager(); sceneMgr->destroySceneNode(adjustment_node_); adjustment_node_ = 0; } }
void EC_Mesh::RemoveAttachmentMesh(uint index) { OgreWorldPtr world = world_.lock(); if (!entity_) return; if (index >= attachment_entities_.size()) return; Ogre::SceneManager* sceneMgr = world->OgreSceneManager(); if (attachment_entities_[index] && attachment_nodes_[index]) { // See if attached to a tagpoint or an ordinary node Ogre::TagPoint* tag = dynamic_cast<Ogre::TagPoint*>(attachment_nodes_[index]); if (tag) { entity_->detachObjectFromBone(attachment_entities_[index]); } else { Ogre::SceneNode* scenenode = dynamic_cast<Ogre::SceneNode*>(attachment_nodes_[index]); if (scenenode) { scenenode->detachObject(attachment_entities_[index]); sceneMgr->destroySceneNode(scenenode); } } attachment_nodes_[index] = 0; } if (attachment_entities_[index]) { if (attachment_entities_[index]->sharesSkeletonInstance()) attachment_entities_[index]->stopSharingSkeletonInstance(); sceneMgr->destroyEntity(attachment_entities_[index]); attachment_entities_[index] = 0; } }
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; }
bool EC_Mesh::SetMesh(QString meshResourceName, bool clone) { if (!ViewEnabled()) return false; OgreWorldPtr world = world_.lock(); std::string mesh_name = meshResourceName.trimmed().toStdString(); RemoveMesh(); // If placeable is not set yet, set it manually by searching it from the parent entity if (!placeable_) { Entity* entity = ParentEntity(); if (entity) { ComponentPtr placeable = entity->GetComponent(EC_Placeable::TypeNameStatic()); if (placeable) placeable_ = placeable; } } Ogre::SceneManager* sceneMgr = world->OgreSceneManager(); Ogre::Mesh* mesh = PrepareMesh(mesh_name, clone); if (!mesh) return false; try { entity_ = sceneMgr->createEntity(world->GetUniqueObjectName("EC_Mesh_entity"), mesh->getName()); if (!entity_) { LogError("EC_Mesh::SetMesh: 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); } // Make sure adjustment node is uptodate Transform newTransform = nodeTransformation.Get(); adjustment_node_->setPosition(newTransform.pos); adjustment_node_->setOrientation(newTransform.Orientation()); // Prevent Ogre exception from zero scale adjustment_node_->setScale(Max(newTransform.scale, float3::FromScalar(0.0000001f))); // Force a re-apply of all materials to this new mesh. ApplyMaterial(); } catch(Ogre::Exception& e) { LogError("EC_Mesh::SetMesh: Could not set mesh " + mesh_name + ": " + std::string(e.what())); return false; } AttachEntity(); emit MeshChanged(); return true; }