diff options
| author | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
|---|---|---|
| committer | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
| commit | 236f03c0b9a4982328ed1201978f7f69d192d9b2 (patch) | |
| tree | e486f2fa39dba203563895541e92c60ed3e25759 /tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp | |
| parent | Added screens to welcome page (diff) | |
| download | blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.tar.xz blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.zip | |
Blast 1.1 release (windows / linux)
see docs/release_notes.txt for details
Diffstat (limited to 'tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp')
| -rw-r--r-- | tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp | 2386 |
1 files changed, 1601 insertions, 785 deletions
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp b/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp index a6cdf64..ab0ca85 100644 --- a/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp +++ b/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp @@ -4,18 +4,50 @@ #include <QtWidgets/QPushButton> #include <QtWidgets/QCheckBox> #include <QtWidgets/QMenu> +#include <QtWidgets/QShortcut> #include <QtCore/QFileInfo> +#include <QtGui/qevent.h> +#include <QtGui/QPainter> #include <assert.h> #include "ProjectParams.h" #include <SimpleScene.h> #include <BlastController.h> +#include "SelectionToolController.h" +#include "GizmoToolController.h" #include <SceneController.h> #include <NvBlastExtPxAsset.h> #include <NvBlastTkAsset.h> #include <NvBlastAsset.h> #include <BlastFamilyModelSimple.h> #include "GlobalSettings.h" +#include <deque> +#include "ViewerOutput.h" +static QIcon sCompositeIcon; +static QIcon sAssetIcon; +static QIcon sChunkUUIcon; +static QIcon sChunkSUIcon; +static QIcon sChunkSSIcon; +static QIcon sBondIcon; +static QIcon sProjectileIcon; + +static QPixmap sVisibleIcon = QPixmap(":/AppMainWindow/images/visibilityToggle_visible.png").scaled(QSize(24, 24), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); +static QPixmap sInVisibleIcon = QPixmap(":/AppMainWindow/images/visibilityToggle_notVisible.png").scaled(QSize(24, 24), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + +class BlastSceneTreeDataLock +{ +public: + BlastSceneTreeDataLock() + { + BlastSceneTree::ins()->_updateData = false; + } + ~BlastSceneTreeDataLock() + { + BlastSceneTree::ins()->_updateData = true; + } +}; + +#if 0 bool isChunkVisible(std::vector<BlastFamily*>& fs, uint32_t chunkIndex) { int fsSize = fs.size(); @@ -35,6 +67,7 @@ bool isChunkVisible(std::vector<BlastFamily*>& fs, uint32_t chunkIndex) } return visible; } +#endif void setChunkVisible(std::vector<BlastFamily*>& fs, uint32_t chunkIndex, bool visible) { @@ -60,13 +93,28 @@ void setChunkSelected(std::vector<BlastFamily*>& fs, uint32_t chunkIndex, bool s for (int i = 0; i < fsSize; i++) { - fs[i]->setChunkSelected(chunkIndex, selected); + BlastFamily* bf = fs[i]; + if(bf) + bf->setChunkSelected(chunkIndex, selected); + } +} + +void BlastNode::traverse(BlastVisitorBase& visitor) +{ + visitor.visit(this); + + for (BlastNode* node : children) + { + if (!visitor.continueTraversing()) + break; + + node->traverse(visitor); } } void BlastChunkNode::setVisible(bool val) { - BPPChunk* pBPPChunk = (BPPChunk*)_data; + BPPChunk* pBPPChunk = (BPPChunk*)getData(); pBPPChunk->visible = val; BlastAsset* pBlastAsset = (BlastAsset*)_assetPtr; @@ -74,32 +122,88 @@ void BlastChunkNode::setVisible(bool val) SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap(); - std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset]; + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator it = AssetFamiliesMap.find(pBlastAsset); + if (it == AssetFamiliesMap.end()) + { + return; + } + std::vector<BlastFamily*>& fs = it->second; setChunkVisible(fs, pBPPChunk->ID, val); } void BlastChunkNode::setSelected(bool val) { - BPPChunk* pBPPChunk = (BPPChunk*)_data; - pBPPChunk->visible = val; + BPPChunk* pBPPChunk = (BPPChunk*)getData(); BlastAsset* pBlastAsset = (BlastAsset*)_assetPtr; SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap(); - std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset]; + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator it = AssetFamiliesMap.find(pBlastAsset); + if (it == AssetFamiliesMap.end()) + { + return; + } + std::vector<BlastFamily*>& fs = it->second; setChunkSelected(fs, pBPPChunk->ID, val); } +void BlastAssetNode::setSelected(bool val) +{ + BPPAsset* pBPPAsset = (BPPAsset*)getData(); + std::string strAsset = pBPPAsset->name.buf; + + BlastAsset* pBlastAsset = nullptr; + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = sampleManager.getAssetDescMap(); + std::map<BlastAsset*, AssetList::ModelAsset>::iterator itAssetDescMap; + for (itAssetDescMap = AssetDescMap.begin(); + itAssetDescMap != AssetDescMap.end(); itAssetDescMap++) + { + AssetList::ModelAsset& model = itAssetDescMap->second; + if (model.name == strAsset) + { + pBlastAsset = itAssetDescMap->first; + break; + } + } + + sampleManager.setCurrentSelectedInstance(pBlastAsset, -1); + + std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap(); + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAFM = AssetFamiliesMap.find(pBlastAsset); + if (itAFM == AssetFamiliesMap.end()) + { + return; + } + std::vector<BlastFamily*>& fs = itAFM->second; + for (BlastFamily* pBlastFamily : fs) + { + pBlastFamily->highlightChunks(); + } +} + +bool BlastProjectileNode::getVisible() +{ + return SampleManager::ins()->getSceneController().getProjectileVisible((PhysXSceneActor*)getData()); +} + +void BlastProjectileNode::setVisible(bool val) +{ + SampleManager::ins()->getSceneController().setProjectileVisible((PhysXSceneActor*)getData(), val); +} + void BlastAssetInstanceNode::setSelected(bool val) { - BPPAssetInstance* pBPPAssetInstance = (BPPAssetInstance*)_data; - std::string name = pBPPAssetInstance->name; + BPPAssetInstance* pBPPAssetInstance = (BPPAssetInstance*)getData(); + if (pBPPAssetInstance == nullptr) + return; + std::string name = pBPPAssetInstance->name.buf; - std::string strAsset = name.substr(0, name.find_first_of("_")); + std::string strAsset = name.substr(0, name.find_last_of("_")); BlastAsset* pBlastAsset = nullptr; SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = sampleManager.getAssetDescMap(); @@ -119,6 +223,9 @@ void BlastAssetInstanceNode::setSelected(bool val) int nIndex = atoi(strIndex.c_str()); sampleManager.setCurrentSelectedInstance(pBlastAsset, nIndex); + + std::vector<BlastFamily*> fs = { SampleManager::ins()->getFamilyByInstance(pBPPAssetInstance) }; + setChunkSelected(fs, 0, val); } BlastTreeData& BlastTreeData::ins() @@ -152,7 +259,7 @@ std::vector<BlastChunkNode*> BlastTreeData::getTopChunkNodes(std::vector<BlastCh bool isCurNodeTop = true; for (size_t j = 0; j < nodes.size(); ++j) { - if (i != j && isChild(nodes[i], nodes[j])) + if (i != j && isChild(nodes[j], nodes[i])) { isCurNodeTop = false; break; @@ -168,6 +275,18 @@ std::vector<BlastChunkNode*> BlastTreeData::getTopChunkNodes(std::vector<BlastCh return result; } +int BlastTreeData::getDepth(BlastNode* node) +{ + int depth = -1; // here it's from -1 because it traverse from Blast asset node + while (nullptr != node && (eBond == node->getType() || eChunk == node->getType())) + { + ++depth; + node = node->getParent(); + } + + return depth; +} + bool BlastTreeData::isRoot(BlastChunkNode* node) { if (node == nullptr || node->getParent() == nullptr) @@ -197,6 +316,7 @@ void removeChunkNodeSupport(BlastChunkNode* node) BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); chunk->support = false; + chunk->staticFlag = false; for (BlastNode* curNode : node->children) { @@ -207,14 +327,72 @@ void removeChunkNodeSupport(BlastChunkNode* node) } } +void setAncestorSupportFlag(BlastChunkNode* ancestor, BlastChunkNode* startChild) +{ + if (nullptr == ancestor || nullptr == startChild) + return; + + { + BPPChunk* bppChunk = (BPPChunk*)(ancestor->getData()); + bppChunk->support = false; + bppChunk->staticFlag = false; + } + + std::deque<BlastChunkNode*> ancestors; + for (BlastNode* node : ancestor->children) + { + if (eChunk == node->getType()) + { + ancestors.push_back(static_cast<BlastChunkNode*>(node)); + } + } + + while (ancestors.size() > 0) + { + BlastChunkNode* curAncestor = ancestors.front(); + ancestors.pop_front(); + + bool isChild = BlastTreeData::isChild(curAncestor, startChild); + if (isChild) + { + if (curAncestor != startChild) + { + for (BlastNode* node : curAncestor->children) + { + if (eChunk == node->getType()) + { + ancestors.push_back(static_cast<BlastChunkNode*>(node)); + } + } + } + } + else + { + BPPChunk* bppChunk = (BPPChunk*)(curAncestor->getData()); + bppChunk->support = true; + bppChunk->staticFlag = false; + } + } +} + void BlastTreeData::makeSupport(BlastChunkNode* node) { if (node == nullptr) return; + + // 1 set flag for current node BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); chunk->staticFlag = false; chunk->support = true; + // 2 set flag for ancestors + BlastChunkNode* supportAncestor = ins().getSupportAncestor(node); + if (supportAncestor) + { + setAncestorSupportFlag(supportAncestor, node); + } + + // 3 set flag for children for (BlastNode* curNode : node->children) { if (eChunk == curNode->getType()) @@ -228,10 +406,20 @@ void BlastTreeData::makeStaticSupport(BlastChunkNode* node) { if (node == nullptr) return; + + // 1 set flag for current node BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); chunk->staticFlag = true; chunk->support = true; + // 2 set flag for ancestors + BlastChunkNode* supportAncestor = ins().getSupportAncestor(node); + if (supportAncestor) + { + setAncestorSupportFlag(supportAncestor, node); + } + + // 3 set flag for children for (BlastNode* curNode : node->children) { if (eChunk == curNode->getType()) @@ -259,8 +447,37 @@ void BlastTreeData::removeSupport(BlastChunkNode* node) { BPPChunk* curChunk = static_cast<BPPChunk*>(curNode->getData()); curChunk->support = true; + curChunk->staticFlag = false; + } + } +} + +std::string BlastTreeData::getAssetName(BlastAsset* asset) +{ + std::map<BlastAsset*, AssetList::ModelAsset>& assetDescMap = SampleManager::ins()->getAssetDescMap(); + std::map<BlastAsset*, AssetList::ModelAsset>::iterator itrAssetDesc = assetDescMap.find(asset); + + if (itrAssetDesc != assetDescMap.end()) + { + return itrAssetDesc->second.name; + } + + return ""; +} + +BlastAsset* BlastTreeData::getAsset(std::string assetName) +{ + std::map<BlastAsset*, AssetList::ModelAsset>& assetDescMap = SampleManager::ins()->getAssetDescMap(); + std::map<BlastAsset*, AssetList::ModelAsset>::iterator itrAssetDesc = assetDescMap.begin(); + for (; itrAssetDesc != assetDescMap.end(); ++itrAssetDesc) + { + if (itrAssetDesc->second.name == assetName) + { + return itrAssetDesc->first; } } + + return nullptr; } BlastNode* BlastTreeData::getBlastNodeByProjectData(void* data) @@ -328,6 +545,53 @@ void BlastTreeData::remove(const BlastAssetInstanceNode* node) //to do } +BlastAssetInstanceNode* BlastTreeData::getAssetInstanceNode(BlastFamily* family) +{ + BPPAssetInstance* instance = SampleManager::ins()->getInstanceByFamily(family); + return getAssetInstanceNode(instance); +} + +BlastAssetInstanceNode* BlastTreeData::getAssetInstanceNode(BPPAssetInstance* instance) +{ + if (nullptr == instance) + return nullptr; + + for (BlastNode* node : _assetInstancesNode->children) + { + if ((BPPAssetInstance*)(node->getData()) == instance) + { + return (BlastAssetInstanceNode*)node; + } + } + + return nullptr; +} + +std::vector<BlastAssetInstanceNode*> BlastTreeData::getAssetInstanceNodes(BlastChunkNode* chunkNode) +{ + std::vector<BlastAssetInstanceNode*> instanceNodes; + + if (nullptr == chunkNode) + return instanceNodes; + + BlastAsset* asset = getAsset(chunkNode); + + if (isRoot(chunkNode)) + { + BPPAssetInstance* instance = (BPPAssetInstance*)(chunkNode->getData()); + + for (BlastNode* instanceNode : _assetInstancesNode->children) + { + BPPAssetInstance* instance = (BPPAssetInstance*)(instanceNode->getData()); + BlastFamily* family = SampleManager::ins()->getFamilyByInstance(instance); + if (&(family->getBlastAsset()) == asset) + instanceNodes.push_back((BlastAssetInstanceNode*)instanceNode); + } + } + + return instanceNodes; +} + void BlastTreeData::update() { _freeBlastNode(); @@ -352,269 +616,20 @@ void BlastTreeData::update() BlastAssetVec.push_back(it->first); } int modelAssetsSize = AssetDescMap.size(); - - std::vector<std::string> projectilesNames; - sceneController.GetProjectilesNames(projectilesNames); - - // compoistie - { - BPPComposite& composite = blast.composite; - composite.composite.buf = nullptr; - composite.visible = true; - copy(composite.composite, "BlastComposite"); - - // asset instance array - { - BPPAssetInstanceArray& instanceArray = composite.blastAssetInstances; - instanceArray.arraySizes[0] = familiesSize; - if (familiesSize > 0) - { - instanceArray.buf = new BPPAssetInstance[familiesSize]; - int curInstanceIndex = 0; - char instancename[MAX_PATH]; - std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAssetFamiliesMap; - for (itAssetFamiliesMap = AssetFamiliesMap.begin(); - itAssetFamiliesMap != AssetFamiliesMap.end(); itAssetFamiliesMap++) - { - BlastAsset* pBlastAsset = itAssetFamiliesMap->first; - std::vector<BlastFamily*>& fs = itAssetFamiliesMap->second; - int fsSize = fs.size(); - for (int i = 0; i < fsSize; i++) - { - BPPAssetInstance& instance = instanceArray.buf[curInstanceIndex]; - instance.name.buf = nullptr; - instance.source.buf = nullptr; - instance.visible = true; - - AssetList::ModelAsset desc = AssetDescMap[pBlastAsset]; - sprintf(instancename, "%s_Instance_%d", desc.name.c_str(), i); - copy(instance.name, instancename); - - std::string assetFilePath = GlobalSettings::MakeFileName(GlobalSettings::Inst().m_projectFileDir.c_str(), std::string(desc.file + ".bpxa").c_str()); - sprintf(instancename, "%s", assetFilePath.c_str()); - copy(instance.source, instancename); - - PxVec3 p = desc.transform.p; - PxQuat q = desc.transform.q; - instanceArray.buf[curInstanceIndex].transform.position = nvidia::NvVec3(p.x, p.y, p.z); - instanceArray.buf[curInstanceIndex].transform.rotation = nvidia::NvVec4(q.x, q.y, q.z, q.w); - - curInstanceIndex++; - } - } - } - } - - // landmark array - if (0) - { - BPPLandmarkArray& landmarkArray = composite.landmarks; - landmarkArray.buf = new BPPLandmark[2]; - landmarkArray.arraySizes[0] = 2; - landmarkArray.buf[0].name.buf = nullptr; - landmarkArray.buf[1].name.buf = nullptr; - - copy(landmarkArray.buf[0].name, "Landmark_1"); - copy(landmarkArray.buf[1].name, "Landmark_2"); - } - } - - // asset array - { - BPPAssetArray& assetArray = blast.blastAssets; - assetArray.arraySizes[0] = modelAssetsSize; - if (modelAssetsSize > 0) - { - assetArray.buf = new BPPAsset[modelAssetsSize]; - int curAssetIndex = 0; - - blast.chunks.buf = nullptr; - blast.chunks.arraySizes[0] = 0; - blast.bonds.buf = nullptr; - blast.bonds.arraySizes[0] = 0; - - std::map<BlastAsset*, AssetList::ModelAsset>::iterator itAssetDescMap; - for (itAssetDescMap = AssetDescMap.begin(); - itAssetDescMap != AssetDescMap.end(); itAssetDescMap++) - { - BlastAsset* pBlastAsset = itAssetDescMap->first; - AssetList::ModelAsset& desc = itAssetDescMap->second; - std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset]; - - BPPAsset& asset = assetArray.buf[curAssetIndex]; - asset.path.buf = nullptr; - asset.activePreset.buf = nullptr; - std::string assetFilePath = GlobalSettings::MakeFileName(GlobalSettings::Inst().m_projectFileDir.c_str(), std::string(desc.file + ".bpxa").c_str()); - copy(asset.path, assetFilePath.c_str()); - - const ExtPxAsset* pExtPxAsset = pBlastAsset->getPxAsset(); - const ExtPxChunk* pExtPxChunk = pExtPxAsset->getChunks(); - - const TkAsset& tkAsset = pExtPxAsset->getTkAsset(); - uint32_t chunkCount = tkAsset.getChunkCount(); - const NvBlastChunk* pNvBlastChunk = tkAsset.getChunks(); - uint32_t bondCount = tkAsset.getBondCount(); - const NvBlastBond* pNvBlastBond = tkAsset.getBonds(); - - const NvBlastSupportGraph supportGraph = tkAsset.getGraph(); - uint32_t* chunkIndices = supportGraph.chunkIndices; - uint32_t* adjacencyPartition = supportGraph.adjacencyPartition; - uint32_t* adjacentNodeIndices = supportGraph.adjacentNodeIndices; - uint32_t* adjacentBondIndices = supportGraph.adjacentBondIndices; - - ChunkSupport* pSupport = new ChunkSupport[chunkCount]; - BondChunkIndices* pBCIndices = new BondChunkIndices[bondCount]; - - for (uint32_t node0 = 0; node0 < supportGraph.nodeCount; ++node0) - { - const uint32_t chunkIndex0 = supportGraph.chunkIndices[node0]; - - pSupport[chunkIndex0].m_bSupport = true; - - for (uint32_t adjacencyIndex = adjacencyPartition[node0]; adjacencyIndex < adjacencyPartition[node0 + 1]; adjacencyIndex++) - { - uint32_t node1 = supportGraph.adjacentNodeIndices[adjacencyIndex]; - - // add this condition if you don't want to iterate all bonds twice - if (node0 > node1) - continue; - - const uint32_t chunkIndex1 = supportGraph.chunkIndices[node1]; - - uint32_t bondIndex = supportGraph.adjacentBondIndices[adjacencyIndex]; - - pBCIndices[bondIndex].SetIndices(chunkIndex0, chunkIndex1); - } - } - - // chunks - { - BPPChunkArray curArray; - curArray.buf = new BPPChunk[chunkCount]; - curArray.arraySizes[0] = chunkCount; - char chunkname[10]; - for (int cc = 0; cc < chunkCount; ++cc) - { - BPPChunk& chunk = curArray.buf[cc]; - chunk.name.buf = nullptr; - chunk.asset.buf = nullptr; - - std::vector<uint32_t> parentChunkIndexes; - parentChunkIndexes.push_back(cc); - uint32_t parentChunkIndex = cc; - while ((parentChunkIndex = pNvBlastChunk[parentChunkIndex].parentChunkIndex) != -1) - { - parentChunkIndexes.push_back(parentChunkIndex); - } - - std::string strChunkName = "Chunk"; - for (int pcIndex = parentChunkIndexes.size() - 1; pcIndex >= 0; pcIndex--) - { - sprintf(chunkname, "_%d", parentChunkIndexes[pcIndex]); - strChunkName += chunkname; - } - copy(chunk.name, strChunkName.c_str()); - - copy(chunk.asset, asset.path); - chunk.ID = cc; - chunk.parentID = pNvBlastChunk[cc].parentChunkIndex; - chunk.staticFlag = pExtPxChunk[cc].isStatic; - chunk.visible = isChunkVisible(fs, cc); - chunk.support = pSupport[cc].m_bSupport; - } - - merge(blast.chunks, curArray); - freeBlast(curArray); - } - - // bonds - { - BPPBondArray curArray; - curArray.buf = new BPPBond[bondCount]; - curArray.arraySizes[0] = bondCount; - char bondname[10]; - bool visible; - for (int bc = 0; bc < bondCount; ++bc) - { - BPPBond& bond = curArray.buf[bc]; - bond.name.buf = nullptr; - bond.asset.buf = nullptr; - - visible = isChunkVisible(fs, pBCIndices[bc].chunkIndices[0]) - || isChunkVisible(fs, pBCIndices[bc].chunkIndices[1]); - bond.visible = visible; - bond.fromChunk = pBCIndices[bc].chunkIndices[0]; - bond.toChunk = pBCIndices[bc].chunkIndices[1]; - - sprintf(bondname, "Bond_%d_%d", bond.fromChunk, bond.toChunk); - copy(bond.name, bondname); - copy(bond.asset, asset.path); - - bond.support.healthMask.buf = nullptr; - bond.support.bondStrength = 1.0; - bond.support.enableJoint = false; - } - - merge(blast.bonds, curArray); - freeBlast(curArray); - } - - delete[] pSupport; - pSupport = nullptr; - delete[] pBCIndices; - pBCIndices = nullptr; - - curAssetIndex++; - } - } - } - - // projectile - { - BPPProjectileArray& projectileArray = blast.projectiles; - int BPPProjectileSize = projectilesNames.size(); - projectileArray.arraySizes[0] = BPPProjectileSize; - if (BPPProjectileSize > 0) - { - projectileArray.buf = new BPPProjectile[BPPProjectileSize]; - for (int i = 0; i < BPPProjectileSize; i++) - { - projectileArray.buf[i].name.buf = nullptr; - copy(projectileArray.buf[i].name, projectilesNames[i].c_str()); - projectileArray.buf[i].visible = true; - } - } - } - - // graphics meshes - if (0) - { - BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes; - graphicsMeshArray.buf = new BPPGraphicsMesh[3]; - graphicsMeshArray.arraySizes[0] = 3; - graphicsMeshArray.buf[0].name.buf = nullptr; - copy(graphicsMeshArray.buf[0].name, "SurfaceMesh1"); - graphicsMeshArray.buf[0].visible = true; - - graphicsMeshArray.buf[1].name.buf = nullptr; - copy(graphicsMeshArray.buf[1].name, "SurfaceMesh2"); - graphicsMeshArray.buf[1].visible = true; - - graphicsMeshArray.buf[2].name.buf = nullptr; - copy(graphicsMeshArray.buf[2].name, "DisplayMesh1"); - graphicsMeshArray.buf[2].visible = true; - } } BPPAssetArray& assetArray = blast.blastAssets; int count = assetArray.arraySizes[0]; + if (BlastAssetVec.size() != count) + { + return; + } for (int c = 0; c < count; ++c) { BPPAsset& asset = assetArray.buf[c]; - QFileInfo fileInfo(asset.path.buf); - BlastAssetNode* assetNode = new BlastAssetNode(fileInfo.baseName().toUtf8().data(), asset); + BlastAssetNode* assetNode = new BlastAssetNode(asset.name.buf, asset); _assets.push_back(assetNode); _blastProjectDataToNodeMap.insert(std::make_pair((void*)&asset, assetNode)); @@ -632,53 +647,41 @@ void BlastTreeData::update() } } - BPPComposite& composite = blast.composite; - _composite = new BlastCompositeNode(composite.composite.buf, composite); - _blastProjectDataToNodeMap.insert(std::make_pair((void*)&composite, _composite)); - BPPAssetInstanceArray& assetInstanceArray = composite.blastAssetInstances; + _assetInstancesNode = new BlastAssetInstancesNode("BlastAssetInstances"); + _blastProjectDataToNodeMap.insert(std::make_pair(nullptr, _assetInstancesNode)); + BPPAssetInstanceArray& assetInstanceArray = blast.blastAssetInstances; count = assetInstanceArray.arraySizes[0]; for (int i = 0; i < count; ++i) { - BPPAssetInstance& blastAssetInstance = composite.blastAssetInstances.buf[i]; + BPPAssetInstance& blastAssetInstance = assetInstanceArray.buf[i]; BlastAssetInstanceNode* blastAssetInstanceNode = new BlastAssetInstanceNode(blastAssetInstance.name.buf, blastAssetInstance); - _composite->children.push_back(blastAssetInstanceNode); - blastAssetInstanceNode->setParent(_composite); + _assetInstancesNode->children.push_back(blastAssetInstanceNode); + blastAssetInstanceNode->setParent(_assetInstancesNode); _blastProjectDataToNodeMap.insert(std::make_pair((void*)&blastAssetInstance, blastAssetInstanceNode)); } - BPPLandmarkArray& landmarkArray = composite.landmarks; - count = landmarkArray.arraySizes[0]; - for (int i = 0; i < count; ++i) - { - BPPLandmark& landmark = composite.landmarks.buf[i]; - BlastLandmarkNode* landmarkNode = new BlastLandmarkNode(landmark.name.buf, landmark); - _composite->children.push_back(landmarkNode); - landmarkNode->setParent(_composite); - _blastProjectDataToNodeMap.insert(std::make_pair((void*)&landmark, landmarkNode)); - } - - BPPProjectileArray& projectileArray = blast.projectiles; - count = projectileArray.arraySizes[0]; - for (int i = 0; i < count; ++i) + SceneController& sceneController = SampleManager::ins()->getSceneController(); + std::vector<PhysXSceneActor*> projectiles = sceneController.getPrejectiles(); + for (PhysXSceneActor* projectile : projectiles) { - BPPProjectile& projectile = projectileArray.buf[i]; - BlastProjectileNode* projectileNode = new BlastProjectileNode(projectile.name.buf, projectile); + BlastProjectileNode* projectileNode = new BlastProjectileNode(sceneController.getProjectileName(projectile), projectile); _projectiles.push_back(projectileNode); _blastProjectDataToNodeMap.insert(std::make_pair((void*)&projectile, projectileNode)); } - BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes; - count = graphicsMeshArray.arraySizes[0]; - for (int i = 0; i < count; ++i) - { - BPPGraphicsMesh& graphicsMesh = graphicsMeshArray.buf[i]; - BlastGraphicsMeshNode* projectileNode = new BlastGraphicsMeshNode(graphicsMesh.name.buf, graphicsMesh); - _graphicsMeshes.push_back(projectileNode); - } + //BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes; + //count = graphicsMeshArray.arraySizes[0]; + //for (int i = 0; i < count; ++i) + //{ + // BPPGraphicsMesh& graphicsMesh = graphicsMeshArray.buf[i]; + // BlastGraphicsMeshNode* graphicsNode = new BlastGraphicsMeshNode(graphicsMesh.name.buf, graphicsMesh); + // _graphicsMeshes.push_back(graphicsNode); + //} } -void BlastTreeData::updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible) +BlastNode* BlastTreeData::getNodeByIndex(uint32_t assetIndex, uint32_t chunkIndex) { + BlastNode* pNode = nullptr; BPPBlast& blast = BlastProject::ins().getParams().blast; BPPAssetArray& assetArray = blast.blastAssets; if (assetIndex < assetArray.arraySizes[0]) @@ -688,13 +691,13 @@ void BlastTreeData::updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset); if (chunkIndex < childChunks.size()) { - BPPChunk& chunk = *(childChunks[chunkIndex]); - chunk.visible = visible; + BPPChunk& chunk = *(childChunks[chunkIndex]); + pNode = getBlastNodeByProjectData(&chunk); } } + return pNode; } - void BlastTreeData::update(const BlastAsset* asset) { //to do @@ -744,15 +747,21 @@ BlastAsset* BlastTreeData::getAsset(BlastNode* node) if (eAsset == node->getType()) { - std::map<BlastAsset*, AssetList::ModelAsset>& assetDescMap = SampleManager::ins()->getAssetDescMap(); - std::map<BlastAsset*, AssetList::ModelAsset>::iterator itrAssetDesc = assetDescMap.begin(); - for (; itrAssetDesc != assetDescMap.end(); ++itrAssetDesc) - { - if (itrAssetDesc->second.name == node->name) - { - return itrAssetDesc->first; - } - } + return getAsset(node->name); + } + + return nullptr; +} + +BlastAssetNode* BlastTreeData::getAssetNode(BlastAsset* asset) +{ + if (nullptr == asset) + return nullptr; + + for (BlastAssetNode* node : _assets) + { + if (node->name == getAssetName(asset)) + return node; } return nullptr; @@ -789,6 +798,250 @@ std::vector<BlastChunkNode*> BlastTreeData::getChunkNodeByBlastChunk(const Blast return chunkNodes; } +std::vector<BlastNode*> _getNodesByDepth(BlastNode* curNode, uint32_t depth, int32_t curDepth) +{ + std::vector<BlastNode*> res; + if (depth == curDepth && curNode != nullptr) + { + res.push_back(curNode); + } + else if (curNode != nullptr) + { + for (BlastNode* node : curNode->children) + { + std::vector<BlastNode*> nodes = _getNodesByDepth(node, depth, curDepth + 1); + res.insert(res.begin(), nodes.begin(), nodes.end()); + } + } + + return res; +} + +std::vector<BlastChunkNode*> BlastTreeData::getRootChunkNodeByInstance(const BlastAssetInstanceNode* node) +{ + std::vector<BlastChunkNode*> chunks; + if (nullptr != node) + { + const BPPAssetInstance* pBPPAssetInstance = (BPPAssetInstance*)(const_cast<BlastAssetInstanceNode*>(node)->getData()); + BlastFamily* family = SampleManager::ins()->getFamilyByInstance(const_cast<BPPAssetInstance*>(pBPPAssetInstance)); + if (family) + { + const BlastAsset& asset = family->getBlastAsset(); + BlastAssetNode* assetNode = getAssetNode(const_cast<BlastAsset*>(&asset)); + if (assetNode) + { + for (BlastNode* curNode : assetNode->children) + { + if (eChunk == curNode->getType()) + { + chunks.push_back((BlastChunkNode*)curNode); + } + } + } + } + } + return chunks; +} + +std::vector<BlastNode*> BlastTreeData::getNodesByDepth(BlastAssetNode* node, uint32_t depth) +{ + return _getNodesByDepth(node, depth, -1); // here it's from -1 because it traverse from Blast asset node +} + +std::vector<BlastNode*> BlastTreeData::getNodesByDepth(uint32_t depth) +{ + std::vector<BlastNode*> res; + for (BlastAssetNode* node : _assets) + { + std::vector<BlastNode*> nodes = getNodesByDepth(node, depth); + res.insert(res.begin(), nodes.begin(), nodes.end()); + } + return res; +} + +std::vector<BlastNode*> BlastTreeData::getNodesByDepth(std::vector<uint32_t> depths) +{ + std::vector<BlastNode*> res; + for (uint32_t depth : depths) + { + std::vector<BlastNode*> nodes = getNodesByDepth(depth); + res.insert(res.begin(), nodes.begin(), nodes.end()); + } + return res; +} + +std::vector<BlastChunkNode*> _getSupportChunkNodes(BlastNode* curNode) +{ + std::vector<BlastChunkNode*> res; + if (nullptr != curNode && eChunk == curNode->getType() && static_cast<BlastChunkNode*>(curNode)->isSupport()) + { + res.push_back(static_cast<BlastChunkNode*>(curNode)); + } + else if (curNode != nullptr) + { + for (BlastNode* node : curNode->children) + { + std::vector<BlastChunkNode*> nodes = _getSupportChunkNodes(node); + res.insert(res.begin(), nodes.begin(), nodes.end()); + } + } + + return res; +} + +std::vector<BlastChunkNode*> BlastTreeData::getSupportChunkNodes(BlastAssetNode* node) +{ + return _getSupportChunkNodes(node); +} + +std::vector<BlastChunkNode*> BlastTreeData::getSupportChunkNodes() +{ + std::vector<BlastChunkNode*> res; + for (BlastAssetNode* node : _assets) + { + std::vector<BlastChunkNode*> nodes = getSupportChunkNodes(node); + res.insert(res.begin(), nodes.begin(), nodes.end()); + } + return res; +} + +const std::vector<BlastNode*>& _getAllChunkNodes(std::vector<BlastNode*>& res, BlastNode* curNode) +{ + if (nullptr == curNode) + return res; + if (eChunk == curNode->getType()) + { + res.push_back(static_cast<BlastNode*>(curNode)); + } + for (BlastNode* node : curNode->children) + { + _getAllChunkNodes(res, node); + } + + return res; +} + +std::vector<BlastChunkNode*> BlastTreeData::getSiblingChunkNodes(BlastChunkNode* node) +{ + std::vector<BlastChunkNode*> res; + + if (nullptr == node) + return res; + + BlastNode* parent = node->getParent(); + if (nullptr == parent || eChunk != parent->getType()) + { + return res; + } + + BlastChunkNode* chunkNodeParent = static_cast<BlastChunkNode*>(parent); + + for (BlastNode* child : chunkNodeParent->children) + { + if (eChunk == child->getType() && child != node) + res.push_back(static_cast<BlastChunkNode*>(child)); + } + return res; +} + +BlastChunkNode* BlastTreeData::getSupportAncestor(BlastChunkNode* node) +{ + if (nullptr == node) + return nullptr; + + BlastNode* parent = node->getParent(); + while (parent && eChunk == parent->getType()) + { + BlastChunkNode* chunkNodeParent = static_cast<BlastChunkNode*>(parent); + BPPChunk* bppChunk = (BPPChunk*)(chunkNodeParent->getData()); + if (bppChunk->support) + return chunkNodeParent; + parent = chunkNodeParent->getParent(); + } + + return nullptr; +} + +const std::vector<BlastNode*>& BlastTreeData::getAllChunkNodes(std::vector<BlastNode*>& res, BlastAssetNode* node) +{ + return _getAllChunkNodes(res, node); +} + +const std::vector<BlastNode*>& BlastTreeData::getAllChunkNodes(std::vector<BlastNode*>& res) +{ + for (BlastAssetNode* node : _assets) + { + getAllChunkNodes(res, node); + } + return res; +} + +const std::vector<BlastNode*>& _getAllLeavesChunkNodes(std::vector<BlastNode*>& res, BlastNode* curNode) +{ + if (nullptr == curNode) + return res; + if (eChunk == curNode->getType()) + { + if (BlastTreeData::isLeaf(dynamic_cast<BlastChunkNode*>(curNode))) + res.push_back(curNode); + } + for (BlastNode* node : curNode->children) + { + _getAllLeavesChunkNodes(res, node); + } + + return res; +} + +const std::vector<BlastNode*>& BlastTreeData::getAllLeavesChunkNodes(std::vector<BlastNode*>& res, BlastAssetNode* node) +{ + return _getAllLeavesChunkNodes(res, node); +} + +const std::vector<BlastNode*>& BlastTreeData::getAllLeavesChunkNodes(std::vector<BlastNode*>& res) +{ + for (BlastAssetNode* node : _assets) + { + getAllLeavesChunkNodes(res, node); + } + return res; +} + +// start from -1 because asset also takes one level. +const std::vector<BlastNode*>& _getChunkNodesFullCoverage(std::vector<BlastNode*>& res, BlastNode* curNode, int depth, int currDepth = -1) +{ + if (nullptr == curNode) + return res; + if (eChunk == curNode->getType()) + { + if((currDepth == depth) || ((currDepth < depth) && BlastTreeData::isLeaf(dynamic_cast<BlastChunkNode*>(curNode)))) + res.push_back(curNode); + } + if (currDepth < depth) + { + for (BlastNode* node : curNode->children) + { + _getChunkNodesFullCoverage(res, node, depth, currDepth + 1); + } + } + + return res; +} + +const std::vector<BlastNode*>& BlastTreeData::getChunkNodesFullCoverage(std::vector<BlastNode*>& res, BlastAssetNode* node, int depth) +{ + return _getChunkNodesFullCoverage(res, node, depth); +} + +const std::vector<BlastNode*>& BlastTreeData::getChunkNodesFullCoverage(std::vector<BlastNode*>& res, int depth) +{ + for (BlastAssetNode* node : _assets) + { + getChunkNodesFullCoverage(res, node, depth); + } + return res; +} + bool isCompleteSupport(BlastChunkNode* node) { if (node == nullptr) @@ -894,36 +1147,83 @@ bool BlastTreeData::isOverlapSupportAsset(const BlastAssetNode* node) return false; } +void BlastTreeData::traverse(BlastVisitorBase& visitor) +{ + for (BlastAssetNode* assetNode : _assets) + { + if (!visitor.continueTraversing()) + break; + + assetNode->traverse(visitor); + } +} + BlastTreeData::BlastTreeData() { + _assetInstancesNode = new BlastAssetInstancesNode("BlastAssetInstances"); + _blastProjectDataToNodeMap.clear(); } -void BlastTreeData::_addChunkNode(const BPPChunk& parentData, BPPAsset& asset, BlastChunkNode* parentNode, void* assetPtr) +void BlastTreeData::_addChunkNode(BPPChunk& parentData, BPPAsset& asset, BlastChunkNode* parentNode, void* assetPtr) { - if (parentNode != nullptr) + if (parentNode == nullptr) { - std::vector<BPPBond*> bonds = BlastProject::ins().getBondsByChunk(asset, parentData.ID); - for (size_t i = 0; i < bonds.size(); ++i) + return; + } + + std::vector<BPPBond*> bonds = BlastProject::ins().getBondsByChunk(asset, parentData.ID); + for (size_t i = 0; i < bonds.size(); ++i) + { + BPPBond* bond = bonds[i]; + BlastBondNode* bondNode = new BlastBondNode(bond->name.buf, *bond); + parentNode->children.push_back(bondNode); + bondNode->setParent(parentNode); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)bond, bondNode)); + } + + std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset, parentData.ID); + for (size_t i = 0; i < childChunks.size(); ++i) + { + BPPChunk& chunk = *(childChunks[i]); + BlastChunkNode* chunkNode = new BlastChunkNode(chunk.name.buf, chunk, assetPtr); + parentNode->children.push_back(chunkNode); + chunkNode->setParent(parentNode); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&chunk, chunkNode)); + _addChunkNode(chunk, asset, chunkNode, assetPtr); + } +} + +void BlastTreeData::_removeChunkNode(BPPAsset& asset) +{ + std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset); + int childChunksSize = childChunks.size(); + for (size_t i = 0; i < childChunksSize; i++) + { + std::map<void*, BlastNode*>::iterator it = _blastProjectDataToNodeMap.find(childChunks[i]); + if (it == _blastProjectDataToNodeMap.end()) { - BPPBond* bond = bonds[i]; - BlastBondNode* bondNode = new BlastBondNode(bond->name.buf, *bond); - parentNode->children.push_back(bondNode); - bondNode->setParent(parentNode); - _blastProjectDataToNodeMap.insert(std::make_pair((void*)bond, bondNode)); + continue; } - std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset, parentData.ID); + BlastNode* node = it->second; + _blastProjectDataToNodeMap.erase(it); + delete node; + } - for (size_t i = 0; i < childChunks.size(); ++i) + std::vector<BPPBond*> childBonds = BlastProject::ins().getChildrenBonds(asset); + int childBondsSize = childBonds.size(); + for (size_t i = 0; i < childBondsSize; i++) + { + std::map<void*, BlastNode*>::iterator it = _blastProjectDataToNodeMap.find(childBonds[i]); + if (it == _blastProjectDataToNodeMap.end()) { - BPPChunk& chunk = *(childChunks[i]); - BlastChunkNode* chunkNode = new BlastChunkNode(chunk.name.buf, chunk, assetPtr); - parentNode->children.push_back(chunkNode); - chunkNode->setParent(parentNode); - _blastProjectDataToNodeMap.insert(std::make_pair((void*)&chunk, chunkNode)); - _addChunkNode(chunk, asset, chunkNode, assetPtr); + continue; } + + BlastNode* node = it->second; + _blastProjectDataToNodeMap.erase(it); + delete node; } } @@ -951,15 +1251,15 @@ void freeChunkNode(BlastChunkNode* chunkNode) void BlastTreeData::_freeBlastNode() { - if (_composite) + if (_assetInstancesNode) { - size_t count = _composite->children.size(); + size_t count = _assetInstancesNode->children.size(); for (size_t i = 0; i < count; ++i) { - delete _composite->children[i]; + delete _assetInstancesNode->children[i]; } - delete _composite; - _composite = nullptr; + delete _assetInstancesNode; + _assetInstancesNode = nullptr; } size_t count = _assets.size(); @@ -1009,76 +1309,78 @@ BlastAssetNode* BlastTreeData::_getAssetNode(const BlastAsset* asset) return foundAssetNode; } -VisualButton::VisualButton(QWidget* parent, BlastNode* blastItem) - : QWidget(parent) - , _button(new QPushButton(parent)) - , _blastItem(blastItem) +QRect _getVisualIconArea(const QStyleOptionViewItem &option) { - connect(_button, SIGNAL(toggled(bool)), this, SLOT(on_visualbility_toggled(bool))); - _button->setCheckable(true); - _button->setChecked(blastItem->getVisible()); - if (blastItem->getVisible()) - _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_visible.png")); - else - _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_notVisible.png")); - _button->setFixedSize(20, 20); - this->setLayoutDirection(Qt::RightToLeft); - this->setLayout(new QHBoxLayout); - this->layout()->setMargin(0); - this->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); - this->layout()->addWidget(_button); + int iconLen = option.rect.height() - 2; + return QRect(option.rect.right() - iconLen, option.rect.top() + 1, iconLen, iconLen); } -void VisualButton::on_visualbility_toggled(bool checked) +BlastTreeViewDelegate::BlastTreeViewDelegate(QObject* parent, QStandardItemModel* model) + : QStyledItemDelegate(parent) + , _treeModel(model) { - if (checked) - { - _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_visible.png")); - } - else - { - _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_notVisible.png")); - } - - if (_blastItem) - { - _blastItem->setVisible(checked); - } + setObjectName("BlastTreeViewDelegate"); } -void VisualButton::_updateBlast(bool visible) +void BlastTreeViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - EBlastNodeType type = _blastItem->getType(); + QStyledItemDelegate::paint(painter, option, index); + + QStandardItem *treeItem = _treeModel->itemFromIndex(index); + BlastSceneTree* tree = BlastSceneTree::ins(); + BlastNode* blastNode = tree->getBlastNodeByItem(treeItem); + PhysXSceneActor* projectileActor = tree->getProjectileActorByItem(treeItem); - switch (type) + if ((nullptr == blastNode && nullptr == projectileActor)) + return; + + if(nullptr != blastNode && eChunk != blastNode->getType() && eBond != blastNode->getType()) + return; + + if (nullptr != blastNode) + painter->drawPixmap(_getVisualIconArea(option), blastNode->getVisible() ? sVisibleIcon : sInVisibleIcon); + else if (nullptr != projectileActor) + painter->drawPixmap(_getVisualIconArea(option), SampleManager::ins()->getSceneController().getProjectileVisible(projectileActor) ? sVisibleIcon : sInVisibleIcon); +} + +bool BlastTreeViewDelegate::editorEvent(QEvent* evt, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) +{ + if (evt->type() == QEvent::MouseButtonRelease) { - case eBond: - ((BPPBond*)_blastItem->getData())->visible = visible; - break; - case eChunk: - ((BPPChunk*)_blastItem->getData())->visible = visible; - break; - case eAsset: - ((BPPAsset*)_blastItem->getData())->visible = visible; - break; - case eProjectile: - ((BPPBond*)_blastItem->getData())->visible = visible; - break; - case eGraphicsMesh: - ((BPPGraphicsMesh*)_blastItem->getData())->visible = visible; - break; - case eAssetInstance: - ((BPPAssetInstance*)_blastItem->getData())->visible = visible; - break; - case eLandmark: - ((BPPLandmark*)_blastItem->getData())->visible = visible; - break; - case eComposite: - ((BPPComposite*)_blastItem->getData())->visible = visible; - break; - default: - break; + QMouseEvent* mouseEvt = (QMouseEvent*)evt; + if (_getVisualIconArea(option).contains(mouseEvt->pos())) + { + QStandardItem *treeItem = _treeModel->itemFromIndex(index); + BlastSceneTree* tree = BlastSceneTree::ins(); + BlastNode* blastNode = tree->getBlastNodeByItem(treeItem); + PhysXSceneActor* projectileActor = tree->getProjectileActorByItem(treeItem); + + if ((nullptr == blastNode && nullptr == projectileActor)) + return QStyledItemDelegate::editorEvent(evt, model, option, index); + + if (nullptr != blastNode && eChunk != blastNode->getType() && eBond != blastNode->getType()) + return QStyledItemDelegate::editorEvent(evt, model, option, index); + + if (nullptr != blastNode) + { + blastNode->setVisible(!blastNode->getVisible()); + } + else if (nullptr != projectileActor) + { + SceneController& sceneController = SampleManager::ins()->getSceneController(); + sceneController.setProjectileVisible(projectileActor, !sceneController.getProjectileVisible(projectileActor)); + } + + BlastSceneTree::ins()->update(); + return true; + } } + return QStyledItemDelegate::editorEvent(evt, model, option, index); +} + +bool BlastTreeViewDelegate::eventFilter(QObject* object, QEvent* event) +{ + return true; } static BlastSceneTree* sBlastSceneTree = nullptr; @@ -1094,37 +1396,74 @@ BlastSceneTree::BlastSceneTree(QWidget *parent) _updateData = true; sBlastSceneTree = this; - ui.blastSceneTree->setStyleSheet("QTreeWidget::item{height:24px}"); - ui.blastSceneTree->setColumnWidth(0, 260); - ui.blastSceneTree->setColumnWidth(1, 20); + sCompositeIcon = QIcon(":/AppMainWindow/images/AssetComposite.png"); + sAssetIcon = QIcon(":/AppMainWindow/images/Asset.png"); + sChunkUUIcon = QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png"); + sChunkSUIcon = QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png"); + sChunkSSIcon = QIcon(":/AppMainWindow/images/Chunk_Support_Static.png"); + sBondIcon = QIcon(":/AppMainWindow/images/Bond.png"); + sProjectileIcon = QIcon(":/AppMainWindow/images/Projectile.png"); + _treeModel = new QStandardItemModel(); + ui.blastSceneTree->setModel(_treeModel); + QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel(); + connect(selectionModel, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(on_blastSceneTree_itemSelectionChanged(const QItemSelection&, const QItemSelection&))); + + BlastTreeViewDelegate* itemDelegate = new BlastTreeViewDelegate(ui.blastSceneTree, _treeModel); + ui.blastSceneTree->setItemDelegate((QAbstractItemDelegate*)itemDelegate); + + ui.blastSceneTree->setStyleSheet("QTreeView::item{height:24px}"); ui.blastSceneTree->setContextMenuPolicy(Qt::CustomContextMenu); - _treeChunkContextMenu = new QMenu(this); + _treeContextMenu = new QMenu(this); _makeSupportAction = new QAction(tr("Make Support"), this); - _treeChunkContextMenu->addAction(_makeSupportAction); + _treeContextMenu->addAction(_makeSupportAction); connect(_makeSupportAction, SIGNAL(triggered()), this, SLOT(onMakeSupportMenuItemClicked())); _makeStaticSupportAction = new QAction(tr("Make Static Support"), this); - _treeChunkContextMenu->addAction(_makeStaticSupportAction); + _treeContextMenu->addAction(_makeStaticSupportAction); connect(_makeStaticSupportAction, SIGNAL(triggered()), this, SLOT(onMakeStaticSupportMenuItemClicked())); _removeSupportAction = new QAction(tr("Remove Support"), this); - _treeChunkContextMenu->addAction(_removeSupportAction); + _treeContextMenu->addAction(_removeSupportAction); connect(_removeSupportAction, SIGNAL(triggered()), this, SLOT(onRemoveSupportMenuItemClicked())); - _treeBondContextMenu = new QMenu(this); - _bondChunksAction = new QAction(tr("Bond Chunks"), this); - _treeBondContextMenu->addAction(_bondChunksAction); - connect(_bondChunksAction, SIGNAL(triggered()), this, SLOT(onBondChunksMenuItemClicked())); + _makeWorldAction = new QAction(tr("Make World"), this); + _treeContextMenu->addAction(_makeWorldAction); + connect(_makeWorldAction, SIGNAL(triggered()), this, SLOT(onMakeWorldMenuItemClicked())); + + _removeWorldAction = new QAction(tr("Remove World"), this); + _treeContextMenu->addAction(_removeWorldAction); + connect(_removeWorldAction, SIGNAL(triggered()), this, SLOT(onRemoveWorldMenuItemClicked())); + + //_bondChunksAction = new QAction(tr("Bond Chunks"), this); + //_treeContextMenu->addAction(_bondChunksAction); + //connect(_bondChunksAction, SIGNAL(triggered()), this, SLOT(onBondChunksMenuItemClicked())); + + + //_bondChunksWithJointsAction = new QAction(tr("Bond Chunks With Joints"), this); + //_treeContextMenu->addAction(_bondChunksWithJointsAction); + //connect(_bondChunksWithJointsAction, SIGNAL(triggered()), this, SLOT(onBondChunksWithJointsMenuItemClicked())); - _bondChunksWithJointsAction = new QAction(tr("Bond Chunks With Joints"), this); - _treeBondContextMenu->addAction(_bondChunksWithJointsAction); - connect(_bondChunksWithJointsAction, SIGNAL(triggered()), this, SLOT(onBondChunksWithJointsMenuItemClicked())); + //_removeAllBondsAction = new QAction(tr("Remove All Bonds"), this); + //_treeContextMenu->addAction(_removeAllBondsAction); + //connect(_removeAllBondsAction, SIGNAL(triggered()), this, SLOT(onRemoveAllBondsMenuItemClicked())); - _removeAllBondsAction = new QAction(tr("Remove All Bonds"), this); - _treeBondContextMenu->addAction(_removeAllBondsAction); - connect(_removeAllBondsAction, SIGNAL(triggered()), this, SLOT(onRemoveAllBondsMenuItemClicked())); + QShortcut* shortCut; + shortCut = new QShortcut(QKeySequence("Alt+C"), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(onCollapseExpandClicked())); + /* + BlastAssetInstancesNode* assetInstancesNode = BlastTreeData::ins().getBlastAssetInstancesNode(); + _compositeTreeItem = new QStandardItem(); + _treeModel->appendRow(_compositeTreeItem); + _compositeTreeItem->setText(assetInstancesNode->name.c_str()); + _compositeTreeItem->setIcon(sCompositeIcon); + _treeItemDataMap.insert(_compositeTreeItem, assetInstancesNode); + _treeDataItemMap.insert(assetInstancesNode, _compositeTreeItem); + */ + + m_pNewBlastAsset = nullptr; + m_NewChunkIndexes.clear(); } BlastSceneTree::~BlastSceneTree() @@ -1139,14 +1478,94 @@ void BlastSceneTree::updateValues(bool updataData) BlastTreeData::ins().update(); } + std::map<BPPAssetInstance*, std::set<uint32_t>> selectChunks; + + SelectionToolController* m_selectionToolController = &SampleManager::ins()->getSelectionToolController(); + GizmoToolController* m_gizmoToolController = &SampleManager::ins()->getGizmoToolController(); + BlastController* m_blastController = &SampleManager::ins()->getBlastController(); + + if (m_selectionToolController->IsEnabled()) + { + std::set<PxActor*> actors = m_selectionToolController->getTargetActors(); + for (PxActor* actor : actors) + { + BlastFamily* pBlastFamily = m_blastController->getFamilyByPxActor(*actor); + if (pBlastFamily) + { + BPPAssetInstance* assetInstance = SampleManager::ins()->getInstanceByFamily(pBlastFamily); + uint32_t chunkIndex = pBlastFamily->getChunkIndexByPxActor(*actor); + selectChunks[assetInstance].insert(chunkIndex); + } + } + } + else if (m_gizmoToolController->IsEnabled()) + { + PxActor* actor = m_gizmoToolController->getTargetActor(); + + if (actor) + { + BlastFamily* pBlastFamily = m_blastController->getFamilyByPxActor(*actor); + if (pBlastFamily) + { + BPPAssetInstance* assetInstance = SampleManager::ins()->getInstanceByFamily(pBlastFamily); + uint32_t chunkIndex = pBlastFamily->getChunkIndexByPxActor(*actor); + selectChunks[assetInstance].insert(chunkIndex); + } + } + } + _updateTreeUIs(); + + BlastSceneTreeDataLock lock; + std::set<PxActor*> actors; + for (std::map<BPPAssetInstance*, std::set<uint32_t>>::iterator itr = selectChunks.begin(); itr != selectChunks.end(); ++itr) + { + BlastFamily* family = SampleManager::ins()->getFamilyByInstance(itr->first); + std::set<uint32_t>& chunkIndexes = itr->second; + + if (nullptr != family) + { + for (uint32_t chunkIndex : chunkIndexes) + { + PxActor* actor = nullptr; + family->getPxActorByChunkIndex(chunkIndex, &actor); + + if (actor) + actors.insert(actor); + } + } + } + + if (m_selectionToolController->IsEnabled()) + { + m_selectionToolController->setTargetActors(actors); + } + else if (m_gizmoToolController->IsEnabled()) + { + if (actors.size() > 0) + m_gizmoToolController->setTargetActor(*actors.begin()); + } +} + +void BlastSceneTree::clear() +{ + _treeModel->clear(); + _treeItemDataMap.clear(); + _treeDataItemMap.clear(); + + // notify no selection + std::vector<BlastNode*> nodes; + for (size_t i = 0; i < _observers.size(); ++i) + { + _observers[i]->dataSelected(nodes); + } } void BlastSceneTree::dataSelected(std::vector<BlastNode*> selections) { for (size_t i = 0; i < selections.size(); ++i) { - _selectTreeItem(selections[i]); + selectTreeItem(selections[i]); } } @@ -1167,7 +1586,11 @@ void BlastSceneTree::removeObserver(ISceneObserver* observer) void BlastSceneTree::updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible) { - BlastTreeData::ins().updateVisible(assetIndex, chunkIndex, visible); + BlastNode* node = BlastTreeData::ins().getNodeByIndex(assetIndex, chunkIndex); + if (node != nullptr && eChunk == node->getType()) + { + static_cast<BlastChunkNode*>(node)->setVisible(visible); + } } void BlastSceneTree::updateChunkItemSelection() @@ -1188,7 +1611,7 @@ void BlastSceneTree::updateChunkItemSelection() for (BlastChunkNode* node : chunkNodes) { - _selectTreeItem(node); + selectTreeItem(node, false); } _updateData = true; @@ -1197,10 +1620,11 @@ void BlastSceneTree::updateChunkItemSelection() void BlastSceneTree::makeSupport() { std::vector<BlastChunkNode*> selectedChunkNodes; - QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); - for (int i = 0; i < selectedItems.size(); ++i) + QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel(); + QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); + for (int i = 0; i < selectedIndexes.count(); ++i) { - QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i))); if (eChunk == itr.value()->getType()) { @@ -1209,22 +1633,36 @@ void BlastSceneTree::makeSupport() } std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes); - for (size_t i = 0; i < topChunkNodes.size(); ++i) + std::set<BlastAsset*> assets; + for (BlastChunkNode* chunkNode : topChunkNodes) { - BlastChunkNode* chunkNode = topChunkNodes[i]; + if (chunkNode->isSupport() && !((BPPChunk*)chunkNode->getData())->staticFlag) + continue; BlastTreeData::makeSupport(chunkNode); + BlastAsset* pBlastAsset = BlastTreeData::ins().getAsset(chunkNode); + assets.insert(pBlastAsset); } - _updateChunkTreeItems(); + if (0 == assets.size()) + return; + + SampleManager* pSampleManager = SampleManager::ins(); + for (BlastAsset* asset : assets) + { + pSampleManager->refreshAsset(asset); + } + + return; } void BlastSceneTree::makeStaticSupport() { std::vector<BlastChunkNode*> selectedChunkNodes; - QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); - for (int i = 0; i < selectedItems.size(); ++i) + QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel(); + QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); + for (int i = 0; i < selectedIndexes.count(); ++i) { - QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i))); if (eChunk == itr.value()->getType()) { @@ -1233,22 +1671,36 @@ void BlastSceneTree::makeStaticSupport() } std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes); - for (size_t i = 0; i < topChunkNodes.size(); ++i) + std::set<BlastAsset*> assets; + for (BlastChunkNode* chunkNode : topChunkNodes) { - BlastChunkNode* chunkNode = topChunkNodes[i]; + if (chunkNode->isSupport() && ((BPPChunk*)chunkNode->getData())->staticFlag) + continue; BlastTreeData::makeStaticSupport(chunkNode); + BlastAsset* pBlastAsset = BlastTreeData::ins().getAsset(chunkNode); + assets.insert(pBlastAsset); } - _updateChunkTreeItems(); + if (0 == assets.size()) + return; + + SampleManager* pSampleManager = SampleManager::ins(); + for (BlastAsset* asset : assets) + { + pSampleManager->refreshAsset(asset); + } + + return; } void BlastSceneTree::removeSupport() { std::vector<BlastChunkNode*> selectedChunkNodes; - QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); - for (int i = 0; i < selectedItems.size(); ++i) + QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel(); + QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); + for (int i = 0; i < selectedIndexes.count(); ++i) { - QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i))); if (eChunk == itr.value()->getType()) { @@ -1257,13 +1709,110 @@ void BlastSceneTree::removeSupport() } std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes); - for (size_t i = 0; i < topChunkNodes.size(); ++i) + std::set<BlastAsset*> assets; + for (BlastChunkNode* chunkNode : topChunkNodes) { - BlastChunkNode* chunkNode = topChunkNodes[i]; + if (!chunkNode->isSupport() || BlastTreeData::isLeaf(chunkNode)) + continue; BlastTreeData::removeSupport(chunkNode); + BlastAsset* pBlastAsset = BlastTreeData::ins().getAsset(chunkNode); + assets.insert(pBlastAsset); + } + + if (0 == assets.size()) + return; + + SampleManager* pSampleManager = SampleManager::ins(); + for (BlastAsset* asset : assets) + { + pSampleManager->refreshAsset(asset); + } + + return; +} + +void BlastSceneTree::makeWorld() +{ + std::vector<BlastBondNode*> selectedBondNodes; + QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel(); + QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); + for (int i = 0; i < selectedIndexes.count(); ++i) + { + QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i))); + + if (eBond == itr.value()->getType()) + { + selectedBondNodes.push_back((BlastBondNode*)itr.value()); + } + } + if (selectedBondNodes.size() == 0) + { + return; + } + + std::vector<BlastBondNode*>::iterator itSBN; + std::map<BlastAsset*, BlastAsset*> UniqueAssets; + for (itSBN = selectedBondNodes.begin(); itSBN != selectedBondNodes.end(); itSBN++) + { + BlastBondNode* node = *itSBN; + + BPPBond* bond = static_cast<BPPBond*>(node->getData()); + bond->toChunk = 0xFFFFFFFF; + + BlastAsset* pBlastAsset = BlastTreeData::ins().getAsset(node); + UniqueAssets[pBlastAsset] = pBlastAsset; + } + + + SampleManager* pSampleManager = SampleManager::ins(); + std::map<BlastAsset*, BlastAsset*>::iterator itUA; + for (itUA = UniqueAssets.begin(); itUA != UniqueAssets.end(); itUA++) + { + BlastAsset* pBlastAsset = itUA->second; + pSampleManager->refreshAsset(pBlastAsset); + } +} + +void BlastSceneTree::removeWorld() +{ + std::vector<BlastBondNode*> selectedBondNodes; + QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel(); + QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); + for (int i = 0; i < selectedIndexes.count(); ++i) + { + QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i))); + + if (eBond == itr.value()->getType()) + { + selectedBondNodes.push_back((BlastBondNode*)itr.value()); + } } + if (selectedBondNodes.size() == 0) + { + return; + } + + std::vector<BlastBondNode*>::iterator itSBN; + std::map<BlastAsset*, BlastAsset*> UniqueAssets; + for (itSBN = selectedBondNodes.begin(); itSBN != selectedBondNodes.end(); itSBN++) + { + BlastBondNode* node = *itSBN; - _updateChunkTreeItems(); + BPPBond* bond = static_cast<BPPBond*>(node->getData()); + bond->toChunk = 0xFFFFFFFF - 1; + + BlastAsset* pBlastAsset = BlastTreeData::ins().getAsset(node); + UniqueAssets[pBlastAsset] = pBlastAsset; + } + + + SampleManager* pSampleManager = SampleManager::ins(); + std::map<BlastAsset*, BlastAsset*>::iterator itUA; + for (itUA = UniqueAssets.begin(); itUA != UniqueAssets.end(); itUA++) + { + BlastAsset* pBlastAsset = itUA->second; + pSampleManager->refreshAsset(pBlastAsset); + } } void BlastSceneTree::bondChunks() @@ -1281,84 +1830,210 @@ void BlastSceneTree::removeAllBonds() } +void BlastSceneTree::setChunkSelected(std::vector<uint32_t> depths, bool selected) +{ + std::vector<BlastNode*> nodes = BlastTreeData::ins().getNodesByDepth(depths); + for (BlastNode* node : nodes) + { + if (eChunk == node->getType()) + { + static_cast<BlastChunkNode*>(node)->setSelected(selected); + selectTreeItem(node); + } + } +} + +void BlastSceneTree::setChunkVisible(std::vector<uint32_t> depths, bool bVisible) +{ + std::vector<BlastNode*> nodes = BlastTreeData::ins().getNodesByDepth(depths); + for (BlastNode* node : nodes) + { + if (eChunk == node->getType()) + { + static_cast<BlastChunkNode*>(node)->setVisible(bVisible); + } + } +} + +void BlastSceneTree::hideAllChunks() +{ + std::vector<BlastNode*> nodes; + BlastTreeData::ins().getAllChunkNodes(nodes); + for (BlastNode* node : nodes) + { + if (eChunk == node->getType()) + { + static_cast<BlastChunkNode*>(node)->setVisible(false); + } + } +} + +void BlastSceneTree::setChunkVisibleFullCoverage(int depth) +{ + std::vector<BlastNode*> nodes; + BlastTreeData::ins().getChunkNodesFullCoverage(nodes, depth); + for (BlastNode* node : nodes) + { + if (eChunk == node->getType()) + { + static_cast<BlastChunkNode*>(node)->setVisible(true); + } + } +} + void BlastSceneTree::on_btnAsset_clicked() { - QMessageBox::information(NULL, "test", "on_btnAsset_clicked"); + QMessageBox::information(NULL, "Blast Tool", "This feature isn't implemented currently!"); } void BlastSceneTree::on_assetComposite_clicked() { - QMessageBox::information(NULL, "test", "on_assetComposite_clicked"); + QMessageBox::information(NULL, "Blast Tool", "This feature isn't implemented currently!"); } void BlastSceneTree::on_btnChunk_clicked() { - QMessageBox::information(NULL, "test", "on_btnChunk_clicked"); + QMessageBox::information(NULL, "Blast Tool", "This feature isn't implemented currently!"); } void BlastSceneTree::on_btnBond_clicked() { - QMessageBox::information(NULL, "test", "on_btnBond_clicked"); + QMessageBox::information(NULL, "Blast Tool", "This feature isn't implemented currently!"); } void BlastSceneTree::on_btnProjectile_clicked() { - QMessageBox::information(NULL, "test", "on_btnProjectile_clicked"); + QMessageBox::information(NULL, "Blast Tool", "This feature isn't implemented currently!"); +} + +void BlastSceneTree::on_btnExpandCollapse_clicked() +{ + onCollapseExpandClicked(); } void BlastSceneTree::on_blastSceneTree_customContextMenuRequested(const QPoint &pos) { - QList<QTreeWidgetItem*> items = ui.blastSceneTree->selectedItems(); + QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel(); + QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); - if (items.count() == 1) + std::vector<BlastChunkNode*> chunkNodes; + std::vector<BlastBondNode*> bondNodes; + for (int i = 0; i < selectedIndexes.count(); ++i) { - QTreeWidgetItem* curItem = items.at(0); - - QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(curItem); + QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i))); if (itr != _treeItemDataMap.end()) { - if (eChunk == itr.value()->getType() || eBond == itr.value()->getType()) + if (eChunk == itr.value()->getType()) { - _treeChunkContextMenu->exec(QCursor::pos()); + chunkNodes.push_back((BlastChunkNode*)itr.value()); + } + else if (eBond == itr.value()->getType()) + { + bondNodes.push_back((BlastBondNode*)itr.value()); } } } - else if (items.count() > 1) + { - bool allSupportChunk = true; - for (int i = 0; i < items.count(); ++i) + std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(chunkNodes); + _makeSupportAction->setEnabled(true); + _makeStaticSupportAction->setEnabled(true); + _removeSupportAction->setEnabled(true); + _makeWorldAction->setEnabled(true); + _removeWorldAction->setEnabled(true); + + //select chunk nodes have parent child relation ship, disable all menu items + if (topChunkNodes.size() < chunkNodes.size()) + { + _makeSupportAction->setEnabled(false); + _makeStaticSupportAction->setEnabled(false); + _removeSupportAction->setEnabled(false); + } + else { - QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(items.at(i)); - if (itr != _treeItemDataMap.end()) + bool allSupported = true, allStaticSupport = true, allUnSupported = true, hasLeaf = false; + + for (BlastChunkNode* chunkNode : chunkNodes) { - if (eChunk != itr.value()->getType()) + BPPChunk* chunk = (BPPChunk*)(chunkNode->getData()); + if (chunk->support) + { + allUnSupported = false; + } + else { - allSupportChunk = false; - break; + allSupported = false; + } + + if (!chunk->staticFlag) + { + allStaticSupport = false; + } + + if (BlastTreeData::isLeaf(chunkNode)) + { + hasLeaf = true; } } - } - if (allSupportChunk) - { - _treeBondContextMenu->exec(QCursor::pos()); + if (allSupported && !allStaticSupport) + { + _makeSupportAction->setEnabled(false); + } + + if (allStaticSupport) + { + _makeStaticSupportAction->setEnabled(false); + } + + if (allUnSupported || hasLeaf) + { + _removeSupportAction->setEnabled(false); + } } } + if (chunkNodes.size() > 0 && bondNodes.size() > 0) + { + _makeSupportAction->setEnabled(false); + _makeStaticSupportAction->setEnabled(false); + _removeSupportAction->setEnabled(false); + _makeWorldAction->setEnabled(false); + _removeWorldAction->setEnabled(false); + } + else if (chunkNodes.size() > 0 && bondNodes.size() == 0) + { + _makeWorldAction->setEnabled(false); + _removeWorldAction->setEnabled(false); + } + else if (chunkNodes.size() == 0 && bondNodes.size() > 0) + { + _makeSupportAction->setEnabled(false); + _makeStaticSupportAction->setEnabled(false); + _removeSupportAction->setEnabled(false); + } + + if (0 < chunkNodes.size() || 0 < bondNodes.size()) + { + _treeContextMenu->exec(QCursor::pos()); + } + } -void BlastSceneTree::on_blastSceneTree_itemSelectionChanged() +void BlastSceneTree::on_blastSceneTree_itemSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { if (!_updateData) return; SampleManager::ins()->clearChunksSelected(); - QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); + QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel(); + QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); + std::vector<BlastNode*> nodes; - for (int i = 0; i < selectedItems.count(); ++i) + for (int i = 0; i < selectedIndexes.count(); ++i) { - QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i))); if (itr != _treeItemDataMap.end()) { nodes.push_back(itr.value()); @@ -1367,10 +2042,32 @@ void BlastSceneTree::on_blastSceneTree_itemSelectionChanged() if (eChunk == node->getType()) { ((BlastChunkNode*)node)->setSelected(true); + + if (BlastTreeData::isRoot((BlastChunkNode*)node)) + { + std::vector<BlastAssetInstanceNode*> instanceNodes = BlastTreeData::ins().getAssetInstanceNodes((BlastChunkNode*)node); + for (BlastAssetInstanceNode* instanceNode : instanceNodes) + { + selectTreeItem(instanceNode, false); + nodes.push_back(instanceNode); + } + } } else if (eAssetInstance == node->getType()) { ((BlastAssetInstanceNode*)node)->setSelected(true); + + BlastSceneTreeDataLock lock; + std::vector<BlastChunkNode*> chunkNodes = BlastTreeData::ins().getRootChunkNodeByInstance((BlastAssetInstanceNode*)node); + for (BlastChunkNode* chunkNode : chunkNodes) + { + selectTreeItem(chunkNode, false); + nodes.push_back(chunkNode); + } + } + else if (eAsset == node->getType()) + { + ((BlastAssetNode*)node)->setSelected(true); } } } @@ -1396,6 +2093,16 @@ void BlastSceneTree::onRemoveSupportMenuItemClicked() removeSupport(); } +void BlastSceneTree::onMakeWorldMenuItemClicked() +{ + makeWorld(); +} + +void BlastSceneTree::onRemoveWorldMenuItemClicked() +{ + removeWorld(); +} + void BlastSceneTree::onBondChunksMenuItemClicked() { bondChunks(); @@ -1411,35 +2118,54 @@ void BlastSceneTree::onRemoveAllBondsMenuItemClicked() removeAllBonds(); } +void BlastSceneTree::onCollapseExpandClicked() +{ + static bool expand = true; + if (expand) + { + ui.blastSceneTree->collapseAll(); + expand = false; + } + else + { + ui.blastSceneTree->expandAll(); + expand = true; + } +} + void BlastSceneTree::_updateTreeUIs() { - ui.blastSceneTree->clear(); +#ifdef _DEBUG + static int gcounter = 0; + static char gbuf[128]; + sprintf(gbuf, "_updateTreeUIs called %d", ++gcounter); + viewer_msg(gbuf); +#endif + //ui.blastSceneTree->setUpdatesEnabled(false); + _treeModel->clear(); _treeItemDataMap.clear(); _treeDataItemMap.clear(); - BlastCompositeNode* compositeNode = BlastTreeData::ins().getCompsiteNode(); - if (compositeNode != nullptr) + BlastAssetInstancesNode* assetInstancesNode = BlastTreeData::ins().getBlastAssetInstancesNode(); + if (assetInstancesNode != nullptr) { - QTreeWidgetItem* compositeTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree); - compositeTreeWidgetItem->setText(0, compositeNode->name.c_str()); - compositeTreeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/AssetComposite.png")); - VisualButton* btn = new VisualButton(this, compositeNode); - ui.blastSceneTree->setItemWidget(compositeTreeWidgetItem, 1, btn); - _treeItemDataMap.insert(compositeTreeWidgetItem, compositeNode); - _treeDataItemMap.insert(compositeNode, compositeTreeWidgetItem); - - size_t count = compositeNode->children.size(); + QStandardItem* compositeTreeItem = new QStandardItem(); + compositeTreeItem->setText(assetInstancesNode->name.c_str()); + compositeTreeItem->setIcon(sCompositeIcon); + _treeItemDataMap.insert(compositeTreeItem, assetInstancesNode); + _treeDataItemMap.insert(assetInstancesNode, compositeTreeItem); + _treeModel->appendRow(compositeTreeItem); + size_t count = assetInstancesNode->children.size(); for (size_t i = 0; i < count; ++i) { - BlastNode* assetInstanceNode = compositeNode->children[i]; - QTreeWidgetItem* assetInstanceWidgetItem = new QTreeWidgetItem(compositeTreeWidgetItem); - assetInstanceWidgetItem->setText(0, assetInstanceNode->name.c_str()); + BlastNode* assetInstanceNode = assetInstancesNode->children[i]; + QStandardItem* assetInstanceItem = new QStandardItem(); + compositeTreeItem->appendRow(assetInstanceItem); + assetInstanceItem->setText(assetInstanceNode->name.c_str()); if (assetInstanceNode->getType() == eAssetInstance) - assetInstanceWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Asset.png")); - VisualButton* btn = new VisualButton(this, assetInstanceNode); - ui.blastSceneTree->setItemWidget(assetInstanceWidgetItem, 1, btn); - _treeItemDataMap.insert(assetInstanceWidgetItem, assetInstanceNode); - _treeDataItemMap.insert(assetInstanceNode, assetInstanceWidgetItem); + assetInstanceItem->setIcon(QIcon(":/AppMainWindow/images/Asset.png")); + _treeItemDataMap.insert(assetInstanceItem, assetInstanceNode); + _treeDataItemMap.insert(assetInstanceNode, assetInstanceItem); } } @@ -1449,11 +2175,10 @@ void BlastSceneTree::_updateTreeUIs() { BlastAssetNode* assetNode = assets[i]; - QTreeWidgetItem* assetTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree); - assetTreeWidgetItem->setText(0, assetNode->name.c_str()); - assetTreeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Asset.png")); - VisualButton* btn = new VisualButton(this, assetNode); - ui.blastSceneTree->setItemWidget(assetTreeWidgetItem, 1, btn); + QStandardItem* assetTreeWidgetItem = new QStandardItem(); + _treeModel->appendRow(assetTreeWidgetItem); + assetTreeWidgetItem->setText(assetNode->name.c_str()); + assetTreeWidgetItem->setIcon(sAssetIcon); _treeItemDataMap.insert(assetTreeWidgetItem, assetNode); _treeDataItemMap.insert(assetNode, assetTreeWidgetItem); @@ -1466,13 +2191,12 @@ void BlastSceneTree::_updateTreeUIs() { BlastProjectileNode* projectileNode = projectiles[i]; - QTreeWidgetItem* projectileTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree); - projectileTreeWidgetItem->setText(0, projectileNode->name.c_str()); - projectileTreeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Projectile.png")); - VisualButton* btn = new VisualButton(this, projectileNode); - ui.blastSceneTree->setItemWidget(projectileTreeWidgetItem, 1, btn); - _treeItemDataMap.insert(projectileTreeWidgetItem, projectileNode); - _treeDataItemMap.insert(projectileNode, projectileTreeWidgetItem); + QStandardItem* projectileTreeItem = new QStandardItem(); + _treeModel->appendRow(projectileTreeItem); + projectileTreeItem->setText(projectileNode->name.c_str()); + projectileTreeItem->setIcon(sProjectileIcon); + _treeItemDataMap.insert(projectileTreeItem, projectileNode); + _treeDataItemMap.insert(projectileNode, projectileTreeItem); } std::vector<BlastGraphicsMeshNode*>& graphicsMeshes = BlastTreeData::ins().getGraphicsMeshNodes(); @@ -1481,23 +2205,52 @@ void BlastSceneTree::_updateTreeUIs() { BlastGraphicsMeshNode* graphicsMesheNode = graphicsMeshes[i]; - QTreeWidgetItem* graphicsMesheTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree); - graphicsMesheTreeWidgetItem->setText(0, graphicsMesheNode->name.c_str()); - VisualButton* btn = new VisualButton(this, graphicsMesheNode); - ui.blastSceneTree->setItemWidget(graphicsMesheTreeWidgetItem, 1, btn); + QStandardItem* graphicsMesheTreeWidgetItem = new QStandardItem(); + _treeModel->appendRow(graphicsMesheTreeWidgetItem); + graphicsMesheTreeWidgetItem->setText(graphicsMesheNode->name.c_str()); _treeItemDataMap.insert(graphicsMesheTreeWidgetItem, graphicsMesheNode); _treeDataItemMap.insert(graphicsMesheNode, graphicsMesheTreeWidgetItem); } - //for (int j = 0; j < ui.blastSceneTree->topLevelItemCount(); ++j) + ui.blastSceneTree->expandAll(); + + // notify no selection + //std::vector<BlastNode*> nodes; + //for (size_t i = 0; i < _observers.size(); ++i) //{ - // QTreeWidgetItem* topLevelItem = ui.blastSceneTree->topLevelItem(j); - // ui.blastSceneTree->expandItem(topLevelItem); + // _observers[i]->dataSelected(nodes); //} - ui.blastSceneTree->expandAll(); + + bool autoSelectNewChunks = BlastProject::ins().getParams().fracture.general.autoSelectNewChunks; + if (!autoSelectNewChunks) + { + m_pNewBlastAsset = nullptr; + m_NewChunkIndexes.clear(); + return; + } + + if (m_pNewBlastAsset == nullptr || m_NewChunkIndexes.size() == 0) + { + return; + } + + _updateData = false; + ui.blastSceneTree->clearSelection(); + std::vector<BlastChunkNode*> chunkNodes = + BlastTreeData::ins().getChunkNodeByBlastChunk(m_pNewBlastAsset, m_NewChunkIndexes); + for (BlastChunkNode* node : chunkNodes) + { + node->setVisible(true); + selectTreeItem(node); + } + + m_pNewBlastAsset = nullptr; + m_NewChunkIndexes.clear(); + + _updateData = true; } -void BlastSceneTree::_addChunkUI(const BlastNode* parentNode, QTreeWidgetItem* parentTreeItem) +void BlastSceneTree::_addChunkUI(const BlastNode* parentNode, QStandardItem* parentTreeItem) { if (parentNode != nullptr && parentTreeItem != nullptr) { @@ -1507,43 +2260,47 @@ void BlastSceneTree::_addChunkUI(const BlastNode* parentNode, QTreeWidgetItem* p if (node == nullptr) continue; - QTreeWidgetItem* treeWidgetItem = nullptr; + QStandardItem* treeWidgetItem = new QStandardItem(); + parentTreeItem->appendRow(treeWidgetItem); if (node->getType() == eChunk) { - BlastChunkNode* chunk = static_cast<BlastChunkNode*>(node); - treeWidgetItem = new QTreeWidgetItem(parentTreeItem); - treeWidgetItem->setText(0, chunk->name.c_str()); - if (chunk->isSupport()) + BlastChunkNode* chunkNode = static_cast<BlastChunkNode*>(node); + treeWidgetItem->setText(chunkNode->name.c_str()); + + BPPChunk* chunk = static_cast<BPPChunk*>(chunkNode->getData()); + if (!chunk->support) { - treeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png")); + treeWidgetItem->setIcon(sChunkUUIcon); } - else + else if (chunk->support && !chunk->staticFlag) + { + treeWidgetItem->setIcon(sChunkSUIcon); + } + else if (chunk->support && chunk->staticFlag) { - treeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png")); + treeWidgetItem->setIcon(sChunkSSIcon); } - _addChunkUI(chunk, treeWidgetItem); + _addChunkUI(chunkNode, treeWidgetItem); } else if (node->getType() == eBond) { BlastBondNode* bond = static_cast<BlastBondNode*>(node); - treeWidgetItem = new QTreeWidgetItem(parentTreeItem); - treeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Bond.png")); - treeWidgetItem->setText(0, bond->name.c_str()); + treeWidgetItem->setIcon(sBondIcon); + treeWidgetItem->setText(bond->name.c_str()); } if (treeWidgetItem == nullptr) continue; - VisualButton* btn = new VisualButton(this, node); - ui.blastSceneTree->setItemWidget(treeWidgetItem, 1, btn); + _treeItemDataMap.insert(treeWidgetItem, node); _treeDataItemMap.insert(node, treeWidgetItem); } } } -void BlastSceneTree::_updateChunkTreeItemAndMenu(BPPChunk* chunk, QTreeWidgetItem* chunkItem) +void BlastSceneTree::_updateChunkTreeItemAndMenu(BPPChunk* chunk, QStandardItem* chunkItem) { assert(chunk != nullptr); @@ -1554,309 +2311,368 @@ void BlastSceneTree::_updateChunkTreeItemAndMenu(BPPChunk* chunk, QTreeWidgetIte if (!chunk->support && !chunk->staticFlag) { _removeSupportAction->setEnabled(false); - chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png")); + chunkItem->setIcon(sChunkUUIcon); } else if (chunk->support && !chunk->staticFlag) { _makeSupportAction->setEnabled(false); - chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png")); + chunkItem->setIcon(sChunkSUIcon); } else if (chunk->support && chunk->staticFlag) { _makeStaticSupportAction->setEnabled(false); - chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Static.png")); + chunkItem->setIcon(sChunkSSIcon); } } void BlastSceneTree::_updateChunkTreeItems() { - for (QMap<BlastNode*, QTreeWidgetItem*>::iterator itr = _treeDataItemMap.begin(); itr != _treeDataItemMap.end(); ++itr) + for (QMap<BlastNode*, QStandardItem*>::iterator itr = _treeDataItemMap.begin(); itr != _treeDataItemMap.end(); ++itr) { BlastNode* node = itr.key(); - QTreeWidgetItem* treeItem = itr.value(); + QStandardItem* treeItem = itr.value(); if (eChunk == node->getType()) { BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); - if (!chunk->support && !chunk->staticFlag) + if (!chunk->support) { - treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png")); + treeItem->setIcon(sChunkUUIcon); } else if (chunk->support && !chunk->staticFlag) { - treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png")); + treeItem->setIcon(sChunkSUIcon); } else if (chunk->support && chunk->staticFlag) { - treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Static.png")); + treeItem->setIcon(sChunkSSIcon); + } + } + } +} + +void BlastSceneTree::ApplyAutoSelectNewChunks(BlastAsset* pNewBlastAsset, std::vector<uint32_t>& NewChunkIndexes) +{ + if (pNewBlastAsset == nullptr || NewChunkIndexes.size() == 0) + { + return; + } + + m_pNewBlastAsset = pNewBlastAsset; + m_NewChunkIndexes.clear(); + for (uint32_t nci : NewChunkIndexes) + { + m_NewChunkIndexes.push_back(nci); + } +} + +/* +BlastAssetNode* BlastTreeData::addBlastAsset(BPPAsset& asset) +{ + BlastAsset* pBlastAsset = nullptr; + SampleManager* pSampleManager = SampleManager::ins(); + std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap(); + std::map<BlastAsset*, AssetList::ModelAsset>::iterator it; + for (it = AssetDescMap.begin(); it != AssetDescMap.end(); it++) + { + std::string assetname = asset.name.buf; + if (it->second.name == assetname) + { + pBlastAsset = it->first; + } + } + + BlastAssetNode* assetNode = new BlastAssetNode(asset.name.buf, asset); + _assets.push_back(assetNode); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&asset, assetNode)); + + std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset, -1); + int childChunksSize = childChunks.size(); + for (size_t i = 0; i < childChunksSize; ++i) + { + BPPChunk& chunk = *(childChunks[i]); + BlastChunkNode* chunkNode = new BlastChunkNode(chunk.name.buf, chunk, pBlastAsset); + assetNode->children.push_back(chunkNode); + chunkNode->setParent(assetNode); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&chunk, chunkNode)); + + _addChunkNode(chunk, asset, chunkNode, pBlastAsset); + } + + return assetNode; +} + +void BlastTreeData::removeBlastAsset(BPPAsset& asset) +{ + _removeChunkNode(asset); + + std::map<void*, BlastNode*>::iterator it = _blastProjectDataToNodeMap.find(&asset); + if (it == _blastProjectDataToNodeMap.end()) + { + return; + } + + BlastNode* node = it->second; + _blastProjectDataToNodeMap.erase(it); + std::vector<BlastAssetNode*>::iterator itAsset; + for (itAsset = _assets.begin(); itAsset != _assets.end(); itAsset++) + { + if (node == *itAsset) + { + _assets.erase(itAsset); + break; + } + } + + delete node; +} + +BlastAssetInstanceNode* BlastTreeData::addBlastInstance(BPPAssetInstance& instance) +{ + BlastAssetInstanceNode* blastAssetInstanceNode = new BlastAssetInstanceNode(instance.name.buf, instance); + _assetInstancesNode->children.push_back(blastAssetInstanceNode); + blastAssetInstanceNode->setParent(_assetInstancesNode); + void* pointer = (void*)&instance; + _blastProjectDataToNodeMap.insert(std::make_pair(pointer, blastAssetInstanceNode)); + return blastAssetInstanceNode; +} + +void BlastTreeData::removeBlastInstance(BPPAssetInstance& instance) +{ + void* pointer = (void*)&instance; + std::map<void*, BlastNode*>::iterator it = _blastProjectDataToNodeMap.find(pointer); + if (it == _blastProjectDataToNodeMap.end()) + { + return; + } + + BlastNode* node = it->second; + _blastProjectDataToNodeMap.erase(it); + delete node; + + int count = _assetInstancesNode->children.size(); + for (int i = count - 1; i >= 0; --i) + { + BlastNode* pBN = _assetInstancesNode->children[i]; + if (pBN == node) + { + _assetInstancesNode->children.erase(_assetInstancesNode->children.begin() + i); + } + else + { + BlastAssetInstanceNode* blastAssetInstanceNode = dynamic_cast<BlastAssetInstanceNode*>(_assetInstancesNode->children[i]); + if (blastAssetInstanceNode && blastAssetInstanceNode->getData() == &instance) + { + _assetInstancesNode->children.erase(_assetInstancesNode->children.begin() + i); } } } } -void BlastSceneTree::_selectTreeItem(BlastNode* node) +BlastProjectileNode* BlastTreeData::addProjectile(PhysXSceneActor* projectile) { - QMap<BlastNode*, QTreeWidgetItem*>::iterator itr = _treeDataItemMap.find(node); + SceneController& sceneController = SampleManager::ins()->getSceneController(); + BlastProjectileNode* projectileNode = new BlastProjectileNode(sceneController.getProjectileName(projectile), projectile); + _projectiles.push_back(projectileNode); + return projectileNode; +} + +void BlastTreeData::clearProjectile() +{ + std::vector<BlastProjectileNode*>::iterator it; + for (it = _projectiles.begin(); it != _projectiles.end(); it++) + { + delete *it; + } + _projectiles.clear(); +} + +void BlastTreeData::refreshProjectDataToNodeMap(std::map<BPPAsset*, BPPAsset*>& changeMap) +{ + std::map<BPPAsset*, BPPAsset*>::iterator it; + std::map<void*, BlastNode*>::iterator itNode; + for (it = changeMap.begin(); it != changeMap.end(); it++) + { + itNode = _blastProjectDataToNodeMap.find(it->first); + if (itNode == _blastProjectDataToNodeMap.end()) + { + continue; + } + + BlastNode* node = itNode->second; + _blastProjectDataToNodeMap.erase(itNode); + _blastProjectDataToNodeMap[it->second] = node; + } +} + +void BlastTreeData::refreshProjectDataToNodeMap(std::map<BPPAssetInstance*, BPPAssetInstance*>& changeMap) +{ + std::map<BPPAssetInstance*, BPPAssetInstance*>::iterator it; + std::map<void*, BlastNode*>::iterator itNode; + for (it = changeMap.begin(); it != changeMap.end(); it++) + { + itNode = _blastProjectDataToNodeMap.find(it->first); + if (itNode == _blastProjectDataToNodeMap.end()) + { + continue; + } + + BlastNode* node = itNode->second; + _blastProjectDataToNodeMap.erase(itNode); + _blastProjectDataToNodeMap[it->second] = node; + node->setData(it->second); + } +} + +void BlastSceneTree::addBlastAsset(BPPAsset& asset) +{ + BlastAssetNode* assetNode = BlastTreeData::ins().addBlastAsset(asset); + if (assetNode == nullptr) + { + return; + } + + QStandardItem* assetTreeWidgetItem = new QStandardItem(); + _treeModel->appendRow(assetTreeWidgetItem); + assetTreeWidgetItem->setText(assetNode->name.c_str()); + assetTreeWidgetItem->setIcon(sAssetIcon); + _treeItemDataMap.insert(assetTreeWidgetItem, assetNode); + _treeDataItemMap.insert(assetNode, assetTreeWidgetItem); + + _addChunkUI(assetNode, assetTreeWidgetItem); + + ui.blastSceneTree->expandAll(); +} + +void BlastSceneTree::removeBlastAsset(BPPAsset& asset) +{ + BlastNode* node = BlastTreeData::ins().getBlastNodeByProjectData(&asset); + + QMap<BlastNode*, QStandardItem*>::iterator it = _treeDataItemMap.find(node); + if (it != _treeDataItemMap.end()) + { + QStandardItem* item = it.value(); + + if (item != nullptr) + { + _treeModel->removeRow(_treeModel->indexFromItem(item).row()); + ui.blastSceneTree->expandAll(); + } + } + + BlastTreeData::ins().removeBlastAsset(asset); +} + +void BlastSceneTree::addBlastInstance(BPPAssetInstance& instance) +{ + BlastAssetInstanceNode* assetInstanceNode = BlastTreeData::ins().addBlastInstance(instance); + if (assetInstanceNode == nullptr) + { + return; + } + + QStandardItem* assetInstanceItem = new QStandardItem(); + _compositeTreeItem->appendRow(assetInstanceItem); + assetInstanceItem->setText(assetInstanceNode->name.c_str()); + if (assetInstanceNode->getType() == eAssetInstance) + assetInstanceItem->setIcon(sAssetIcon); + _treeItemDataMap.insert(assetInstanceItem, assetInstanceNode); + _treeDataItemMap.insert(assetInstanceNode, assetInstanceItem); + + ui.blastSceneTree->expandAll(); +} + +void BlastSceneTree::removeBlastInstance(BPPAssetInstance& instance) +{ + BlastNode* node = BlastTreeData::ins().getBlastNodeByProjectData(&instance); + + QMap<BlastNode*, QStandardItem*>::iterator it = _treeDataItemMap.find(node); + if (it != _treeDataItemMap.end()) + { + QStandardItem* item = it.value(); + + if (item != nullptr) + { + _compositeTreeItem->removeRow(_treeModel->indexFromItem(_compositeTreeItem).row()); + ui.blastSceneTree->expandAll(); + } + } + + BlastTreeData::ins().removeBlastInstance(instance); +} + +void BlastSceneTree::removeBlastInstances(BPPAsset& asset) +{ + std::vector<BPPAssetInstance*> instances; + BlastProject::ins().getAssetInstances(asset.ID, instances); + + std::vector<BPPAssetInstance*>::iterator it; + for (it = instances.begin(); it != instances.end(); it++) + { + removeBlastInstance(**it); + BlastTreeData::ins().removeBlastInstance(**it); + } +} + +void BlastSceneTree::addProjectile(PhysXSceneActor* projectile) +{ + BlastProjectileNode* projectileNode = BlastTreeData::ins().addProjectile(projectile); + if (projectileNode == nullptr) + { + return; + } + + QStandardItem* projectileTreeItem = new QStandardItem(); + projectileTreeItem->setText(projectileNode->name.c_str()); + projectileTreeItem->setIcon(sProjectileIcon); + _treeModel->appendRow(projectileTreeItem); + _projectileItemActorMap[projectileTreeItem] = projectile;; +} + +void BlastSceneTree::clearProjectile() +{ + QMap<QStandardItem*, PhysXSceneActor*>::iterator it; + for (it =_projectileItemActorMap.begin(); it != _projectileItemActorMap.end(); it++) + { + _treeModel->removeRow(_treeModel->indexFromItem(it.key()).row()); + } + _projectileItemActorMap.clear(); + + BlastTreeData::ins().clearProjectile(); +} +*/ +BlastNode* BlastSceneTree::getBlastNodeByItem(QStandardItem* item) +{ + QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(item); + if (itr == _treeItemDataMap.end()) + return nullptr; + + return itr.value(); +} + +PhysXSceneActor* BlastSceneTree::getProjectileActorByItem(QStandardItem* item) +{ + QMap<QStandardItem*, PhysXSceneActor*>::iterator itr = _projectileItemActorMap.find(item); + if (itr == _projectileItemActorMap.end()) + return nullptr; + + return itr.value(); +} + +void BlastSceneTree::selectTreeItem(BlastNode* node, bool updateData) +{ + _updateData = updateData; + QMap<BlastNode*, QStandardItem*>::iterator itr = _treeDataItemMap.find(node); if (itr != _treeDataItemMap.end()) { - ui.blastSceneTree->setItemSelected(itr.value(), true); - } -} - -//void BlastSceneTree::_createTestData() -//{ -// BPPBlast& blast = BlastProject::ins().getParams().blast; -// -// // compoistie -// { -// BPPComposite& composite = blast.composite; -// composite.composite.buf = nullptr; -// composite.visible = true; -// -// copy(composite.composite, "BlastComposite"); -// -// // asset instance array -// { -// BPPAssetInstanceArray& instanceArray = composite.blastAssetInstances; -// instanceArray.buf = new BPPAssetInstance[4]; -// instanceArray.arraySizes[0] = 4; -// instanceArray.buf[0].name.buf = nullptr; -// instanceArray.buf[1].name.buf = nullptr; -// instanceArray.buf[2].name.buf = nullptr; -// instanceArray.buf[3].name.buf = nullptr; -// instanceArray.buf[0].source.buf = nullptr; -// instanceArray.buf[1].source.buf = nullptr; -// instanceArray.buf[2].source.buf = nullptr; -// instanceArray.buf[3].source.buf = nullptr; -// -// copy(instanceArray.buf[0].name, "BlastAsset_instance1"); -// instanceArray.buf[0].visible = true; -// -// copy(instanceArray.buf[1].name, "BlastAsset_instance2"); -// instanceArray.buf[1].visible = true; -// -// copy(instanceArray.buf[2].name, "BlastAsset1_instance1"); -// instanceArray.buf[2].visible = true; -// -// copy(instanceArray.buf[3].name, "BlastAsset1_instance2"); -// instanceArray.buf[3].visible = true; -// } -// -// // landmark array -// { -// BPPLandmarkArray& landmarkArray = composite.landmarks; -// landmarkArray.buf = new BPPLandmark[2]; -// landmarkArray.arraySizes[0] = 2; -// landmarkArray.buf[0].name.buf = nullptr; -// landmarkArray.buf[1].name.buf = nullptr; -// -// copy(landmarkArray.buf[0].name, "Landmark_1"); -// copy(landmarkArray.buf[1].name, "Landmark_2"); -// } -// } -// -// // asset array -// { -// BPPAssetArray& assetArray = blast.blastAssets; -// assetArray.buf = new BPPAsset[2]; -// assetArray.arraySizes[0] = 2; -// -// // asset 0 -// { -// BPPAsset& asset = assetArray.buf[0]; -// asset.path.buf = nullptr; -// asset.activePreset.buf = nullptr; -// asset.bonds.buf = nullptr; -// asset.chunks.buf = nullptr; -// -// copy(asset.path, "c:/temp/BlastAsset.asset"); -// -// // chunks -// { -// asset.chunks.buf = new BPPChunk[10]; -// asset.chunks.arraySizes[0] = 10; -// for (int i = 0; i < 10; ++i) -// { -// asset.chunks.buf[i].name.buf = nullptr; -// asset.chunks.buf[i].visible = true; -// asset.chunks.buf[i].staticFlag = false; -// } -// -// copy(asset.chunks.buf[0].name, "Chunk_L0_00"); -// asset.chunks.buf[0].ID = 0; -// asset.chunks.buf[0].parentID = -1; -// asset.chunks.buf[0].support = false; -// -// copy(asset.chunks.buf[1].name, "Chunk_L0_01"); -// asset.chunks.buf[1].ID = 1; -// asset.chunks.buf[1].parentID = -1; -// asset.chunks.buf[1].support = false; -// -// copy(asset.chunks.buf[2].name, "Chunk_L1_02"); -// asset.chunks.buf[2].ID = 2; -// asset.chunks.buf[2].parentID = 0; -// asset.chunks.buf[2].support = false; -// -// copy(asset.chunks.buf[3].name, "Chunk_L1_03"); -// asset.chunks.buf[3].ID = 3; -// asset.chunks.buf[3].parentID = 0; -// asset.chunks.buf[3].support = false; -// -// copy(asset.chunks.buf[4].name, "Chunk_L1_04"); -// asset.chunks.buf[4].ID = 4; -// asset.chunks.buf[4].parentID = 1; -// asset.chunks.buf[4].support = false; -// -// copy(asset.chunks.buf[5].name, "Chunk_L1_05"); -// asset.chunks.buf[5].ID = 5; -// asset.chunks.buf[5].parentID = 1; -// asset.chunks.buf[5].support = false; -// -// copy(asset.chunks.buf[6].name, "Chunk_L2_06"); -// asset.chunks.buf[6].ID = 6; -// asset.chunks.buf[6].parentID = 2; -// asset.chunks.buf[6].support = true; -// -// copy(asset.chunks.buf[7].name, "Chunk_L2_07"); -// asset.chunks.buf[7].ID = 7; -// asset.chunks.buf[7].parentID = 2; -// asset.chunks.buf[7].support = true; -// -// copy(asset.chunks.buf[8].name, "Chunk_L2_08"); -// asset.chunks.buf[8].ID = 8; -// asset.chunks.buf[8].parentID = 3; -// asset.chunks.buf[8].support = true; -// -// copy(asset.chunks.buf[9].name, "Chunk_L2_09"); -// asset.chunks.buf[9].ID = 9; -// asset.chunks.buf[9].parentID = 3; -// asset.chunks.buf[9].support = true; -// } -// -// // bonds -// { -// asset.bonds.buf = new BPPBond[4]; -// asset.bonds.arraySizes[0] = 4; -// for (int i = 0; i < 4; ++i) -// { -// asset.bonds.buf[i].name.buf = nullptr; -// asset.bonds.buf[i].visible = true; -// asset.bonds.buf[i].support.healthMask.buf = nullptr; -// } -// -// copy(asset.bonds.buf[0].name, "Chunk_L2_08"); -// asset.bonds.buf[0].fromChunk = 6; -// asset.bonds.buf[0].toChunk = 8; -// -// copy(asset.bonds.buf[1].name, "Chunk_L2_06"); -// asset.bonds.buf[1].fromChunk = 6; -// asset.bonds.buf[1].toChunk = 8; -// -// copy(asset.bonds.buf[2].name, "Chunk_L2_09"); -// asset.bonds.buf[2].fromChunk = 7; -// asset.bonds.buf[2].toChunk = 9; -// -// copy(asset.bonds.buf[3].name, "Chunk_L2_07"); -// asset.bonds.buf[3].fromChunk = 7; -// asset.bonds.buf[3].toChunk = 9; -// } -// } -// -// // asset 1 -// { -// BPPAsset& asset = assetArray.buf[1]; -// asset.path.buf = nullptr; -// asset.activePreset.buf = nullptr; -// asset.bonds.buf = nullptr; -// asset.chunks.buf = nullptr; -// -// copy(asset.path, "c:/temp/BlastAsset1.asset"); -// { -// asset.chunks.buf = new BPPChunk[10]; -// asset.chunks.arraySizes[0] = 10; -// for (int i = 0; i < 10; ++i) -// { -// asset.chunks.buf[i].name.buf = nullptr; -// asset.chunks.buf[i].visible = true; -// } -// -// copy(asset.chunks.buf[0].name, "Chunk_L0_00"); -// asset.chunks.buf[0].ID = 0; -// asset.chunks.buf[0].parentID = -1; -// asset.chunks.buf[0].support = false; -// -// copy(asset.chunks.buf[1].name, "Chunk_L0_01"); -// asset.chunks.buf[1].ID = 1; -// asset.chunks.buf[1].parentID = -1; -// asset.chunks.buf[1].support = false; -// -// copy(asset.chunks.buf[2].name, "Chunk_L1_02"); -// asset.chunks.buf[2].ID = 2; -// asset.chunks.buf[2].parentID = 0; -// asset.chunks.buf[2].support = false; -// -// copy(asset.chunks.buf[3].name, "Chunk_L1_03"); -// asset.chunks.buf[3].ID = 3; -// asset.chunks.buf[3].parentID = 0; -// asset.chunks.buf[3].support = false; -// -// copy(asset.chunks.buf[4].name, "Chunk_L1_04"); -// asset.chunks.buf[4].ID = 4; -// asset.chunks.buf[4].parentID = 1; -// asset.chunks.buf[4].support = false; -// -// copy(asset.chunks.buf[5].name, "Chunk_L1_05"); -// asset.chunks.buf[5].ID = 5; -// asset.chunks.buf[5].parentID = 1; -// asset.chunks.buf[5].support = false; -// -// copy(asset.chunks.buf[6].name, "Chunk_L2_06"); -// asset.chunks.buf[6].ID = 6; -// asset.chunks.buf[6].parentID = 2; -// asset.chunks.buf[6].support = true; -// -// copy(asset.chunks.buf[7].name, "Chunk_L2_07"); -// asset.chunks.buf[7].ID = 7; -// asset.chunks.buf[7].parentID = 2; -// asset.chunks.buf[7].support = true; -// -// copy(asset.chunks.buf[8].name, "Chunk_L2_08"); -// asset.chunks.buf[8].ID = 8; -// asset.chunks.buf[8].parentID = 3; -// asset.chunks.buf[8].support = true; -// -// copy(asset.chunks.buf[9].name, "Chunk_L2_09"); -// asset.chunks.buf[9].ID = 9; -// asset.chunks.buf[9].parentID = 3; -// asset.chunks.buf[9].support = true; -// } -// } -// } -// -// // projectile -// { -// BPPProjectileArray& projectileArray = blast.projectiles; -// projectileArray.buf = new BPPProjectile[1]; -// projectileArray.arraySizes[0] = 1; -// projectileArray.buf[0].name.buf = nullptr; -// copy(projectileArray.buf[0].name, "Projectile"); -// projectileArray.buf[0].visible = true; -// } -// -// // graphics meshes -// { -// BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes; -// graphicsMeshArray.buf = new BPPGraphicsMesh[3]; -// graphicsMeshArray.arraySizes[0] = 3; -// graphicsMeshArray.buf[0].name.buf = nullptr; -// copy(graphicsMeshArray.buf[0].name, "SurfaceMesh1"); -// graphicsMeshArray.buf[0].visible = true; -// -// graphicsMeshArray.buf[1].name.buf = nullptr; -// copy(graphicsMeshArray.buf[1].name, "SurfaceMesh2"); -// graphicsMeshArray.buf[1].visible = true; -// -// graphicsMeshArray.buf[2].name.buf = nullptr; -// copy(graphicsMeshArray.buf[2].name, "DisplayMesh1"); -// graphicsMeshArray.buf[2].visible = true; -// } -//} + QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel(); + selectionModel->select(_treeModel->indexFromItem(itr.value()), QItemSelectionModel::Select); + } + + _updateData = true; +} + +void BlastSceneTree::selectTreeItem(BlastFamily* family) +{ + BlastAssetInstanceNode* instanceNode = BlastTreeData::ins().getAssetInstanceNode(family); + selectTreeItem(instanceNode, false); +}
\ No newline at end of file |