diff options
| author | Bryan Galdrikian <[email protected]> | 2017-02-21 12:07:59 -0800 |
|---|---|---|
| committer | Bryan Galdrikian <[email protected]> | 2017-02-21 12:07:59 -0800 |
| commit | 446ce137c6823ba9eff273bdafdaf266287c7c98 (patch) | |
| tree | d20aab3e2ed08d7b3ca71c2f40db6a93ea00c459 /NvBlast/tools/ArtistTools/source/BlastPlugin/Window | |
| download | blast-1.0.0-beta.tar.xz blast-1.0.0-beta.zip | |
first commitv1.0.0-beta
Diffstat (limited to 'NvBlast/tools/ArtistTools/source/BlastPlugin/Window')
40 files changed, 6655 insertions, 0 deletions
diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.cpp new file mode 100644 index 0000000..b42a4f5 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.cpp @@ -0,0 +1,306 @@ +#include "BlastCompositePanel.h" +#include "ui_BlastCompositePanel.h" +#include "ProjectParams.h" +#include <QtCore/QFileInfo> +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> + +BlastCompositePanel::BlastCompositePanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::BlastCompositePanel), + _selectedAsset(-1) +{ + ui->setupUi(this); + + ui->btnRemoveAsset->setEnabled(false); + ui->btnModifyLandmark->setEnabled(false); + ui->btnRemoveLandmark->setEnabled(false); +} + +BlastCompositePanel::~BlastCompositePanel() +{ + delete ui; +} + +void BlastCompositePanel::updateValues() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + + ui->lineEditComposite->setText(composite.composite.buf); + + _updateAssetComboBox(); + + _updateAssetInstanceListWidget(); + + ui->spinBoxBondByThreshold->setValue(composite.bondThreshold); + ui->spinBoxNewBondStrength->setValue(composite.bondStrength); + + _updateLandmarkListWidget(); + + ui->checkBoxEnableLandmark->setChecked(false); + ui->spinBoxLandmarkRadius->setValue(false); +} + +void BlastCompositePanel::on_btnCollapse_clicked() +{ + +} + +void BlastCompositePanel::on_btnSave_clicked() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + + QByteArray tmp = ui->lineEditComposite->text().toUtf8(); + copy(composite.composite, tmp.data()); +} + +void BlastCompositePanel::on_comboBoxAsset_currentIndexChanged(int index) +{ + _selectedAsset = index; +} + +void BlastCompositePanel::on_btnAddAsset_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new blast instance:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isAssetInstanceNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addAssetInstance(_selectedAsset, name.toUtf8().data()); + _updateAssetInstanceListWidget(); + ui->listWidgetBlastAsset->setCurrentRow(ui->listWidgetBlastAsset->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new preset!"); + } +} + +void BlastCompositePanel::on_btnRemoveAsset_clicked() +{ + QList<QListWidgetItem*> items = ui->listWidgetBlastAsset->selectedItems(); + BlastProject::ins().removeAssetInstance(items.at(0)->text().toUtf8().data()); +} + +void BlastCompositePanel::on_listWidgetBlastAsset_itemSelectionChanged() +{ + QList<QListWidgetItem*> items = ui->listWidgetBlastAsset->selectedItems(); + if (items.count() > 0) + ui->btnRemoveAsset->setEnabled(true); + else + ui->btnRemoveAsset->setEnabled(false); +} + +void BlastCompositePanel::on_spinBoxBondByThreshold_valueChanged(double arg1) +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + composite.bondThreshold = arg1; +} + +void BlastCompositePanel::on_spinBoxNewBondStrength_valueChanged(double arg1) +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + composite.bondStrength = arg1; +} + +void BlastCompositePanel::on_btnAddLandmark_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new landmark:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isLandmarkNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addLandmark(name.toUtf8().data()); + _updateLandmarkListWidget(); + ui->listWidgetLandmark->setCurrentRow(ui->listWidgetLandmark->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new landmark!"); + } +} + +void BlastCompositePanel::on_btnModifyLandmark_clicked() +{ + QList<QListWidgetItem*> items = ui->listWidgetLandmark->selectedItems(); + QByteArray tem = items.at(0)->text().toUtf8(); + const char* oldName = tem.data(); + + bool ok = false; + QString newName = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input new name for the selected landmark:"), + QLineEdit::Normal, + oldName, + &ok); + bool nameExist = BlastProject::ins().isLandmarkNameExist(newName.toUtf8().data()); + if (ok && !newName.isEmpty() && !nameExist) + { + int selectIndex = ui->listWidgetLandmark->currentRow(); + BlastProject::ins().renameLandmark(oldName, newName.toUtf8().data()); + _updateLandmarkListWidget(); + ui->listWidgetLandmark->setCurrentRow(selectIndex); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && newName.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new landmark!"); + } +} + +void BlastCompositePanel::on_btnRemoveLandmark_clicked() +{ + QList<QListWidgetItem*> items = ui->listWidgetLandmark->selectedItems(); + QByteArray tem = items.at(0)->text().toUtf8(); + const char* name = tem.data(); + BlastProject::ins().removeLandmark(name); + _updateLandmarkListWidget(); +} + +void BlastCompositePanel::on_listWidgetLandmark_itemSelectionChanged() +{ + _updateLandmarkUIs(); +} + +void BlastCompositePanel::on_checkBoxEnableLandmark_stateChanged(int arg1) +{ + QList<QListWidgetItem*> items = ui->listWidgetLandmark->selectedItems(); + + int count = items.count(); + for (int i = 0; i < count; ++i) + { + BPPLandmark* landmark = BlastProject::ins().getLandmark(items.at(0)->text().toUtf8().data()); + if (landmark != nullptr) + { + landmark->enable = ui->checkBoxEnableLandmark->isChecked(); + } + } +} + +void BlastCompositePanel::on_spinBoxLandmarkRadius_valueChanged(double arg1) +{ + QList<QListWidgetItem*> items = ui->listWidgetLandmark->selectedItems(); + + int count = items.count(); + for (int i = 0; i < count; ++i) + { + BPPLandmark* landmark = BlastProject::ins().getLandmark(items.at(0)->text().toUtf8().data()); + if (landmark != nullptr) + { + landmark->radius = ui->spinBoxLandmarkRadius->value(); + } + } +} + +void BlastCompositePanel::_updateAssetComboBox() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPAssetArray& blastAssetArray = projectParams.blast.blastAssets; + BPPComposite& composite = projectParams.blast.composite; + + ui->comboBoxAsset->clear(); + int countAssets = blastAssetArray.arraySizes[0]; + if (countAssets > 0) + { + QStringList assets; + for (int i = 0; i < countAssets; ++i) + { + QFileInfo fileInfo(blastAssetArray.buf[i].path.buf); + assets.append(fileInfo.baseName()); + } + ui->comboBoxAsset->addItems(assets); + } + else + { + ui->btnAddAsset->setEnabled(false); + ui->btnRemoveAsset->setEnabled(false); + } +} + +void BlastCompositePanel::_updateAssetInstanceListWidget() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + + ui->listWidgetBlastAsset->clear(); + int countAssetInstances = composite.blastAssetInstances.arraySizes[0]; + if (countAssetInstances > 0) + { + QStringList assetInstances; + + for (int i = 0; i < countAssetInstances; ++i) + { + assetInstances.append(composite.blastAssetInstances.buf[i].name.buf); + } + ui->listWidgetBlastAsset->addItems(assetInstances); + } +} + +void BlastCompositePanel::_updateLandmarkListWidget() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + + ui->listWidgetLandmark->clear(); + int countJoints = composite.landmarks.arraySizes[0]; + if (countJoints > 0) + { + QStringList landmarks; + + for (int i = 0; i < countJoints; ++i) + { + landmarks.append(composite.landmarks.buf[i].name.buf); + } + ui->listWidgetLandmark->addItems(landmarks); + } +} + +void BlastCompositePanel::_updateLandmarkUIs() +{ + QList<QListWidgetItem*> items = ui->listWidgetLandmark->selectedItems(); + + if (items.count() > 0) + { + BPPLandmark* landmark = BlastProject::ins().getLandmark(items.at(0)->text().toUtf8().data()); + if (landmark != nullptr) + { + ui->btnModifyLandmark->setEnabled(true); + ui->btnRemoveLandmark->setEnabled(true); + ui->checkBoxEnableLandmark->setChecked(landmark->enable); + ui->spinBoxLandmarkRadius->setValue(landmark->radius); + } + } + else + { + ui->btnModifyLandmark->setEnabled(false); + ui->btnRemoveLandmark->setEnabled(false); + ui->checkBoxEnableLandmark->setChecked(false); + ui->spinBoxLandmarkRadius->setValue(0.0f); + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.h new file mode 100644 index 0000000..b4e5bcf --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.h @@ -0,0 +1,59 @@ +#ifndef BLASTCOMPOSITEPANEL_H +#define BLASTCOMPOSITEPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class BlastCompositePanel; +} + +class BlastCompositePanel : public QWidget +{ + Q_OBJECT + +public: + explicit BlastCompositePanel(QWidget *parent = 0); + ~BlastCompositePanel(); + void updateValues(); + +private slots: + void on_btnCollapse_clicked(); + + void on_btnSave_clicked(); + + void on_comboBoxAsset_currentIndexChanged(int index); + + void on_btnAddAsset_clicked(); + + void on_btnRemoveAsset_clicked(); + + void on_listWidgetBlastAsset_itemSelectionChanged(); + + void on_spinBoxBondByThreshold_valueChanged(double arg1); + + void on_spinBoxNewBondStrength_valueChanged(double arg1); + + void on_btnAddLandmark_clicked(); + + void on_btnModifyLandmark_clicked(); + + void on_btnRemoveLandmark_clicked(); + + void on_listWidgetLandmark_itemSelectionChanged(); + + void on_checkBoxEnableLandmark_stateChanged(int arg1); + + void on_spinBoxLandmarkRadius_valueChanged(double arg1); + +private: + void _updateAssetComboBox(); + void _updateAssetInstanceListWidget(); + void _updateLandmarkListWidget(); + void _updateLandmarkUIs(); + +private: + Ui::BlastCompositePanel *ui; + int _selectedAsset; +}; + +#endif // BLASTCOMPOSITEPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp new file mode 100644 index 0000000..64a7c2f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp @@ -0,0 +1,1804 @@ +#include "BlastSceneTree.h" +#include <QtWidgets/QMessageBox> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QPushButton> +#include <QtWidgets/QCheckBox> +#include <QtWidgets/QMenu> +#include <QtCore/QFileInfo> +#include <assert.h> +#include "ProjectParams.h" +#include <SimpleScene.h> +#include <BlastController.h> +#include <SceneController.h> +#include <NvBlastExtPxAsset.h> +#include <NvBlastTkAsset.h> +#include <NvBlastAsset.h> +#include <BlastFamilyModelSimple.h> + +bool isChunkVisible(std::vector<BlastFamily*>& fs, uint32_t chunkIndex) +{ + int fsSize = fs.size(); + if (fsSize == 0) + { + return false; + } + + bool visible = false; + for (int i = 0; i < fsSize; i++) + { + if (fs[i]->isChunkVisible(chunkIndex)) + { + visible = true; + break; + } + } + return visible; +} + +void setChunkVisible(std::vector<BlastFamily*>& fs, uint32_t chunkIndex, bool visible) +{ + int fsSize = fs.size(); + if (fsSize == 0) + { + return; + } + + for (int i = 0; i < fsSize; i++) + { + fs[i]->setChunkVisible(chunkIndex, visible); + } +} + +void setChunkSelected(std::vector<BlastFamily*>& fs, uint32_t chunkIndex, bool selected) +{ + int fsSize = fs.size(); + if (fsSize == 0) + { + return; + } + + for (int i = 0; i < fsSize; i++) + { + fs[i]->setChunkSelected(chunkIndex, selected); + } +} + +void BlastChunkNode::setVisible(bool val) +{ + BPPChunk* pBPPChunk = (BPPChunk*)_data; + pBPPChunk->visible = val; + + BlastAsset* pBlastAsset = (BlastAsset*)_assetPtr; + + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + + std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap(); + std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset]; + + setChunkVisible(fs, pBPPChunk->ID, val); +} + +void BlastChunkNode::setSelected(bool val) +{ + BPPChunk* pBPPChunk = (BPPChunk*)_data; + pBPPChunk->visible = val; + + BlastAsset* pBlastAsset = (BlastAsset*)_assetPtr; + + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + + std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap(); + std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset]; + + setChunkSelected(fs, pBPPChunk->ID, val); +} + +void BlastAssetInstanceNode::setSelected(bool val) +{ + BPPAssetInstance* pBPPAssetInstance = (BPPAssetInstance*)_data; + std::string name = pBPPAssetInstance->name; + + std::string strAsset = name.substr(0, name.find_first_of("_")); + 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; + } + } + + std::string strIndex = name.substr(name.find_last_of("_") + 1); + int nIndex = atoi(strIndex.c_str()); + + sampleManager.setCurrentSelectedInstance(pBlastAsset, nIndex); +} + +BlastTreeData& BlastTreeData::ins() +{ + static BlastTreeData _ins; + return _ins; +} + +bool BlastTreeData::isChild(BlastChunkNode* parent, BlastChunkNode* child) +{ + if (parent == nullptr || child == nullptr) + return false; + + BlastNode* curParent = child->getParent(); + while (eChunk == curParent->getType() && curParent != nullptr) + { + if (curParent == parent) + return true; + curParent = curParent->getParent(); + } + + return false; +} + +std::vector<BlastChunkNode*> BlastTreeData::getTopChunkNodes(std::vector<BlastChunkNode*>& nodes) +{ + std::vector<BlastChunkNode*> result; + + for (size_t i = 0; i < nodes.size(); ++i) + { + bool isCurNodeTop = true; + for (size_t j = 0; j < nodes.size(); ++j) + { + if (i != j && isChild(nodes[i], nodes[j])) + { + isCurNodeTop = false; + break; + } + } + + if (isCurNodeTop) + { + result.push_back(nodes[i]); + } + } + + return result; +} + +bool BlastTreeData::isRoot(BlastChunkNode* node) +{ + if (node == nullptr || node->getParent() == nullptr) + return false; + + return eAsset == node->getParent()->getType(); +} + +bool BlastTreeData::isLeaf(BlastChunkNode* node) +{ + if (node == nullptr) + return false; + + for (BlastNode* curNode : node->children) + { + if (eChunk == curNode->getType()) + return false; + } + + return true; +} + +void removeChunkNodeSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return; + + BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); + chunk->support = false; + + for (BlastNode* curNode : node->children) + { + if (eChunk == curNode->getType()) + { + removeChunkNodeSupport((BlastChunkNode*)curNode); + } + } +} + +void BlastTreeData::makeSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return; + BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); + chunk->staticFlag = false; + chunk->support = true; + + for (BlastNode* curNode : node->children) + { + if (eChunk == curNode->getType()) + { + removeChunkNodeSupport((BlastChunkNode*)curNode); + } + } +} + +void BlastTreeData::makeStaticSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return; + BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); + chunk->staticFlag = true; + chunk->support = true; + + for (BlastNode* curNode : node->children) + { + if (eChunk == curNode->getType()) + { + removeChunkNodeSupport((BlastChunkNode*)curNode); + } + } +} + +void BlastTreeData::removeSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return; + + if (isLeaf(node)) + return; + + BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); + chunk->support = false; + chunk->staticFlag = false; + + for (BlastNode* curNode : node->children) + { + if (eChunk == curNode->getType()) + { + BPPChunk* curChunk = static_cast<BPPChunk*>(curNode->getData()); + curChunk->support = true; + } + } +} + +BlastNode* BlastTreeData::getBlastNodeByProjectData(void* data) +{ + std::map<void*, BlastNode*>::iterator itr = _blastProjectDataToNodeMap.find(data); + if (itr != _blastProjectDataToNodeMap.end()) + return itr->second; + + return nullptr; +} + +struct ChunkSupport +{ + ChunkSupport() + { + m_bSupport = false; + } + + bool m_bSupport; +}; + +struct BondChunkIndices +{ + BondChunkIndices() + { + chunkIndices[0] = -1; + chunkIndices[1] = -1; + } + + void SetIndices(uint32_t chunkIndex0, uint32_t chunkIndex1) + { + if (chunkIndex0 < chunkIndex1) + { + chunkIndices[0] = chunkIndex0; + chunkIndices[1] = chunkIndex1; + } + else + { + chunkIndices[0] = chunkIndex1; + chunkIndices[1] = chunkIndex0; + } + } + + uint32_t chunkIndices[2]; +}; + +void BlastTreeData::update() +{ + _freeBlastNode(); + + BPPBlast& blast = BlastProject::ins().getParams().blast; + std::vector<BlastAsset*> BlastAssetVec; + { + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + + std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap(); + std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = sampleManager.getAssetDescMap(); + + BlastController& blastController = sampleManager.getBlastController(); + SceneController& sceneController = sampleManager.getSceneController(); + + std::vector<BlastFamilyPtr>& families = blastController.getFamilies(); + int familiesSize = families.size(); + + std::map<BlastAsset*, AssetList::ModelAsset>::iterator it; + for (it = AssetDescMap.begin(); it != AssetDescMap.end(); it++) + { + 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[50]; + 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 = SampleManager::ins()->getConfig().additionalResourcesDir.back() + "/models/" + desc.file + ".bpxa"; + 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 = SampleManager::ins()->getConfig().additionalResourcesDir.back() + "/models/" + desc.file + ".bpxa"; + 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.support.healthMask.buf = nullptr; // ? + 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); + } + + 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]; + 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); + _assets.push_back(assetNode); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&asset, assetNode)); + + // get the firlst level chunks whose parentID is -1 + std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset, -1); + + for (size_t i = 0; i < childChunks.size(); ++i) + { + BPPChunk& chunk = *(childChunks[i]); + BlastChunkNode* chunkNode = new BlastChunkNode(chunk.name.buf, chunk, BlastAssetVec[c]); + assetNode->children.push_back(chunkNode); + chunkNode->setParent(assetNode); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&chunk, chunkNode)); + _addChunkNode(chunk, asset, chunkNode, BlastAssetVec[c]); + } + } + + BPPComposite& composite = blast.composite; + _composite = new BlastCompositeNode(composite.composite.buf, composite); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&composite, _composite)); + BPPAssetInstanceArray& assetInstanceArray = composite.blastAssetInstances; + count = assetInstanceArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + BPPAssetInstance& blastAssetInstance = composite.blastAssetInstances.buf[i]; + BlastAssetInstanceNode* blastAssetInstanceNode = new BlastAssetInstanceNode(blastAssetInstance.name.buf, blastAssetInstance); + _composite->children.push_back(blastAssetInstanceNode); + blastAssetInstanceNode->setParent(_composite); + _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) + { + BPPProjectile& projectile = projectileArray.buf[i]; + BlastProjectileNode* projectileNode = new BlastProjectileNode(projectile.name.buf, 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); + } +} + +void BlastTreeData::updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible) +{ + BPPBlast& blast = BlastProject::ins().getParams().blast; + BPPAssetArray& assetArray = blast.blastAssets; + if (assetIndex < assetArray.arraySizes[0]) + { + BPPAsset& asset = assetArray.buf[assetIndex]; + + std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset); + if (chunkIndex < childChunks.size()) + { + BPPChunk& chunk = *(childChunks[chunkIndex]); + chunk.visible = visible; + } + } +} + + +BlastChunkNode* findChunkNode(BlastChunkNode* chunkNode, uint32_t chunkIndex) +{ + if (chunkNode == nullptr) + return nullptr; + + if (((BPPChunk*)chunkNode->getData())->ID == chunkIndex) + return chunkNode; + + std::vector<BlastNode*>& children = chunkNode->children; + for (size_t i = 0; i < children.size(); ++i) + { + BlastNode* node = children[i]; + if (node->getType() == eChunk) + { + BlastChunkNode* chunkNode = findChunkNode(static_cast<BlastChunkNode*>(node), chunkIndex); + if (chunkNode) + { + return chunkNode; + } + else + continue; + } + + else + continue; + } + + return nullptr; +} + +std::vector<BlastChunkNode*> BlastTreeData::getChunkNodeByBlastChunk(const BlastAsset* asset, const std::vector<uint32_t>& chunkIndexes) +{ + std::vector<BlastChunkNode*> chunkNodes; + if (asset == nullptr || chunkIndexes.size() == 0) + { + return chunkNodes; + } + + BlastAssetNode* assetNode = _getAssetNode(asset); + if (assetNode) + { + std::vector<BlastNode*>& children = assetNode->children; + for (BlastNode* node : children) + { + if (node->getType() == eChunk) + { + for (uint32_t chunkId : chunkIndexes) + { + BlastChunkNode* chunkNode = findChunkNode(static_cast<BlastChunkNode*>(node), chunkId); + if (chunkNode) + { + chunkNodes.push_back(chunkNode); + } + } + } + } + } + + return chunkNodes; +} + +bool isCompleteSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return false; + + if (node->isSupport()) + return true; + + const std::vector<BlastNode*>& children = node->children; + for (BlastNode* curNode : children) + { + if (eChunk == curNode->getType()) + { + BlastChunkNode* chunkNode = (BlastChunkNode*)curNode; + if (0 == chunkNode->children.size()) + { + if (!chunkNode->isSupport()) + return false; + } + + if (!isCompleteSupport(chunkNode)) + return false; + } + } + + return true; +} + +bool BlastTreeData::isCompleteSupportAsset(const BlastAsset* asset) +{ + BlastAssetNode* assetNode = _getAssetNode(asset); + return isCompleteSupportAsset(assetNode); +} + +bool BlastTreeData::isCompleteSupportAsset(const BlastAssetNode* node) +{ + if (node == nullptr) + return false; + + const std::vector<BlastNode*>& children = node->children; + for (BlastNode* curNode : children) + { + if (eChunk == curNode->getType()) + { + BlastChunkNode* chunkNode = (BlastChunkNode*)curNode; + if (!isCompleteSupport(chunkNode)) + return false; + } + } + + return true; +} + +bool BlastTreeData::isOverlapSupportAsset(const BlastAsset* asset) +{ + BlastAssetNode* assetNode = _getAssetNode(asset); + return isOverlapSupportAsset(assetNode); +} + +bool isOverlapSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return false; + + bool isParentSupport = node->isSupport(); + + const std::vector<BlastNode*>& children = node->children; + for (BlastNode* curNode : children) + { + if (eChunk == curNode->getType()) + { + BlastChunkNode* chunkNode = (BlastChunkNode*)curNode; + if (0 == chunkNode->children.size()) + { + if (isParentSupport && chunkNode->isSupport()) + return true; + } + + if (isParentSupport && isOverlapSupport(chunkNode)) + return true; + } + } + + return false; +} + +bool BlastTreeData::isOverlapSupportAsset(const BlastAssetNode* node) +{ + if (node == nullptr) + return false; + + const std::vector<BlastNode*>& children = node->children; + for (BlastNode* curNode : children) + { + if (eChunk == curNode->getType()) + { + BlastChunkNode* chunkNode = (BlastChunkNode*)curNode; + if (isOverlapSupport(chunkNode)) + return true; + } + } + + return false; +} + +BlastTreeData::BlastTreeData() +{ + +} + +void BlastTreeData::_addChunkNode(const BPPChunk& parentData, BPPAsset& asset, BlastChunkNode* parentNode, void* assetPtr) +{ + if (parentNode != nullptr) + { + 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 freeChunkNode(BlastChunkNode* chunkNode) +{ + if (chunkNode == nullptr) + return; + + std::vector<BlastNode*>& children = chunkNode->children; + for (size_t i = 0; i < children.size(); ++i) + { + BlastNode* node = children[i]; + if (node->getType() == eChunk) + freeChunkNode(static_cast<BlastChunkNode*>(node)); + else + { + delete node; + node = nullptr; + } + } + + delete chunkNode; + chunkNode = nullptr; +} + +void BlastTreeData::_freeBlastNode() +{ + if (_composite) + { + size_t count = _composite->children.size(); + for (size_t i = 0; i < count; ++i) + { + delete _composite->children[i]; + } + delete _composite; + _composite = nullptr; + } + + size_t count = _assets.size(); + for (size_t i = 0; i < count; ++i) + { + std::vector<BlastNode*>& children = _assets[i]->children; + for (size_t j = 0; j < children.size(); ++j) + { + freeChunkNode(static_cast<BlastChunkNode*>(children[j])); + } + delete _assets[i]; + } + _assets.clear(); + + count = _projectiles.size(); + for (size_t i = 0; i < count; ++i) + { + delete _projectiles[i]; + } + _projectiles.clear(); + + count = _graphicsMeshes.size(); + for (size_t i = 0; i < count; ++i) + { + delete _graphicsMeshes[i]; + } + _graphicsMeshes.clear(); + + _blastProjectDataToNodeMap.clear(); +} + +BlastAssetNode* BlastTreeData::_getAssetNode(const BlastAsset* asset) +{ + std::map<BlastAsset*, AssetList::ModelAsset>& assetDescMap = SampleManager::ins()->getAssetDescMap(); + std::map<BlastAsset*, AssetList::ModelAsset>::iterator itrAssetDesc = assetDescMap.find(const_cast<BlastAsset*>(asset)); + + BlastAssetNode* foundAssetNode = nullptr; + for (BlastAssetNode* assetNode : _assets) + { + if (itrAssetDesc->second.name == assetNode->name) + { + foundAssetNode = assetNode; + break; + } + } + + return foundAssetNode; +} + +VisualButton::VisualButton(QWidget* parent, BlastNode* blastItem) + : QWidget(parent) + , _button(new QPushButton(parent)) + , _blastItem(blastItem) +{ + 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); +} + +void VisualButton::on_visualbility_toggled(bool checked) +{ + if (checked) + { + _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_visible.png")); + } + else + { + _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_notVisible.png")); + } + + if (_blastItem) + { + _blastItem->setVisible(checked); + } +} + +void VisualButton::_updateBlast(bool visible) +{ + EBlastNodeType type = _blastItem->getType(); + + switch (type) + { + 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; + } +} + +static BlastSceneTree* sBlastSceneTree = nullptr; +BlastSceneTree* BlastSceneTree::ins() +{ + return sBlastSceneTree; +} + +BlastSceneTree::BlastSceneTree(QWidget *parent) + : QDockWidget(parent) +{ + ui.setupUi(this); + _updateData = true; + sBlastSceneTree = this; + + ui.blastSceneTree->setStyleSheet("QTreeWidget::item{height:24px}"); + ui.blastSceneTree->setColumnWidth(0, 260); + ui.blastSceneTree->setColumnWidth(1, 20); + + ui.blastSceneTree->setContextMenuPolicy(Qt::CustomContextMenu); + + _treeChunkContextMenu = new QMenu(this); + _makeSupportAction = new QAction(tr("Make Support"), this); + _treeChunkContextMenu->addAction(_makeSupportAction); + connect(_makeSupportAction, SIGNAL(triggered()), this, SLOT(onMakeSupportMenuItemClicked())); + + _makeStaticSupportAction = new QAction(tr("Make Static Support"), this); + _treeChunkContextMenu->addAction(_makeStaticSupportAction); + connect(_makeStaticSupportAction, SIGNAL(triggered()), this, SLOT(onMakeStaticSupportMenuItemClicked())); + + _removeSupportAction = new QAction(tr("Remove Support"), this); + _treeChunkContextMenu->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())); + + _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); + _treeBondContextMenu->addAction(_removeAllBondsAction); + connect(_removeAllBondsAction, SIGNAL(triggered()), this, SLOT(onRemoveAllBondsMenuItemClicked())); +} + +BlastSceneTree::~BlastSceneTree() +{ + +} + +void BlastSceneTree::updateValues(bool updataData) +{ + if (updataData) + { + BlastTreeData::ins().update(); + } + + _updateTreeUIs(); +} + +void BlastSceneTree::dataSelected(std::vector<BlastNode*> selections) +{ + for (size_t i = 0; i < selections.size(); ++i) + { + _selectTreeItem(selections[i]); + } +} + +void BlastSceneTree::addObserver(ISceneObserver* observer) +{ + std::vector<ISceneObserver*>::iterator itr = std::find(_observers.begin(), _observers.end(), observer); + if (itr == _observers.end()) + { + _observers.push_back(observer); + } +} + +void BlastSceneTree::removeObserver(ISceneObserver* observer) +{ + std::vector<ISceneObserver*>::iterator itr = std::find(_observers.begin(), _observers.end(), observer); + _observers.erase(itr); +} + +void BlastSceneTree::updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible) +{ + BlastTreeData::ins().updateVisible(assetIndex, chunkIndex, visible); +} + +void BlastSceneTree::updateChunkItemSelection() +{ + _updateData = false; + + ui.blastSceneTree->clearSelection(); + BlastTreeData& treeData = BlastTreeData::ins(); + std::vector<BlastChunkNode*> chunkNodes; + + std::map<BlastAsset*, std::vector<uint32_t>> selectedChunks = SampleManager::ins()->getSelectedChunks(); + std::map<BlastAsset*, std::vector<uint32_t>>::iterator itrAssetSelectedChunks = selectedChunks.begin(); + for (; itrAssetSelectedChunks != selectedChunks.end(); ++itrAssetSelectedChunks) + { + std::vector<BlastChunkNode*> aseetNodes = treeData.getChunkNodeByBlastChunk(itrAssetSelectedChunks->first, itrAssetSelectedChunks->second); + chunkNodes.insert(chunkNodes.end(), aseetNodes.begin(), aseetNodes.end()); + } + + for (BlastChunkNode* node : chunkNodes) + { + _selectTreeItem(node); + } + + _updateData = true; +} + +void BlastSceneTree::makeSupport() +{ + std::vector<BlastChunkNode*> selectedChunkNodes; + QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); + for (int i = 0; i < selectedItems.size(); ++i) + { + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + + if (eChunk == itr.value()->getType()) + { + selectedChunkNodes.push_back((BlastChunkNode*)itr.value()); + } + } + + std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes); + for (size_t i = 0; i < topChunkNodes.size(); ++i) + { + BlastChunkNode* chunkNode = topChunkNodes[i]; + BlastTreeData::makeSupport(chunkNode); + } + + _updateChunkTreeItems(); +} + +void BlastSceneTree::makeStaticSupport() +{ + std::vector<BlastChunkNode*> selectedChunkNodes; + QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); + for (int i = 0; i < selectedItems.size(); ++i) + { + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + + if (eChunk == itr.value()->getType()) + { + selectedChunkNodes.push_back((BlastChunkNode*)itr.value()); + } + } + + std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes); + for (size_t i = 0; i < topChunkNodes.size(); ++i) + { + BlastChunkNode* chunkNode = topChunkNodes[i]; + BlastTreeData::makeStaticSupport(chunkNode); + } + + _updateChunkTreeItems(); +} + +void BlastSceneTree::removeSupport() +{ + std::vector<BlastChunkNode*> selectedChunkNodes; + QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); + for (int i = 0; i < selectedItems.size(); ++i) + { + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + + if (eChunk == itr.value()->getType()) + { + selectedChunkNodes.push_back((BlastChunkNode*)itr.value()); + } + } + + std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes); + for (size_t i = 0; i < topChunkNodes.size(); ++i) + { + BlastChunkNode* chunkNode = topChunkNodes[i]; + BlastTreeData::removeSupport(chunkNode); + } + + _updateChunkTreeItems(); +} + +void BlastSceneTree::bondChunks() +{ + +} + +void BlastSceneTree::bondChunksWithJoints() +{ + +} + +void BlastSceneTree::removeAllBonds() +{ + +} + +void BlastSceneTree::on_btnAsset_clicked() +{ + QMessageBox::information(NULL, "test", "on_btnAsset_clicked"); +} + +void BlastSceneTree::on_assetComposite_clicked() +{ + QMessageBox::information(NULL, "test", "on_assetComposite_clicked"); +} + +void BlastSceneTree::on_btnChunk_clicked() +{ + QMessageBox::information(NULL, "test", "on_btnChunk_clicked"); +} + +void BlastSceneTree::on_btnBond_clicked() +{ + QMessageBox::information(NULL, "test", "on_btnBond_clicked"); +} + +void BlastSceneTree::on_btnProjectile_clicked() +{ + QMessageBox::information(NULL, "test", "on_btnProjectile_clicked"); +} + +void BlastSceneTree::on_blastSceneTree_customContextMenuRequested(const QPoint &pos) +{ + QList<QTreeWidgetItem*> items = ui.blastSceneTree->selectedItems(); + + if (items.count() == 1) + { + QTreeWidgetItem* curItem = items.at(0); + + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(curItem); + if (itr != _treeItemDataMap.end()) + { + if (eChunk == itr.value()->getType() || eBond == itr.value()->getType()) + { + _treeChunkContextMenu->exec(QCursor::pos()); + } + } + } + else if (items.count() > 1) + { + bool allSupportChunk = true; + for (int i = 0; i < items.count(); ++i) + { + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(items.at(i)); + if (itr != _treeItemDataMap.end()) + { + if (eChunk != itr.value()->getType()) + { + allSupportChunk = false; + break; + } + } + } + + if (allSupportChunk) + { + _treeBondContextMenu->exec(QCursor::pos()); + } + } + +} + +void BlastSceneTree::on_blastSceneTree_itemSelectionChanged() +{ + if (!_updateData) + return; + + SampleManager::ins()->clearChunksSelected(); + + QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); + std::vector<BlastNode*> nodes; + for (int i = 0; i < selectedItems.count(); ++i) + { + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + if (itr != _treeItemDataMap.end()) + { + nodes.push_back(itr.value()); + + BlastNode* node = itr.value(); + if (eChunk == node->getType()) + { + ((BlastChunkNode*)node)->setSelected(true); + } + else if (eAssetInstance == node->getType()) + { + ((BlastAssetInstanceNode*)node)->setSelected(true); + } + } + } + + for (size_t i = 0; i < _observers.size(); ++i) + { + _observers[i]->dataSelected(nodes); + } +} + +void BlastSceneTree::onMakeSupportMenuItemClicked() +{ + makeSupport(); +} + +void BlastSceneTree::onMakeStaticSupportMenuItemClicked() +{ + makeStaticSupport(); +} + +void BlastSceneTree::onRemoveSupportMenuItemClicked() +{ + removeSupport(); +} + +void BlastSceneTree::onBondChunksMenuItemClicked() +{ + bondChunks(); +} + +void BlastSceneTree::onBondChunksWithJointsMenuItemClicked() +{ + bondChunksWithJoints(); +} + +void BlastSceneTree::onRemoveAllBondsMenuItemClicked() +{ + removeAllBonds(); +} + +void BlastSceneTree::_updateTreeUIs() +{ + ui.blastSceneTree->clear(); + _treeItemDataMap.clear(); + _treeDataItemMap.clear(); + + BlastCompositeNode* compositeNode = BlastTreeData::ins().getCompsiteNode(); + if (compositeNode != 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(); + 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()); + 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); + } + } + + std::vector<BlastAssetNode*>& assets = BlastTreeData::ins().getAssetNodes(); + size_t count = assets.size(); + for (size_t i = 0; i < count; ++i) + { + 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); + _treeItemDataMap.insert(assetTreeWidgetItem, assetNode); + _treeDataItemMap.insert(assetNode, assetTreeWidgetItem); + + _addChunkUI(assetNode, assetTreeWidgetItem); + } + + std::vector<BlastProjectileNode*>& projectiles = BlastTreeData::ins().getProjectileNodes(); + count = projectiles.size(); + for (int i = 0; i < count; ++i) + { + 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); + } + + std::vector<BlastGraphicsMeshNode*>& graphicsMeshes = BlastTreeData::ins().getGraphicsMeshNodes(); + count = graphicsMeshes.size(); + for (int i = 0; i < count; ++i) + { + 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); + _treeItemDataMap.insert(graphicsMesheTreeWidgetItem, graphicsMesheNode); + _treeDataItemMap.insert(graphicsMesheNode, graphicsMesheTreeWidgetItem); + } + + //for (int j = 0; j < ui.blastSceneTree->topLevelItemCount(); ++j) + //{ + // QTreeWidgetItem* topLevelItem = ui.blastSceneTree->topLevelItem(j); + // ui.blastSceneTree->expandItem(topLevelItem); + //} + ui.blastSceneTree->expandAll(); +} + +void BlastSceneTree::_addChunkUI(const BlastNode* parentNode, QTreeWidgetItem* parentTreeItem) +{ + if (parentNode != nullptr && parentTreeItem != nullptr) + { + for (size_t i = 0; i < parentNode->children.size(); ++i) + { + BlastNode* node = parentNode->children[i]; + if (node == nullptr) + continue; + + QTreeWidgetItem* treeWidgetItem = nullptr; + + if (node->getType() == eChunk) + { + BlastChunkNode* chunk = static_cast<BlastChunkNode*>(node); + treeWidgetItem = new QTreeWidgetItem(parentTreeItem); + treeWidgetItem->setText(0, chunk->name.c_str()); + if (chunk->isSupport()) + { + treeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png")); + } + else + { + treeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png")); + } + + _addChunkUI(chunk, 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()); + } + + 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) +{ + assert(chunk != nullptr); + + _removeSupportAction->setEnabled(true); + _makeSupportAction->setEnabled(true); + _makeStaticSupportAction->setEnabled(true); + + if (!chunk->support && !chunk->staticFlag) + { + _removeSupportAction->setEnabled(false); + chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png")); + } + else if (chunk->support && !chunk->staticFlag) + { + _makeSupportAction->setEnabled(false); + chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png")); + } + else if (chunk->support && chunk->staticFlag) + { + _makeStaticSupportAction->setEnabled(false); + chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Static.png")); + } +} + +void BlastSceneTree::_updateChunkTreeItems() +{ + for (QMap<BlastNode*, QTreeWidgetItem*>::iterator itr = _treeDataItemMap.begin(); itr != _treeDataItemMap.end(); ++itr) + { + BlastNode* node = itr.key(); + QTreeWidgetItem* treeItem = itr.value(); + if (eChunk == node->getType()) + { + BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); + if (!chunk->support && !chunk->staticFlag) + { + treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png")); + } + else if (chunk->support && !chunk->staticFlag) + { + treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png")); + } + else if (chunk->support && chunk->staticFlag) + { + treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Static.png")); + } + } + } +} + +void BlastSceneTree::_selectTreeItem(BlastNode* node) +{ + QMap<BlastNode*, QTreeWidgetItem*>::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; +// } +//} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h new file mode 100644 index 0000000..540f420 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h @@ -0,0 +1,284 @@ +#ifndef BLASTSCENETREE_H +#define BLASTSCENETREE_H + +#include <QtWidgets/QDockWidget> +#include "ui_BlastSceneTree.h" +#include "ProjectParams.h" +#include <vector> +#include <string> +#include <QtCore/QMap> + +class QTreeWidgetItem; +class BlastAsset; + +enum EBlastNodeType +{ + eBond, + eChunk, + eAsset, + eProjectile, + eGraphicsMesh, + eAssetInstance, + eLandmark, + eComposite, +}; + +class BlastNode +{ +public: + BlastNode(const std::string& inName, void* inData) + : name(inName) + , _data(inData) + { + } + + void* getData() { return _data; } + void setParent(BlastNode* parent) { _parent = parent; } + BlastNode* getParent() { return _parent; } + virtual EBlastNodeType getType() = 0; + virtual bool getVisible() = 0; + virtual void setVisible(bool val) = 0; + + std::string name; + std::vector<BlastNode*> children; + +protected: + void* _data; + BlastNode* _parent; +}; + +class BlastBondNode : public BlastNode +{ +public: + BlastBondNode(const std::string& inName, BPPBond& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eBond; } + virtual bool getVisible() { return ((BPPBond*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPBond*)_data)->visible = val; } + +private: + std::vector<BlastNode*> children; +}; + +class BlastChunkNode : public BlastNode +{ +public: + BlastChunkNode(const std::string& inName, BPPChunk& inData, void* assetPtr) + : BlastNode(inName, &inData) + { + _assetPtr = assetPtr; + } + virtual EBlastNodeType getType() { return eChunk; } + virtual bool getVisible() { return ((BPPChunk*)_data)->visible; } + virtual void setVisible(bool val);// { ((BPPChunk*)_data)->visible = val; } + void setSelected(bool val); + bool isSupport() { return ((BPPChunk*)_data)->support; } + void* _assetPtr; +}; + +class BlastAssetNode : public BlastNode +{ +public: + BlastAssetNode(const std::string& inName, BPPAsset& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eAsset; } + virtual bool getVisible() { return ((BPPAsset*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPAsset*)_data)->visible = val; } +}; + +class BlastProjectileNode : public BlastNode +{ +public: + BlastProjectileNode(const std::string& inName, BPPProjectile& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eProjectile; } + virtual bool getVisible() { return ((BPPProjectile*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPProjectile*)_data)->visible = val; } +}; + +class BlastGraphicsMeshNode : public BlastNode +{ +public: + BlastGraphicsMeshNode(const std::string& inName, BPPGraphicsMesh& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eGraphicsMesh; } + virtual bool getVisible() { return ((BPPGraphicsMesh*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPGraphicsMesh*)_data)->visible = val; } +}; + +class BlastAssetInstanceNode : public BlastNode +{ +public: + BlastAssetInstanceNode(const std::string& inName, BPPAssetInstance& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eAssetInstance; } + virtual bool getVisible() { return ((BPPAssetInstance*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPAssetInstance*)_data)->visible = val; } + void setSelected(bool val); +}; + +class BlastLandmarkNode : public BlastNode +{ +public: + BlastLandmarkNode(const std::string& inName, BPPLandmark& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eLandmark; } + virtual bool getVisible() { return ((BPPLandmark*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPLandmark*)_data)->visible = val; } +}; + +class BlastCompositeNode : public BlastNode +{ +public: + BlastCompositeNode(const std::string& inName, BPPComposite& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eComposite; } + virtual bool getVisible() { return ((BPPComposite*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPComposite*)_data)->visible = val; } +}; + +class BlastTreeData +{ +public: + static BlastTreeData& ins(); + static bool isChild(BlastChunkNode* parent, BlastChunkNode* child); + static std::vector<BlastChunkNode*> getTopChunkNodes(std::vector<BlastChunkNode*>& nodes); + static bool isRoot(BlastChunkNode* node); + static bool isLeaf(BlastChunkNode* node); + static void makeSupport(BlastChunkNode* node); + static void makeStaticSupport(BlastChunkNode* node); + static void removeSupport(BlastChunkNode* node); + + BlastNode* getBlastNodeByProjectData(void* blastProjectData); + BlastCompositeNode* getCompsiteNode() { return _composite; } + std::vector<BlastAssetNode*>& getAssetNodes() { return _assets; } + std::vector<BlastProjectileNode*>& getProjectileNodes() { return _projectiles; } + std::vector<BlastGraphicsMeshNode*>& getGraphicsMeshNodes() { return _graphicsMeshes; } + std::vector<BlastChunkNode*> getChunkNodeByBlastChunk(const BlastAsset* asset, const std::vector<uint32_t>& chunkIndexes); + bool isCompleteSupportAsset(const BlastAsset* asset); + bool isCompleteSupportAsset(const BlastAssetNode* node); + bool isOverlapSupportAsset(const BlastAsset* asset); + bool isOverlapSupportAsset(const BlastAssetNode* node); + void update(); + + void updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible); + +private: + BlastTreeData(); + void _addChunkNode(const BPPChunk& parentData, BPPAsset& asset, BlastChunkNode* parentNode, void* assetPtr); + void _freeBlastNode(); + BlastAssetNode* _getAssetNode(const BlastAsset* asset); + +private: + BlastCompositeNode* _composite; + std::vector<BlastAssetNode*> _assets; + std::vector<BlastProjectileNode*> _projectiles; + std::vector<BlastGraphicsMeshNode*> _graphicsMeshes; + std::map<void*, BlastNode*> _blastProjectDataToNodeMap; +}; + +class ISceneObserver +{ +public: + virtual void dataSelected(std::vector<BlastNode*> selections) = 0; +}; + +class VisualButton : public QWidget +{ + Q_OBJECT +public: + VisualButton(QWidget* parent, BlastNode* blastItem); + +protected slots: + void on_visualbility_toggled(bool checked); +private: + void _updateBlast(bool visible); + +private: + QPushButton* _button; + BlastNode* _blastItem; +}; + +class BlastSceneTree : public QDockWidget, public ISceneObserver +{ + Q_OBJECT + +public: + static BlastSceneTree* ins(); + + BlastSceneTree(QWidget *parent = 0); + ~BlastSceneTree(); + + void updateValues(bool updataData = true); + + virtual void dataSelected(std::vector<BlastNode*> selections); + + void addObserver(ISceneObserver* observer); + void removeObserver(ISceneObserver* observer); + + void updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible); + void updateChunkItemSelection(); + + void makeSupport(); + void makeStaticSupport(); + void removeSupport(); + void bondChunks(); + void bondChunksWithJoints(); + void removeAllBonds(); + +protected slots: + void on_btnAsset_clicked(); + void on_assetComposite_clicked(); + void on_btnChunk_clicked(); + void on_btnBond_clicked(); + void on_btnProjectile_clicked(); + void on_blastSceneTree_customContextMenuRequested(const QPoint &pos); + void on_blastSceneTree_itemSelectionChanged(); + void onMakeSupportMenuItemClicked(); + void onMakeStaticSupportMenuItemClicked(); + void onRemoveSupportMenuItemClicked(); + void onBondChunksMenuItemClicked(); + void onBondChunksWithJointsMenuItemClicked(); + void onRemoveAllBondsMenuItemClicked(); + +private: + void _updateTreeUIs(); + void _addChunkUI(const BlastNode* parentNode, QTreeWidgetItem* parentTreeItem); + void _updateChunkTreeItemAndMenu(BPPChunk* chunk, QTreeWidgetItem* chunkItem); + void _updateChunkTreeItems(); + + void _selectTreeItem(BlastNode* node); + + //void _createTestData(); + +private: + Ui::BlastSceneTree ui; + QMap<QTreeWidgetItem*, BlastNode*> _treeItemDataMap; + QMap<BlastNode*, QTreeWidgetItem*> _treeDataItemMap; + QMenu* _treeChunkContextMenu; + QMenu* _treeBondContextMenu; + QAction* _makeSupportAction; + QAction* _makeStaticSupportAction; + QAction* _removeSupportAction; + QAction* _bondChunksAction; + QAction* _bondChunksWithJointsAction; + QAction* _removeAllBondsAction; + std::vector<ISceneObserver*> _observers; + bool _updateData; +}; + +#endif // BLASTSCENETREE_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp new file mode 100644 index 0000000..98b5646 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp @@ -0,0 +1,523 @@ +#include "BlastToolbar.h" + +#include <QtWidgets/QFileDialog> +#include "AppMainWindow.h" +#include "PhysXController.h" +#include "QtUtil.h" + +BlastToolbar::BlastToolbar(QWidget* parent) + : QDockWidget(parent) +{ + // to hide the title bar completely must replace the default widget with a generic one + QWidget* titleWidget = new QWidget(this); + this->setTitleBarWidget(titleWidget); + this->setObjectName(QString::fromUtf8("AppMainToolbar")); + this->setMinimumSize(QSize(0, 50)); + this->setMaximumSize(QSize(16777215, 80)); + + if (this->objectName().isEmpty()) + this->setObjectName(QStringLiteral("AppMainToolbar")); + this->resize(1330, 54); + + QWidget* widget = new QWidget(); + hLayout = new QHBoxLayout(widget); + hLayout->setObjectName(QStringLiteral("hLayout")); + hLayout->setContentsMargins(-1, 3, -1, 3); + + QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + + btnOpenProject = new QPushButton(widget); + setStyledToolTip(btnOpenProject, "Open Blast Asset"); + const QFont& font = btnOpenProject->font(); + QFont fontCopy(font); + fontCopy.setPixelSize(9); + + btnOpenProject->setObjectName(QStringLiteral("btnOpenProject")); + sizePolicy1.setHeightForWidth(btnOpenProject->sizePolicy().hasHeightForWidth()); + btnOpenProject->setSizePolicy(sizePolicy1); + btnOpenProject->setMinimumSize(QSize(40, 40)); + btnOpenProject->setMaximumSize(QSize(40, 40)); + btnOpenProject->setText(QApplication::translate("AppMainToolbar", "Open", 0)); + hLayout->addWidget(btnOpenProject); + + btnSaveProject = new QPushButton(widget); + setStyledToolTip(btnSaveProject, "Not Implement"); + btnSaveProject->setObjectName(QStringLiteral("btnSaveProject")); + sizePolicy1.setHeightForWidth(btnOpenProject->sizePolicy().hasHeightForWidth()); + btnSaveProject->setSizePolicy(sizePolicy1); + btnSaveProject->setMinimumSize(QSize(40, 40)); + btnSaveProject->setMaximumSize(QSize(40, 40)); + btnSaveProject->setText(QApplication::translate("AppMainToolbar", "Save\nAll", 0)); + hLayout->addWidget(btnSaveProject); + + btnExportAssets = new QPushButton(widget); + setStyledToolTip(btnExportAssets, "Not Implement"); + btnExportAssets->setObjectName(QStringLiteral("btnExportAssets")); + sizePolicy1.setHeightForWidth(btnExportAssets->sizePolicy().hasHeightForWidth()); + btnExportAssets->setSizePolicy(sizePolicy1); + btnExportAssets->setMinimumSize(QSize(40, 40)); + btnExportAssets->setMaximumSize(QSize(40, 40)); + btnExportAssets->setText(QApplication::translate("AppMainToolbar", "Export", 0)); + hLayout->addWidget(btnExportAssets); + + vLayoutExport = new QVBoxLayout(); + vLayoutExport->setObjectName(QStringLiteral("vLayoutExport")); + + hLayoutExport = new QHBoxLayout(); + hLayoutExport->setObjectName(QStringLiteral("hLayoutExport")); + + lExportFilepath = new QLabel(widget); + lExportFilepath->setObjectName(QStringLiteral("lExportFilepath")); + lExportFilepath->setText(QApplication::translate("AppMainToolbar", "Export Path", 0)); + hLayoutExport->addWidget(lExportFilepath); + + btnExportFilepath = new QPushButton(widget); + btnExportFilepath->setObjectName(QStringLiteral("btnExportFilepath")); + sizePolicy1.setHeightForWidth(btnExportFilepath->sizePolicy().hasHeightForWidth()); + btnExportFilepath->setSizePolicy(sizePolicy1); + btnExportFilepath->setMinimumSize(QSize(14, 14)); + btnExportFilepath->setMaximumSize(QSize(14, 14)); + btnExportFilepath->setText(QApplication::translate("AppMainToolbar", "", 0)); + btnExportFilepath->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnExportFilepath.png")); + btnExportFilepath->setIconSize(QSize(14, 14)); + hLayoutExport->addWidget(btnExportFilepath); + + vLayoutExport->addLayout(hLayoutExport); + + leExportFilepath = new QLineEdit(widget); + leExportFilepath->setObjectName(QStringLiteral("leExportFilepath")); + sizePolicy1.setHeightForWidth(leExportFilepath->sizePolicy().hasHeightForWidth()); + leExportFilepath->setSizePolicy(sizePolicy1); + leExportFilepath->setMinimumSize(QSize(150, 20)); + leExportFilepath->setMaximumSize(QSize(150, 20)); + leExportFilepath->setText(QApplication::translate("AppMainToolbar", "", 0)); + vLayoutExport->addWidget(leExportFilepath); + + hLayout->addLayout(vLayoutExport); + + fSeparate = new QFrame(widget); + fSeparate->setObjectName(QStringLiteral("fSeparate")); + fSeparate->setFrameShape(QFrame::VLine); + fSeparate->setFrameShadow(QFrame::Sunken); + hLayout->addWidget(fSeparate); + + vLayoutDepthCoverage = new QVBoxLayout(); + vLayoutDepthCoverage->setObjectName(QStringLiteral("vLayoutDepthCoverage")); + + hlDepthPreview = new QHBoxLayout(); + hlDepthPreview->setObjectName(QStringLiteral("hlDepthPreview")); + + lbDepthPreview = new QLabel(widget); + lbDepthPreview->setObjectName(QStringLiteral("lbDepthPreview")); + lbDepthPreview->setText(QApplication::translate("AppMainToolbar", "Depth Preview", 0)); + hlDepthPreview->addWidget(lbDepthPreview); + + ssbiDepthPreview = new SlideSpinBoxInt(widget); + ssbiDepthPreview->setObjectName(QStringLiteral("ssbiDepthPreview")); + QSizePolicy sizePolicy2(QSizePolicy::Minimum, QSizePolicy::Fixed); + sizePolicy2.setHorizontalStretch(0); + sizePolicy2.setVerticalStretch(0); + sizePolicy2.setHeightForWidth(ssbiDepthPreview->sizePolicy().hasHeightForWidth()); + ssbiDepthPreview->setSizePolicy(sizePolicy2); + ssbiDepthPreview->setMinimumSize(QSize(40, 20)); + ssbiDepthPreview->setMaximumSize(QSize(100, 16777215)); + hlDepthPreview->addWidget(ssbiDepthPreview); + + vLayoutDepthCoverage->addLayout(hlDepthPreview); + + hlExactCoverage = new QHBoxLayout(); + hlExactCoverage->setObjectName(QStringLiteral("hlExactCoverage")); + + lbDepthPreview = new QLabel(widget); + lbDepthPreview->setObjectName(QStringLiteral("hlExactCoverage")); + lbDepthPreview->setText(QApplication::translate("AppMainToolbar", "Exact Coverage", 0)); + hlExactCoverage->addWidget(lbDepthPreview); + + cbExactCoverage = new QCheckBox(widget); + cbExactCoverage->setObjectName(QStringLiteral("cbExactCoverage")); + sizePolicy1.setHeightForWidth(cbExactCoverage->sizePolicy().hasHeightForWidth()); + cbExactCoverage->setSizePolicy(sizePolicy1); + cbExactCoverage->setLayoutDirection(Qt::RightToLeft); + hlExactCoverage->addWidget(cbExactCoverage); + + vLayoutDepthCoverage->addLayout(hlExactCoverage); + + hLayout->addLayout(vLayoutDepthCoverage); + + fSeparate = new QFrame(widget); + fSeparate->setObjectName(QStringLiteral("fSeparate")); + fSeparate->setFrameShape(QFrame::VLine); + fSeparate->setFrameShadow(QFrame::Sunken); + hLayout->addWidget(fSeparate); + + btnSelectTool = new QPushButton(widget); + setStyledToolTip(btnSelectTool, "Switch to Selection Mode"); + btnSelectTool->setObjectName(QStringLiteral("btnSelectTool")); + sizePolicy1.setHeightForWidth(btnSelectTool->sizePolicy().hasHeightForWidth()); + btnSelectTool->setSizePolicy(sizePolicy1); + btnSelectTool->setMinimumSize(QSize(40, 40)); + btnSelectTool->setMaximumSize(QSize(40, 40)); + btnSelectTool->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnSelectTool.png")); + btnSelectTool->setIconSize(QSize(40, 40)); + QAction* pointselect_action = new QAction(tr("point select"), this); + QAction* rectselect_action = new QAction(tr("rect select"), this); + QAction* drawselect_action = new QAction(tr("draw select"), this); + connect(pointselect_action, SIGNAL(triggered()), this, SLOT(on_pointselect_action())); + connect(rectselect_action, SIGNAL(triggered()), this, SLOT(on_rectselect_action())); + connect(drawselect_action, SIGNAL(triggered()), this, SLOT(on_drawselect_action())); + QMenu* menu = new QMenu(btnSelectTool); + menu->addAction(pointselect_action); + menu->addAction(rectselect_action); + menu->addAction(drawselect_action); + btnSelectTool->setMenu(menu); + hLayout->addWidget(btnSelectTool); + + btnPaintbrush = new QPushButton(widget); + setStyledToolTip(btnPaintbrush, "Not Implement"); + btnPaintbrush->setObjectName(QStringLiteral("btnPaintbrush")); + sizePolicy1.setHeightForWidth(btnPaintbrush->sizePolicy().hasHeightForWidth()); + btnPaintbrush->setSizePolicy(sizePolicy1); + btnPaintbrush->setMinimumSize(QSize(40, 40)); + btnPaintbrush->setMaximumSize(QSize(40, 40)); + btnPaintbrush->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnPaintbrush.png")); + btnPaintbrush->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnPaintbrush); + + btnFractureTool = new QPushButton(widget); + setStyledToolTip(btnFractureTool, "Not Implement"); + btnFractureTool->setObjectName(QStringLiteral("btnFractureTool")); + sizePolicy1.setHeightForWidth(btnFractureTool->sizePolicy().hasHeightForWidth()); + btnFractureTool->setSizePolicy(sizePolicy1); + btnFractureTool->setMinimumSize(QSize(40, 40)); + btnFractureTool->setMaximumSize(QSize(40, 40)); + btnFractureTool->setText(QApplication::translate("AppMainToolbar", "Fracture", 0)); + btnFractureTool->setFont(fontCopy); + hLayout->addWidget(btnFractureTool); + + btnExplodedViewTool = new QPushButton(widget); + setStyledToolTip(btnExplodedViewTool, "Not Implement"); + btnExplodedViewTool->setObjectName(QStringLiteral("btnExplodedViewTool")); + sizePolicy1.setHeightForWidth(btnExplodedViewTool->sizePolicy().hasHeightForWidth()); + btnExplodedViewTool->setSizePolicy(sizePolicy1); + btnExplodedViewTool->setMinimumSize(QSize(40, 40)); + btnExplodedViewTool->setMaximumSize(QSize(40, 40)); + btnExplodedViewTool->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnExplodedViewTool.png")); + btnExplodedViewTool->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnExplodedViewTool); + + btnJointsTool = new QPushButton(widget); + setStyledToolTip(btnJointsTool, "Not Implement"); + btnJointsTool->setObjectName(QStringLiteral("btnJointsTool")); + sizePolicy1.setHeightForWidth(btnJointsTool->sizePolicy().hasHeightForWidth()); + btnJointsTool->setSizePolicy(sizePolicy1); + btnJointsTool->setMinimumSize(QSize(40, 40)); + btnJointsTool->setMaximumSize(QSize(40, 40)); + btnJointsTool->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnJointsTool.png")); + btnJointsTool->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnJointsTool); + + btnFuseSelectedChunks = new QPushButton(widget); + setStyledToolTip(btnFuseSelectedChunks, "Not Implement"); + btnFuseSelectedChunks->setObjectName(QStringLiteral("btnFuseSelectedChunks")); + sizePolicy1.setHeightForWidth(btnFuseSelectedChunks->sizePolicy().hasHeightForWidth()); + btnFuseSelectedChunks->setSizePolicy(sizePolicy1); + btnFuseSelectedChunks->setMinimumSize(QSize(40, 40)); + btnFuseSelectedChunks->setMaximumSize(QSize(40, 40)); + btnFuseSelectedChunks->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnFuseSelectedChunks.png")); + btnFuseSelectedChunks->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnFuseSelectedChunks); + + fSeparate = new QFrame(widget); + fSeparate->setObjectName(QStringLiteral("fSeparate")); + fSeparate->setFrameShape(QFrame::VLine); + fSeparate->setFrameShadow(QFrame::Sunken); + hLayout->addWidget(fSeparate); + + btnReset = new QPushButton(widget); + setStyledToolTip(btnReset, "Reset Chunks and Switch to Edition Mode"); + btnReset->setObjectName(QStringLiteral("btnReset")); + sizePolicy1.setHeightForWidth(btnReset->sizePolicy().hasHeightForWidth()); + btnReset->setSizePolicy(sizePolicy1); + btnReset->setMinimumSize(QSize(40, 40)); + btnReset->setMaximumSize(QSize(40, 40)); + btnReset->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnReset.png")); + btnReset->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnReset); + + btnSimulatePlay = new QPushButton(widget); + setStyledToolTip(btnSimulatePlay, "Switch to Simulate Mode"); + btnSimulatePlay->setObjectName(QStringLiteral("btnSimulatePlay")); + sizePolicy1.setHeightForWidth(btnSimulatePlay->sizePolicy().hasHeightForWidth()); + btnSimulatePlay->setSizePolicy(sizePolicy1); + btnSimulatePlay->setMinimumSize(QSize(40, 40)); + btnSimulatePlay->setMaximumSize(QSize(40, 40)); + btnSimulatePlay->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnSimulatePlay.png")); + btnSimulatePlay->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnSimulatePlay); + + btnFrameStepForward = new QPushButton(widget); + setStyledToolTip(btnFrameStepForward, "Switch to StepForward Mode"); + btnFrameStepForward->setObjectName(QStringLiteral("btnFrameStepForward")); + sizePolicy1.setHeightForWidth(btnFrameStepForward->sizePolicy().hasHeightForWidth()); + btnFrameStepForward->setSizePolicy(sizePolicy1); + btnFrameStepForward->setMinimumSize(QSize(40, 40)); + btnFrameStepForward->setMaximumSize(QSize(40, 40)); + btnFrameStepForward->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnFrameStepForward.png")); + btnFrameStepForward->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnFrameStepForward); + + fSeparate = new QFrame(widget); + fSeparate->setObjectName(QStringLiteral("fSeparate")); + fSeparate->setFrameShape(QFrame::VLine); + fSeparate->setFrameShadow(QFrame::Sunken); + hLayout->addWidget(fSeparate); + + btnBomb = new QPushButton(widget); + setStyledToolTip(btnBomb, "Not Implement"); + btnBomb->setObjectName(QStringLiteral("btnBomb")); + sizePolicy1.setHeightForWidth(btnBomb->sizePolicy().hasHeightForWidth()); + btnBomb->setSizePolicy(sizePolicy1); + btnBomb->setMinimumSize(QSize(40, 40)); + btnBomb->setMaximumSize(QSize(40, 40)); + btnBomb->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnBomb.png")); + btnBomb->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnBomb); + + btnProjectile = new QPushButton(widget); + setStyledToolTip(btnProjectile, "Throw a Box to Chunks"); + btnProjectile->setObjectName(QStringLiteral("btnProjectile")); + sizePolicy1.setHeightForWidth(btnProjectile->sizePolicy().hasHeightForWidth()); + btnProjectile->setSizePolicy(sizePolicy1); + btnProjectile->setMinimumSize(QSize(40, 40)); + btnProjectile->setMaximumSize(QSize(40, 40)); + btnProjectile->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnProjectile.png")); + btnProjectile->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnProjectile); + + btnDropObject = new QPushButton(widget); + setStyledToolTip(btnDropObject, "Not Implement"); + btnDropObject->setObjectName(QStringLiteral("btnDropObject")); + sizePolicy1.setHeightForWidth(btnDropObject->sizePolicy().hasHeightForWidth()); + btnDropObject->setSizePolicy(sizePolicy1); + btnDropObject->setMinimumSize(QSize(40, 40)); + btnDropObject->setMaximumSize(QSize(40, 40)); + btnDropObject->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnDropObject.png")); + btnDropObject->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnDropObject); + + fSeparate = new QFrame(widget); + fSeparate->setObjectName(QStringLiteral("fSeparate")); + fSeparate->setFrameShape(QFrame::VLine); + fSeparate->setFrameShadow(QFrame::Sunken); + hLayout->addWidget(fSeparate); + + btnPreferences = new QPushButton(widget); + setStyledToolTip(btnPreferences, "Save Blast Asset"); + btnPreferences->setObjectName(QStringLiteral("btnPreferences")); + sizePolicy1.setHeightForWidth(btnPreferences->sizePolicy().hasHeightForWidth()); + btnPreferences->setSizePolicy(sizePolicy1); + btnPreferences->setMinimumSize(QSize(40, 40)); + btnPreferences->setMaximumSize(QSize(40, 40)); + btnPreferences->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnPreferences.png")); + btnPreferences->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnPreferences); + + QSpacerItem *horizontalSpacer; + horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + hLayout->addItem(horizontalSpacer); + + this->setWidget(widget); + + connect(btnOpenProject, SIGNAL(clicked()), this, SLOT(on_btnOpenProject_clicked())); + connect(btnSaveProject, SIGNAL(clicked()), this, SLOT(on_btnSaveProject_clicked())); + connect(btnExportAssets, SIGNAL(clicked()), this, SLOT(on_btnExportAssets_clicked())); + connect(btnExportFilepath, SIGNAL(clicked()), this, SLOT(on_btnExportFilepath_clicked())); + connect(ssbiDepthPreview, SIGNAL(valueChanged(int)), this, SLOT(on_ssbiDepthPreview_valueChanged(int))); + connect(cbExactCoverage, SIGNAL(stateChanged(int)), this, SLOT(on_cbExactCoverage_stateChanged(int))); + connect(btnSelectTool, SIGNAL(clicked()), this, SLOT(on_btnSelectTool_clicked())); + connect(btnPaintbrush, SIGNAL(clicked()), this, SLOT(on_btnPaintbrush_clicked())); + connect(btnFractureTool, SIGNAL(clicked()), this, SLOT(on_btnFractureTool_clicked())); + connect(btnExplodedViewTool, SIGNAL(clicked()), this, SLOT(on_btnExplodedViewTool_clicked())); + connect(btnJointsTool, SIGNAL(clicked()), this, SLOT(on_btnJointsTool_clicked())); + connect(btnFuseSelectedChunks, SIGNAL(clicked()), this, SLOT(on_btnFuseSelectedChunks_clicked())); + connect(btnReset, SIGNAL(clicked()), this, SLOT(on_btnReset_clicked())); + connect(btnSimulatePlay, SIGNAL(clicked()), this, SLOT(on_btnSimulatePlay_clicked())); + connect(btnFrameStepForward, SIGNAL(clicked()), this, SLOT(on_btnFrameStepForward_clicked())); + connect(btnBomb, SIGNAL(clicked()), this, SLOT(on_btnBomb_clicked())); + connect(btnProjectile, SIGNAL(clicked()), this, SLOT(on_btnProjectile_clicked())); + connect(btnDropObject, SIGNAL(clicked()), this, SLOT(on_btnDropObject_clicked())); + connect(btnPreferences, SIGNAL(clicked()), this, SLOT(on_btnPreferences_clicked())); +} + +void BlastToolbar::updateValues() +{ +} + +#include <Sample.h> +#include <SimpleScene.h> +#include <SampleManager.h> +#include <SceneController.h> +#include <SourceAssetOpenDlg.h> + +void BlastToolbar::on_btnOpenProject_clicked() +{ + qDebug("%s", __FUNCTION__); + + SourceAssetOpenDlg dlg(true, &AppMainWindow::Inst()); + int res = dlg.exec(); + if (res != QDialog::Accepted || dlg.getFile().isEmpty()) + return; + + QFileInfo fileInfo(dlg.getFile()); + std::string dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + std::string file = fileInfo.baseName().toLocal8Bit(); + + physx::PxTransform t(physx::PxIdentity); + { + QVector3D Position = dlg.getPosition(); + t.p = physx::PxVec3(Position.x(), Position.y(), Position.z()); + + QVector3D RotationAxis = dlg.getRotationAxis(); + physx::PxVec3 Axis = physx::PxVec3(RotationAxis.x(), RotationAxis.y(), RotationAxis.z()); + Axis = Axis.getNormalized(); + float RotationDegree = dlg.getRotationDegree(); + float DEGREE_TO_RAD = acos(-1.0) / 180.0; + RotationDegree = RotationDegree * DEGREE_TO_RAD; + t.q = physx::PxQuat(RotationDegree, Axis); + } + + SimpleScene::Inst()->GetSampleManager().addModelAsset(file, dlg.getSkinned(), t, !dlg.isAppend()); +} + +void BlastToolbar::on_btnSaveProject_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnExportAssets_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnExportFilepath_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_ssbiDepthPreview_valueChanged(int v) +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_cbExactCoverage_stateChanged(int state) +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnSelectTool_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_pointselect_action() +{ + qDebug("%s", __FUNCTION__); + + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + sampleManager.setBlastToolType(BTT_Select); +} + +void BlastToolbar::on_rectselect_action() +{ + qDebug("%s", __FUNCTION__); + + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + sampleManager.setBlastToolType(BTT_Select); +} + +void BlastToolbar::on_drawselect_action() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnPaintbrush_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnFractureTool_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnExplodedViewTool_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnJointsTool_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnFuseSelectedChunks_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnReset_clicked() +{ + qDebug("%s", __FUNCTION__); + + SampleManager* pSampleManager = SampleManager::ins(); + SceneController& sceneController = pSampleManager->getSceneController(); + sceneController.ResetScene(); + pSampleManager->setBlastToolType(BTT_Edit); +} + +void BlastToolbar::on_btnSimulatePlay_clicked() +{ + qDebug("%s", __FUNCTION__); + + SampleManager* pSampleManager = SampleManager::ins(); + pSampleManager->setBlastToolType(BTT_Damage); +} + +void BlastToolbar::on_btnFrameStepForward_clicked() +{ + qDebug("%s", __FUNCTION__); + + SampleManager* pSampleManager = SampleManager::ins(); + pSampleManager->setBlastToolType(BTT_Damage); + PhysXController& physXController = pSampleManager->getPhysXController(); + physXController.m_bForce = true; +} + +void BlastToolbar::on_btnBomb_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnProjectile_clicked() +{ + qDebug("%s", __FUNCTION__); + + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + SceneController& sceneController = sampleManager.getSceneController(); + sceneController.addProjectile(); +} + +void BlastToolbar::on_btnDropObject_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnPreferences_clicked() +{ + qDebug("%s", __FUNCTION__); + + SampleManager* pSampleManager = SampleManager::ins(); + pSampleManager->saveAsset(); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h new file mode 100644 index 0000000..f44dcfb --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h @@ -0,0 +1,94 @@ +#ifndef BlastToolbar_h__ +#define BlastToolbar_h__ + +#include <QtWidgets/QApplication> +#include <QtWidgets/QCheckBox> +#include <QtWidgets/QDockWidget> +#include <QtWidgets/QHBoxLayout> +#include <QtWidgets/QLabel> +#include <QtWidgets/QPushButton> +#include <QtWidgets/QMenu> +#include <QtWidgets/QVBoxLayout> +#include <QtWidgets/QLineEdit> + +#include "SlideSpinBox.h" + +class BlastToolbar : public QDockWidget +{ + Q_OBJECT + +public: + BlastToolbar(QWidget* parent); + + void updateValues(); + +public slots: + void on_btnOpenProject_clicked(); + void on_btnSaveProject_clicked(); + void on_btnExportAssets_clicked(); + + void on_btnExportFilepath_clicked(); + void on_ssbiDepthPreview_valueChanged(int v); + void on_cbExactCoverage_stateChanged(int state); + + void on_btnSelectTool_clicked(); + void on_pointselect_action(); + void on_rectselect_action(); + void on_drawselect_action(); + + void on_btnPaintbrush_clicked(); + void on_btnFractureTool_clicked(); + void on_btnExplodedViewTool_clicked(); + void on_btnJointsTool_clicked(); + void on_btnFuseSelectedChunks_clicked(); + + void on_btnReset_clicked(); + void on_btnSimulatePlay_clicked(); + void on_btnFrameStepForward_clicked(); + + void on_btnBomb_clicked(); + void on_btnProjectile_clicked(); + void on_btnDropObject_clicked(); + + void on_btnPreferences_clicked(); + +private: + QHBoxLayout *hLayout; + QFrame *fSeparate; + + QPushButton *btnOpenProject; + QPushButton *btnSaveProject; + QPushButton *btnExportAssets; + + QVBoxLayout *vLayoutExport; + QHBoxLayout *hLayoutExport; + QLabel *lExportFilepath; + QPushButton *btnExportFilepath; + QLineEdit* leExportFilepath; + + QVBoxLayout *vLayoutDepthCoverage; + QHBoxLayout *hlDepthPreview; + QLabel *lbDepthPreview; + SlideSpinBoxInt* ssbiDepthPreview; + QHBoxLayout *hlExactCoverage; + QLabel *lbExactCoverage; + QCheckBox* cbExactCoverage; + + QPushButton *btnSelectTool; + QPushButton *btnPaintbrush; + QPushButton *btnFractureTool; + QPushButton *btnExplodedViewTool; + QPushButton *btnJointsTool; + QPushButton *btnFuseSelectedChunks; + + QPushButton *btnReset; + QPushButton *btnSimulatePlay; + QPushButton *btnFrameStepForward; + + QPushButton *btnBomb; + QPushButton *btnProjectile; + QPushButton *btnDropObject; + + QPushButton *btnPreferences; +}; +#endif // BlastToolbar_h__ diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.cpp new file mode 100644 index 0000000..4aa2b79 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.cpp @@ -0,0 +1,54 @@ +#include "CollisionToolsDlg.h" +#include "ui_CollisionToolsDlg.h" + +CollisionToolsDlg::CollisionToolsDlg(QWidget *parent) : + QDialog(parent), + ui(new Ui::CollisionToolsDlg) +{ + ui->setupUi(this); +} + +CollisionToolsDlg::~CollisionToolsDlg() +{ + delete ui; +} + +void CollisionToolsDlg::on_comboBoxApplyFilter_currentIndexChanged(int index) +{ + +} + +void CollisionToolsDlg::on_comboBoxCollisionShape_currentIndexChanged(int index) +{ + +} + +void CollisionToolsDlg::on_spinBoxQuality_valueChanged(int arg1) +{ + +} + +void CollisionToolsDlg::on_spinBoxMaxHulls_valueChanged(int arg1) +{ + +} + +void CollisionToolsDlg::on_spinBoxTrimHulls_valueChanged(int arg1) +{ + +} + +void CollisionToolsDlg::on_comboBoxTargetPlatform_currentIndexChanged(int index) +{ + +} + +void CollisionToolsDlg::on_btnReset_clicked() +{ + +} + +void CollisionToolsDlg::on_btnApply_clicked() +{ + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.h new file mode 100644 index 0000000..d3c8c00 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.h @@ -0,0 +1,39 @@ +#ifndef COLLISIONTOOLSDLG_H +#define COLLISIONTOOLSDLG_H + +#include <QtWidgets/QDialog> + +namespace Ui { +class CollisionToolsDlg; +} + +class CollisionToolsDlg : public QDialog +{ + Q_OBJECT + +public: + explicit CollisionToolsDlg(QWidget *parent = 0); + ~CollisionToolsDlg(); + +private slots: + void on_comboBoxApplyFilter_currentIndexChanged(int index); + + void on_comboBoxCollisionShape_currentIndexChanged(int index); + + void on_spinBoxQuality_valueChanged(int arg1); + + void on_spinBoxMaxHulls_valueChanged(int arg1); + + void on_spinBoxTrimHulls_valueChanged(int arg1); + + void on_comboBoxTargetPlatform_currentIndexChanged(int index); + + void on_btnReset_clicked(); + + void on_btnApply_clicked(); + +private: + Ui::CollisionToolsDlg *ui; +}; + +#endif // COLLISIONTOOLSDLG_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp new file mode 100644 index 0000000..e52dfb2 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp @@ -0,0 +1,104 @@ +#include "DefaultDamagePanel.h" +#include "ui_DefaultDamagePanel.h" +#include "ProjectParams.h" +#include "BlastSceneTree.h" + +DefaultDamagePanel::DefaultDamagePanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::DefaultDamagePanel) +{ + ui->setupUi(this); +} + +DefaultDamagePanel::~DefaultDamagePanel() +{ + delete ui; +} + +void DefaultDamagePanel::updateValues() +{ + if (_selectedAssets.size() > 0) + { + BPPDefaultDamage& damage = _selectedAssets[0]->defaultDamage; + + ui->spinBoxMinRadius->setValue(damage.minRadius); + ui->spinBoxMaxRadius->setValue(damage.maxRadius); + ui->comboBoxFallOff->setCurrentIndex(damage.FallOff); + ui->spinBoxMaxChunkSpeed->setValue(damage.maxChunkSpeed); + } + else + { + ui->spinBoxMinRadius->setValue(0.0f); + ui->spinBoxMaxRadius->setValue(0.0f); + ui->checkBoxMaxRadius->setChecked(false); + ui->comboBoxFallOff->setCurrentIndex(-1); + ui->spinBoxMaxChunkSpeed->setValue(0.0f); + } +} + +void DefaultDamagePanel::dataSelected(std::vector<BlastNode*> selections) +{ + _selectedAssets.clear(); + + for (BlastNode* node: selections) + { + if (eAsset == node->getType()) + { + BPPAsset* asset = static_cast<BPPAsset*>(node->getData()); + _selectedAssets.push_back(asset); + } + } + + updateValues(); +} + +void DefaultDamagePanel::on_spinBoxMinRadius_valueChanged(double arg1) +{ + for (size_t i = 0; i < _selectedAssets.size(); ++i) + { + BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage; + damage.minRadius = arg1; + } +} + +void DefaultDamagePanel::on_spinBoxMaxRadius_valueChanged(double arg1) +{ + for (size_t i = 0; i < _selectedAssets.size(); ++i) + { + BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage; + + damage.maxRadius = arg1; + + if (arg1 < damage.minRadius) + { + damage.maxRadius = damage.minRadius; + } + } +} + +void DefaultDamagePanel::on_checkBoxMaxRadius_stateChanged(int arg1) +{ + for (size_t i = 0; i < _selectedAssets.size(); ++i) + { + BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage; + damage.maxRadiusEnable = (arg1 != 0 ? true: false); + } +} + +void DefaultDamagePanel::on_comboBoxFallOff_currentIndexChanged(int index) +{ + for (size_t i = 0; i < _selectedAssets.size(); ++i) + { + BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage; + damage.FallOff = index; + } +} + +void DefaultDamagePanel::on_spinBoxMaxChunkSpeed_valueChanged(double arg1) +{ + for (size_t i = 0; i < _selectedAssets.size(); ++i) + { + BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage; + damage.maxChunkSpeed = arg1; + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h new file mode 100644 index 0000000..bbd4d3e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h @@ -0,0 +1,38 @@ +#ifndef DEFAULTDAMAGEPANEL_H +#define DEFAULTDAMAGEPANEL_H + +#include <QtWidgets/QWidget> +#include "BlastSceneTree.h" + +namespace Ui { +class DefaultDamagePanel; +} + +class DefaultDamagePanel : public QWidget, public ISceneObserver +{ + Q_OBJECT + +public: + explicit DefaultDamagePanel(QWidget *parent = 0); + ~DefaultDamagePanel(); + void updateValues(); + + virtual void dataSelected(std::vector<BlastNode*> selections); + +private slots: + void on_spinBoxMinRadius_valueChanged(double arg1); + + void on_spinBoxMaxRadius_valueChanged(double arg1); + + void on_checkBoxMaxRadius_stateChanged(int arg1); + + void on_comboBoxFallOff_currentIndexChanged(int index); + + void on_spinBoxMaxChunkSpeed_valueChanged(double arg1); + +private: + Ui::DefaultDamagePanel *ui; + std::vector<BPPAsset*> _selectedAssets; +}; + +#endif // DEFAULTDAMAGEPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp new file mode 100644 index 0000000..62b294c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp @@ -0,0 +1,148 @@ +#include "FileReferencesPanel.h" +#include "ui_FileReferencesPanel.h" +#include "AppMainWindow.h" +#include <QtWidgets/QFileDialog> +#include "ProjectParams.h" +#include <QtCore/QFile> +#include <QtCore/QDebug> +#include "GlobalSettings.h" + +FileReferencesPanel::FileReferencesPanel(QWidget *parent) + : QWidget(parent) + , ui(new Ui::FileReferencesPanel) + , _saveFBX(true) + , _saveBlast(true) + , _saveCollision(true) +{ + ui->setupUi(this); + ui->lineEditFBXSourceAsset->setReadOnly(true); + + ui->checkBoxFBX->setChecked(_saveFBX); + ui->checkBoxBlast->setChecked(_saveBlast); + ui->checkBoxCollision->setChecked(_saveCollision); + + updateValues(); +} + +FileReferencesPanel::~FileReferencesPanel() +{ + delete ui; +} + +void FileReferencesPanel::updateValues() +{ + AppMainWindow& window = AppMainWindow::Inst(); + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFileReferences& fileReferences = projectParams.blast.fileReferences; + if (fileReferences.fbxSourceAsset.buf != nullptr) + ui->lineEditFBXSourceAsset->setText(fileReferences.fbxSourceAsset.buf); + else + ui->lineEditFBXSourceAsset->setText(""); + + GlobalSettings& globalSettings = GlobalSettings::Inst(); + QString projectFileName = globalSettings.m_projectFileName.c_str(); + + if (projectFileName.isEmpty()) + { + ui->lineEditFBX->setText("New.fbx"); + ui->lineEditBlast->setText("New.Blast"); + ui->lineEditCollision->setText("New.repx"); + } + else + { + QFileInfo fileInfo(projectFileName); + + if (fileReferences.fbx.buf != nullptr) + ui->lineEditFBX->setText(fileReferences.fbx.buf); + else + { + ui->lineEditFBX->setText(fileInfo.baseName() + " New.fbx"); + } + + if (fileReferences.blast.buf != nullptr) + ui->lineEditBlast->setText(fileReferences.blast.buf); + else + { + ui->lineEditBlast->setText(fileInfo.baseName() + " New.Blast"); + } + + if (fileReferences.collision.buf != nullptr) + ui->lineEditCollision->setText(fileReferences.collision.buf); + else + { + ui->lineEditCollision->setText(fileInfo.baseName() + " New.repX"); + } + } +} + +void FileReferencesPanel::on_btnOpenFile_clicked() +{ + AppMainWindow& window = AppMainWindow::Inst(); + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFileReferences& fileReferences = projectParams.blast.fileReferences; + const char* fbxSourceAsset = fileReferences.fbxSourceAsset.buf; + QString lastDir = (fbxSourceAsset != nullptr ? fbxSourceAsset : window._lastFilePath); + QString fileName = QFileDialog::getOpenFileName(&window, "Open FBX File", lastDir, "FBX File (*.FBX)"); + + ui->lineEditFBXSourceAsset->setText(fileName); +} + +void FileReferencesPanel::on_btnReload_clicked() +{ + +} + +void FileReferencesPanel::on_btnRemove_clicked() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFileReferences& fileReferences = projectParams.blast.fileReferences; + if (fileReferences.fbxSourceAsset.buf != nullptr) + { + ui->lineEditFBXSourceAsset->setText(""); + freeString(fileReferences.fbxSourceAsset); + // to do: remove source fbx file + } +} + +void FileReferencesPanel::on_checkBoxFBX_stateChanged(int arg1) +{ + _saveFBX = (arg1 == 0 ? false : true); +} + +void FileReferencesPanel::on_checkBoxBlast_stateChanged(int arg1) +{ + _saveBlast = (arg1 == 0 ? false : true); +} + +void FileReferencesPanel::on_checkBoxCollision_stateChanged(int arg1) +{ + _saveCollision = (arg1 == 0 ? false : true); +} + +void FileReferencesPanel::on_btnSave_clicked() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFileReferences& fileReferences = projectParams.blast.fileReferences; + + copy(fileReferences.fbxSourceAsset, ui->lineEditFBXSourceAsset->text().toUtf8().data()); + + if (_saveFBX) + { + copy(fileReferences.fbx, ui->lineEditFBX->text().toUtf8().data()); + // to do: save fbx file + } + + if (_saveBlast) + { + copy(fileReferences.blast, ui->lineEditBlast->text().toUtf8().data()); + // to do: save blast file + } + + if (_saveCollision) + { + copy(fileReferences.collision, ui->lineEditCollision->text().toUtf8().data()); + // to do: save collision file + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h new file mode 100644 index 0000000..e393f33 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h @@ -0,0 +1,41 @@ +#ifndef FILEREFERENCESPANEL_H +#define FILEREFERENCESPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FileReferencesPanel; +} + +class FileReferencesPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FileReferencesPanel(QWidget *parent = 0); + ~FileReferencesPanel(); + void updateValues(); + +private slots: + void on_btnOpenFile_clicked(); + + void on_btnReload_clicked(); + + void on_btnRemove_clicked(); + + void on_checkBoxFBX_stateChanged(int arg1); + + void on_checkBoxBlast_stateChanged(int arg1); + + void on_checkBoxCollision_stateChanged(int arg1); + + void on_btnSave_clicked(); + +private: + Ui::FileReferencesPanel *ui; + bool _saveFBX; + bool _saveBlast; + bool _saveCollision; +}; + +#endif // FILEREFERENCESPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp new file mode 100644 index 0000000..a537140 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp @@ -0,0 +1,389 @@ +#include "FiltersDockWidget.h" +#include "ui_FiltersDockWidget.h" +#include "ProjectParams.h" +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> +#include "SampleManager.h" + +const QString LISTITEM_NORMAL_STYLESHEET = ":enabled { background: rgb(68,68,68); }"; + +const QString LISTITEM_SELECTED_STYLESHEET = ":enabled { background: rgba(118,185,0, 250); }"; + +const QString LISTITEM_BUTTON_STYLESHEET = ":enabled { border: 0px; }"; + +class FilterItemWidget; + +struct FilterItemInfo +{ +public: + FilterItemInfo(FilterItemWidget* inWidget, const QString& inText) + : itemWidget(inWidget) + , text(inText) + { + } + + FilterItemWidget* itemWidget; + QString text; +}; + +FilterItemWidget::FilterItemWidget(FiltersDockWidget* parent, QListWidgetItem* item, const QString& filterPreset, int depth) + : QWidget(parent) + , _relatedListWidgetItem(item) + , _filterPreset(filterPreset) + , _depth(depth) +{ + QHBoxLayout* layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + _label = new QLabel(this); + + _removeBtn = new QPushButton(this); + _removeBtn->setMaximumSize(20, 20); + _removeBtn->setText("X"); + _removeBtn->setStyleSheet(LISTITEM_BUTTON_STYLESHEET); + + layout->addWidget(_label); + layout->addWidget(_removeBtn); + + this->setLayout(layout); + + QObject::connect(_removeBtn, SIGNAL(clicked()), this, SLOT(onRemoveButtonClicked())); + QObject::connect(this, SIGNAL(RemoveItem(QListWidgetItem*)), parent, SLOT(onListWidgetRemoveBtnClicked(QListWidgetItem*))); + + deSelect(); +} + +void FilterItemWidget::setText(const QString& title) +{ + _label->setText(title); +} + +void FilterItemWidget::select() +{ + _label->setStyleSheet(LISTITEM_SELECTED_STYLESHEET); +} + +void FilterItemWidget::deSelect() +{ + _label->setStyleSheet(LISTITEM_NORMAL_STYLESHEET); +} + +void FilterItemWidget::onRemoveButtonClicked() +{ + emit RemoveItem(_relatedListWidgetItem); +} + +FiltersDockWidget::FiltersDockWidget(QWidget *parent) : + QDockWidget(parent), + ui(new Ui::FiltersDockWidget), + _filterUIItems(), + _filterItemWidgets(), + _lastSelectRow(-1) +{ + ui->setupUi(this); + + _depthButtons.push_back(ui->btnDepth0); + _depthButtons.push_back(ui->btnDepth1); + _depthButtons.push_back(ui->btnDepth2); + _depthButtons.push_back(ui->btnDepth3); + _depthButtons.push_back(ui->btnDepth4); + _depthButtons.push_back(ui->btnDepth5); + + _updateFilterItemList(); + _updateFilterDepthBtns(); +} + +FiltersDockWidget::~FiltersDockWidget() +{ + delete ui; +} + +void FiltersDockWidget::updateValues() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFilterPresetArray& filterPresetArray = projectParams.filter.filters; + + ui->comboBoxFilterPreset->clear(); + QStringList filterNames; + int count = filterPresetArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + filterNames.append(filterPresetArray.buf[i].name.buf); + } + ui->comboBoxFilterPreset->addItems(filterNames); + + if (count > 0) + { + ui->btnModifyFilterPreset->setEnabled(true); + ui->btnRemoveFilterPreset->setEnabled(true); + } + else + { + ui->btnModifyFilterPreset->setEnabled(false); + ui->btnRemoveFilterPreset->setEnabled(false); + } +} + +void FiltersDockWidget::on_comboBoxFilterPreset_currentIndexChanged(int index) +{ + BPParams& projectParams = BlastProject::ins().getParams(); + projectParams.filter.activeFilter = index; + + _updateFilterItemList(); + _updateFilterDepthBtns(); +} + +void FiltersDockWidget::on_btnAddFilterPrest_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new filter preset:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isFilterPresetNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addFilterPreset(name.toUtf8().data()); + updateValues(); + ui->comboBoxFilterPreset->setCurrentIndex(ui->comboBoxFilterPreset->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new filter preset!"); + } +} + +void FiltersDockWidget::on_btnModifyFilterPreset_clicked() +{ + QByteArray tmp = ui->comboBoxFilterPreset->currentText().toUtf8(); + const char* oldName = tmp.data(); + + bool ok = false; + QString newName = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input new name for the selected filter preset:"), + QLineEdit::Normal, + oldName, + &ok); + bool nameExist = BlastProject::ins().isFilterPresetNameExist(newName.toUtf8().data()); + if (ok && !newName.isEmpty() && !nameExist) + { + int index = ui->comboBoxFilterPreset->currentIndex(); + BlastProject::ins().renameFilterPreset(oldName, newName.toUtf8().data()); + updateValues(); + ui->comboBoxFilterPreset->setCurrentIndex(index); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && newName.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the selected filter preset!"); + } +} + +void FiltersDockWidget::on_btnRemoveFilterPreset_clicked() +{ + QByteArray tmp = ui->comboBoxFilterPreset->currentText().toUtf8(); + const char* name = tmp.data(); + BlastProject::ins().removeFilterPreset(name); + updateValues(); +} + +void FiltersDockWidget::on_btnDepth0_clicked(bool val) +{ + _addRemoveDepthFilter(0, val); +} + +void FiltersDockWidget::on_btnDepth1_clicked(bool val) +{ + _addRemoveDepthFilter(1, val); +} + +void FiltersDockWidget::on_btnDepth2_clicked(bool val) +{ + _addRemoveDepthFilter(2, val); +} + +void FiltersDockWidget::on_btnDepth3_clicked(bool val) +{ + _addRemoveDepthFilter(3, val); +} + +void FiltersDockWidget::on_btnDepth4_clicked(bool val) +{ + _addRemoveDepthFilter(4, val); +} + +void FiltersDockWidget::on_btnDepth5_clicked(bool val) +{ + _addRemoveDepthFilter(5, val); +} + +void FiltersDockWidget::on_btnAddDepthFilter_clicked() +{ + +} + +void FiltersDockWidget::on_btnAddFilter_clicked() +{ + +} + +void FiltersDockWidget::on_btnSelect_clicked() +{ + std::vector<uint32_t> depths; + int row = ui->listWidget->currentRow(); + if (-1 != row) + { + depths.push_back(_filterItemWidgets[row]->_depth); + } + SampleManager::ins()->setChunkSelected(depths, true); +} + +void FiltersDockWidget::on_btnVisible_clicked() +{ + std::vector<uint32_t> depths; + int row = ui->listWidget->currentRow(); + if (-1 != row) + { + depths.push_back(_filterItemWidgets[row]->_depth); + } + SampleManager::ins()->setChunkVisible(depths, true); +} + +void FiltersDockWidget::on_btnInVisible_clicked() +{ + std::vector<uint32_t> depths; + int row = ui->listWidget->currentRow(); + if (-1 != row) + { + depths.push_back(_filterItemWidgets[row]->_depth); + } + SampleManager::ins()->setChunkVisible(depths, false); +} + +void FiltersDockWidget::on_listWidget_currentRowChanged(int index) +{ + if (-1 != _lastSelectRow && _lastSelectRow < _filterItemWidgets.size()) + static_cast<FilterItemWidget*>(_filterItemWidgets[_lastSelectRow])->deSelect(); + + if (-1 != index && index < _filterItemWidgets.size()) + static_cast<FilterItemWidget*>(_filterItemWidgets[index])->select(); + + _lastSelectRow = index; +} + +void FiltersDockWidget::onListWidgetRemoveBtnClicked(QListWidgetItem* item) +{ + /// remove former ui info + map<QListWidgetItem*, FilterItemInfo*>::iterator toRemoveItem = _filterUIItems.find(item); + if (toRemoveItem != _filterUIItems.end()) + { + FilterItemWidget* itemWidget = toRemoveItem->second->itemWidget; + itemWidget->setParent(nullptr); + + _filterItemWidgets.erase(std::find(_filterItemWidgets.begin(), _filterItemWidgets.end(), toRemoveItem->second->itemWidget)); + + if (ui->comboBoxFilterPreset->currentIndex() != -1) + { + QByteArray filterPreset = itemWidget->_filterPreset.toUtf8(); + BlastProject::ins().removeFilterDepth(filterPreset.data(), itemWidget->_depth); + } + + ui->listWidget->takeItem(ui->listWidget->row(item)); + ui->listWidget->removeItemWidget(item); + delete item; + delete itemWidget; + _filterUIItems.erase(toRemoveItem); + + //_updateFilterItemList(); + _updateFilterDepthBtns(); + } +} + +void FiltersDockWidget::_updateFilterItemList() +{ + /// remove former ui info + map<QListWidgetItem*, FilterItemInfo*>::iterator theEnd = _filterUIItems.end(); + for (map<QListWidgetItem*, FilterItemInfo*>::iterator itr = _filterUIItems.begin(); itr != theEnd; ++itr) + { + itr->second->itemWidget->setParent(nullptr); + delete itr->first; + delete itr->second->itemWidget; + delete itr->second; + } + _filterUIItems.clear(); + ui->listWidget->clear(); + _filterItemWidgets.clear(); + + int filterPresetIndex = ui->comboBoxFilterPreset->currentIndex(); + if (filterPresetIndex < 0) + return; + + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFilterPresetArray& filterPresetArray = projectParams.filter.filters; + BPPFilterPreset& filterPresset = filterPresetArray.buf[filterPresetIndex]; + + int filterCount = filterPresset.depthFilters.arraySizes[0]; + + for (int i = 0; i < filterCount; ++i) + { + QListWidgetItem* item = new QListWidgetItem(NULL); + int depth = filterPresset.depthFilters.buf[i]; + FilterItemWidget* itemWidget = new FilterItemWidget(this, item, filterPresset.name.buf, depth); + + QString depthFilterLabel = QString(QObject::tr("Depth-%1")).arg(depth); + _filterUIItems.insert(std::make_pair(item, new FilterItemInfo(itemWidget, depthFilterLabel))); + itemWidget->setText(depthFilterLabel); + _filterItemWidgets.push_back(itemWidget); + + ui->listWidget->addItem(item); + ui->listWidget->setItemWidget(item, itemWidget); + } +} + +void FiltersDockWidget::_updateFilterDepthBtns() +{ + for (int i = 0; i <= 5; ++i) + _depthButtons[i]->setChecked(false); + + int filterPresetIndex = ui->comboBoxFilterPreset->currentIndex(); + if (filterPresetIndex < 0) + return; + + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFilterPresetArray& filterPresetArray = projectParams.filter.filters; + BPPFilterPreset& filterPresset = filterPresetArray.buf[filterPresetIndex]; + + int filterCount = filterPresset.depthFilters.arraySizes[0]; + + for (int i = 0; i < filterCount; ++i) + { + int depth = filterPresset.depthFilters.buf[i]; + + _depthButtons[depth]->setChecked(true); + } +} + +void FiltersDockWidget::_addRemoveDepthFilter(int depth, bool add) +{ + if (ui->comboBoxFilterPreset->currentIndex() != -1) + { + QByteArray filterPreset = ui->comboBoxFilterPreset->currentText().toUtf8(); + + if (add) + BlastProject::ins().addFilterDepth(filterPreset.data(), depth); + else + BlastProject::ins().removeFilterDepth(filterPreset.data(), depth); + + _updateFilterItemList(); + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h new file mode 100644 index 0000000..cf25073 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h @@ -0,0 +1,104 @@ +#ifndef FILTERSDOCKWIDGET_H +#define FILTERSDOCKWIDGET_H + +#include <QtWidgets/QDockWidget> +#include <vector> +#include <map> +using namespace std; + +namespace Ui { +class FiltersDockWidget; +} + +class QLabel; +class QPushButton; +class QListWidgetItem; +struct FilterItemInfo; +class FilterItemWidget; +class FiltersDockWidget; + +class FilterItemWidget : public QWidget +{ + Q_OBJECT +public: + FilterItemWidget(FiltersDockWidget* parent, QListWidgetItem* item, const QString& filterPreset, int depth); + ~FilterItemWidget() + { + } + + void setText(const QString& title); + void select(); + void deSelect(); + +signals: + void RemoveItem(QListWidgetItem* item); + +private slots: + void onRemoveButtonClicked(); + +public: + QLabel* _label; + QPushButton* _removeBtn; + QListWidgetItem* _relatedListWidgetItem; + QString _filterPreset; + int _depth; +}; + +class FiltersDockWidget : public QDockWidget +{ + Q_OBJECT + +public: + explicit FiltersDockWidget(QWidget *parent = 0); + ~FiltersDockWidget(); + void updateValues(); + +private slots: + void on_comboBoxFilterPreset_currentIndexChanged(int index); + + void on_btnAddFilterPrest_clicked(); + + void on_btnModifyFilterPreset_clicked(); + + void on_btnRemoveFilterPreset_clicked(); + + void on_btnDepth0_clicked(bool val); + + void on_btnDepth1_clicked(bool val); + + void on_btnDepth2_clicked(bool val); + + void on_btnDepth3_clicked(bool val); + + void on_btnDepth4_clicked(bool val); + + void on_btnDepth5_clicked(bool val); + + void on_btnAddDepthFilter_clicked(); + + void on_btnAddFilter_clicked(); + + void on_btnSelect_clicked(); + + void on_btnVisible_clicked(); + + void on_btnInVisible_clicked(); + + void on_listWidget_currentRowChanged(int index); + + void onListWidgetRemoveBtnClicked(QListWidgetItem* item); + +private: + void _updateFilterItemList(); + void _updateFilterDepthBtns(); + void _addRemoveDepthFilter(int depth, bool add); + +private: + Ui::FiltersDockWidget *ui; + map<QListWidgetItem*, FilterItemInfo*> _filterUIItems; + vector<FilterItemWidget*> _filterItemWidgets; + int _lastSelectRow; + vector<QPushButton*> _depthButtons; +}; + +#endif // FILTERSDOCKWIDGET_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.cpp new file mode 100644 index 0000000..ea24278 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.cpp @@ -0,0 +1,155 @@ +#include "FractureCutoutSettingsPanel.h" +#include "ui_FractureCutoutSettingsPanel.h" +#include "ProjectParams.h" +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> +#include <QtCore/QFileInfo> +#include "AppMainWindow.h" + +FractureCutoutSettingsPanel::FractureCutoutSettingsPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureCutoutSettingsPanel) +{ + ui->setupUi(this); +} + +FractureCutoutSettingsPanel::~FractureCutoutSettingsPanel() +{ + delete ui; +} + +void FractureCutoutSettingsPanel::updateValues() +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + + _updateTextureListWidget(); + + ui->comboBoxCutoutType->setCurrentIndex(cutoutProjection.cutoutType); + ui->spinBoxPixelThreshold->setValue(cutoutProjection.pixelThreshold); + ui->checkBoxTiled->setChecked(cutoutProjection.tiled); + ui->checkBoxInvertU->setChecked(cutoutProjection.invertU); + ui->checkBoxInvertV->setChecked(cutoutProjection.invertV); +} + +void FractureCutoutSettingsPanel::on_btnAddTexture_clicked() +{ + QString texName = AppMainWindow::Inst().OpenTextureFile(); + + if (texName.isEmpty()) + return; + + QFileInfo fileInfo(texName); + QByteArray ba = fileInfo.absoluteFilePath().toLocal8Bit(); + const char* filePath = (const char*)(ba); + + if (!BlastProject::ins().isCutoutTextureNameExist(texName.toUtf8().data())) + { + BlastProject::ins().addCutoutTexture(filePath); + _updateTextureListWidget(); + ui->listWidget->setCurrentRow(ui->listWidget->count() - 1); + } + else + { + QMessageBox::warning(this, "Blast Tool", "The texture you selected is already exist!"); + } +} + +void FractureCutoutSettingsPanel::on_btnReloadTexture_clicked() +{ + +} + +void FractureCutoutSettingsPanel::on_btnRemoveTexture_clicked() +{ + if (ui->listWidget->currentRow() != -1) + { + QListWidgetItem *item = ui->listWidget->currentItem(); + QString texture = _getTexturePathByName(item->text()); + QByteArray ba = texture.toLocal8Bit(); + BlastProject::ins().removeCutoutTexture(ba.data()); + _updateTextureListWidget(); + } +} + +void FractureCutoutSettingsPanel::on_listWidget_currentRowChanged(int currentRow) +{ + +} + +void FractureCutoutSettingsPanel::on_btnTextureMap_clicked() +{ + +} + +void FractureCutoutSettingsPanel::on_comboBoxCutoutType_currentIndexChanged(int index) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + cutoutProjection.cutoutType = index; +} + +void FractureCutoutSettingsPanel::on_spinBoxPixelThreshold_valueChanged(int arg1) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + cutoutProjection.pixelThreshold = arg1; +} + +void FractureCutoutSettingsPanel::on_checkBoxTiled_stateChanged(int arg1) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + cutoutProjection.tiled = (arg1 != 0 ? true : false); +} + +void FractureCutoutSettingsPanel::on_checkBoxInvertU_stateChanged(int arg1) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + cutoutProjection.invertU = (arg1 != 0 ? true : false); +} + +void FractureCutoutSettingsPanel::on_checkBoxInvertV_stateChanged(int arg1) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + cutoutProjection.invertV = (arg1 != 0 ? true : false); +} + +void FractureCutoutSettingsPanel::on_btnFitToObject_clicked() +{ + +} + +void FractureCutoutSettingsPanel::on_btnApplyFracture_clicked() +{ + +} + +QString FractureCutoutSettingsPanel::_getTexturePathByName(const QString& name) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + BPPStringArray& textureArray = cutoutProjection.textures; + + int count = textureArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + QFileInfo fileInfo(textureArray.buf[i].buf); + if (fileInfo.baseName() == name) + return textureArray.buf[i].buf; + } + + return ""; +} + +void FractureCutoutSettingsPanel::_updateTextureListWidget() +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + + ui->listWidget->clear(); + QStringList items; + for (int i = 0; i < cutoutProjection.textures.arraySizes[0]; ++i) + { + QFileInfo fileInfo(cutoutProjection.textures.buf[i].buf); + QByteArray ba = fileInfo.baseName().toLocal8Bit(); + const char* texture = (const char*)(ba); + items.append(texture); + } + ui->listWidget->addItems(items); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.h new file mode 100644 index 0000000..7faf2ae --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.h @@ -0,0 +1,52 @@ +#ifndef FRACTURECUTOUTSETTINGSPANEL_H +#define FRACTURECUTOUTSETTINGSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureCutoutSettingsPanel; +} + +class FractureCutoutSettingsPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureCutoutSettingsPanel(QWidget *parent = 0); + ~FractureCutoutSettingsPanel(); + void updateValues(); + +private slots: + void on_btnAddTexture_clicked(); + + void on_btnReloadTexture_clicked(); + + void on_btnRemoveTexture_clicked(); + + void on_listWidget_currentRowChanged(int currentRow); + + void on_btnTextureMap_clicked(); + + void on_comboBoxCutoutType_currentIndexChanged(int index); + + void on_spinBoxPixelThreshold_valueChanged(int arg1); + + void on_checkBoxTiled_stateChanged(int arg1); + + void on_checkBoxInvertU_stateChanged(int arg1); + + void on_checkBoxInvertV_stateChanged(int arg1); + + void on_btnFitToObject_clicked(); + + void on_btnApplyFracture_clicked(); + +private: + QString _getTexturePathByName(const QString& name); + void _updateTextureListWidget(); + +private: + Ui::FractureCutoutSettingsPanel *ui; +}; + +#endif // FRACTURECUTOUTSETTINGSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp new file mode 100644 index 0000000..1f7068d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp @@ -0,0 +1,63 @@ +#include "FractureGeneralPanel.h" +#include "ui_FractureGeneralPanel.h" +#include "ProjectParams.h" + +FractureGeneralPanel::FractureGeneralPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureGeneralPanel) +{ + ui->setupUi(this); +} + +FractureGeneralPanel::~FractureGeneralPanel() +{ + delete ui; +} + +void FractureGeneralPanel::updateValues() +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + + ui->comboBoxFracturePreset->setCurrentIndex(fractureGeneral.fracturePreset); + ui->comboBoxFractureType->setCurrentIndex(fractureGeneral.fractureType); + ui->checkBoxAddDepth->setChecked(fractureGeneral.addDepth); + ui->checkBoxPerChunk->setChecked(fractureGeneral.perChunk); + ui->checkBoxNewMatID->setChecked(fractureGeneral.newMatID); + ui->comboBoxApplyMaterial->setCurrentIndex(fractureGeneral.applyMaterial); +} + +void FractureGeneralPanel::on_comboBoxFracturePreset_currentIndexChanged(int index) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.fracturePreset = index; +} + +void FractureGeneralPanel::on_comboBoxFractureType_currentIndexChanged(int index) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.fractureType = index; +} + +void FractureGeneralPanel::on_checkBoxAddDepth_stateChanged(int arg1) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.addDepth = (arg1 != 0 ? true : false); +} + +void FractureGeneralPanel::on_checkBoxPerChunk_stateChanged(int arg1) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.perChunk = (arg1 != 0 ? true : false); +} + +void FractureGeneralPanel::on_checkBoxNewMatID_stateChanged(int arg1) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.newMatID = (arg1 != 0 ? true:false); +} + +void FractureGeneralPanel::on_comboBoxApplyMaterial_currentIndexChanged(int index) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.applyMaterial = index; +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h new file mode 100644 index 0000000..4b51f5e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h @@ -0,0 +1,36 @@ +#ifndef FRACTUREGENERALPANEL_H +#define FRACTUREGENERALPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureGeneralPanel; +} + +class FractureGeneralPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureGeneralPanel(QWidget *parent = 0); + ~FractureGeneralPanel(); + void updateValues(); + +private slots: + void on_comboBoxFracturePreset_currentIndexChanged(int index); + + void on_comboBoxFractureType_currentIndexChanged(int index); + + void on_checkBoxAddDepth_stateChanged(int arg1); + + void on_checkBoxPerChunk_stateChanged(int arg1); + + void on_checkBoxNewMatID_stateChanged(int arg1); + + void on_comboBoxApplyMaterial_currentIndexChanged(int index); + +private: + Ui::FractureGeneralPanel *ui; +}; + +#endif // FRACTUREGENERALPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.cpp new file mode 100644 index 0000000..c08e3ba --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.cpp @@ -0,0 +1,40 @@ +#include "FractureShellCutSettingsPanel.h" +#include "ui_FractureShellCutSettingsPanel.h" +#include "ProjectParams.h" + +FractureShellCutSettingsPanel::FractureShellCutSettingsPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureShellCutSettingsPanel) +{ + ui->setupUi(this); +} + +FractureShellCutSettingsPanel::~FractureShellCutSettingsPanel() +{ + delete ui; +} + +void FractureShellCutSettingsPanel::updateValues() +{ + BPPShellCut& shellCut = BlastProject::ins().getParams().fracture.shellCut; + + ui->spinBoxThickness->setValue(shellCut.thickness); + ui->spinBoxThicknessVariation->setValue(shellCut.thicknessVariation); +} + +void FractureShellCutSettingsPanel::on_spinBoxThickness_valueChanged(double arg1) +{ + BPPShellCut& shellCut = BlastProject::ins().getParams().fracture.shellCut; + shellCut.thickness = arg1; +} + +void FractureShellCutSettingsPanel::on_spinBoxThicknessVariation_valueChanged(double arg1) +{ + BPPShellCut& shellCut = BlastProject::ins().getParams().fracture.shellCut; + shellCut.thicknessVariation = arg1; +} + +void FractureShellCutSettingsPanel::on_btnApplyFracture_clicked() +{ + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.h new file mode 100644 index 0000000..a664adb --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.h @@ -0,0 +1,30 @@ +#ifndef FRACTURESHELLCUTSETTINGSPANEL_H +#define FRACTURESHELLCUTSETTINGSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureShellCutSettingsPanel; +} + +class FractureShellCutSettingsPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureShellCutSettingsPanel(QWidget *parent = 0); + ~FractureShellCutSettingsPanel(); + void updateValues(); + +private slots: +void on_spinBoxThickness_valueChanged(double arg1); + + void on_spinBoxThicknessVariation_valueChanged(double arg1); + + void on_btnApplyFracture_clicked(); + +private: + Ui::FractureShellCutSettingsPanel *ui; +}; + +#endif // FRACTURESHELLCUTSETTINGSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp new file mode 100644 index 0000000..fa82ee2 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp @@ -0,0 +1,105 @@ +#include "FractureSliceSettingsPanel.h" +#include "ui_FractureSliceSettingsPanel.h" +#include "ProjectParams.h" +#include "SimpleScene.h" +#include "SampleManager.h" +#include <QtWidgets/QMessageBox> + +FractureSliceSettingsPanel::FractureSliceSettingsPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureSliceSettingsPanel) +{ + ui->setupUi(this); +} + +FractureSliceSettingsPanel::~FractureSliceSettingsPanel() +{ + delete ui; +} + +void FractureSliceSettingsPanel::updateValues() +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + + ui->spinBoxNumSlices->setValue(slice.numSlices); + ui->spinBoxOffsetVariation->setValue(slice.offsetVariation); + ui->spinBoxRotationVariation->setValue(slice.rotationVariation); + ui->spinBoxNoiseAmplitude->setValue(slice.noiseAmplitude); + ui->spinBoxNoiseFrequency->setValue(slice.noiseFrequency); + ui->spinBoxNoiseSeed->setValue(slice.noiseSeed); +} + +void FractureSliceSettingsPanel::on_spinBoxNumSlices_valueChanged(int arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.numSlices = arg1; +} + +void FractureSliceSettingsPanel::on_spinBoxOffsetVariation_valueChanged(double arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.offsetVariation = arg1; +} + +void FractureSliceSettingsPanel::on_spinBoxRotationVariation_valueChanged(double arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.rotationVariation = arg1; +} + +void FractureSliceSettingsPanel::on_spinBoxNoiseAmplitude_valueChanged(double arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.noiseAmplitude = arg1; +} + +void FractureSliceSettingsPanel::on_spinBoxNoiseFrequency_valueChanged(double arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.noiseFrequency = arg1; +} + +void FractureSliceSettingsPanel::on_spinBoxNoiseSeed_valueChanged(int arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.noiseSeed = arg1; +} + +void FractureSliceSettingsPanel::on_btnApplyFracture_clicked() +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + SliceFractureExecutor executor; + executor.applyNoise(slice.noiseAmplitude, slice.noiseAmplitude, 0, 0, 0, slice.noiseSeed); + executor.applyConfig(slice.numSlices, slice.numSlices, slice.numSlices, slice.offsetVariation, slice.rotationVariation); + + bool multiplyChunksSelected = false; + std::map<BlastAsset*, std::vector<uint32_t>> selectedChunks = SampleManager::ins()->getSelectedChunks(); + std::map<BlastAsset*, std::vector<uint32_t>>::iterator itrAssetSelectedChunks = selectedChunks.begin(); + + if (selectedChunks.size() > 1) + { + multiplyChunksSelected = true; + } + else if (selectedChunks.size() == 1 && itrAssetSelectedChunks->second.size() > 1) + { + multiplyChunksSelected = true; + } + else if((selectedChunks.size() == 1 && itrAssetSelectedChunks->second.size() == 0) || (selectedChunks.size() == 0)) + { + return; + } + + if (multiplyChunksSelected) + { + QMessageBox::warning(NULL, "Blast Tool", "Now, this tool can only fracture one chunk!"); + return; + } + + executor.setSourceAsset(itrAssetSelectedChunks->first); + executor.setTargetChunk(itrAssetSelectedChunks->second.at(0)); + executor.execute(); + + //VoronoiFractureExecutor executor; + //executor.setTargetChunk(0); + //executor.execute(); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h new file mode 100644 index 0000000..b85b58f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h @@ -0,0 +1,38 @@ +#ifndef FRACTURESLICESETTINGSPANEL_H +#define FRACTURESLICESETTINGSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureSliceSettingsPanel; +} + +class FractureSliceSettingsPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureSliceSettingsPanel(QWidget *parent = 0); + ~FractureSliceSettingsPanel(); + void updateValues(); + +private slots: + void on_spinBoxNumSlices_valueChanged(int arg1); + + void on_spinBoxOffsetVariation_valueChanged(double arg1); + + void on_spinBoxRotationVariation_valueChanged(double arg1); + + void on_spinBoxNoiseAmplitude_valueChanged(double arg1); + + void on_spinBoxNoiseFrequency_valueChanged(double arg1); + + void on_spinBoxNoiseSeed_valueChanged(int arg1); + + void on_btnApplyFracture_clicked(); + +private: + Ui::FractureSliceSettingsPanel *ui; +}; + +#endif // FRACTURESLICESETTINGSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp new file mode 100644 index 0000000..0f77e27 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp @@ -0,0 +1,36 @@ +#include "FractureVisualizersPanel.h" +#include "ui_FractureVisualizersPanel.h" +#include "ProjectParams.h" + +FractureVisualizersPanel::FractureVisualizersPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureVisualizersPanel) +{ + ui->setupUi(this); +} + +FractureVisualizersPanel::~FractureVisualizersPanel() +{ + delete ui; +} + +void FractureVisualizersPanel::updateValues() +{ + BPPFractureVisualization& fractureVisualization = BlastProject::ins().getParams().fracture.visualization; + + ui->checkBoxFracturePreview->setChecked(fractureVisualization.fracturePreview); + ui->checkBoxDisplayFractureWidget->setChecked(fractureVisualization.displayFractureWidget); +} + +void FractureVisualizersPanel::on_checkBoxFracturePreview_stateChanged(int arg1) +{ + BPPFractureVisualization& fractureVisualization = BlastProject::ins().getParams().fracture.visualization; + fractureVisualization.fracturePreview = (arg1 != 0 ? true : false); +} + +void FractureVisualizersPanel::on_checkBoxDisplayFractureWidget_stateChanged(int arg1) +{ + BPPFractureVisualization& fractureVisualization = BlastProject::ins().getParams().fracture.visualization; + fractureVisualization.displayFractureWidget = (arg1 != 0 ? true : false); +} + diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h new file mode 100644 index 0000000..d542d7f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h @@ -0,0 +1,28 @@ +#ifndef FRACTUREVISUALIZERSPANEL_H +#define FRACTUREVISUALIZERSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureVisualizersPanel; +} + +class FractureVisualizersPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureVisualizersPanel(QWidget *parent = 0); + ~FractureVisualizersPanel(); + void updateValues(); + +private slots: + void on_checkBoxFracturePreview_stateChanged(int arg1); + + void on_checkBoxDisplayFractureWidget_stateChanged(int arg1); + +private: + Ui::FractureVisualizersPanel *ui; +}; + +#endif // FRACTUREVISUALIZERSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp new file mode 100644 index 0000000..2142f80 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp @@ -0,0 +1,354 @@ +#include "FractureVoronoiSettingsPanel.h" +#include "ui_FractureVoronoiSettingsPanel.h" +#include "ProjectParams.h" +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> +#include <QtCore/QFileInfo> +#include "AppMainWindow.h" +#include "ProjectParams.h" +#include "SimpleScene.h" +#include "SampleManager.h" + +FractureVoronoiSettingsPanel::FractureVoronoiSettingsPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureVoronoiSettingsPanel), + _updateData(true) +{ + ui->setupUi(this); + + ui->groupBoxVisualizers->hide(); +} + +FractureVoronoiSettingsPanel::~FractureVoronoiSettingsPanel() +{ + delete ui; +} + +void FractureVoronoiSettingsPanel::updateValues() +{ + _updateData = false; + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + + ui->spinBoxNumberOfSites->setValue(voronoi.numSites); + ui->comboBoxSiteGeneration->setCurrentIndex(voronoi.siteGeneration); + ui->spinBoxGridSize->setValue(voronoi.gridSize); + ui->spinBoxGridScale->setValue(voronoi.gridScale); + ui->spinBoxAmplitude->setValue(voronoi.amplitude); + ui->spinBoxFrequency->setValue(voronoi.frequency); + + _updatePaintMaskComboBox(); + + _updateMeshCutterComboBox(); + ui->checkBoxFractureInsideCutter->setChecked(voronoi.fractureInsideCutter); + ui->checkBoxFractureOutsideCutter->setChecked(voronoi.fractureOutsideCutter); + + ui->spinBoxTextureSites->setValue(voronoi.numTextureSites); + + _updateTextureListWidget(); + _updateData = true; +} + +void FractureVoronoiSettingsPanel::on_checkBoxGridPreview_stateChanged(int arg1) +{ + +} + +void FractureVoronoiSettingsPanel::on_checkBoxFracturePreview_stateChanged(int arg1) +{ + +} + +void FractureVoronoiSettingsPanel::on_checkBoxCutterMesh_stateChanged(int arg1) +{ + +} + +void FractureVoronoiSettingsPanel::on_spinBoxNumberOfSites_valueChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.numSites = arg1; +} + +void FractureVoronoiSettingsPanel::on_comboBoxSiteGeneration_currentIndexChanged(int index) +{ + if (!_updateData) + return; + + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.siteGeneration = index; +} + +void FractureVoronoiSettingsPanel::on_spinBoxGridSize_valueChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.gridSize = arg1; +} + +void FractureVoronoiSettingsPanel::on_spinBoxGridScale_valueChanged(double arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.gridScale = arg1; +} + +void FractureVoronoiSettingsPanel::on_spinBoxAmplitude_valueChanged(double arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.amplitude = arg1; +} + +void FractureVoronoiSettingsPanel::on_spinBoxFrequency_valueChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.frequency = arg1; +} + +void FractureVoronoiSettingsPanel::on_comboBoxPaintMasks_currentIndexChanged(int index) +{ + if (!_updateData) + return; + + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.activePaintMask = index; +} + +void FractureVoronoiSettingsPanel::on_btnAddPaintMasks_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new paint mask:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isPaintMaskNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addPaintMasks(name.toUtf8().data()); + _updatePaintMaskComboBox(); + ui->comboBoxPaintMasks->setCurrentIndex(ui->comboBoxPaintMasks->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new paint mask!"); + } +} + +void FractureVoronoiSettingsPanel::on_btnRemovePaintMasks_clicked() +{ + if (ui->comboBoxPaintMasks->currentIndex() > -1) + { + BlastProject::ins().removePaintMasks(ui->comboBoxPaintMasks->currentText().toUtf8().data()); + _updatePaintMaskComboBox(); + } +} + +void FractureVoronoiSettingsPanel::on_comboBoxMeshCutter_currentIndexChanged(int index) +{ + if (!_updateData) + return; + + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.activeMeshCutter = index; +} + +void FractureVoronoiSettingsPanel::on_btnAddMeshCutter_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new mesh cutter:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isMeshCutterNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addMeshCutter(name.toUtf8().data()); + _updateMeshCutterComboBox(); + ui->comboBoxMeshCutter->setCurrentIndex(ui->comboBoxMeshCutter->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new cutter mesh!"); + } +} + +void FractureVoronoiSettingsPanel::on_btnRemoveMeshCutter_clicked() +{ + if (ui->comboBoxMeshCutter->currentIndex() > -1) + { + BlastProject::ins().removeMeshCutter(ui->comboBoxMeshCutter->currentText().toUtf8().data()); + _updateMeshCutterComboBox(); + } +} + +void FractureVoronoiSettingsPanel::on_checkBoxFractureInsideCutter_stateChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.fractureInsideCutter = (arg1 != 0 ? true : false); +} + +void FractureVoronoiSettingsPanel::on_checkBoxFractureOutsideCutter_stateChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.fractureOutsideCutter = (arg1 != 0 ? true : false); +} + +void FractureVoronoiSettingsPanel::on_btnAddTexture_clicked() +{ + QString texName = AppMainWindow::Inst().OpenTextureFile(); + + if (texName.isEmpty()) + return; + + QFileInfo fileInfo(texName); + QByteArray ba = fileInfo.absoluteFilePath().toLocal8Bit(); + const char* filePath = (const char*)(ba); + + if (!BlastProject::ins().isVoronoiTextureNameExist(texName.toUtf8().data())) + { + BlastProject::ins().addVoronoiTexture(filePath); + _updateTextureListWidget(); + ui->listWidgetTexture->setCurrentRow(ui->listWidgetTexture->count() - 1); + } + else + { + QMessageBox::warning(this, "Blast Tool", "The texture you selected is already exist!"); + } +} + +void FractureVoronoiSettingsPanel::on_btnReloadTexture_clicked() +{ + +} + +void FractureVoronoiSettingsPanel::on_btnRemoveTexture_clicked() +{ + if (ui->listWidgetTexture->currentRow() != -1) + { + QListWidgetItem *item = ui->listWidgetTexture->currentItem(); + QString texture = _getTexturePathByName(item->text()); + QByteArray ba = texture.toLocal8Bit(); + BlastProject::ins().removeVoronoiTexture(ba.data()); + _updateTextureListWidget(); + } +} + +void FractureVoronoiSettingsPanel::on_spinBoxTextureSites_valueChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.numTextureSites = arg1; +} + +void FractureVoronoiSettingsPanel::on_listWidgetTexture_itemSelectionChanged() +{ + +} + +void FractureVoronoiSettingsPanel::on_btnTextureMap_clicked() +{ + +} + +void FractureVoronoiSettingsPanel::on_btnApplyFracture_clicked() +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + VoronoiFractureExecutor executor; + executor.setCellsCount(voronoi.numSites); + + bool multiplyChunksSelected = false; + std::map<BlastAsset*, std::vector<uint32_t>> selectedChunks = SampleManager::ins()->getSelectedChunks(); + std::map<BlastAsset*, std::vector<uint32_t>>::iterator itrAssetSelectedChunks = selectedChunks.begin(); + + if (selectedChunks.size() > 1) + { + multiplyChunksSelected = true; + } + else if (selectedChunks.size() == 1 && itrAssetSelectedChunks->second.size() > 1) + { + multiplyChunksSelected = true; + } + else if ((selectedChunks.size() == 1 && itrAssetSelectedChunks->second.size() == 0) || (selectedChunks.size() == 0)) + { + return; + } + + if (multiplyChunksSelected) + { + QMessageBox::warning(NULL, "Blast Tool", "Now, this tool can only fracture one chunk!"); + return; + } + + executor.setSourceAsset(itrAssetSelectedChunks->first); + executor.setTargetChunk(itrAssetSelectedChunks->second.at(0)); + executor.execute(); +} + +QString FractureVoronoiSettingsPanel::_getTexturePathByName(const QString& name) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + BPPStringArray& textureArray = voronoi.textureSites; + + int count = textureArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + QFileInfo fileInfo(textureArray.buf[i].buf); + if (fileInfo.baseName() == name) + return textureArray.buf[i].buf; + } + + return ""; +} + +void FractureVoronoiSettingsPanel::_updatePaintMaskComboBox() +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + + ui->comboBoxPaintMasks->clear(); + QStringList items; + for (int i = 0; i < voronoi.paintMasks.arraySizes[0]; ++i) + { + items.append(voronoi.paintMasks.buf[i].buf); + } + ui->comboBoxPaintMasks->addItems(items); + ui->comboBoxPaintMasks->setCurrentIndex(voronoi.activePaintMask); +} + +void FractureVoronoiSettingsPanel::_updateMeshCutterComboBox() +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + + ui->comboBoxMeshCutter->clear(); + QStringList items; + for (int i = 0; i < voronoi.meshCutters.arraySizes[0]; ++i) + { + items.append(voronoi.meshCutters.buf[i].buf); + } + ui->comboBoxMeshCutter->addItems(items); + ui->comboBoxMeshCutter->setCurrentIndex(voronoi.activeMeshCutter); +} + +void FractureVoronoiSettingsPanel::_updateTextureListWidget() +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + + ui->listWidgetTexture->clear(); + QStringList items; + for (int i = 0; i < voronoi.textureSites.arraySizes[0]; ++i) + { + QFileInfo fileInfo(voronoi.textureSites.buf[i].buf); + QByteArray ba = fileInfo.baseName().toLocal8Bit(); + const char* texture = (const char*)(ba); + items.append(texture); + } + ui->listWidgetTexture->addItems(items); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h new file mode 100644 index 0000000..6a0668d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h @@ -0,0 +1,79 @@ +#ifndef FRACTUREVORONOISETTINGSPANEL_H +#define FRACTUREVORONOISETTINGSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureVoronoiSettingsPanel; +} + +class FractureVoronoiSettingsPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureVoronoiSettingsPanel(QWidget *parent = 0); + ~FractureVoronoiSettingsPanel(); + void updateValues(); + +private slots: + void on_checkBoxGridPreview_stateChanged(int arg1); + + void on_checkBoxFracturePreview_stateChanged(int arg1); + + void on_checkBoxCutterMesh_stateChanged(int arg1); + + void on_spinBoxNumberOfSites_valueChanged(int arg1); + + void on_comboBoxSiteGeneration_currentIndexChanged(int index); + + void on_spinBoxGridSize_valueChanged(int arg1); + + void on_spinBoxGridScale_valueChanged(double arg1); + + void on_spinBoxAmplitude_valueChanged(double arg1); + + void on_spinBoxFrequency_valueChanged(int arg1); + + void on_comboBoxPaintMasks_currentIndexChanged(int index); + + void on_btnAddPaintMasks_clicked(); + + void on_btnRemovePaintMasks_clicked(); + + void on_comboBoxMeshCutter_currentIndexChanged(int index); + + void on_btnAddMeshCutter_clicked(); + + void on_btnRemoveMeshCutter_clicked(); + + void on_checkBoxFractureInsideCutter_stateChanged(int arg1); + + void on_checkBoxFractureOutsideCutter_stateChanged(int arg1); + + void on_btnAddTexture_clicked(); + + void on_btnReloadTexture_clicked(); + + void on_btnRemoveTexture_clicked(); + + void on_spinBoxTextureSites_valueChanged(int arg1); + + void on_listWidgetTexture_itemSelectionChanged(); + + void on_btnTextureMap_clicked(); + + void on_btnApplyFracture_clicked(); + +private: + QString _getTexturePathByName(const QString& name); + void _updatePaintMaskComboBox(); + void _updateMeshCutterComboBox(); + void _updateTextureListWidget(); + +private: + Ui::FractureVoronoiSettingsPanel *ui; + bool _updateData; +}; + +#endif // FRACTUREVORONOISETTINGSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp new file mode 100644 index 0000000..88915f1 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp @@ -0,0 +1,281 @@ +#include "GeneralPanel.h" +#include "ui_GeneralPanel.h" +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> + +GeneralPanel::GeneralPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::GeneralPanel) +{ + ui->setupUi(this); +} + +GeneralPanel::~GeneralPanel() +{ + delete ui; +} + +void GeneralPanel::updateValues() +{ + std::vector<StressSolverUserPreset> presets = BlastProject::ins().getUserPresets(); + ui->comboBoxUserPreset->clear(); + int countUserPresets = (int)presets.size(); + if (countUserPresets > 0) + { + QStringList userPresets; + for (int i = 0; i < countUserPresets; ++i) + { + userPresets.append(presets[i].name.c_str()); + } + ui->comboBoxUserPreset->addItems(userPresets); + } + + std::vector<BPPAsset*> selectedAssets = BlastProject::ins().getSelectedBlastAssets(); + if (selectedAssets.size() > 0) + { + ui->comboBoxUserPreset->setCurrentText(selectedAssets[0]->activePreset.buf); + + _updateStressSolverUIs(); + } + else + { + ui->comboBoxUserPreset->setCurrentIndex(-1); + + } +} + +void GeneralPanel::on_comboBoxUserPreset_currentIndexChanged(int index) +{ + std::vector<BPPAsset*> assets = BlastProject::ins().getSelectedBlastAssets(); + for (size_t i = 0; i < assets.size(); ++i) + { + QByteArray tem = ui->comboBoxUserPreset->currentText().toUtf8(); + copy(assets[i]->activePreset, tem.data()); + + BPPStressSolver* preset = _getUserPreset(tem.data()); + if (preset) + { + copy(assets[i]->stressSolver, *preset); + } + } + _updateStressSolverUIs(); +} + +void GeneralPanel::on_btnAddUserPreset_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new User preset:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isUserPresetNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addUserPreset(name.toUtf8().data()); + updateValues(); + ui->comboBoxUserPreset->setCurrentIndex(ui->comboBoxUserPreset->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new preset!"); + } +} + +void GeneralPanel::on_btnModifyUserPreset_clicked() +{ + if (ui->comboBoxUserPreset->currentIndex() == -1) + { + QMessageBox::warning(this, "Blast Tool", "You should select an user preset!"); + return; + } + + QByteArray tmp = ui->comboBoxUserPreset->currentText().toUtf8(); + const char* oldName = tmp.data(); + + bool ok = false; + QString newName = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input new name for the selected user preset:"), + QLineEdit::Normal, + oldName, + &ok); + bool nameExist = BlastProject::ins().isUserPresetNameExist(newName.toUtf8().data()); + if (ok && !newName.isEmpty() && !nameExist) + { + int curIndex = ui->comboBoxUserPreset->currentIndex(); + + std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets(); + presets[curIndex].name = newName.toUtf8().data(); + updateValues(); + ui->comboBoxUserPreset->setCurrentIndex(curIndex); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && newName.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the selected graphics material!"); + } +} + +void GeneralPanel::on_btnSaveUserPreset_clicked() +{ + int currentUserPreset = ui->comboBoxUserPreset->currentIndex(); + if (-1 != currentUserPreset) + { + std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets(); + BPPStressSolver& stressSolver = presets[currentUserPreset].stressSolver; + stressSolver.solverMode = ui->comboBoxSolverMode->currentIndex(); + stressSolver.linearFactor = ui->spinBoxLinearFactor->value(); + stressSolver.angularFactor = ui->spinBoxAngularFactor->value(); + stressSolver.meanError = ui->spinBoxMeanError->value(); + stressSolver.varianceError = ui->spinBoxVarianceError->value(); + stressSolver.bondsPerFrame = ui->spinBoxBondsPerFrame->value(); + stressSolver.bondsIterations = ui->spinBoxBondsIterations->value(); + } + + BlastProject::ins().saveUserPreset(); +} + +void GeneralPanel::on_comboBoxSolverMode_currentIndexChanged(int index) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->solverMode = index; + } +} + +void GeneralPanel::on_spinBoxLinearFactor_valueChanged(double arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->linearFactor = arg1; + } + +} + +void GeneralPanel::on_spinBoxAngularFactor_valueChanged(double arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->angularFactor = arg1; + } +} + +void GeneralPanel::on_spinBoxMeanError_valueChanged(double arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->meanError = arg1; + } +} + +void GeneralPanel::on_spinBoxVarianceError_valueChanged(double arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->varianceError = arg1; + } +} + +void GeneralPanel::on_spinBoxBondsPerFrame_valueChanged(int arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->bondsPerFrame = arg1; + } +} + +void GeneralPanel::on_spinBoxBondsIterations_valueChanged(int arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->bondsIterations = arg1; + } +} + +BPPStressSolver* GeneralPanel::_getCurrentStressSolver() +{ + int currentUserPreset = ui->comboBoxUserPreset->currentIndex(); + + if (-1 != currentUserPreset) + { + std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets(); + return &(presets[currentUserPreset].stressSolver); + } + else + { + std::vector<BPPAsset*> assets = BlastProject::ins().getSelectedBlastAssets(); + + if (assets.size() > 0) + { + return &(assets[0]->stressSolver); + } + } + + return nullptr; +} + +BPPStressSolver* GeneralPanel::_getUserPreset(const char* name) +{ + std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets(); + + for (size_t i = 0; i < presets.size(); ++i) + { + if (presets[i].name == name) + return &(presets[i].stressSolver); + } + + return nullptr; +} + +void GeneralPanel::_updateStressSolverUIs() +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + if (stressSolver != nullptr) + { + ui->comboBoxSolverMode->setCurrentIndex(stressSolver->solverMode); + ui->spinBoxLinearFactor->setValue(stressSolver->linearFactor); + ui->spinBoxAngularFactor->setValue(stressSolver->angularFactor); + ui->spinBoxMeanError->setValue(stressSolver->meanError); + ui->spinBoxVarianceError->setValue(stressSolver->varianceError); + ui->spinBoxBondsPerFrame->setValue(stressSolver->bondsPerFrame); + ui->spinBoxBondsIterations->setValue(stressSolver->bondsIterations); + } + else + { + BPPStressSolver noStressSolver; + init(noStressSolver); + + ui->comboBoxSolverMode->setCurrentIndex(noStressSolver.solverMode); + ui->spinBoxLinearFactor->setValue(noStressSolver.linearFactor); + ui->spinBoxAngularFactor->setValue(noStressSolver.angularFactor); + ui->spinBoxMeanError->setValue(noStressSolver.meanError); + ui->spinBoxVarianceError->setValue(noStressSolver.varianceError); + ui->spinBoxBondsPerFrame->setValue(noStressSolver.bondsPerFrame); + ui->spinBoxBondsIterations->setValue(noStressSolver.bondsIterations); + } + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h new file mode 100644 index 0000000..a7a52e3 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h @@ -0,0 +1,52 @@ +#ifndef GENERALPANEL_H +#define GENERALPANEL_H + +#include <QtWidgets/QWidget> +#include "ProjectParams.h" + +namespace Ui { +class GeneralPanel; +} + +class GeneralPanel : public QWidget +{ + Q_OBJECT + +public: + explicit GeneralPanel(QWidget *parent = 0); + ~GeneralPanel(); + void updateValues(); + +private slots: + void on_comboBoxUserPreset_currentIndexChanged(int index); + + void on_btnAddUserPreset_clicked(); + + void on_btnModifyUserPreset_clicked(); + + void on_btnSaveUserPreset_clicked(); + + void on_comboBoxSolverMode_currentIndexChanged(int index); + + void on_spinBoxLinearFactor_valueChanged(double arg1); + + void on_spinBoxAngularFactor_valueChanged(double arg1); + + void on_spinBoxMeanError_valueChanged(double arg1); + + void on_spinBoxVarianceError_valueChanged(double arg1); + + void on_spinBoxBondsPerFrame_valueChanged(int arg1); + + void on_spinBoxBondsIterations_valueChanged(int arg1); + +private: + BPPStressSolver* _getCurrentStressSolver(); + BPPStressSolver* _getUserPreset(const char* name); + void _updateStressSolverUIs(); + +private: + Ui::GeneralPanel *ui; +}; + +#endif // GENERALPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp new file mode 100644 index 0000000..6095f67 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp @@ -0,0 +1,265 @@ +#include "MaterialAssignmentsPanel.h" +#include "ui_MaterialAssignmentsPanel.h" +#include "ProjectParams.h" +#include "RenderMaterial.h" +#include "SampleManager.h" +#include "MaterialLibraryPanel.h" + +MaterialAssignmentsPanel* pMaterialAssignmentsPanel = nullptr; +MaterialAssignmentsPanel* MaterialAssignmentsPanel::ins() +{ + return pMaterialAssignmentsPanel; +} + +MaterialAssignmentsPanel::MaterialAssignmentsPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::MaterialAssignmentsPanel), + _selectedGraphicsMesh(-1) +{ + ui->setupUi(this); + pMaterialAssignmentsPanel = this; + m_bValid = true; +} + +void MaterialAssignmentsPanel::getMaterialNameAndPaths(std::vector<std::string>& materialNames, std::vector<std::string>& materialPaths) +{ + QString m1 = ui->comboBoxMaterialID1->currentText(); + QString m2 = ui->comboBoxMaterialID2->currentText(); + std::string name1 = m1.toUtf8().data(); + std::string name2 = m2.toUtf8().data(); + std::string path1 = ""; + std::string path2 = ""; + + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& theArray = projectParams.graphicsMaterials; + int count = theArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + BPPGraphicsMaterial& item = theArray.buf[i]; + std::string name = item.name.buf; + std::string path = item.diffuseTextureFilePath.buf; + if (name1 == name) + { + path1 = path; + } + else if (name2 == name) + { + path2 = path; + } + else if (path1 != "" && path2 != "") + { + break; + } + } + + materialNames.push_back(name1); + materialNames.push_back(name2); + materialPaths.push_back(path1); + materialPaths.push_back(path2); +} + +MaterialAssignmentsPanel::~MaterialAssignmentsPanel() +{ + delete ui; +} + +void MaterialAssignmentsPanel::updateValues() +{ + m_bValid = false; + ui->comboBoxMaterialID1->clear(); + ui->comboBoxMaterialID2->clear(); + m_bValid = true; + + QStringList materialNames; + materialNames.append("None"); + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& theArray = projectParams.graphicsMaterials; + int count = theArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + BPPGraphicsMaterial& item = theArray.buf[i]; + materialNames.append(item.name.buf); + } + + m_bValid = false; + ui->comboBoxMaterialID1->insertItems(0, materialNames); + ui->comboBoxMaterialID2->insertItems(0, materialNames); + m_bValid = true; + + SampleManager* pSampleManager = SampleManager::ins(); + if (pSampleManager == nullptr) + { + return; + } + + BlastAsset* pBlastAsset = nullptr; + int index = -1; + pSampleManager->getCurrentSelectedInstance(&pBlastAsset, index); + if (pBlastAsset == nullptr || index == -1) + { + return; + } + + RenderMaterial* pRenderMaterial[] = { nullptr, nullptr }; + std::string strMaterialNames[] = { "None", "None" }; + bool ex[] = { true, false }; + for (int i = 0; i < 2; i++) + { + pSampleManager->getMaterialForCurrentFamily(&pRenderMaterial[i], ex[i]); + if (pRenderMaterial[i] != nullptr) + { + std::string m = pRenderMaterial[i]->getMaterialName(); + if (m != "") + { + strMaterialNames[i] = m; + } + } + } + + m_bValid = false; + ui->comboBoxMaterialID1->setCurrentText(strMaterialNames[0].c_str()); + ui->comboBoxMaterialID2->setCurrentText(strMaterialNames[1].c_str()); + m_bValid = true; + + return; + + if (_selectedGraphicsMesh > -1) + { + BPParams& projectParams = BlastProject::ins().getParams(); + BPPBlast& blast = projectParams.blast; + BPPGraphicsMaterialArray& graphicsMaterialsArray = projectParams.graphicsMaterials; + + BPPMaterialAssignments& assignment = blast.graphicsMeshes.buf[_selectedGraphicsMesh].materialAssignments; + + ui->comboBoxMaterialID1->clear(); + ui->comboBoxMaterialID2->clear(); + ui->comboBoxMaterialID3->clear(); + ui->comboBoxMaterialID4->clear(); + + QStringList materialNames; + materialNames.append("None"); + int count = graphicsMaterialsArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + materialNames.append(graphicsMaterialsArray.buf[i].name.buf); + } + + ui->comboBoxMaterialID1->insertItems(0, materialNames); + ui->comboBoxMaterialID2->insertItems(0, materialNames); + ui->comboBoxMaterialID3->insertItems(0, materialNames); + ui->comboBoxMaterialID4->insertItems(0, materialNames); + + ui->comboBoxMaterialID1->setCurrentIndex(assignment.materialIndexes[0] + 1); + ui->comboBoxMaterialID2->setCurrentIndex(assignment.materialIndexes[1] + 1); + ui->comboBoxMaterialID3->setCurrentIndex(assignment.materialIndexes[2] + 1); + ui->comboBoxMaterialID4->setCurrentIndex(assignment.materialIndexes[3] + 1); + } + + +} + +void MaterialAssignmentsPanel::on_comboBoxMaterialID1_currentIndexChanged(int index) +{ + if (index < 0 || !m_bValid) + return; + + RenderMaterial* pRenderMaterial = nullptr; + + QString currentText = ui->comboBoxMaterialID1->currentText(); + std::string name = currentText.toUtf8().data(); + + SampleManager* pSampleManager = SampleManager::ins(); + if (pSampleManager == nullptr) + { + return; + } + std::map<std::string, RenderMaterial*>& renderMaterials = pSampleManager->getRenderMaterials(); + std::map<std::string, RenderMaterial*>::iterator it = renderMaterials.find(name); + if (it != renderMaterials.end()) + { + pRenderMaterial = it->second; + } + else + { + MaterialLibraryPanel* pMaterialLibraryPanel = MaterialLibraryPanel::ins(); + std::map<std::string, RenderMaterial*>& renderMaterials2 = pMaterialLibraryPanel->getRenderMaterials(); + it = renderMaterials2.find(name); + if (it != renderMaterials2.end()) + { + pRenderMaterial = it->second; + } + } + + pSampleManager->setMaterialForCurrentFamily(pRenderMaterial, true); + + return; + assignMaterialToMaterialID(0, index - 1); +} + +void MaterialAssignmentsPanel::on_comboBoxMaterialID2_currentIndexChanged(int index) +{ + if (index < 0 || !m_bValid) + return; + + RenderMaterial* pRenderMaterial = nullptr; + + QString currentText = ui->comboBoxMaterialID2->currentText(); + std::string name = currentText.toUtf8().data(); + + SampleManager* pSampleManager = SampleManager::ins(); + if (pSampleManager == nullptr) + { + return; + } + std::map<std::string, RenderMaterial*>& renderMaterials = pSampleManager->getRenderMaterials(); + std::map<std::string, RenderMaterial*>::iterator it = renderMaterials.find(name); + if (it != renderMaterials.end()) + { + pRenderMaterial = it->second; + } + else + { + MaterialLibraryPanel* pMaterialLibraryPanel = MaterialLibraryPanel::ins(); + std::map<std::string, RenderMaterial*>& renderMaterials2 = pMaterialLibraryPanel->getRenderMaterials(); + it = renderMaterials2.find(name); + if (it != renderMaterials2.end()) + { + pRenderMaterial = it->second; + } + } + + pSampleManager->setMaterialForCurrentFamily(pRenderMaterial, false); + + return; + assignMaterialToMaterialID(1, index - 1); +} + +void MaterialAssignmentsPanel::on_comboBoxMaterialID3_currentIndexChanged(int index) +{ + assignMaterialToMaterialID(2, index - 1); +} + +void MaterialAssignmentsPanel::on_comboBoxMaterialID4_currentIndexChanged(int index) +{ + assignMaterialToMaterialID(3, index - 1); +} + +void MaterialAssignmentsPanel::assignMaterialToMaterialID(int materialID, int materialIndex) +{ + if (materialID < 0 || materialID > 3 || materialIndex < 0) + return; + + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& graphicsMaterialArray = projectParams.graphicsMaterials; + BPPBlast& blast = projectParams.blast; + + if (materialIndex >= graphicsMaterialArray.arraySizes[0]) + return; + + BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes; + + if (_selectedGraphicsMesh > -1 && _selectedGraphicsMesh < graphicsMeshArray.arraySizes[0]) + { + graphicsMeshArray.buf[_selectedGraphicsMesh].materialAssignments.materialIndexes[materialID] = materialIndex; + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.h new file mode 100644 index 0000000..782baa8 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.h @@ -0,0 +1,40 @@ +#ifndef MATERIALASSIGNMENTSPANEL_H +#define MATERIALASSIGNMENTSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class MaterialAssignmentsPanel; +} + +class MaterialAssignmentsPanel : public QWidget +{ + Q_OBJECT + +public: + explicit MaterialAssignmentsPanel(QWidget *parent = 0); + ~MaterialAssignmentsPanel(); + void updateValues(); + + static MaterialAssignmentsPanel* ins(); + void getMaterialNameAndPaths(std::vector<std::string>& materialNames, std::vector<std::string>& materialPaths); + +private slots: + void on_comboBoxMaterialID1_currentIndexChanged(int index); + + void on_comboBoxMaterialID2_currentIndexChanged(int index); + + void on_comboBoxMaterialID3_currentIndexChanged(int index); + + void on_comboBoxMaterialID4_currentIndexChanged(int index); + +private: + void assignMaterialToMaterialID(int materialID, int materialIndex); + +private: + Ui::MaterialAssignmentsPanel *ui; + int _selectedGraphicsMesh; + bool m_bValid; +}; + +#endif // MATERIALASSIGNMENTSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp new file mode 100644 index 0000000..963326c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp @@ -0,0 +1,473 @@ +#include "MaterialLibraryPanel.h" +#include "ui_MaterialLibraryPanel.h" +#include <QtCore/QFileInfo> +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> +#include "QtUtil.h" +#include "AppMainWindow.h" +#include "SimpleScene.h" +#include "RenderMaterial.h" +#include "ResourceManager.h" +#include "SampleManager.h" +#include "MaterialAssignmentsPanel.h" +#include "Renderable.h" +enum ETextureType +{ + eDiffuseTexture, + eSpecularTexture, + eNormalTexture +}; + +void OnTextureButtonClicked(BPPGraphicsMaterial& material, ETextureType t, QPushButton* pButton) +{ + QString texName = AppMainWindow::Inst().OpenTextureFile(); + + QFileInfo fileInfo(texName); + QByteArray ba = fileInfo.absoluteFilePath().toLocal8Bit(); + const char* filePath = (const char*)(ba); + + switch (t) + { + case eDiffuseTexture: + copy(material.diffuseTextureFilePath, filePath); + break; + case eSpecularTexture: + copy(material.specularTextureFilePath, filePath); + break; + case eNormalTexture: + copy(material.normalTextureFilePath, filePath); + break; + } + + if (texName.isEmpty()) + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + else + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png")); + + SimpleScene::Inst()->SetFurModified(true); +} + +void OnTextureReload(BPPGraphicsMaterial& material, ETextureType t, QPushButton* pButton) +{ + QString texName; + switch (t) + { + case eDiffuseTexture: + texName = material.diffuseTextureFilePath.buf; + // to do: reload texture + break; + case eSpecularTexture: + texName = material.specularTextureFilePath.buf; + // to do: reload texture + break; + case eNormalTexture: + texName = material.normalTextureFilePath.buf; + // to do: reload texture + break; + } + + if (texName.isEmpty()) + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + else + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png")); + + SimpleScene::Inst()->SetFurModified(true); +} + +void OnTextureClear(BPPGraphicsMaterial& material, ETextureType t, QPushButton* pButton) +{ + switch (t) + { + case eDiffuseTexture: + freeString(material.diffuseTextureFilePath); + // to do: clear texture + break; + case eSpecularTexture: + freeString(material.specularTextureFilePath); + // to do: clear texture + break; + case eNormalTexture: + freeString(material.normalTextureFilePath); + // to do: clear texture + break; + } + + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + + SimpleScene::Inst()->SetFurModified(true); +} + +MaterialLibraryPanel* pMaterialLibraryPanel = nullptr; +MaterialLibraryPanel* MaterialLibraryPanel::ins() +{ + return pMaterialLibraryPanel; +} + +void MaterialLibraryPanel::addMaterial(std::string materialName, std::string diffuseTexture) +{ + if (!BlastProject::ins().isGraphicsMaterialNameExist(materialName.c_str())) + { + BlastProject::ins().addGraphicsMaterial(materialName.c_str(), diffuseTexture.c_str()); + updateValues(); + ui->listWidget->setCurrentRow(ui->listWidget->count() - 1); + } +} + +void MaterialLibraryPanel::removeMaterial(std::string name) +{ + BlastProject::ins().removeGraphicsMaterial(name.c_str()); + updateValues(); + ui->listWidget->setCurrentRow(ui->listWidget->count() - 1); +} + +void MaterialLibraryPanel::deleteMaterials() +{ + std::vector<std::string>::iterator itStr; + std::vector<Renderable*>::iterator itRenderable; + + for (itStr = m_NeedDeleteRenderMaterials.begin(); itStr != m_NeedDeleteRenderMaterials.end(); itStr++) + { + std::string materialName = *itStr; + RenderMaterial* pRenderMaterial = m_RenderMaterialMap[materialName]; + std::vector<Renderable*>& renderables = pRenderMaterial->getRelatedRenderables(); + for (itRenderable = renderables.begin(); itRenderable != renderables.end(); itRenderable++) + { + Renderable* pRenderable = *itRenderable; + pRenderable->setMaterial(*RenderMaterial::getDefaultRenderMaterial()); + } + + std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(materialName); + if (it != m_RenderMaterialMap.end()) + { + m_RenderMaterialMap.erase(it); + MaterialLibraryPanel::ins()->removeMaterial(materialName); + } + } + + m_NeedDeleteRenderMaterials.clear(); +} + +MaterialLibraryPanel::MaterialLibraryPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::MaterialLibraryPanel) +{ + ui->setupUi(this); + + pMaterialLibraryPanel = this; +} + +MaterialLibraryPanel::~MaterialLibraryPanel() +{ + delete ui; +} + +void MaterialLibraryPanel::updateValues() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& graphicsMaterialArray = projectParams.graphicsMaterials; + + ui->listWidget->clear(); + QStringList materialNames; + int count = graphicsMaterialArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + materialNames.append(graphicsMaterialArray.buf[i].name.buf); + } + ui->listWidget->addItems(materialNames); + + if (count > 0) + { + ui->btnModifyMat->setEnabled(true); + ui->btnRemoveMat->setEnabled(true); + } + else + { + ui->btnModifyMat->setEnabled(false); + ui->btnRemoveMat->setEnabled(false); + } + + MaterialAssignmentsPanel::ins()->updateValues(); +} + +void MaterialLibraryPanel::on_btnAddMat_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new graphics material:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isGraphicsMaterialNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + ResourceManager* pResourceManager = ResourceManager::ins(); + std::string strName = name.toUtf8().data(); + RenderMaterial* pRenderMaterial = new RenderMaterial(strName.c_str(), *pResourceManager, "model_simple_textured_ex"); + m_RenderMaterialMap[strName] = pRenderMaterial; + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new graphics material!"); + } +} + +void MaterialLibraryPanel::on_btnModifyMat_clicked() +{ + QList<QListWidgetItem*> items = ui->listWidget->selectedItems(); + if (items.size() == 0) + { + SampleManager::ins()->output("please select a material first !"); + return; + } + QByteArray tmp = items.at(0)->text().toUtf8(); + const char* oldName = tmp.data(); + + bool ok = false; + QString newName = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input new name for the selected graphics material:"), + QLineEdit::Normal, + oldName, + &ok); + bool nameExist = BlastProject::ins().isGraphicsMaterialNameExist(newName.toUtf8().data()); + if (ok && !newName.isEmpty() && !nameExist) + { + std::string strOldName = oldName; + std::string strNewName = newName.toUtf8().data(); + + std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(strOldName); + if (it != m_RenderMaterialMap.end()) + { + RenderMaterial* pRenderMaterial = it->second; + m_RenderMaterialMap.erase(it); + m_RenderMaterialMap[strNewName] = pRenderMaterial; + } + + SampleManager::ins()->renameRenderMaterial(strOldName, strNewName); + + BlastProject::ins().renameGraphicsMaterial(oldName, newName.toUtf8().data()); + updateValues(); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && newName.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the selected graphics material!"); + } +} + +void MaterialLibraryPanel::on_btnRemoveMat_clicked() +{ + QList<QListWidgetItem*> items = ui->listWidget->selectedItems(); + if (items.size() == 0) + { + SampleManager::ins()->output("please select a material first !"); + return; + } + QByteArray tem = items.at(0)->text().toUtf8(); + + std::string strName = tem.data(); + std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(strName); + if (it != m_RenderMaterialMap.end()) + { + m_NeedDeleteRenderMaterials.push_back(it->second->getMaterialName()); + } + else + { + SampleManager::ins()->deleteRenderMaterial(strName); + } +} + +void MaterialLibraryPanel::on_listWidget_currentRowChanged(int currentRow) +{ + _refreshMaterialValues(currentRow); +} + +void MaterialLibraryPanel::on_btnDiffuseColor_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + atcore_float4* color = (atcore_float4*)&(material->diffuseColor); + pickColor(*color); + setButtonColor(ui->btnDiffuseColor, color->x, color->y, color->z); + } +} + +void MaterialLibraryPanel::on_btnDiffuseColorTex_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureButtonClicked(*material, eDiffuseTexture, ui->btnDiffuseColorTex); + } +} + +void MaterialLibraryPanel::on_btnDiffuseColorTexReload_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureReload(*material, eDiffuseTexture, ui->btnDiffuseColorTex); + + QString qName = material->name.buf; + std::string strName = qName.toUtf8().data(); + QString qTexture = material->diffuseTextureFilePath.buf; + std::string strTexture = qTexture.toUtf8().data(); + + std::map<std::string, RenderMaterial*>& renderMaterials = SampleManager::ins()->getRenderMaterials(); + std::map<std::string, RenderMaterial*>::iterator it = renderMaterials.find(strName); + if (it != renderMaterials.end()) + { + it->second->setTextureFileName(strTexture); + } + } +} + +void MaterialLibraryPanel::on_btnDiffuseColorTexClear_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureClear(*material, eDiffuseTexture, ui->btnDiffuseColorTex); + + QString qName = material->name.buf; + std::string strName = qName.toUtf8().data(); + QString qTexture = material->diffuseTextureFilePath.buf; + std::string strTexture = qTexture.toUtf8().data(); + + std::map<std::string, RenderMaterial*>& renderMaterials = SampleManager::ins()->getRenderMaterials(); + std::map<std::string, RenderMaterial*>::iterator it = renderMaterials.find(strName); + if (it != renderMaterials.end()) + { + it->second->setTextureFileName(strTexture); + } + } +} + +void MaterialLibraryPanel::on_btnSpecularColor_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + atcore_float4* color = (atcore_float4*)&(material->specularColor); + pickColor(*color); + setButtonColor(ui->btnSpecularColor, color->x, color->y, color->z); + } +} + +void MaterialLibraryPanel::on_btnSpecularColorTex_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureButtonClicked(*material, eSpecularTexture, ui->btnSpecularColorTex); + } +} + +void MaterialLibraryPanel::on_btnSpecularColorTexReload_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureReload(*material, eSpecularTexture, ui->btnSpecularColorTex); + } +} + +void MaterialLibraryPanel::on_btnSpecularColorTexClear_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureClear(*material, eSpecularTexture, ui->btnSpecularColorTex); + } +} + +void MaterialLibraryPanel::on_spinSpecularShin_valueChanged(double arg1) +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + material->specularShininess = (float)arg1; + } +} + +void MaterialLibraryPanel::on_btnNormalColorTex_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureButtonClicked(*material, eNormalTexture, ui->btnNormalColorTex); + } +} + +void MaterialLibraryPanel::on_btnNormalColorTexReload_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureReload(*material, eNormalTexture, ui->btnNormalColorTex); + } +} + +void MaterialLibraryPanel::on_btnNormalColorTexClear_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureClear(*material, eNormalTexture, ui->btnNormalColorTex); + } +} + +void MaterialLibraryPanel::_refreshMaterialValues(int idx) +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& graphicsMaterialArray = projectParams.graphicsMaterials; + int count = graphicsMaterialArray.arraySizes[0]; + if (idx >= 0 && idx < count) + { + const BPPGraphicsMaterial& material = graphicsMaterialArray.buf[idx]; + + ui->spinSpecularShin->setValue(material.specularShininess); + + const nvidia::NvVec4& diffuseColor = material.diffuseColor; + const nvidia::NvVec4& specularColor = material.specularColor; + setButtonColor(ui->btnDiffuseColor, diffuseColor.x, diffuseColor.y, diffuseColor.z); + setButtonColor(ui->btnSpecularColor, specularColor.x, specularColor.y, specularColor.z); + + updateTextureButton(ui->btnDiffuseColorTex, material.diffuseTextureFilePath.buf); + updateTextureButton(ui->btnSpecularColorTex, material.specularTextureFilePath.buf); + updateTextureButton(ui->btnNormalColorTex, material.normalTextureFilePath.buf); + } + else + { + ui->spinSpecularShin->setValue(0.0f); + + setButtonColor(ui->btnDiffuseColor, 0, 0, 0); + setButtonColor(ui->btnSpecularColor, 0, 0, 0); + updateTextureButton(ui->btnDiffuseColorTex, ""); + updateTextureButton(ui->btnSpecularColorTex, ""); + updateTextureButton(ui->btnNormalColorTex, ""); + } +} + +BPPGraphicsMaterial* MaterialLibraryPanel::_getSelectedMaterial() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& graphicsMaterialArray = projectParams.graphicsMaterials; + + int idx = ui->listWidget->currentRow(); + int count = graphicsMaterialArray.arraySizes[0]; + if (idx < 0 || idx > count) + return nullptr; + + return &(graphicsMaterialArray.buf[idx]); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h new file mode 100644 index 0000000..5c2c970 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h @@ -0,0 +1,72 @@ +#ifndef MATERIALLIBRARYPANEL_H +#define MATERIALLIBRARYPANEL_H + +#include <QtWidgets/QWidget> +#include "ProjectParams.h" + +class RenderMaterial; + +namespace Ui { +class MaterialLibraryPanel; +} + +class MaterialLibraryPanel : public QWidget +{ + Q_OBJECT + +public: + explicit MaterialLibraryPanel(QWidget *parent = 0); + ~MaterialLibraryPanel(); + void updateValues(); + + static MaterialLibraryPanel* ins(); + void addMaterial(std::string materialName, std::string diffuseTexture); + void removeMaterial(std::string name); + std::map<std::string, RenderMaterial*>& getRenderMaterials(){ return m_RenderMaterialMap; } + void deleteMaterials(); + +private slots: + void on_btnAddMat_clicked(); + + void on_btnModifyMat_clicked(); + + void on_btnRemoveMat_clicked(); + + void on_listWidget_currentRowChanged(int currentRow); + + void on_btnDiffuseColor_clicked(); + + void on_btnDiffuseColorTex_clicked(); + + void on_btnDiffuseColorTexReload_clicked(); + + void on_btnDiffuseColorTexClear_clicked(); + + void on_btnSpecularColor_clicked(); + + void on_btnSpecularColorTex_clicked(); + + void on_btnSpecularColorTexReload_clicked(); + + void on_btnSpecularColorTexClear_clicked(); + + void on_spinSpecularShin_valueChanged(double arg1); + + void on_btnNormalColorTex_clicked(); + + void on_btnNormalColorTexReload_clicked(); + + void on_btnNormalColorTexClear_clicked(); + +private: + void _refreshMaterialValues(int idx); + BPPGraphicsMaterial* _getSelectedMaterial(); + + std::map<std::string, RenderMaterial*> m_RenderMaterialMap; + std::vector<std::string> m_NeedDeleteRenderMaterials; + +private: + Ui::MaterialLibraryPanel *ui; +}; + +#endif // MATERIALLIBRARYPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.cpp new file mode 100644 index 0000000..748002c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.cpp @@ -0,0 +1,39 @@ +#include "NoiseToolsDlg.h" +#include "ui_NoiseToolsDlg.h" + +NoiseToolsDlg::NoiseToolsDlg(QWidget *parent) : + QDialog(parent), + ui(new Ui::NoiseToolsDlg) +{ + ui->setupUi(this); +} + +NoiseToolsDlg::~NoiseToolsDlg() +{ + delete ui; +} + +void NoiseToolsDlg::on_comboBoxApplyByMaterial_currentIndexChanged(int index) +{ + +} + +void NoiseToolsDlg::on_spinBoxAmplitude_valueChanged(double arg1) +{ + +} + +void NoiseToolsDlg::on_spinBoxFrequency_valueChanged(double arg1) +{ + +} + +void NoiseToolsDlg::on_spinBoxAmplitude_3_valueChanged(double arg1) +{ + +} + +void NoiseToolsDlg::on_btnApply_clicked() +{ + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.h new file mode 100644 index 0000000..057dd42 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.h @@ -0,0 +1,33 @@ +#ifndef NOISETOOLSDLG_H +#define NOISETOOLSDLG_H + +#include <QtWidgets/QDialog> + +namespace Ui { +class NoiseToolsDlg; +} + +class NoiseToolsDlg : public QDialog +{ + Q_OBJECT + +public: + explicit NoiseToolsDlg(QWidget *parent = 0); + ~NoiseToolsDlg(); + +private slots: + void on_comboBoxApplyByMaterial_currentIndexChanged(int index); + + void on_spinBoxAmplitude_valueChanged(double arg1); + + void on_spinBoxFrequency_valueChanged(double arg1); + + void on_spinBoxAmplitude_3_valueChanged(double arg1); + + void on_btnApply_clicked(); + +private: + Ui::NoiseToolsDlg *ui; +}; + +#endif // NOISETOOLSDLG_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.cpp new file mode 100644 index 0000000..b2fdd75 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.cpp @@ -0,0 +1,155 @@ +#include "QtUtil.h" + +#include <QtWidgets/QLabel> +#include "AppMainWindow.h" + +#include "SimpleScene.h" + +////////////////////////////////////////////////////////// +void setStyledToolTip(QPushButton *pButton, const char *tooltip) +{ + char styledString[1024]; + sprintf(styledString, "<span style=\"color:black;\">%s</span>", tooltip); + pButton->setToolTip(styledString); +} + +////////////////////////////////////////////////////////// +QString addStar(QString text, bool add) +{ + QByteArray ba = text.toUtf8(); + + const char* in = ba.data(); + char out[1024]; + + int i = 0; + for (i = 0; i < strlen(in); i++) + { + if (in[i] == '*') + break; + out[i] = in[i]; + } + out[i] = 0; + + QString newtext; + if (add) + newtext = QString((const char*)out) + QString("*"); + else + newtext = QString((const char*)out) ; + return newtext; +} + +////////////////////////////////////////////////////////// +void setFocusColor(QWidget* qWidget, bool sameAsDefault, bool sameForAllAssets) +{ + if (!qWidget) + return; + + QString sameStyle = QString("font: ; color: rgb(150,150,150);") ; + QString differentStyle = QString("font: bold; color: rgb(255,55,55);"); + QString style = (sameForAllAssets) ? sameStyle : differentStyle; + + qWidget->setStyleSheet(style); + + QLabel* label = dynamic_cast<QLabel*>(qWidget); + if (label) + { + QString newtext = addStar(label->text(), !sameAsDefault); + + label->setFrameStyle(0); + label->setText(newtext); + } +} + +////////////////////////////////////////////////////////// +void pickColor(atcore_float4& color) +{ + QColor currentColor; + currentColor.setRgbF(color.x, color.y, color.z); + + QColor newColor = QColorDialog::getColor(currentColor, NV_NULL); + if(newColor.isValid()) + { + qreal r,g,b; + newColor.getRgbF(&r, &g, &b); + + color.x = r; + color.y = g; + color.z = b; + } +} + +////////////////////////////////////////////////////////// +void setButtonColor(QPushButton *button, float r, float g, float b) +{ + QColor specColor; + specColor.setRgbF(r,g,b); + QString specBtnStyle = QString("background-color: rgb(%1,%2,%3);") + .arg(specColor.red()) + .arg(specColor.green()) + .arg(specColor.blue()); + + button->setStyleSheet(specBtnStyle); +} + + +///////////////////////////////////////////////////////////////////////////////////// +void updateColorButton(QPushButton* button, int paramID, QLabel* label) +{ + //atcore_float4 v; + //SimpleScene::Inst()->GetFurCharacter().GetHairParam(paramID, &v); + + //setButtonColor(button, v.x, v.y, v.z); + + //if (label) + // setFocusColor(label, paramID); +} + +///////////////////////////////////////////////////////////////////////////////////// +void setClearButtonIcon(QPushButton *pButton) +{ + pButton->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); +} + +///////////////////////////////////////////////////////////////////////////////////// +void setTextureButtons(QPushButton *pTex, QPushButton *pReload, QPushButton *pClear) +{ + pTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + pReload->setIcon(QIcon(":/AppMainWindow/images/Refresh_icon.png")); + pClear->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); + + pTex->setIconSize(QSize(12,12)); + pReload->setIconSize(QSize(12,12)); + pClear->setIconSize(QSize(12,12)); +} + +///////////////////////////////////////////////////////////////////////////////////// +void updateTextureButton(QPushButton* pButton, const QString& texturePath) +{ + if (!texturePath.isEmpty()) setStyledToolTip(pButton, texturePath.toUtf8().data()); + + bool isTextureUsed = true; + QIcon notUsedIcon = QIcon(":/AppMainWindow/images/TextureEnabled_icon.png"); + QIcon isUsedIcon = QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png"); + QIcon disabledIcon = QIcon(":/AppMainWindow/images/TextureDisabled_icon.png"); + + pButton->setIcon(!texturePath.isEmpty() ? isUsedIcon : notUsedIcon); +} + +/////////////////////////////////////////////////////////////////////////////////////// +//bool LoadHairTexture(NvHair::TextureType::Enum textureType) +//{ +// QString texName = AppMainWindow::Inst().OpenTextureFile(); +// return SimpleScene::Inst()->GetFurCharacter().LoadHairTexture(textureType, texName.toLocal8Bit()); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +//bool ReloadHairTexture(NvHair::TextureType::Enum textureType) +//{ +// return SimpleScene::Inst()->GetFurCharacter().ReloadHairTexture(textureType); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +//bool ClearHairTexture(NvHair::TextureType::Enum textureType) +//{ +// return SimpleScene::Inst()->GetFurCharacter().ClearHairTexture(textureType); +//} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.h new file mode 100644 index 0000000..2372b06 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.h @@ -0,0 +1,37 @@ +#ifndef QtUtil_h__ +#define QtUtil_h__ + +#include <QtCore/QFileInfo> +#include <QtCore/QDir> +#include <QtWidgets/QColorDialog> +#include <QtGui/QPalette> +#include <QtWidgets/QWidget> +#include <QtWidgets/QPushButton> +#include <QtWidgets/QSpinBox> +#include <QtWidgets/QDoubleSpinBox> +#include <QtWidgets/QCheckBox> +#include <QtWidgets/QComboBox> +#include <QtWidgets/QLabel> +#include <QtWidgets/QSlider> +#include "corelib_global.h" + +// utility functions to quickly set and update UI + +void setStyledToolTip(QPushButton *pButton, const char *tooltip); +void pickColor(atcore_float4& color); +void setButtonColor(QPushButton *button, float r, float g, float b); + +void setFocusColor(QWidget* qWidget, bool sameAsDefault, bool sameForAllAssets); + +void updateColorButton(QPushButton* pButton, int paramID, QLabel* label = 0); + +void setTextureButtons(QPushButton *pButton, QPushButton *pReload, QPushButton *pClear); +void updateTextureButton(QPushButton* pButton, const QString& texturePath); + +void setClearButtonIcon(QPushButton *pButton); + +//bool LoadHairTexture(NvHair::TextureType::Enum textureType); +//bool ReloadHairTexture(NvHair::TextureType::Enum textureType); +//bool ClearHairTexture(NvHair::TextureType::Enum textureType); + +#endif diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp new file mode 100644 index 0000000..db40407 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp @@ -0,0 +1,82 @@ +#include "SourceAssetOpenDlg.h" +#include "ui_SourceAssetOpenDlg.h" +#include <QtWidgets/QFileDialog> +#include "AppMainWindow.h" + +SourceAssetOpenDlg::SourceAssetOpenDlg(bool bOpenBlastFile, QWidget *parent) : + QDialog(parent), + ui(new Ui::SourceAssetOpenDlg) +{ + ui->setupUi(this); + + m_bOpenBlastFile = bOpenBlastFile; + ui->buttonBox->button(QDialogButtonBox::Ok)->setFixedWidth(100); + ui->buttonBox->button(QDialogButtonBox::Cancel)->setFixedWidth(100); + ui->spinBoxDegree->setMaximum(180); + ui->spinBoxDegree->setMinimum(-180); +} + +SourceAssetOpenDlg::~SourceAssetOpenDlg() +{ + delete ui; +} + +QString SourceAssetOpenDlg::getFile() +{ + return ui->lineEditFile->text(); +} + +bool SourceAssetOpenDlg::getSkinned() +{ + return ui->checkBoxSkinned->isChecked(); +} + +QVector3D SourceAssetOpenDlg::getPosition() +{ + return QVector3D(ui->spinBoxXPosition->value(), ui->spinBoxYPosition->value(), ui->spinBoxZPosition->value()); +} + +QVector3D SourceAssetOpenDlg::getRotationAxis() +{ + return QVector3D(ui->spinBoxXAxis->value(), ui->spinBoxYAxis->value(), ui->spinBoxZAxis->value()); +} + +double SourceAssetOpenDlg::getRotationDegree() +{ + return ui->spinBoxDegree->value(); +} + +bool SourceAssetOpenDlg::isAppend() +{ + return ui->checkBoxAppend->isChecked(); +} + +void SourceAssetOpenDlg::on_btnOpenFile_clicked() +{ + QString lastDir = AppMainWindow::Inst()._lastFilePath; + QString titleStr = "Open Source Asset File"; + + QString filetype = "Source Asset (*.fbx)"; + if (m_bOpenBlastFile) + { + filetype = "Source Asset (*.bpxa)"; + } + QString fileName = QFileDialog::getOpenFileName(this, titleStr, lastDir, filetype); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + AppMainWindow::Inst()._lastFilePath = fileInfo.absoluteDir().absolutePath(); + } + + ui->lineEditFile->setText(fileName); +} + +void SourceAssetOpenDlg::on_buttonBox_accepted() +{ + +} + +void SourceAssetOpenDlg::on_buttonBox_rejected() +{ + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h new file mode 100644 index 0000000..ec03ee9 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h @@ -0,0 +1,38 @@ +#ifndef SOURCEASSETOPENDLG_H +#define SOURCEASSETOPENDLG_H + +#include <QtWidgets/QDialog> +#include <QtGui/QVector3D> + +namespace Ui { +class SourceAssetOpenDlg; +} + +class SourceAssetOpenDlg : public QDialog +{ + Q_OBJECT + +public: + explicit SourceAssetOpenDlg(bool bOpenBlastFile = true, QWidget *parent = 0); + ~SourceAssetOpenDlg(); + + QString getFile(); + bool getSkinned(); + QVector3D getPosition(); + QVector3D getRotationAxis(); + double getRotationDegree(); + bool isAppend(); + +private slots: + void on_btnOpenFile_clicked(); + + void on_buttonBox_accepted(); + + void on_buttonBox_rejected(); + +private: + Ui::SourceAssetOpenDlg *ui; + bool m_bOpenBlastFile; +}; + +#endif // SOURCEASSETOPENDLG_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp new file mode 100644 index 0000000..1057402 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp @@ -0,0 +1,49 @@ +#include "SupportPanel.h" +#include "ui_SupportPanel.h" + +SupportPanel::SupportPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::SupportPanel) +{ + ui->setupUi(this); +} + +SupportPanel::~SupportPanel() +{ + delete ui; +} + +void SupportPanel::updateValues() +{ + +} + +void SupportPanel::on_comboBoxHealthMask_currentIndexChanged(int index) +{ + +} + +void SupportPanel::on_btnAddHealthMask_clicked() +{ + +} + +void SupportPanel::on_btnPen_clicked() +{ + +} + +void SupportPanel::on_btnRemove_clicked() +{ + +} + +void SupportPanel::on_spinBoxBondStrength_valueChanged(double arg1) +{ + +} + +void SupportPanel::on_checkBoxEnableJoint_stateChanged(int arg1) +{ + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.h new file mode 100644 index 0000000..518d2cd --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.h @@ -0,0 +1,36 @@ +#ifndef SUPPORTPANEL_H +#define SUPPORTPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class SupportPanel; +} + +class SupportPanel : public QWidget +{ + Q_OBJECT + +public: + explicit SupportPanel(QWidget *parent = 0); + ~SupportPanel(); + void updateValues(); + +private slots: + void on_comboBoxHealthMask_currentIndexChanged(int index); + + void on_btnAddHealthMask_clicked(); + + void on_btnPen_clicked(); + + void on_btnRemove_clicked(); + + void on_spinBoxBondStrength_valueChanged(double arg1); + + void on_checkBoxEnableJoint_stateChanged(int arg1); + +private: + Ui::SupportPanel *ui; +}; + +#endif // SUPPORTPANEL_H |