void AssetsWindow::AddAsset(AssetPtr asset) { ///\todo Check that the asset doesn't already exists AssetItem *item = new AssetItem(asset); AddChildren(asset, item); connect(asset.get(), SIGNAL(Loaded(AssetPtr)), SLOT(HandleAssetLoaded(AssetPtr))); connect(asset.get(), SIGNAL(Unloaded(IAsset *)), SLOT(HandleAssetUnloaded(IAsset *))); bool storageFound = false; AssetStoragePtr storage = asset->GetAssetStorage(); if (storage) for(int i = 0; i < treeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem *storageItem = treeWidget->topLevelItem(i); if (storageItem->text(0) == storage->ToString()) { storageItem->addChild(item); storageFound = true; break; } } if (!storageFound) noProviderItem->addChild(item); noProviderItem->setHidden(noProviderItem->childCount() == 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()); } }
QWidget *UiAPI::LoadFromFile(const QString &filePath, bool addToScene, QWidget *parent) { QWidget *widget = 0; if (AssetAPI::ParseAssetRefType(filePath) != AssetAPI::AssetRefLocalPath) { AssetPtr asset = owner->Asset()->GetAsset(filePath); if (!asset) { LogError(("LoadFromFile: Asset \"" + filePath + "\" is not loaded to the asset system. Call RequestAsset prior to use!").toStdString()); return 0; } QtUiAsset *uiAsset = dynamic_cast<QtUiAsset*>(asset.get()); if (!uiAsset) { LogError(("LoadFromFile: Asset \"" + filePath + "\" is not of type QtUiFile!").toStdString()); return 0; } if (!uiAsset->IsLoaded()) { LogError(("LoadFromFile: Asset \"" + filePath + "\" data is not valid!").toStdString()); return 0; } // Get the asset data with the assetrefs replaced to point to the disk sources on the current local system. QByteArray data = uiAsset->GetRefReplacedAssetData(); QUiLoader loader; QDataStream dataStream(&data, QIODevice::ReadOnly); widget = loader.load(dataStream.device(), parent); } else // The file is from absolute source location. { QFile file(filePath); QUiLoader loader; file.open(QFile::ReadOnly); widget = loader.load(&file, parent); } if (!widget) { LogError(("LoadFromFile: Failed to load widget from file \"" + filePath + "\"!").toStdString()); return 0; } if (addToScene && widget) AddWidgetToScene(widget); return widget; }
void EC_Sky::OnTextureAssetLoaded(AssetPtr tex) { std::vector<std::string> texture_names; texture_names.reserve(cSkyBoxTextureCount); AssetReferenceList textureList = textureRefs.Get(); const char * const defaultSkyTextures[cSkyBoxTextureCount] = { "rex_sky_front.dds", "rex_sky_back.dds", "rex_sky_left.dds", "rex_sky_right.dds", "rex_sky_top.dds", "rex_sky_bot.dds" }; for(size_t i = 0; i < textureAssets.size() || i < cSkyBoxTextureCount; ++i) if (i < textureAssets.size() && textureAssets[i]) { AssetPtr asset = textureAssets[i]->Asset(); TextureAsset *textureAsset = dynamic_cast<TextureAsset*>(asset.get()); if (textureAsset) texture_names.push_back(textureAsset->ogreAssetName.toStdString()); else texture_names.push_back(defaultSkyTextures[i]); } else texture_names.push_back(defaultSkyTextures[i]); assert(texture_names.size() == cSkyBoxTextureCount); ///\todo Use AssetAPI for the material. Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().getByName(materialRef.Get().ref.toStdString().c_str()); if (materialPtr.isNull()) { LogError("EC_Sky::OnTextureAssetLoaded: Cannot find Ogre material \"" + materialRef.Get().ref.toStdString() + "\"!"); return; } if (materialPtr->getNumTechniques() == 0 || materialPtr->getTechnique(0) == 0 || materialPtr->getTechnique(0)->getNumPasses() == 0 || materialPtr->getTechnique(0)->getPass(0) == 0 || materialPtr->getTechnique(0)->getPass(0)->getNumTextureUnitStates() == 0 || materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0) == 0) { LogError("EC_Sky::OnTextureAssetLoaded: Cannot use material \"" + materialRef.Get().ref.toStdString() + "\" as Skybox material: It has 0 techniques, passes or texture unit states!"); return; } materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setCubicTextureName(&texture_names[0], false); CreateSky(); }
void EC_Mesh::OnMeshAssetLoaded(AssetPtr asset) { OgreMeshAsset *mesh = dynamic_cast<OgreMeshAsset*>(asset.get()); if (!mesh) { LogError("OnMeshAssetLoaded: Mesh asset load finished for asset \"" + asset->Name().toStdString() + "\", but downloaded asset was not of type OgreMeshAsset!"); return; } QString ogreMeshName = mesh->Name(); if (mesh) { if (mesh->ogreMesh.get()) { ogreMeshName = QString::fromStdString(mesh->ogreMesh->getName()).trimmed(); // Do not reload if all of the following are met // 1. Ogre::Entity and Ogre::Mesh are valid (aka this is not the first load for this EC_Mesh) // 2. Mesh name is same (aka asset reference with ogre sanitations) // 3. Content hash has not changed (aka data has not changed) if (entity_ && entity_->getMesh().get()) { QString currentMeshName = QString::fromStdString(entity_->getMesh()->getName()).trimmed(); if (currentMeshName == ogreMeshName && mesh->ContentHashChanged() == false) return; } } else LogError("OnMeshAssetLoaded: Mesh asset load finished for asset \"" + asset->Name().toStdString() + "\", but Ogre::Mesh pointer was null!"); } SetMesh(ogreMeshName); // Force a re-application of the skeleton on this mesh. ///\todo This path should be re-evaluated to see if we have potential performance issues here. -jj. if (skeletonAsset->Asset()) OnSkeletonAssetLoaded(skeletonAsset->Asset()); // Apply pending materials, these were tried to be applied before the mesh was loaded if (!pendingMaterialApplies.empty()) { for(int idx = 0; idx < pendingMaterialApplies.size(); ++idx) SetMaterial(idx, pendingMaterialApplies[idx]); pendingMaterialApplies.clear(); } }
void EC_Mesh::OnSkeletonAssetLoaded(AssetPtr asset) { OgreSkeletonAsset *skeletonAsset = dynamic_cast<OgreSkeletonAsset*>(asset.get()); if (!skeletonAsset) { LogError("OnSkeletonAssetLoaded: Skeleton asset load finished for asset \"" + asset->Name().toStdString() + "\", but downloaded asset was not of type OgreSkeletonAsset!"); return; } Ogre::SkeletonPtr skeleton = skeletonAsset->ogreSkeleton; if (skeleton.isNull()) { LogError("OnSkeletonAssetLoaded: Skeleton asset load finished for asset \"" + asset->Name().toStdString() + "\", but Ogre::Skeleton pointer was null!"); return; } if(!entity_) { LogDebug("Could not set skeleton yet because entity is not yet created"); return; } try { // If old skeleton is same as a new one no need to replace it. if (entity_->getSkeleton() && entity_->getSkeleton()->getName() == skeleton->getName()) return; entity_->getMesh()->_notifySkeleton(skeleton); // LogDebug("Set skeleton " + skeleton->getName() + " to mesh " + entity_->getName()); emit SkeletonChanged(QString::fromStdString(skeleton->getName())); } catch (...) { LogError("Exception while setting skeleton to mesh" + entity_->getName()); } // Now we have to recreate the entity to get proper animations etc. SetMesh(entity_->getMesh()->getName().c_str(), false); }
QByteArray QtUiAsset::GetRefReplacedAssetData() const { if (originalData.size() == 0) return QByteArray(); QByteArray refRewrittenData((const char *)&originalData[0], originalData.size()); // The AssetRef indices need to be adjusted with an offset after rewriting each ref, since the lengths of the refs change in the file. // This variable tracks the accumulated byte offset that takes this into account. int indexAdjustment = 0; for(size_t i = 0; i < refs.size(); ++i) { QString assetDiskSource = ""; AssetPtr asset = assetAPI->GetAsset(refs[i].parsedRef); if (!asset.get()) { LogError("ReplaceAssetReferences: Asset not found from asset system even when it was marked as a dependency earlier, skipping: " + refs[i].parsedRef.toStdString()); } else { assetDiskSource = asset->DiskSource(); if (assetDiskSource.isEmpty()) LogWarning("ReplaceAssetReferences: Asset disk source empty, skipping: " + refs[i].parsedRef.toStdString()); } assetDiskSource = assetDiskSource.trimmed(); if (!assetDiskSource.isEmpty() && QFile::exists(assetDiskSource)) { QByteArray refAsByteArray = (QString("\"") + assetDiskSource + QString("\"")).toUtf8(); refRewrittenData.replace(refs[i].index + indexAdjustment, refs[i].length, refAsByteArray); indexAdjustment += refAsByteArray.length() - refs[i].length; } else { LogWarning("ReplaceAssetReferences: Asset disk source does not exist, skipping: " + refs[i].parsedRef.toStdString()); } } return refRewrittenData; }
AssetItem::AssetItem(const AssetPtr &asset, QTreeWidgetItem *parent) : QTreeWidgetItem(parent), assetPtr(asset) { SetText(asset.get()); }