Пример #1
0
void AssetRefListListener::HandleChange(const AssetReferenceList &refs)
{
    if (!assetAPI_)
        return;

    // Does a size check and compares each element with case-sensitive compare.
    if (refs == current_)
        return;

    AssetReferenceList prev = current_;

    // Set current internal refs
    current_ = refs;
    uint numRefs = current_.Size();

    // Trim and resolve internal refs
    for (uint i=0; i<numRefs; ++i)
    {
        AssetReference &ref = current_[i];
        ref.ref = ref.ref.Trimmed();
        if (!ref.ref.Empty())
            ref.ref = assetAPI_->ResolveAssetRef("", ref.ref);
    }

    // Changed
    Changed.Emit(current_);

    // Cleared
    for (uint i=0; i<numRefs; ++i)
    {
        const AssetReference &ref = current_[i];
        const AssetReference &prevRef = (i < prev.Size() ? prev[i] : AssetReference());
        if (ref.ref.Empty() && !prevRef.ref.Empty())
            Cleared.Emit(i);
    }
    for(uint i = numRefs; i < prev.Size(); ++i)
    {
        if (!prev[i].ref.Empty())
            Cleared.Emit(i);
    }

    // Request
    while(listeners_.Size() > numRefs)
        listeners_.Pop();
    while(listeners_.Size() < numRefs)
    {
        // Connect to signals once on creation. AssetRefListeners
        // are reusable for multiple refs/requests.
        AssetRefListenerPtr listener(new AssetRefListener());
        listener->TransferFailed.Connect(this, &AssetRefListListener::OnAssetFailed);
        listener->Loaded.Connect(this, &AssetRefListListener::OnAssetLoaded);
        listeners_.Push(listener);
    }
    for (uint i=0; i<numRefs; ++i)
    {
        const AssetReference &ref = current_[i];
        if (!ref.ref.Empty())
            listeners_[i]->HandleAssetRefChange(assetAPI_, ref.ref, ref.type);
    }
}
Пример #2
0
void EC_Mesh::OnMaterialAssetLoaded(AssetPtr asset)
{
    OgreMaterialAsset *ogreMaterial = dynamic_cast<OgreMaterialAsset*>(asset.get());
    if (!ogreMaterial)
    {
        LogError("OnMaterialAssetLoaded: Material asset load finished for asset \"" +
            asset->Name().toStdString() + "\", but downloaded asset was not of type OgreMaterialAsset!");
        return;
    }

    Ogre::MaterialPtr material = ogreMaterial->ogreMaterial;
    bool assetUsed = false;

    AssetReferenceList materialList = meshMaterial.Get();
    for(int i = 0; i < materialList.Size(); ++i)
        if (materialList[i].ref == ogreMaterial->Name() ||
            framework_->Asset()->LookupAssetRefToStorage(materialList[i].ref) == ogreMaterial->Name()) ///<///\todo The design of whether the LookupAssetRefToStorage should occur here, or internal to Asset API needs to be revisited.
        {
            SetMaterial(i, ogreMaterial->Name());
            assetUsed = true;
        }

    if (!assetUsed)
    {
        LogWarning("OnMaterialAssetLoaded: Trying to apply material \"" + ogreMaterial->Name().toStdString() + "\" to mesh " +
            meshRef.Get().ref.toStdString() + ", but no submesh refers to the given material! The references are: ");
        for(int i = 0; i < materialList.Size(); ++i)
            LogWarning(QString::number(i).toStdString() + ": " + materialList[i].ref.toStdString());
    }
}
static duk_ret_t AssetReferenceList_Size(duk_context* ctx)
{
    AssetReferenceList* thisObj = GetThisValueObject<AssetReferenceList>(ctx, AssetReferenceList_ID);
    uint ret = thisObj->Size();
    duk_push_number(ctx, ret);
    return 1;
}
Пример #4
0
template<> void TUNDRACORE_API Attribute<AssetReferenceList>::FromString(const std::string& str, AttributeChange::Type change)
{
    AssetReferenceList value;
    QString strValue = QString::fromStdString(str);
    QStringList components = strValue.split(';');
    for(int i = 0; i < components.size(); i++)
        value.Append(AssetReference(components[i]));
    if (value.Size() == 1 && value[0].ref.trimmed().isEmpty())
        value.RemoveLast();

    Set(value, change);
}
Пример #5
0
void EC_Sky::OnAttributeUpdated(IAttribute* attribute)
{
    if (!ViewEnabled())
        return;

    if ((attribute->Name() == materialRef.Name() && materialRef.Get().ref != lastMaterial_ ) ||
        (attribute->Name() ==  distance.Name() && distance.Get() != lastDistance_ ) ||
        (attribute->Name() == drawFirst.Name() && drawFirst.Get() != lastDrawFirst_ ))
    {
        DisableSky();
        CreateSky();

        lastMaterial_ = materialRef.Get().ref;
        lastDistance_ = distance.Get();
        lastDrawFirst_ = drawFirst.Get();
    }
    else if (attribute->Name() == textureRefs.Name())
    {
        AssetReferenceList textures = textureRefs.Get();
        // Make sure that the asset ref list type stays intact.
        textures.type = "Texture";
        textureRefs.Set(textures, AttributeChange::Disconnected);

        // Reallocate the number of texture asset reflisteners.
        while(textureAssets.size() > (size_t)textures.Size())
            textureAssets.pop_back();
        while(textureAssets.size() < (size_t)textures.Size())
            textureAssets.push_back(boost::shared_ptr<AssetRefListener>(new AssetRefListener));

        for(int i = 0; i < textures.Size(); ++i)
        {
            connect(textureAssets[i].get(), SIGNAL(Loaded(AssetPtr)), this, SLOT(OnTextureAssetLoaded(AssetPtr)), Qt::UniqueConnection);
            textureAssets[i]->HandleAssetRefChange(framework->Asset(), textures[i].ref);
        }

        //SetTextures();
    }
}
Пример #6
0
void EC_Mesh::ApplyMaterial()
{
    AssetReferenceList materialList = meshMaterial.Get();
    AssetAPI *assetAPI = framework_->Asset();
    for(int i = 0; i < materialList.Size(); ++i)
    {
        if (!materialList[i].ref.isEmpty())
        {
            // Only apply the material if it is loaded and has no dependencies
            QString assetFullName = assetAPI->LookupAssetRefToStorage(materialList[i].ref);
            AssetPtr asset = assetAPI->GetAsset(assetFullName);
            if ((asset) && (assetAPI->NumPendingDependencies(asset) == 0))
                SetMaterial(i, assetFullName);
        }
    }
}
Пример #7
0
bool EC_Mesh::HasMaterialsChanged() const
{
    if(!entity_ || !meshMaterial.Get().Size())
        return false;

    AssetReferenceList materials = meshMaterial.Get();
    for(uint i = 0; i < entity_->getNumSubEntities(); i++)
    {
        // No point to continue if all materials are not set.
        if(i >= materials.Size())
            break;

        if(entity_->getSubEntity(i)->getMaterial()->getName() != SanitateAssetIdForOgre(materials[i].ref.toStdString()))
            return true;
    }
    return false;
}
Пример #8
0
bool EC_Mesh::SetMaterial(uint index, const QString& material_name, AttributeChange::Type change)
{
    if (!entity_)
        return false;
    
    if (index >= entity_->getNumSubEntities())
    {
        LogError("EC_Mesh::SetMaterial: Could not set material " + material_name + ": illegal submesh index " + QString::number(index) + 
            ". Mesh \"" + meshRef.Get().ref + "\" has only " + QString::number(entity_->getNumSubEntities()) + " submeshes!");
        return false;
    }
    
    try
    {
        entity_->getSubEntity(index)->setMaterialName(AssetAPI::SanitateAssetRef(material_name.toStdString()));

        if (pendingFailedMaterials_.contains(index))
            pendingFailedMaterials_.removeAll(index);

        // Update the EC_Mesh material attribute list so that users can call EC_Mesh::SetMaterial as a replacement for setting
        // meshMaterial attribute. Only apply the change if the value really changed.
        AssetReferenceList materials = meshMaterial.Get();
        while(materials.Size() <= (int)index)
            materials.Append(AssetReference());
        if (material_name.compare(materials[index].ref, Qt::CaseSensitive) != 0)
        {
            materials.Set(index, AssetReference(material_name));
            meshMaterial.Set(materials, change); // Potentially signal the change of attribute, if requested so.
        }

        // To retain compatibility with old behavior, always fire the EC_Mesh -specific change signal independent of the value of 'change'.
        emit MaterialChanged(index, material_name);
    }
    catch(Ogre::Exception& e)
    {
        LogError("EC_Mesh::SetMaterial: Could not set material " + material_name + ": " + e.what());
        return false;
    }
    
    return true;
}
Пример #9
0
void EC_SkyBox::SetTextures()
{
    if (!ViewEnabled())
        return;

    AssetReferenceList lst = textureRefs.Get();
    std::vector<std::string> texture_names;
    texture_names.reserve(6);

    for(int i = 0; i < lst.Size() && i <= 6; ++i)
        texture_names.push_back(lst[i].ref.toStdString());

    Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().getByName(materialRef.Get().ref.toStdString().c_str());
    if (!materialPtr.isNull() && texture_names.size() == 6)
        materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setCubicTextureName(&texture_names[0], false);
        //skyMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureScale(1, -1);
    else if(!materialPtr.isNull() )
        for(int i = 0; i < texture_names.size(); ++i)
            materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setFrameTextureName(Ogre::String(texture_names[i].c_str()), i);

    DisableSky();
    CreateSky();
}
Пример #10
0
void EC_Mesh::AttributesChanged()
{
    if (drawDistance.ValueChanged())
    {
        if(entity_)
            entity_->setRenderingDistance(drawDistance.Get());
    }
    if (castShadows.ValueChanged())
    {
        if(entity_)
        {
            if (entity_)
                entity_->setCastShadows(castShadows.Get());
            /// \todo might want to disable shadows for some attachments
            for(uint i = 0; i < attachment_entities_.size(); ++i)
            {
                if (attachment_entities_[i])
                    attachment_entities_[i]->setCastShadows(castShadows.Get());
            }
        }
    }
    if (nodeTransformation.ValueChanged())
    {
        Transform newTransform = nodeTransformation.Get();
        adjustment_node_->setPosition(newTransform.pos);
        adjustment_node_->setOrientation(newTransform.Orientation());
        
        // Prevent Ogre exception from zero scale
        newTransform.scale = Max(newTransform.scale, float3::FromScalar(0.0000001f));
        
        adjustment_node_->setScale(newTransform.scale);
    }
    if (meshRef.ValueChanged())
    {
        if (!ViewEnabled())
            return;

        if (meshRef.Get().ref.trimmed().isEmpty())
            LogDebug("Warning: Mesh \"" + this->parentEntity->Name() + "\" mesh ref was set to an empty reference!");
        meshAsset->HandleAssetRefChange(&meshRef);
    }
    if (meshMaterial.ValueChanged())
    {
        if (!ViewEnabled())
            return;

        AssetReferenceList materials = meshMaterial.Get();

        // Reset all the materials from the submeshes which now have an empty material asset reference set.
        for(uint i = 0; i < GetNumMaterials(); ++i)
        {
            if ((int)i >= materials.Size() || materials[i].ref.trimmed().isEmpty())
            {
                if (entity_ && entity_->getSubEntity(i))
                    entity_->getSubEntity(i)->setMaterialName("");
            }
        }

        // Reallocate the number of material asset ref listeners.
        while(materialAssets.size() > (size_t)materials.Size())
            materialAssets.pop_back();
        while(materialAssets.size() < (size_t)materials.Size())
            materialAssets.push_back(shared_ptr<AssetRefListener>(new AssetRefListener));

        for(int i = 0; i < materials.Size(); ++i)
        {
            // Don't request empty refs. HandleAssetRefChange will just do unnecessary work and the below connections are for nothing.
            if (!materials[i].ref.trimmed().isEmpty())
            {
                connect(materialAssets[i].get(), SIGNAL(Loaded(AssetPtr)), this, SLOT(OnMaterialAssetLoaded(AssetPtr)), Qt::UniqueConnection);
                connect(materialAssets[i].get(), SIGNAL(TransferFailed(IAssetTransfer*, QString)), this, SLOT(OnMaterialAssetFailed(IAssetTransfer*, QString)), Qt::UniqueConnection);
                materialAssets[i]->HandleAssetRefChange(framework->Asset(), materials[i].ref);
            }
        }
    }
Пример #11
0
void EC_Mesh::OnAttributeUpdated(IAttribute *attribute)
{
    if (attribute == &drawDistance)
    {
        if(entity_)
            entity_->setRenderingDistance(drawDistance.Get());
    }
    else if (attribute == &castShadows)
    {
        if(entity_)
        {
            if (entity_)
                entity_->setCastShadows(castShadows.Get());
            /// \todo might want to disable shadows for some attachments
            for(uint i = 0; i < attachment_entities_.size(); ++i)
            {
                if (attachment_entities_[i])
                    attachment_entities_[i]->setCastShadows(castShadows.Get());
            }
        }
    }
    else if (attribute == &nodeTransformation)
    {
        Transform newTransform = nodeTransformation.Get();
        adjustment_node_->setPosition(newTransform.pos);
        adjustment_node_->setOrientation(newTransform.Orientation());
        
        // Prevent Ogre exception from zero scale
        if (newTransform.scale.x < 0.0000001f)
            newTransform.scale.x = 0.0000001f;
        if (newTransform.scale.y < 0.0000001f)
            newTransform.scale.y = 0.0000001f;
        if (newTransform.scale.z < 0.0000001f)
            newTransform.scale.z = 0.0000001f;
        
        adjustment_node_->setScale(newTransform.scale);
    }
    else if (attribute == &meshRef)
    {
        if (!ViewEnabled())
            return;
            
        //Ensure that mesh is requested only when it's has actually changed.
//        if(entity_)
 //           if(QString::fromStdString(entity_->getMesh()->getName()) == meshRef.Get().ref/*meshResourceId.Get()*/)
  //              return;
/*
        AssetTransferPtr transfer = GetFramework()->Asset()->RequestAsset(meshRef.Get());
        if (transfer)
        {
            connect(transfer.get(), SIGNAL(Succeeded(AssetPtr)), SLOT(OnMeshAssetLoaded()), Qt::UniqueConnection);
        }
        else
        {
            RemoveMesh();
        }
        */
        if (meshRef.Get().ref.trimmed().isEmpty())
            LogDebug("Warning: Mesh \"" + this->parentEntity->Name().toStdString() + "\" mesh ref was set to an empty reference!");
        meshAsset->HandleAssetRefChange(&meshRef);
    }
    else if (attribute == &meshMaterial)
    {
        if (!ViewEnabled())
            return;
        
        // We won't request materials until we are sure that mesh has been loaded and it's safe to apply materials into it.
        // This logic shouldn't be necessary anymore. -jj.
//        if(!HasMaterialsChanged())
//            return;

        AssetReferenceList materials = meshMaterial.Get();
        // Make sure that the asset ref list type stays intact.
        materials.type = "OgreMaterial";
        meshMaterial.Set(materials, AttributeChange::Disconnected);

        // Reallocate the number of material asset reflisteners.
        while(materialAssets.size() > (size_t)materials.Size())
            materialAssets.pop_back();
        while(materialAssets.size() < (size_t)materials.Size())
            materialAssets.push_back(boost::shared_ptr<AssetRefListener>(new AssetRefListener));

        for(int i = 0; i < materials.Size(); ++i)
        {
            connect(materialAssets[i].get(), SIGNAL(Loaded(AssetPtr)), this, SLOT(OnMaterialAssetLoaded(AssetPtr)), Qt::UniqueConnection);
            connect(materialAssets[i].get(), SIGNAL(TransferFailed(IAssetTransfer*, QString)), this, SLOT(OnMaterialAssetFailed(IAssetTransfer*, QString)), Qt::UniqueConnection);
            materialAssets[i]->HandleAssetRefChange(framework->Asset(), materials[i].ref);
        }
    }
    else if((attribute == &skeletonRef) && (!skeletonRef.Get().ref.isEmpty()))
Пример #12
0
void EC_Mesh::OnAttributeUpdated(IAttribute *attribute)
{
    if (attribute == &drawDistance)
    {
        if(entity_)
            entity_->setRenderingDistance(drawDistance.Get());
    }
    else if (attribute == &castShadows)
    {
        if(entity_)
        {
            if (entity_)
                entity_->setCastShadows(castShadows.Get());
            //! \todo might want to disable shadows for some attachments
            for (uint i = 0; i < attachment_entities_.size(); ++i)
            {
                if (attachment_entities_[i])
                    attachment_entities_[i]->setCastShadows(castShadows.Get());
            }
        }
    }
    else if (attribute == &nodeTransformation)
    {
        Ogre::Node* adjustmentTarget = adjustment_node_;
        if (bone_tagpoint_)
            adjustmentTarget = bone_tagpoint_;
        
        if (adjustmentTarget)
        {
            Transform newTransform = nodeTransformation.Get();
            adjustmentTarget->setPosition(newTransform.position.x, newTransform.position.y, newTransform.position.z);
            Quaternion adjust(DEGTORAD * newTransform.rotation.x,
                              DEGTORAD * newTransform.rotation.y,
                              DEGTORAD * newTransform.rotation.z);
            // Let's not assume the needed haxor adjustment here, but let user specify it as necessary
            //adjust = Quaternion(PI/2, 0, PI) * adjust;
            adjustmentTarget->setOrientation(Ogre::Quaternion(adjust.w, adjust.x, adjust.y, adjust.z));
            
            // Prevent Ogre exception from zero scale
            if (newTransform.scale.x < 0.0000001f)
                newTransform.scale.x = 0.0000001f;
            if (newTransform.scale.y < 0.0000001f)
                newTransform.scale.y = 0.0000001f;
            if (newTransform.scale.z < 0.0000001f)
                newTransform.scale.z = 0.0000001f;
            
            adjustmentTarget->setScale(newTransform.scale.x, newTransform.scale.y, newTransform.scale.z);
        }
    }
    else if (attribute == &meshRef)
    {
        if (!ViewEnabled())
            return;
            
        //Ensure that mesh is requested only when it's has actually changed.
//        if(entity_)
 //           if(QString::fromStdString(entity_->getMesh()->getName()) == meshRef.Get().ref/*meshResourceId.Get()*/)
  //              return;
/*
        AssetTransferPtr transfer = GetFramework()->Asset()->RequestAsset(meshRef.Get());
        if (transfer)
        {
            connect(transfer.get(), SIGNAL(Loaded(AssetPtr)), SLOT(OnMeshAssetLoaded()), Qt::UniqueConnection);
        }
        else
        {
            RemoveMesh();
        }
        */
        if (meshRef.Get().ref.trimmed().isEmpty())
            LogDebug("Warning: Mesh \"" + this->parent_entity_->GetName().toStdString() + "\" mesh ref was set to an empty reference!");
        meshAsset->HandleAssetRefChange(&meshRef);
    }
    else if (attribute == &meshMaterial)
    {
        if (!ViewEnabled())
            return;
        
        // We won't request materials until we are sure that mesh has been loaded and it's safe to apply materials into it.
        // This logic shouldn't be necessary anymore. -jj.
//        if(!HasMaterialsChanged())
//            return;

        AssetReferenceList materials = meshMaterial.Get();

        // Reallocate the number of material asset reflisteners.
        while(materialAssets.size() > materials.Size())
            materialAssets.pop_back();
        while(materialAssets.size() < materials.Size())
            materialAssets.push_back(boost::shared_ptr<AssetRefListener>(new AssetRefListener));

        for(int i = 0; i < materials.Size(); ++i)
        {
            connect(materialAssets[i].get(), SIGNAL(Loaded(AssetPtr)), this, SLOT(OnMaterialAssetLoaded(AssetPtr)), Qt::UniqueConnection);
            materialAssets[i]->HandleAssetRefChange(framework_->Asset(), materials[i].ref);
        }
    }
    else if((attribute == &skeletonRef) && (!skeletonRef.Get().ref.isEmpty()))
    {
        if (!ViewEnabled())
            return;
        
        // If same name skeleton already set no point to do it again.
//        if (entity_ && entity_->getSkeleton() && entity_->getSkeleton()->getName() == skeletonRef.Get().ref/*skeletonId.Get()*/.toStdString())
 //           return;

  //      AssetTransferPtr transfer = GetFramework()->Asset()->RequestAsset(skeletonRef.Get().ref);
   //     if (transfer)
    //        connect(transfer.get(), SIGNAL(Loaded(AssetPtr)), SLOT(OnSkeletonAssetLoaded(AssetPtr)), Qt::UniqueConnection);
        skeletonAsset->HandleAssetRefChange(&skeletonRef);
    }
}