示例#1
0
文件: EC_Mesh.cpp 项目: A-K/naali
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;
}
示例#2
0
void EC_MediaPlayer::OnFrameUpdate(QImage frame)
{
    // Don't do anything if rendering is not enabled
    if (!ViewEnabled() || GetFramework()->IsHeadless())
        return;
    if (!componentPrepared_)
        return;
    if (!getenabled())
        return;

    // Get needed components, something is fatally wrong if these are not present but componentPrepared_ is true.
    EC_Mesh *mesh = GetMeshComponent();
    EC_WidgetCanvas *sceneCanvas = GetSceneCanvasComponent();
    if (!mesh || !sceneCanvas)
    {
        // In the case someone destroyed EC_WidgetCanvas or EC_Mesh from our entity
        // lets stop our running timer (if its running), so we don't unnecessarily poll here.
        componentPrepared_ = false;
        return;
    }

    // Validate submesh index from EC_Mesh
    uint submeshIndex = (uint)getrenderSubmeshIndex();
    if (submeshIndex >= mesh->GetNumSubMeshes())
    {
        /// \note ResetSubmeshIndex() is called with a small delay here, or the ec editor UI wont react to it. Resetting the index back to 0 will call Render() again.
        LogWarning("Render submesh index " + QString::number(submeshIndex).toStdString() + " is illegal, restoring default value.");
        QTimer::singleShot(1, this, SLOT(ResetSubmeshIndex()));
        return;
    }

    // Set submesh to EC_WidgetCanvas if different from current
    if (!sceneCanvas->GetSubMeshes().contains(submeshIndex))
        sceneCanvas->SetSubmesh(submeshIndex);

    sceneCanvas->Update(frame);
}
示例#3
0
void EC_Placeable::AttachNode()
{
    if (world_.expired())
    {
        LogError("EC_Placeable::AttachNode: No OgreWorld available to call this function!");
        return;
    }
    OgreWorldPtr world = world_.lock();
    
    try
    {
        // If already attached, detach first
        if (attached_)
            DetachNode();
        
        Ogre::SceneManager* sceneMgr = world->GetSceneManager();
        Ogre::SceneNode* root_node = sceneMgr->getRootSceneNode();
        
        // Three possible cases
        // 1) attach to scene root node
        // 2) attach to another EC_Placeable's scene node
        // 3) attach to a bone on a skeletal mesh
        // Disconnect from the EntityCreated & ParentMeshChanged signals, as responding to them might not be needed anymore.
        // We will reconnect signals as necessary
        disconnect(this, SLOT(CheckParentEntityCreated(Entity*, AttributeChange::Type)));
        disconnect(this, SLOT(OnParentMeshChanged()));
        disconnect(this, SLOT(OnComponentAdded(IComponent*, AttributeChange::Type)));
        
        // Try to attach to another entity if the parent ref is non-empty
        // Make sure we're not trying to attach to ourselves as the parent
        const EntityReference& parent = parentRef.Get();
        if (!parent.IsEmpty())
        {
            Entity* ownEntity = ParentEntity();
            if (!ownEntity)
                return;
            Scene* scene = ownEntity->ParentScene();
            if (!scene)
                return;

            Entity* parentEntity = parent.Lookup(scene).get();
            if (parentEntity == ownEntity)
            {
                // If we refer to self, attach to the root
                root_node->addChild(sceneNode_);
                attached_ = true;
                return;
            }
            
            if (parentEntity)
            {
                // Note: if we don't find the correct bone, we attach to the root
                QString boneName = parentBone.Get();
                if (!boneName.isEmpty())
                {
                    EC_Mesh* parentMesh = parentEntity->GetComponent<EC_Mesh>().get();
                    if (parentMesh)
                    {
                        Ogre::Bone* bone = parentMesh->GetBone(boneName);
                        if (bone)
                        {
                            // Create the node for bone attachment if it did not exist already
                            if (!boneAttachmentNode_)
                            {
                                boneAttachmentNode_ = sceneMgr->createSceneNode(world->GetUniqueObjectName("EC_Placeable_BoneAttachmentNode"));
                                root_node->addChild(boneAttachmentNode_);
                            }
                            
                            // Setup manual bone tracking, as Ogre does not allow to attach scene nodes to bones
                            attachmentListener.AddAttachment(parentMesh->GetEntity(), bone, this);
                            
                            boneAttachmentNode_->addChild(sceneNode_);
                            
                            parentBone_ = bone;
                            parentMesh_ = parentMesh;
                            connect(parentMesh, SIGNAL(MeshAboutToBeDestroyed()), this, SLOT(OnParentMeshDestroyed()), Qt::UniqueConnection);
                            attached_ = true;
                            return;
                        }
                        else
                        {
                            // Could not find the bone. Connect to the parent mesh MeshChanged signal to wait for the proper mesh to be assigned.
                            connect(parentMesh, SIGNAL(MeshChanged()), this, SLOT(OnParentMeshChanged()), Qt::UniqueConnection);
                            return;
                        }
                    }
                    else
                    {
                        // If can't find the mesh component yet, wait for it to be created
                        connect(parentEntity, SIGNAL(ComponentAdded(IComponent*, AttributeChange::Type)), this, SLOT(OnComponentAdded(IComponent*, AttributeChange::Type)), Qt::UniqueConnection);
                        return;
                    }
                }
                
                parentPlaceable_ = parentEntity->GetComponent<EC_Placeable>().get();
                if (parentPlaceable_)
                {
                    parentPlaceable_->GetSceneNode()->addChild(sceneNode_);
                    
                    // Connect to destruction of the placeable to be able to detach gracefully
                    connect(parentPlaceable_, SIGNAL(AboutToBeDestroyed()), this, SLOT(OnParentPlaceableDestroyed()), Qt::UniqueConnection);
                    attached_ = true;
                    return;
                }
                else
                {
                    // If can't find the placeable component yet, wait for it to be created
                    connect(parentEntity, SIGNAL(ComponentAdded(IComponent*, AttributeChange::Type)), this, SLOT(OnComponentAdded(IComponent*, AttributeChange::Type)), Qt::UniqueConnection);
                    return;
                }
            }
            else
            {
                // Could not find parent entity. Check for it later, when new entities are created into the scene
                connect(scene, SIGNAL(EntityCreated(Entity*, AttributeChange::Type)), this, SLOT(CheckParentEntityCreated(Entity*, AttributeChange::Type)), Qt::UniqueConnection);
                return;
            }
        }
示例#4
0
void EC_MediaPlayer::PrepareComponent()
{
    // Don't do anything if rendering is not enabled
    if (!ViewEnabled() || GetFramework()->IsHeadless())
        return;

    // Some security checks
    if (componentPrepared_)
    {
        LogWarning("EC_MediaPlayer: Preparations seem to be done already, you might not want to do this multiple times.");
    }
    if (!mediaPlayer_)
    {
        LogError("EC_MediaPlayer: Cannot start preparing, webview object is null. This should never happen!");
        return;
    }

    // Get parent and connect to the component removed signal.
    Entity *parent = ParentEntity();
    if (parent)
        connect(parent, SIGNAL(ComponentRemoved(IComponent*, AttributeChange::Type)), SLOT(ComponentRemoved(IComponent*, AttributeChange::Type)), Qt::UniqueConnection);
    else
    {
        LogError("EC_MediaPlayer: Could not get parent entity pointer!");
        return;
    }

    // Get EC_Mesh component
    EC_Mesh *mesh = GetMeshComponent();
    if (!mesh)
    {
        // Wait for EC_Mesh to be added.
        connect(parent, SIGNAL(ComponentAdded(IComponent*, AttributeChange::Type)), SLOT(ComponentAdded(IComponent*, AttributeChange::Type)), Qt::UniqueConnection);
        return;
    }
    else
    {
        // Inspect if this mesh is ready for rendering. EC_Mesh being present != being loaded into Ogre and ready for rendering.
        if (!mesh->GetEntity())
        {
            connect(mesh, SIGNAL(MeshChanged()), SLOT(TargetMeshReady()), Qt::UniqueConnection);
            return;
        }
        else
            connect(mesh, SIGNAL(MaterialChanged(uint, const QString&)), SLOT(TargetMeshMaterialChanged(uint, const QString&)), Qt::UniqueConnection);
    }

    if (sceneCanvasName_.isEmpty())
        sceneCanvasName_ = "VlcMediaPlayerCanvas-" + QUuid::createUuid().toString().replace("{", "").replace("}", "");

    // Get or create local EC_WidgetCanvas component
    ComponentPtr iComponent = parent->GetOrCreateComponent(EC_WidgetCanvas::TypeNameStatic(), sceneCanvasName_, AttributeChange::LocalOnly, false);
    EC_WidgetCanvas *sceneCanvas = dynamic_cast<EC_WidgetCanvas*>(iComponent.get());
    if (!sceneCanvas)
    {
        LogError("EC_MediaPlayer: Could not get or create EC_WidgetCanvas component!");
        return;
    }
    sceneCanvas->SetTemporary(true);
    sceneCanvas->SetSelfIllumination(getilluminating());

    // All the needed components are present, mark prepared as true.
    componentPrepared_ = true;

    // We are now prepared, check enabled state and restore possible materials now
    if (!getenabled())
        sceneCanvas->RestoreOriginalMeshMaterials();

    // Show downloading info icon or if not downloading, 
    // ask for a image update from the player
    if (pendingMediaDownload_)
        OnFrameUpdate(downloadingLogo_);
    else
        mediaPlayer_->ForceUpdateImage();
}