aboutsummaryrefslogtreecommitdiff
path: root/NvBlast/tools/ArtistTools/source/BlastPlugin/Window
diff options
context:
space:
mode:
authorBryan Galdrikian <[email protected]>2017-02-21 12:07:59 -0800
committerBryan Galdrikian <[email protected]>2017-02-21 12:07:59 -0800
commit446ce137c6823ba9eff273bdafdaf266287c7c98 (patch)
treed20aab3e2ed08d7b3ca71c2f40db6a93ea00c459 /NvBlast/tools/ArtistTools/source/BlastPlugin/Window
downloadblast-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')
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.cpp306
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.h59
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp1804
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h284
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp523
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h94
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.cpp54
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.h39
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp104
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h38
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp148
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h41
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp389
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h104
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.cpp155
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.h52
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp63
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h36
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.cpp40
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.h30
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp105
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h38
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp36
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h28
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp354
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h79
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp281
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h52
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp265
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.h40
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp473
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h72
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.cpp39
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.h33
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.cpp155
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.h37
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp82
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h38
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp49
-rw-r--r--NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.h36
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