aboutsummaryrefslogtreecommitdiff
path: root/tools/ArtistTools/source
diff options
context:
space:
mode:
authorAnton Novoselov <[email protected]>2017-08-01 12:53:38 +0300
committerAnton Novoselov <[email protected]>2017-08-01 12:53:38 +0300
commit236f03c0b9a4982328ed1201978f7f69d192d9b2 (patch)
treee486f2fa39dba203563895541e92c60ed3e25759 /tools/ArtistTools/source
parentAdded screens to welcome page (diff)
downloadblast-236f03c0b9a4982328ed1201978f7f69d192d9b2.tar.xz
blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.zip
Blast 1.1 release (windows / linux)
see docs/release_notes.txt for details
Diffstat (limited to 'tools/ArtistTools/source')
-rw-r--r--tools/ArtistTools/source/BlastPlugin/BlastPlugin.cpp1381
-rw-r--r--tools/ArtistTools/source/BlastPlugin/BlastPlugin.h43
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Parameters/BlastProjectParams.pl1514
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Parameters/HackNvParamBug.cpp25
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.cpp2229
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.h211
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Parameters/go.bat3
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/Sample.h40
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.cpp114
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.h52
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.cpp42
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.cpp235
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.h40
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.cpp74
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.h47
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.cpp42
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.h38
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.cpp359
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.h69
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.cpp248
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.h93
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.cpp35
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.cpp489
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.h63
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.cpp36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.cpp104
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.h40
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.cpp175
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.h42
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.cpp36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.cpp36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/core/DeviceManager.cpp13
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.cpp40
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.h41
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.cpp2865
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.h221
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.cpp327
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.h87
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.cpp36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.cpp36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/DebugRenderBuffer.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.cpp35
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.h37
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.cpp35
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.cpp156
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.h73
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderUtils.h59
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.cpp96
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.h58
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.cpp140
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.h59
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.cpp35
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.cpp67
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.h41
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.cpp85
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.h40
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ShaderUtils.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.cpp35
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.cpp48
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.cpp573
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.h52
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp426
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h110
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp69
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.cpp256
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.h100
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp1165
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h65
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp271
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h62
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/utils/PxInputDataFromPxFileBuf.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.cpp35
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleTime.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/utils/UIHelpers.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.cpp28
-rw-r--r--tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.h28
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Shaders/common_buffers_ex.hlsl60
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Shaders/lighting_ex.hlsl51
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Shaders/model_simple_ex.hlsl56
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Shaders/model_simple_textured_ex.hlsl160
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/BlastSceneTree.ui237
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/BlastToolBar.qrc66
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/CollisionToolsDlg.ui337
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/DefaultDamagePanel.ui332
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/FileReferencesPanel.ui427
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/FiltersDockWidget.ui565
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/FractureGeneralPanel.ui359
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/FractureSliceSettingsPanel.ui486
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/FractureVisualizersPanel.ui70
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/FractureVoronoiSettingsPanel.ui500
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/GeneralPanel.ui492
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/MaterialAssignmentsPanel.ui240
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/MaterialLibraryPanel.ui753
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/NoiseToolsDlg.ui238
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/SourceAssetOpenDlg.ui496
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/SupportPanel.ui120
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/ThemeDark.qss457
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/ThemeDefault.qss76
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Add.pngbin0 -> 1200 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/ArrowDown.pngbin0 -> 84 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/ArrowUp.pngbin0 -> 87 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Asset.pngbin0 -> 442 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/AssetComposite.pngbin0 -> 490 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnBomb.pngbin0 -> 1820 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnDamage.pngbin0 -> 3228 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnDropObject.pngbin0 -> 1864 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnExplodedViewTool.pngbin0 -> 1027 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnExportFilepath.pngbin0 -> 726 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnFrameStepForward.pngbin0 -> 1304 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnFuseSelectedChunks.pngbin0 -> 1534 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnGizmoWithGlobal.pngbin0 -> 648 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnGizmoWithLocal.pngbin0 -> 193 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnJointsTool.pngbin0 -> 1091 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnPaintbrush.pngbin0 -> 1083 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnPreferences.pngbin0 -> 922 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnProjectile.pngbin0 -> 1476 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnReset.pngbin0 -> 1205 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnRotate.pngbin0 -> 740 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnScale.pngbin0 -> 676 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnSelectTool.pngbin0 -> 1260 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnSimulatePlay.pngbin0 -> 1469 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnTranslate.pngbin0 -> 571 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Bond.pngbin0 -> 227 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/CheckBox.pngbin0 -> 202 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_Support_Static.pngbin0 -> 568 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_Support_Unstatic.pngbin0 -> 451 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_UnSupport_UnStatic.pngbin0 -> 427 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/CurveEditor.pngbin0 -> 3263 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/DarkBorder.pngbin0 -> 156 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Down.pngbin0 -> 591 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/EditWrench.pngbin0 -> 4041 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/ExpanCollapse.pngbin0 -> 1036 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Pen.pngbin0 -> 333 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Projectile.pngbin0 -> 491 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Refresh_icon.pngbin0 -> 3702 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Remove_icon.pngbin0 -> 3383 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Select.pngbin0 -> 865 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/TextureBox.bmpbin0 -> 1062 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/TextureDisabled_icon.pngbin0 -> 3031 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/TextureEnabled_icon.pngbin0 -> 636 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/TextureIsUsed_icon.pngbin0 -> 541 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/Up.pngbin0 -> 304 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/importFile.pngbin0 -> 3018 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/openFile.pngbin0 -> 1150 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/playlist.pngbin0 -> 1767 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/refreshReload.pngbin0 -> 3164 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/saveDisc.pngbin0 -> 3065 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/simulationPlay.pngbin0 -> 4060 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/simulationStep.pngbin0 -> 4774 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/simulationStop.pngbin0 -> 1748 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/transportLoop.pngbin0 -> 4660 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/transportPlay.pngbin0 -> 3465 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/transportRewind.pngbin0 -> 4649 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/transportStepForward.pngbin0 -> 3762 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/transportStop.pngbin0 -> 2946 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/visibilityToggle_notVisible.pngbin0 -> 19891 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/UI/images/visibilityToggle_visible.pngbin0 -> 20126 bytes
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.cpp306
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.h59
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp2386
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h218
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp743
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h22
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp153
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h22
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp520
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h16
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp668
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h70
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.cpp155
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.h52
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp276
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h36
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.cpp40
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.h30
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp189
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h18
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp57
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h12
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp340
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h50
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp252
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h23
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp171
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp205
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h8
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp77
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h17
-rw-r--r--tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp14
-rw-r--r--tools/ArtistTools/source/BlastPlugin/blastplugin.json1
-rw-r--r--tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp8
-rw-r--r--tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h16
-rw-r--r--tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp60
-rw-r--r--tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h5
-rw-r--r--tools/ArtistTools/source/CoreLib/CoreLib.cpp56
-rw-r--r--tools/ArtistTools/source/CoreLib/CoreLib.h7
-rw-r--r--tools/ArtistTools/source/CoreLib/Parameters/HackNvParamBug.cpp6
-rw-r--r--tools/ArtistTools/source/CoreLib/Parameters/PlaylistParams.pl33
-rw-r--r--tools/ArtistTools/source/CoreLib/Parameters/go.bat6
-rw-r--r--tools/ArtistTools/source/CoreLib/PluginInterface.h6
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp24
-rw-r--r--tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp33
-rw-r--r--tools/ArtistTools/source/CoreLib/Resource/AppMainWindow.qrc4
-rw-r--r--tools/ArtistTools/source/CoreLib/Resource/D3DQt-CC.icobin0 -> 24358 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/Resource/resource.rc2
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/Camera.cpp6
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp15
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp40
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h4
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/Light.cpp2
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp87
-rw-r--r--tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h29
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/AppMainWindow.qrc36
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/AppMainWindow.ui428
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/CameraBookmarksDialog.ui76
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/DisplayLightPanel.ui645
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/DisplayPreferencesPanel.ui885
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/DisplayScenePanel.ui616
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/OutputWindow.ui19
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/ThemeDark.qss457
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/ThemeDefault.qss76
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/Add.pngbin0 -> 1200 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/ArrowDown.pngbin0 -> 84 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/ArrowUp.pngbin0 -> 87 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/CheckBox.pngbin0 -> 202 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/CurveEditor.pngbin0 -> 3263 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/DarkBorder.pngbin0 -> 156 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/Down.pngbin0 -> 591 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/EditWrench.pngbin0 -> 4041 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/Refresh_icon.pngbin0 -> 3702 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/Remove_icon.pngbin0 -> 3383 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/TextureBox.bmpbin0 -> 1062 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/TextureDisabled_icon.pngbin0 -> 3031 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/TextureEnabled_icon.pngbin0 -> 636 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/TextureIsUsed_icon.pngbin0 -> 541 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/Up.pngbin0 -> 304 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/importFile.pngbin0 -> 3018 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/openFile.pngbin0 -> 1150 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/playlist.pngbin0 -> 1767 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/refreshReload.pngbin0 -> 3164 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/saveDisc.pngbin0 -> 3065 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/simulationPlay.pngbin0 -> 4060 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/simulationStep.pngbin0 -> 4774 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/simulationStop.pngbin0 -> 1748 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/transportLoop.pngbin0 -> 4660 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/transportPlay.pngbin0 -> 3465 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/transportRewind.pngbin0 -> 4649 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/transportStepForward.pngbin0 -> 3762 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/transportStop.pngbin0 -> 2946 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/visibilityToggle_notVisible.pngbin0 -> 19891 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/UI/images/visibilityToggle_visible.pngbin0 -> 20126 bytes
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/XMLHelper.cpp121
-rw-r--r--tools/ArtistTools/source/CoreLib/Utils/XMLHelper.h39
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp161
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h15
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp29
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp33
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp13
-rw-r--r--tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h2
-rw-r--r--tools/ArtistTools/source/Shaders/BodyShader.hlsl370
-rw-r--r--tools/ArtistTools/source/Shaders/BodyShaderCommon.hlsl204
-rw-r--r--tools/ArtistTools/source/Shaders/BodyShadow.hlsl109
-rw-r--r--tools/ArtistTools/source/Shaders/Light.hlsl69
-rw-r--r--tools/ArtistTools/source/Shaders/ScreenQuad.hlsl66
-rw-r--r--tools/ArtistTools/source/Shaders/ScreenQuadColor.hlsl71
-rw-r--r--tools/ArtistTools/source/Shaders/VisualizeShadow.hlsl81
-rw-r--r--tools/ArtistTools/source/Shaders/color.hlsl67
282 files changed, 29256 insertions, 6345 deletions
diff --git a/tools/ArtistTools/source/BlastPlugin/BlastPlugin.cpp b/tools/ArtistTools/source/BlastPlugin/BlastPlugin.cpp
index 2e40f6a..582a5e5 100644
--- a/tools/ArtistTools/source/BlastPlugin/BlastPlugin.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/BlastPlugin.cpp
@@ -1,15 +1,18 @@
#include <QtCore/QtPlugin>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
+#include <QtCore/QVariant>
+
+#include <QtGui/QDesktopServices>
+
#include <QtWidgets/QMenuBar>
+#include <QtWidgets/QMenu>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QTabWidget>
#include <QtWidgets/QAction>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QFileDialog>
-#include <QtGui/QDesktopServices>
#include <QtWidgets/QPushButton>
-#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QCheckBox>
@@ -23,6 +26,9 @@
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
+#include <Shlwapi.h>
+#include <string>
+
#include "PluginBlast.h"
#include "BlastPlugin.h"
#include "SlideSpinBox.h"
@@ -39,31 +45,180 @@
#include "ViewerOutput.h"
#include "ExpandablePanel.h"
#include "DisplayMeshesPanel.h"
-#include "PluginBlast.h"
#include "BlastToolbar.h"
#include "MaterialLibraryPanel.h"
#include "MaterialAssignmentsPanel.h"
#include "FileReferencesPanel.h"
#include "GeneralPanel.h"
-#include "BlastCompositePanel.h"
-#include "BlastSceneTree.h"
#include "FiltersDockWidget.h"
#include "DefaultDamagePanel.h"
-#include "FiltersDockWidget.h"
-#include "FractureCutoutSettingsPanel.h"
#include "FractureGeneralPanel.h"
-#include "FractureShellCutSettingsPanel.h"
#include "FractureSliceSettingsPanel.h"
#include "FractureVisualizersPanel.h"
#include "FractureVoronoiSettingsPanel.h"
#include "SupportPanel.h"
#include "BlastSceneTree.h"
-#include "FiltersDockWidget.h"
+#include "SceneController.h"
+
+#include <Shlwapi.h>
+#include "FbxUtil.h"
+#include "MeshData.h"
+#include "PxVec2.h"
+#include "SourceAssetOpenDlg.h"
+#include "NvBlastExtAuthoringMesh.h"
+#include "PxScene.h"
+#include "BlastController.h"
+#include "PhysXController.h"
+#include "SelectionToolController.h"
+#include "GizmoToolController.h"
+#include <QtCore/QTimer>
+
+const float tolenrance = 10e-6;
+
+QTimer gPlayTimer;
+
+// Determine whether point P in triangle ABC
+// Use this method if not volumn check does not work
+/*
+bool pointintriangle(PxVec3 A, PxVec3 B, PxVec3 C, PxVec3 P)
+{
+PxVec3 v0 = C - A;
+PxVec3 v1 = B - A;
+PxVec3 v2 = P - A;
+
+float dot00 = v0.dot(v0);
+float dot01 = v0.dot(v1);
+float dot02 = v0.dot(v2);
+float dot11 = v1.dot(v1);
+float dot12 = v1.dot(v2);
+
+float inverDeno = 1 / (dot00 * dot11 - dot01 * dot01);
+
+float u = (dot11 * dot02 - dot01 * dot12) * inverDeno;
+if (u < 0 || u > 1) // if u out of range, return directly
+{
+return false;
+}
+
+float v = (dot00 * dot12 - dot01 * dot02) * inverDeno;
+if (v < 0 || v > 1) // if v out of range, return directly
+{
+return false;
+}
+
+return u + v <= 1;
+}
+*/
+
+bool outside(int vc1, int fc1, Vertex* pv1, physx::PxBounds3& b1,
+ int vc2, int fc2, Vertex* pv2, physx::PxBounds3& b2)
+{
+ // mesh2 is not a volumn
+ if (fc2 < 4)
+ {
+ return true;
+ }
+
+ float test;
+
+ for (int nv = 0; nv < vc1; nv++)
+ {
+ Vertex v1 = pv1[nv];
+
+ if ((test = v1.p.x - b2.minimum.x) < -tolenrance)
+ {
+ return true;
+ }
+ if ((test = v1.p.y - b2.minimum.y) < -tolenrance)
+ {
+ return true;
+ }
+ if ((test = v1.p.z - b2.minimum.z) < -tolenrance)
+ {
+ return true;
+ }
+ if ((test = v1.p.x - b2.maximum.x) > tolenrance)
+ {
+ return true;
+ }
+ if ((test = v1.p.y - b2.maximum.y) > tolenrance)
+ {
+ return true;
+ }
+ if ((test = v1.p.z - b2.maximum.z) > tolenrance)
+ {
+ return true;
+ }
+
+ for (int nt = 0; nt < fc2; nt++)
+ {
+ Vertex v20 = pv2[nt * 3 + 0];
+ Vertex v21 = pv2[nt * 3 + 1];
+ Vertex v22 = pv2[nt * 3 + 2];
+
+ PxVec3 distance = v1.p - v20.p;
+
+ PxVec3 e1 = v21.p - v20.p;
+ PxVec3 e2 = v22.p - v20.p;
+ PxVec3 normal = e1.cross(e2);
+ normal = normal.getNormalized();
+
+ test = distance.dot(normal);
+ if (test > tolenrance)
+ {
+ return true;
+ }
+ /*
+ else if (test > -tolenrance)
+ {
+ if (fc2 < 4 && !pointintriangle(v20.p, v21.p, v22.p, v1.p))
+ {
+ return true;
+ }
+ }
+ */
+ }
+ }
+
+ return false;
+}
+
+/*
+return value
+-1 : meshDesc1 contains meshDesc2
+1 : meshDesc2 contains meshDesc1
+0 : no relation
+*/
+int contains(Nv::Blast::Mesh* pMesh1, Nv::Blast::Mesh* pMesh2)
+{
+ int ret = 0;
+
+ int vc1 = pMesh1->getVerticesCount();
+ int fc1 = pMesh1->getFacetCount();
+ Vertex* pv1 = pMesh1->getVertices();
+ physx::PxBounds3& b1 = pMesh1->getBoundingBox();
+ int vc2 = pMesh2->getVerticesCount();
+ int fc2 = pMesh2->getFacetCount();
+ Vertex* pv2 = pMesh2->getVertices();
+ physx::PxBounds3& b2 = pMesh2->getBoundingBox();
+
+ if (outside(vc1, fc1, pv1, b1, vc2, fc2, pv2, b2))
+ {
+ ret--;
+ }
+ if (outside(vc2, fc2, pv2, b2, vc1, fc1, pv1, b1))
+ {
+ ret++;
+ }
+
+ return ret;
+}
// A singleton, sort of... To pass the events from WindowProc to the object.
DeviceManager* g_DeviceManagerInstance = NULL;
HWND g_hWnd = 0;
+BlastPlugin* gBlastPlugin = nullptr;
DeviceManager* GetDeviceManager()
{
@@ -80,6 +235,23 @@ bool BlastPlugin::CoreLib_RunApp()
return true;
}
+BlastPlugin::BlastPlugin()
+ : QObject()
+ , _recentProjectMenu(NV_NULL)
+ , _recentProjectRecordFile("RecentProjects", "Project")
+{
+ gBlastPlugin = this;
+}
+
+BlastPlugin::~BlastPlugin()
+{
+ gBlastPlugin = nullptr;
+}
+
+BlastPlugin& BlastPlugin::Inst()
+{
+ return *gBlastPlugin;
+}
bool BlastPlugin::LoadRenderPlugin(std::string api)
{
return PluginBlast::Create(api);
@@ -92,6 +264,7 @@ bool BlastPlugin::GetBoneNames(std::vector<std::string>& BoneNames)
bool BlastPlugin::MainToolbar_updateValues()
{
+ _mainToolbar->updateValues();
return true;
}
@@ -172,8 +345,19 @@ bool BlastPlugin::Gamepad_ResetScene()
return true;
}
-bool BlastPlugin::Gamepad_StartAnimation()
+void BlastPlugin::slot_Gamepad_PlaySample()
+{
+ gPlayTimer.stop();
+ _mainToolbar->on_btnSimulatePlay_clicked();
+}
+
+bool BlastPlugin::Gamepad_PlaySample()
{
+ if (_mainToolbar)
+ {
+ _mainToolbar->on_btnReset_clicked();
+ gPlayTimer.start(10);
+ }
return true;
}
@@ -319,9 +503,6 @@ bool BlastPlugin::SimpleScene_Initialize(int backdoor)
QShortcut* shortCut;
- shortCut = new QShortcut(QKeySequence(Qt::Key_K), d3dWidget);
- connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_damagetool()));
-
shortCut = new QShortcut(QKeySequence(Qt::Key_Q), d3dWidget);
connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_selecttool()));
@@ -332,35 +513,42 @@ bool BlastPlugin::SimpleScene_Initialize(int backdoor)
shortCut = new QShortcut(QKeySequence(Qt::Key_R), d3dWidget);
connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_Scale()));
- shortCut = new QShortcut(QKeySequence(Qt::Key_L), d3dWidget);
- connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_edittool()));
+ shortCut = new QShortcut(QKeySequence(Qt::Key_T), d3dWidget);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_damagetool()));
+
+ //shortCut = new QShortcut(QKeySequence(Qt::Key_E), d3dWidget);
+ //connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_edittool()));
+
+ shortCut = new QShortcut(QKeySequence(Qt::Key_I), d3dWidget);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_addFamily()));
- _chunkContextMenu = new QMenu();
+ _contextMenu = new QMenu();
action_Make_Support = new QAction(tr("Make Support"), d3dWidget);
- _chunkContextMenu->addAction(action_Make_Support);
+ _contextMenu->addAction(action_Make_Support);
connect(action_Make_Support, SIGNAL(triggered()), this, SLOT(slot_Make_Support()));
action_Make_Static_Support = new QAction(tr("Make Static Support"), d3dWidget);
- _chunkContextMenu->addAction(action_Make_Static_Support);
+ _contextMenu->addAction(action_Make_Static_Support);
connect(action_Make_Static_Support, SIGNAL(triggered()), this, SLOT(slot_Make_Static_Support()));
action_Remove_Support = new QAction(tr("Remove Support"), d3dWidget);
- _chunkContextMenu->addAction(action_Remove_Support);
+ _contextMenu->addAction(action_Remove_Support);
connect(action_Remove_Support, SIGNAL(triggered()), this, SLOT(slot_Remove_Support()));
- _bondContextMenu = new QMenu();
- action_Bond_Chunks = new QAction(tr("Bond Chunks"), d3dWidget);
- _bondContextMenu->addAction(action_Bond_Chunks);
- connect(action_Bond_Chunks, SIGNAL(triggered()), this, SLOT(slot_Bond_Chunks()));
+ //action_Bond_Chunks = new QAction(tr("Bond Chunks"), d3dWidget);
+ //_contextMenu->addAction(action_Bond_Chunks);
+ //connect(action_Bond_Chunks, SIGNAL(triggered()), this, SLOT(slot_Bond_Chunks()));
- action_Bond_Chunks_with_Joints = new QAction(tr("Bond Chunks With Joints"), d3dWidget);
- _bondContextMenu->addAction(action_Bond_Chunks_with_Joints);
- connect(action_Bond_Chunks_with_Joints, SIGNAL(triggered()), this, SLOT(slot_Bond_Chunks_with_Joints()));
+ //action_Bond_Chunks_with_Joints = new QAction(tr("Bond Chunks With Joints"), d3dWidget);
+ //_contextMenu->addAction(action_Bond_Chunks_with_Joints);
+ //connect(action_Bond_Chunks_with_Joints, SIGNAL(triggered()), this, SLOT(slot_Bond_Chunks_with_Joints()));
+
+ //action_Remove_all_Bonds = new QAction(tr("Remove All Bonds"), d3dWidget);
+ //_contextMenu->addAction(action_Remove_all_Bonds);
+ //connect(action_Remove_all_Bonds, SIGNAL(triggered()), this, SLOT(slot_Remove_all_Bonds()));
+
+ connect(&gPlayTimer, SIGNAL(timeout()), this, SLOT(slot_Gamepad_PlaySample()));
- action_Remove_all_Bonds = new QAction(tr("Remove All Bonds"), d3dWidget);
- _bondContextMenu->addAction(action_Remove_all_Bonds);
- connect(action_Remove_all_Bonds, SIGNAL(triggered()), this, SLOT(slot_Remove_all_Bonds()));
-
return true;
}
bool BlastPlugin::SimpleScene_Shutdown()
@@ -379,13 +567,13 @@ bool BlastPlugin::SimpleScene_Shutdown()
//#include "SceneController.h"
bool BlastPlugin::SimpleScene_Clear()
{
- SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
- sampleManager.clearScene();
-// SceneController& sceneController = sampleManager.getSceneController();
-// sceneController.ClearScene();
+ SampleManager* pSampleManager = SampleManager::ins();
+ pSampleManager->clearScene();
BlastProject::ins().clear();
+ BlastSceneTree::ins()->clear();
+
GlobalSettings& globalSettings = GlobalSettings::Inst();
globalSettings.m_projectFileDir.clear();
globalSettings.m_projectFileName.clear();
@@ -591,14 +779,86 @@ void BlastPlugin::DrawHUD()
bool BlastPlugin::SimpleScene_Draw_DX11()
{
- BlastPlugin::DrawHUD();
+ D3DWidget_paintEvent(NULL);
+ DrawHUD();
return true;
}
bool BlastPlugin::SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents)
{
+ atcore_float3 bbMin = gfsdk_makeFloat3(FLT_MAX, FLT_MAX, FLT_MAX);
+ atcore_float3 bbMax = gfsdk_makeFloat3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ PxScene& scene = pSampleManager->getPhysXController().getEditPhysXScene();
+ const PxU32 actorsCount = scene.getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC);
+ if (actorsCount == 0)
+ {
+ return false;
+ }
+
+ std::vector<PxActor*> actors(actorsCount);
+ PxU32 nbActors = scene.getActors(PxActorTypeFlag::eRIGID_DYNAMIC, &actors[0], actorsCount, 0);
+ PX_ASSERT(actorsCount == nbActors);
+
+ BlastFamily* pFamily = nullptr;
+ {
+ BlastAsset* pBlastAsset = pSampleManager->getCurBlastAsset();
+ if (pBlastAsset != nullptr)
+ {
+ std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = pSampleManager->getAssetFamiliesMap();
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAFM = AssetFamiliesMap.find(pBlastAsset);
+ if (itAFM != AssetFamiliesMap.end())
+ {
+ std::vector<BlastFamily*> families = itAFM->second;
+ if (families.size() > 0)
+ {
+ pFamily = families[0];
+ }
+ }
+ }
+ }
+
+ if (pFamily == nullptr)
+ {
+ for (int act = 0; act < actorsCount; act++)
+ {
+ PxActor* actor = actors[act];
+ PxBounds3 bound = actor->getWorldBounds();
+ atcore_float3 minimum = gfsdk_makeFloat3(bound.minimum.x, bound.minimum.y, bound.minimum.z);
+ atcore_float3 maximum = gfsdk_makeFloat3(bound.maximum.x, bound.maximum.y, bound.maximum.z);
+ bbMin = gfsdk_min(bbMin, minimum);
+ bbMax = gfsdk_max(bbMax, maximum);
+ }
+ }
+ else
+ {
+ for (int act = 0; act < actorsCount; act++)
+ {
+ PxActor* actor = actors[act];
+ if (!pFamily->find(*actors[act]))
+ {
+ continue;
+ }
+ PxBounds3 bound = actor->getWorldBounds();
+ atcore_float3 minimum = gfsdk_makeFloat3(bound.minimum.x, bound.minimum.y, bound.minimum.z);
+ atcore_float3 maximum = gfsdk_makeFloat3(bound.maximum.x, bound.maximum.y, bound.maximum.z);
+ bbMin = gfsdk_min(bbMin, minimum);
+ bbMax = gfsdk_max(bbMax, maximum);
+ }
+ }
+
+ center = 0.5f * (bbMin + bbMax);
+ extents = 1.1f * (bbMax - bbMin);
+
return true;
}
+bool BlastPlugin::SimpleScene_UpdateCamera()
+{
+ SampleManager* pSampleManager = SampleManager::ins();
+ pSampleManager->UpdateCamera();
+ return true;
+}
bool BlastPlugin::SimpleScene_DrawGround()
{
return true;
@@ -612,32 +872,199 @@ bool BlastPlugin::SimpleScene_DrawAxis()
return true;
}
-#include <Shlwapi.h>
-#include <FbxUtil.h>
-#include <MeshData.h>
-#include <PxVec2.h>
-#include <SourceAssetOpenDlg.h>
+void BlastPlugin::SimpleScene_OpenFilesByDrop(const QStringList& fileNames)
+{
+ QString projName, fbxName, bpxaName;
+ int projCount = 0, fbxCount = 0, bpxaCount = 0;
+ for (int i = 0; i < fileNames.size(); ++i)
+ {
+ QString fn = fileNames[i];
+ QFileInfo fileInfo(fn);
+ std::string ext = fileInfo.suffix().toLower().toUtf8().data();
+ if (ext == "blastproj")
+ {
+ ++projCount;
+ projName = fn;
+ }
+ else if (ext == "fbx")
+ {
+ ++fbxCount;
+ fbxName = fn;
+ }
+ else if (ext == "blast")
+ {
+ ++bpxaCount;
+ bpxaName = fn;
+ }
+ }
+ bool bUpdateUI = false;
+ if (projCount == 1)
+ {
+ QFileInfo fileInfo(projName);
+ GlobalSettings& globalSettings = GlobalSettings::Inst();
+ globalSettings.m_projectFileDir = fileInfo.absolutePath().toUtf8().data();
+ globalSettings.m_projectFileName = fileInfo.fileName().toUtf8().data();
+ SimpleScene_LoadProject(fileInfo.absolutePath().toUtf8().data(), fileInfo.fileName().toUtf8().data());
+ bUpdateUI = true;
+ }
+ else if (fbxCount == 1)
+ {
+ QFileInfo fileInfo(fbxName);
+ SimpleScene_LoadSceneFromFbx(fileInfo.absolutePath().toUtf8().data(), fileInfo.fileName().toUtf8().data());
+ bUpdateUI = true;
+ }
+ else if (bpxaCount == 1)
+ {
+ QFileInfo fileInfo(bpxaName);
+ OpenBpxa(fileInfo.absolutePath().toUtf8().data(), fileInfo.fileName().toUtf8().data());
+ bUpdateUI = true;
+ }
+ if (bUpdateUI)
+ {
+ AppMainWindow::Inst().endProgress();
+ AppMainWindow::Inst().updateUI();
+ }
+}
+
+void BlastPlugin::OpenBpxa(const char* d, const char* f)
+{
+ qDebug("%s", __FUNCTION__);
+ SourceAssetOpenDlg dlg(1, &AppMainWindow::Inst());
+ QString fn = QString(d) + "/" + QString(f);
+ if (fn.length() > 1)
+ dlg.setDefaultFile(fn);
+ int res = dlg.exec();
+ if (res != QDialog::Accepted || dlg.getFile().isEmpty())
+ return;
+
+ if (!dlg.isAppend())
+ {
+ SimpleScene::Inst()->Clear();
+ // it is not nice to call AppMainWindow::Inst().updateUI(). but it helps to clear some data in former editing project.
+ // 1. open box.fbx 2. open teapot.fbx 3. now there are two materials in material list, one for box and one for teapot.
+ // need improve it later.
+ AppMainWindow::Inst().updateUI();
+ }
+
+ AppMainWindow::Inst().addRecentFile(dlg.getFile());
+
+ 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);
+ }
+
+ AssetList::ModelAsset modelAsset;
+ modelAsset.name = file;
+ modelAsset.id = file;
+ modelAsset.file = file;
+ modelAsset.isSkinned = dlg.getSkinned();
+ modelAsset.transform = t;
+ char fullpath[MAX_PATH];
+ PathCombineA(fullpath, dir.c_str(), modelAsset.file.c_str());
+ modelAsset.fullpath = fullpath;
+ modelAsset.fullpath = modelAsset.fullpath + ".blast";
+ std::string objPath = std::string(fullpath) + ".obj";
+ std::string fbxPath = std::string(fullpath) + ".fbx";
+ bool bMeshExist = QFile::exists(objPath.c_str()) || QFile::exists(fbxPath.c_str());
+ if (bMeshExist)
+ {
+ SampleManager* pSampleManager = SampleManager::ins();
+ BlastAsset* pBlastAsset = pSampleManager->loadBlastFile(dir, file, modelAsset);
+ pSampleManager->addBlastFamily(pBlastAsset, t);
+ }
+ else
+ {
+ viewer_err("Mesh geometry does not exist!");
+ }
+}
+
bool BlastPlugin::SimpleScene_LoadSceneFromFbx(const char* d, const char* f)
{
- SourceAssetOpenDlg dlg(false, &AppMainWindow::Inst());
+ SourceAssetOpenDlg dlg(0, &AppMainWindow::Inst());
+ QString fn = QString(d) + "/" + QString(f);
+ if (fn.length() > 1)
+ dlg.setDefaultFile(fn);
int res = dlg.exec();
if (res != QDialog::Accepted || dlg.getFile().isEmpty())
return false;
+ if (!dlg.isAppend())
+ {
+ SimpleScene::Inst()->Clear();
+ // it is not nice to call AppMainWindow::Inst().updateUI(). but it helps to clear some data in former editing project.
+ // 1. open box.fbx 2. open teapot.fbx 3. now there are two materials in material list, one for box and one for teapot.
+ // need improve it later.
+ AppMainWindow::Inst().updateUI();
+ }
+ AppMainWindow::Inst().addRecentFile(dlg.getFile());
QFileInfo fileInfo(dlg.getFile());
std::string dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit();
+ std::string filebase = fileInfo.baseName().toLocal8Bit();
std::string fbxName = fileInfo.fileName().toLocal8Bit();
GlobalSettings& globalSettings = GlobalSettings::Inst();
+ if (!dlg.isAppend())
+ {
+ globalSettings.m_projectFileDir = dir;
+ globalSettings.m_projectFileName = filebase + ".blastProj";
+ }
char fbxFilePath[MAX_PATH];
- float sceneUnit = globalSettings.getSceneUnitInCentimeters();
+ int unitIndex = dlg.sceneUnitIndex();
+ float sceneUnit = globalSettings.getSceneUnitInCentimeters(unitIndex); //globalSettings.getSceneUnitInCentimeters();
+ bool bConvertUnit = true;
+ if (unitIndex == SCENE_UNIT_UNKNOWN)
+ {
+ // use FBX unit
+ bConvertUnit = false;
+ }
PathCombineA(fbxFilePath, dir.c_str(), fbxName.c_str());
AppMainWindow::Inst().setProgress("Initializing FBX loader", 0);
- FbxUtil::Initialize(fbxFilePath, sceneUnit);
+ float fbxSceneUnit = -1.0f;
+ FbxUtil::Initialize(fbxFilePath, fbxSceneUnit, sceneUnit, bConvertUnit);
+ float fError = 0.001f;
+ if (!bConvertUnit)
+ {
+ // we intend to use FBX's unit, but if FBX has a non-supported unit, we still convert its unit.
+ bool bSupported = GlobalSettings::Inst().isSupportedUnitByUnitInCm(fbxSceneUnit);
+ if (!bSupported)
+ {
+ viewer_msg("FBX scene is scaled to unit, %f cm.", sceneUnit);
+ }
+ else
+ {
+ sceneUnit = fbxSceneUnit;
+ viewer_msg("Use FBX's default unit, %f cm.", sceneUnit);
+ }
+ }
+ else
+ {
+ if (fabs(fbxSceneUnit - sceneUnit) > fError)
+ {
+ viewer_msg("FBX scene is scaled to unit, %f cm.", sceneUnit);
+ }
+ else
+ {
+ viewer_msg("FBX has a same unit, %f cm.", sceneUnit);
+ }
+ }
+ globalSettings.setSceneUnitByUnitInCm(sceneUnit);
char rootBoneName[MAX_PATH];
int upAxis = 0;
@@ -653,30 +1080,66 @@ bool BlastPlugin::SimpleScene_LoadSceneFromFbx(const char* d, const char* f)
else if (upAxis = 2)
SimpleScene::Inst()->ResetUpDir(true);
- SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
+ SampleManager *pSampleManager = SampleManager::ins();
int numMeshes = 0;
char* meshNames = 0;
+ char* parents = 0;
char* skinned = 0;
- FbxUtil::GetMeshInfo(&numMeshes, &meshNames, &skinned);
- if (numMeshes > 1)
+ FbxUtil::GetMeshInfo(&numMeshes, &meshNames, &parents, &skinned);
+
+ if (numMeshes == 0)
{
- //return false;
+ FbxUtil::Release();
+ return false;
+ }
+
+ if (!dlg.isPreFractured())
+ {
+ numMeshes = 1;
}
- // to do later when numMeshes is more than one
- numMeshes = 1;
-
- for (int i = 0; i < numMeshes; i++)
+ std::vector<Nv::Blast::Mesh*> meshes(numMeshes);
+ std::vector<int32_t> parentIds(numMeshes);
+ std::vector<std::string> materialNames(numMeshes);
+ bool bMaterial = false;
+ for (int nm = 0; nm < numMeshes; nm++)
{
- const char* meshName = meshNames + i * 128;
+ const char* meshName = meshNames + nm * 128;
MeshDesc meshDesc;
FbxUtil::CreateMeshDescriptor(meshName, meshDesc);
- MeshMaterial* materials = 0;
+ MeshMaterial* pMeshMaterial = 0;
int numMaterials = 0;
- FbxUtil::GetMeshMaterials(meshName, &numMaterials, &materials);
+ FbxUtil::GetMeshMaterials(meshName, &numMaterials, &pMeshMaterial);
+
+ if (numMaterials > 0)
+ {
+ std::string materialName = pMeshMaterial->m_name;
+ if (materialName != "" && !BlastProject::ins().isGraphicsMaterialNameExist(materialName.c_str()))
+ {
+ BlastProject::ins().addGraphicsMaterial(materialName.c_str());
+ BlastProject::ins().reloadDiffuseTexture(materialName.c_str(),
+ pMeshMaterial->m_diffuseTexture);
+ BlastProject::ins().reloadDiffuseColor(materialName.c_str(),
+ pMeshMaterial->m_diffuseColor.x,
+ pMeshMaterial->m_diffuseColor.y,
+ pMeshMaterial->m_diffuseColor.z);
+ materialNames[nm] = materialName;
+ bMaterial = true;
+ }
+ }
+ if(!bMaterial)
+ {
+ std::string materialName = BlastProject::ins().generateNewMaterialName(meshName);
+ BlastProject::ins().addGraphicsMaterial(materialName.c_str());
+ BlastProject::ins().reloadDiffuseColor(materialName.c_str(),
+ meshDesc.m_ColorRGB.x,
+ meshDesc.m_ColorRGB.y,
+ meshDesc.m_ColorRGB.z);
+ materialNames[nm] = materialName;
+ }
SkinData skinData;
FbxUtil::InitializeSkinData(meshName, skinData);
@@ -688,42 +1151,230 @@ bool BlastPlugin::SimpleScene_LoadSceneFromFbx(const char* d, const char* f)
std::vector<physx::PxVec2> uv;
std::vector<unsigned int> indices;
- for (uint32_t i = 0; i < meshDesc.m_NumVertices; ++i)
+ for (uint32_t nt = 0; nt < meshDesc.m_NumTriangles; nt++)
{
- atcore_float3 pos = meshDesc.m_pVertices[i];
- atcore_float3 vertexNormal = meshDesc.m_pVertexNormals[i];
- atcore_float2 texcoord = meshDesc.m_pTexCoords[i];
+ for (int vi = 0; vi < 3; vi++)
+ {
+ NvUInt32 nti = nt * 3 + vi;
- positions.push_back(physx::PxVec3(pos.x, pos.y, pos.z));
- normals.push_back(physx::PxVec3(vertexNormal.x, vertexNormal.y, vertexNormal.z));
- uv.push_back(physx::PxVec2(texcoord.x, texcoord.y));
+ NvUInt32 posIndex = meshDesc.m_pIndices[nti];
+ atcore_float3 pos = meshDesc.m_pVertices[posIndex];
+ positions.push_back(physx::PxVec3(pos.x, pos.y, pos.z));
+
+ atcore_float3 vertexNormal = meshDesc.m_pVertexNormals[nti];
+ normals.push_back(physx::PxVec3(vertexNormal.x, vertexNormal.y, vertexNormal.z));
+
+ atcore_float2 texcoord = meshDesc.m_pTexCoords[nti];
+ uv.push_back(physx::PxVec2(texcoord.x, texcoord.y));
+
+ indices.push_back(nti);
+ }
}
- for (uint32_t i = 0; i < meshDesc.m_NumTriangles; ++i)
+ physx::PxVec3* nr = (!normals.empty()) ? normals.data() : 0;
+ physx::PxVec2* uvp = (!uv.empty()) ? uv.data() : 0;
+ Nv::Blast::Mesh* pMesh = new Nv::Blast::Mesh(positions.data(), nr, uvp, static_cast<uint32_t>(positions.size()),
+ indices.data(), static_cast<uint32_t>(indices.size()));
+ meshes[nm] = pMesh;
+
+ const char* parentName = parents + nm * 128;
+ int nfind = 0;
+ for (; nfind < numMeshes; nfind++)
{
- indices.push_back(meshDesc.m_pIndices[i * 3 + 0]);
- indices.push_back(meshDesc.m_pIndices[i * 3 + 1]);
- indices.push_back(meshDesc.m_pIndices[i * 3 + 2]);
+ const char* mName = meshNames + nfind * 128;
+ if (!strcmp(parentName, mName))
+ {
+ break;
+ }
}
+ if (nfind == numMeshes)
+ {
+ nfind = -1;
+ }
+ parentIds[nm] = nfind;
+ }
+
+ if (dlg.isAutoCompute())
+ {
+ parentIds.assign(numMeshes, -1);
+
+ std::map<int, std::vector<int>> ParentIDsMap;
+ std::map<int, std::vector<int>> ExistIDsMap;
+ bool exist;
+ for (int nm1 = 0; nm1 < numMeshes; nm1++)
+ {
+ Nv::Blast::Mesh* pMesh1 = meshes[nm1];
+ std::vector<int>& HandleList1 = ExistIDsMap[nm1];
- sampleManager.createAsset(dir, meshName, positions, normals, uv, indices);
+ for (int nm2 = 0; nm2 < numMeshes; nm2++)
+ {
+ if (nm1 == nm2)
+ {
+ continue;
+ }
+
+ exist = false;
+ for (int pid1 : HandleList1)
+ {
+ if (pid1 == nm2)
+ {
+ exist = true;
+ break;
+ }
+ }
+ if (exist)
+ {
+ continue;
+ }
- physx::PxTransform t(physx::PxIdentity);
+ std::vector<int>& HandleList2 = ExistIDsMap[nm2];
+ exist = false;
+ for (int pid2 : HandleList2)
+ {
+ if (pid2 == nm1)
+ {
+ exist = true;
+ break;
+ }
+ }
+ if (exist)
+ {
+ continue;
+ }
+
+ Nv::Blast::Mesh* pMesh2 = meshes[nm2];
+
+ ExistIDsMap[nm1].push_back(nm2);
+ ExistIDsMap[nm2].push_back(nm1);
+
+ /*
+ return value
+ -1 : meshDesc1 contains meshDesc2
+ 1 : meshDesc2 contains meshDesc1
+ 0 : no relation
+ */
+ int ret = contains(pMesh1, pMesh2);
+ if (ret == 0)
+ {
+ continue;
+ }
+
+ if (ret == -1)
+ {
+ ParentIDsMap[nm2].push_back(nm1);
+ }
+ else if (ret == 1)
+ {
+ ParentIDsMap[nm1].push_back(nm2);
+ }
+ }
+ }
+ std::map<int, std::vector<int>>::iterator itPIM;
+ for (std::pair<int, std::vector<int>> pidPair : ParentIDsMap)
{
- 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);
+ std::vector<int>& ParentIDsList = pidPair.second;
+ int targetSize = ParentIDsList.size();
+ if (targetSize == 0)
+ {
+ continue;
+ }
+
+ int childId = pidPair.first;
+ int parentId = ParentIDsList[0];
+
+ if (targetSize > 1)
+ {
+ targetSize = targetSize - 1;
+ for (int pid : ParentIDsList)
+ {
+ int parentSize = 0;
+ itPIM = ParentIDsMap.find(pid);
+ if (itPIM != ParentIDsMap.end())
+ {
+ parentSize = itPIM->second.size();
+ }
+ if (parentSize == targetSize)
+ {
+ parentId = pid;
+ break;
+ }
+ }
+ }
+
+ if (parentIds[childId] == -1)
+ {
+ parentIds[childId] = parentId;
+ }
}
- sampleManager.addModelAsset(dir, meshName, dlg.getSkinned(), t, !dlg.isAppend());
}
+ BlastAssetModelSimple* pBlastAssetModelSimple;
+ std::vector<bool> supports;
+ std::vector<bool> statics;
+ std::vector<uint8_t> joints;
+ std::vector<uint32_t> worlds;
+ pSampleManager->createAsset(&pBlastAssetModelSimple, meshes, parentIds, supports, statics, joints, worlds);
+
+ 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);
+ }
+
+ std::string validName = filebase;
+ std::map<BlastAsset*, AssetList::ModelAsset>& assetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM;
+ std::map<std::string, int> existNameMap;
+ std::map<std::string, int>::iterator itENM;
+ for (itADM = assetDescMap.begin(); itADM != assetDescMap.end(); itADM++)
+ {
+ AssetList::ModelAsset m = itADM->second;
+ existNameMap[m.id] = 0;
+ }
+ char vn[MAX_PATH];
+ for (int ind = 0; existNameMap.find(validName) != existNameMap.end(); ind++)
+ {
+ sprintf(vn, "%s_%d", filebase.c_str(), ind);
+ validName = vn;
+ }
+
+ AssetList::ModelAsset modelAsset;
+ modelAsset.name = validName;
+ modelAsset.id = validName;
+ modelAsset.file = validName;
+ modelAsset.isSkinned = dlg.getSkinned();
+ modelAsset.transform = t;
+ char fullpath[MAX_PATH];
+ PathCombineA(fullpath, dir.c_str(), filebase.c_str());
+ modelAsset.fullpath = fullpath;
+ modelAsset.fullpath = modelAsset.fullpath + ".blast";
+
+ pSampleManager->addBlastAsset(pBlastAssetModelSimple, modelAsset);
+ pSampleManager->addBlastFamily((BlastAsset*)pBlastAssetModelSimple, t);
+
+ if (materialNames.size() > 0)
+ {
+ BlastAsset* pBlastAsset = (BlastAsset*)pBlastAssetModelSimple;
+ pSampleManager->setCurrentSelectedInstance(pBlastAsset, 0);
+ pSampleManager->setMaterialForCurrentFamily(materialNames[0], true);
+ pSampleManager->setMaterialForCurrentFamily(materialNames[0], false);
+ }
+
+ std::vector<Nv::Blast::Mesh*>::iterator itMesh;
+ for (itMesh = meshes.begin(); itMesh != meshes.end(); itMesh++)
+ {
+ delete *itMesh;
+ }
+ meshes.clear();
+
FbxUtil::Release();
globalSettings.m_sceneLoaded = true;
@@ -764,30 +1415,160 @@ bool BlastPlugin::SimpleScene_SaveProject(const char* dir, const char* file)
return false;
}
+
+
bool BlastPlugin::SimpleScene_LoadParameters(NvParameterized::Interface* iface)
-{
+{
nvidia::parameterized::BlastProjectParameters* params = static_cast<nvidia::parameterized::BlastProjectParameters*>(iface);
nvidia::parameterized::BlastProjectParametersNS::ParametersStruct& srcDesc = params->parameters();
copy(BlastProject::ins().getParams(), srcDesc);
- for (int i = 0; i < srcDesc.blast.blastAssets.arraySizes[0]; ++i)
+ SampleManager* pSampleManager = SampleManager::ins();
+ std::string dir = GlobalSettings::Inst().m_projectFileDir;
+
+ int assetCount = srcDesc.blast.blastAssets.arraySizes[0];
+ BPPChunkArray& chunkArray = srcDesc.blast.chunks;
+ int chunkCount = chunkArray.arraySizes[0];
+ BPPBondArray& bondArray = srcDesc.blast.bonds;
+ int bondCount = bondArray.arraySizes[0];
+
+ for (int ac = 0; ac < assetCount; ac++)
{
- BPPAsset& asset = srcDesc.blast.blastAssets.buf[i];
- QFileInfo fileInfo(asset.path.buf);
- QByteArray tmp = fileInfo.baseName().toUtf8();
- QByteArray tmpPath = fileInfo.absolutePath().toUtf8();
- const char* fileName = tmp.data();
- physx::PxTransform t(physx::PxIdentity);
- BPPAssetInstance* instance = BlastProject::ins().getAssetInstance(asset.path.buf, 0);
- if (instance != nullptr)
+ BPPAsset& asset = srcDesc.blast.blastAssets.buf[ac];
+
+ std::vector<BPPAssetInstance*> instances;
+ BlastProject::ins().getAssetInstances(asset.ID, instances);
+ int instanceSize = instances.size();
+ if (instanceSize == 0)
{
+ continue;
+ }
+
+ AssetList::ModelAsset modelAsset;
+ modelAsset.name = asset.name.buf;
+ modelAsset.id = asset.name.buf;
+ modelAsset.file = asset.name.buf;
+ modelAsset.isSkinned = false;
+ modelAsset.fullpath = asset.name.buf;
+
+ std::vector<Nv::Blast::Mesh*> meshes;
+ std::vector<int32_t> parentIds;
+ std::vector<bool> supports;
+ std::vector<bool> statics;
+ std::vector<bool> visibles;
+
+ for (int cc = 0; cc < chunkCount; cc++)
+ {
+ BPPChunk& chunk = chunkArray.buf[cc];
+ if (chunk.asset != asset.ID)
+ {
+ continue;
+ }
+
+ std::vector<physx::PxVec3> positions;
+ std::vector<physx::PxVec3> normals;
+ std::vector<physx::PxVec3> tangents;
+ std::vector<physx::PxVec2> uv;
+ std::vector<unsigned int> indices;
+
+ BPPVEC3Array& positionArray = chunk.graphicsMesh.positions;
+ BPPVEC3Array& normalArray = chunk.graphicsMesh.normals;
+ BPPVEC3Array& tangentArray = chunk.graphicsMesh.tangents;
+ BPPVEC2Array& uvArray = chunk.graphicsMesh.texcoords;
+ BPPI32Array& materialIDArray = chunk.graphicsMesh.materialIDs;
+
+ BPPI32Array& indexArray = chunk.graphicsMesh.positionIndexes;
+
+ int numVertices = positionArray.arraySizes[0];
+ int numIndics = indexArray.arraySizes[0];
+ int numFaces = materialIDArray.arraySizes[0];
+
+ for (uint32_t nv = 0; nv < numVertices; nv++)
+ {
+ nvidia::NvVec3& position = positionArray.buf[nv];
+ nvidia::NvVec3& normal = normalArray.buf[nv];
+ nvidia::NvVec3& tangent = tangentArray.buf[nv];
+ nvidia::NvVec2& texcoord = uvArray.buf[nv];
+
+ positions.push_back(physx::PxVec3(position.x, position.y, position.z));
+ normals.push_back(physx::PxVec3(normal.x, normal.y, normal.z));
+ tangents.push_back(physx::PxVec3(tangent.x, tangent.y, tangent.z));
+ uv.push_back(physx::PxVec2(texcoord.x, texcoord.y));
+ }
+
+ for (uint32_t ni = 0; ni < numIndics; ni++)
+ {
+ indices.push_back(indexArray.buf[ni]);
+ }
+
+ physx::PxVec3* nr = (!normals.empty()) ? normals.data() : 0;
+ physx::PxVec2* uvp = (!uv.empty()) ? uv.data() : 0;
+ Nv::Blast::Mesh* pMesh = new Nv::Blast::Mesh(positions.data(), nr, uvp, static_cast<uint32_t>(positions.size()),
+ indices.data(), static_cast<uint32_t>(indices.size()));
+ for (uint32_t nf = 0; nf < numFaces; nf++)
+ {
+ pMesh->getFacet(nf)->userData = materialIDArray.buf[nf];
+ }
+
+ meshes.push_back(pMesh);
+
+ parentIds.push_back(chunk.parentID);
+
+ supports.push_back(chunk.support);
+
+ statics.push_back(chunk.staticFlag);
+
+ visibles.push_back(chunk.visible);
+ }
+
+ std::vector<uint8_t> joints;
+ std::vector<uint32_t> worlds;
+ for (int bc = 0; bc < bondCount; bc++)
+ {
+ BPPBond& bond = bondArray.buf[bc];
+ if (bond.asset != asset.ID)
+ {
+ continue;
+ }
+
+ uint8_t enableJoint = bond.support.enableJoint ? 1 : 0;
+ joints.push_back(enableJoint);
+
+ worlds.push_back(bond.toChunk);
+ }
+
+ BlastAssetModelSimple* pBlastAssetModelSimple;
+ pSampleManager->createAsset(&pBlastAssetModelSimple, meshes, parentIds, supports, statics, joints, worlds);
+ pSampleManager->addBlastAsset(pBlastAssetModelSimple, modelAsset, true);
+
+ BlastAsset* pBlastAsset = (BlastAsset*)pBlastAssetModelSimple;
+ physx::PxTransform t;
+ for (int is = 0; is < instanceSize; is++)
+ {
+ BPPAssetInstance* instance = instances[is];
nvidia::NvVec3& postion = instance->transform.position;
- nvidia::NvVec4& rotation = instance->transform.rotation;
+ nvidia::NvVec4& rotation = instance->transform.rotation;
t.p = physx::PxVec3(postion.x, postion.y, postion.z);
t.q = physx::PxQuat(rotation.x, rotation.y, rotation.z, rotation.w);
+
+ BlastFamily* pBlastFamily = pSampleManager->addBlastFamily(pBlastAsset, t, true);
+ int visibleCount = visibles.size();
+ for (int vc = 0; vc < visibleCount; vc++)
+ {
+ pBlastFamily->setChunkVisible(vc, visibles[vc]);
+ }
+
+ pSampleManager->setCurrentSelectedInstance(pBlastAsset, is);
+ if (nullptr != instance->exMaterial.buf)
+ {
+ pSampleManager->setMaterialForCurrentFamily(instance->exMaterial.buf, true);
+ }
+ if (nullptr != instance->inMaterial.buf)
+ {
+ pSampleManager->setMaterialForCurrentFamily(instance->inMaterial.buf, false);
+ }
}
- SimpleScene::Inst()->GetSampleManager().addModelAsset(tmpPath.data(), fileName, false, t, true);
}
SimpleScene* pScene = SimpleScene::Inst();
@@ -854,10 +1635,9 @@ bool BlastPlugin::SimpleScene_LoadParameters(NvParameterized::Interface* iface)
// if (false == pScene->GetFurCharacter().LoadHairParameters(handle))
// return false;
//}
-
- BlastProject::ins().loadUserPreset();
return true;
}
+
bool BlastPlugin::SimpleScene_SaveParameters(NvParameterized::Interface* iface)
{
nvidia::parameterized::BlastProjectParameters* params = static_cast<nvidia::parameterized::BlastProjectParameters*>(iface);
@@ -865,7 +1645,16 @@ bool BlastPlugin::SimpleScene_SaveParameters(NvParameterized::Interface* iface)
memset(&targetDesc, sizeof(BPParams), 0);
BPParams& srcParams = BlastProject::ins().getParams();
copy(targetDesc, srcParams);
-
+ /*
+ SampleManager* pSampleManager = SampleManager::ins();
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM;
+ for (itADM = AssetDescMap.begin(); itADM != AssetDescMap.end(); itADM++)
+ {
+ BlastAsset* pBlastAsset = itADM->first;
+ pSampleManager->saveAsset(pBlastAsset);
+ }
+ */
SimpleScene* pScene = SimpleScene::Inst();
if (pScene->m_pCamera)
@@ -1036,6 +1825,9 @@ bool BlastPlugin::D3DWidget_mouseMoveEvent(QMouseEvent* e)
LPARAM lParam = MAKELPARAM(x, y);
deviceManager.MsgProc(g_hWnd, WM_MOUSEMOVE, wParam, lParam);
+ if(SampleManager::ins()->eventAlreadyHandled())
+ e->setAccepted(false);
+
return true;
}
@@ -1068,37 +1860,80 @@ bool BlastPlugin::D3DWidget_contextMenuEvent(QContextMenuEvent *e)
{
QPoint pos = QCursor::pos();
+ std::vector<BlastChunkNode*> chunkNodes;
std::map<BlastAsset*, std::vector<uint32_t>> selectedAssetChunks = SampleManager::ins()->getSelectedChunks();
- if (1 == selectedAssetChunks.size())
+ std::map<BlastAsset*, std::vector<uint32_t>>::iterator itr = selectedAssetChunks.begin();
+ for (; itr != selectedAssetChunks.end(); ++itr)
{
- std::map<BlastAsset*, std::vector<uint32_t>>::iterator itr = selectedAssetChunks.begin();
BlastAsset* asset = itr->first;
std::vector<uint32_t> selectChunks = itr->second;
- std::vector<BlastChunkNode*> chunkNodes = BlastTreeData::ins().getChunkNodeByBlastChunk(asset, selectChunks);
- if (1 == chunkNodes.size())
+ std::vector<BlastChunkNode*> curChunkNodes = BlastTreeData::ins().getChunkNodeByBlastChunk(asset, selectChunks);
+ chunkNodes.insert(chunkNodes.end(), curChunkNodes.begin(), curChunkNodes.end());
+ }
+
+ {
+ std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(chunkNodes);
+ action_Make_Support->setEnabled(true);
+ action_Make_Static_Support->setEnabled(true);
+ action_Remove_Support->setEnabled(true);
+
+ //select chunk nodes have parent child relation ship, disable all menu items
+ if (topChunkNodes.size() < chunkNodes.size())
{
- _chunkContextMenu->exec(pos);
+ action_Make_Support->setEnabled(false);
+ action_Make_Static_Support->setEnabled(false);
+ action_Remove_Support->setEnabled(false);
}
- else if (1 < chunkNodes.size())
+ else
{
- bool allSupportChunk = true;
- for (size_t i = 0; i < chunkNodes.size(); ++i)
+ bool allSupported = true, allStaticSupport = true, allUnSupported = true, hasLeaf = false;
+
+ for (BlastChunkNode* chunkNode : chunkNodes)
{
- BlastChunkNode* chunkNode = chunkNodes[i];
- if (eChunk != chunkNode->getType())
+ BPPChunk* chunk = (BPPChunk*)(chunkNode->getData());
+ if (chunk->support)
+ {
+ allUnSupported = false;
+ }
+ else
+ {
+ allSupported = false;
+ }
+
+ if (!chunk->staticFlag)
{
- allSupportChunk = false;
- break;
+ allStaticSupport = false;
}
+
+ if (BlastTreeData::isLeaf(chunkNode))
+ {
+ hasLeaf = true;
+ }
+ }
+
+ if (allSupported && !allStaticSupport)
+ {
+ action_Make_Support->setEnabled(false);
+ }
+
+ if (allStaticSupport)
+ {
+ action_Make_Static_Support->setEnabled(false);
}
- if (allSupportChunk)
+ if (allUnSupported || hasLeaf)
{
- _bondContextMenu->exec(QCursor::pos());
+ action_Remove_Support->setEnabled(false);
}
}
}
+
+ if (0 < chunkNodes.size())
+ {
+ _contextMenu->exec(QCursor::pos());
+ }
+
e->accept();
return true;
}
@@ -1112,21 +1947,25 @@ bool BlastPlugin::D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderS
bool BlastPlugin::AppMainWindow_AppMainWindow()
{
- _mainToolbar = 0;
- _materialLibraryPanel = 0;
- _materialAssignmentsPanel = 0;
- _fileReferencesPanel = 0;
- _generalPanel = 0;
- _defaultDamagePanel = 0;
- _fractureCutoutSettingsPanel = 0;
- _fractureGeneralPanel = 0;
- _fractureShellCutSettingPanel = 0;
- _fractureSliceSettingsPanel = 0;
- _fractureVisualizersPanel = 0;
- _fractureVoronoiSettingsPanel = 0;
- _supportPanel = 0;
- _blastSceneTree = 0;
- _filtersDockWidget = 0;
+ _mainToolbar = nullptr;
+ _materialLibraryPanel = nullptr;
+ _materialAssignmentsPanel = nullptr;
+ _fileReferencesPanel = nullptr;
+ _generalPanel = nullptr;
+ _defaultDamagePanel = nullptr;
+ _fractureGeneralPanel = nullptr;
+ _fractureSliceSettingsPanel = nullptr;
+ _fractureVisualizersPanel = nullptr;
+ _fractureVoronoiSettingsPanel = nullptr;
+ _supportPanel = nullptr;
+ _fractureVoronoiSettingsExpandlePanel = nullptr;
+ _fractureSliceSettingsExpandlePanel = nullptr;
+ _blastSceneTree = nullptr;
+ _filtersDockWidget = nullptr;
+
+ BlastProject::ins().loadUserPreset();
+ BlastProject::ins().loadFracturePreset();
+ BlastProject::ins().loadFilterPreset();
return true;
}
@@ -1141,6 +1980,11 @@ bool BlastPlugin::AppMainWindow_InitMenuItems(QMenuBar* pMenuBar)
connect(act, SIGNAL(triggered()), this, SLOT(menu_openProject()));
pMenu->addAction(act);
+ act = new QAction("Recents", this);
+ pMenu->addAction(act);
+ _recentProjectMenu = new QMenu("Recents", pMenuBar);
+ act->setMenu(_recentProjectMenu);
+
act = new QAction("Save project file", this);
act->setShortcut(QKeySequence::Save);
connect(act, SIGNAL(triggered()), this, SLOT(menu_saveProject()));
@@ -1152,6 +1996,8 @@ bool BlastPlugin::AppMainWindow_InitMenuItems(QMenuBar* pMenuBar)
pMenu->addSeparator();
+ _loadRecentProject();
+
return true;
}
@@ -1160,14 +2006,15 @@ bool BlastPlugin::AppMainWindow_InitMainTab(QWidget *displayScrollAreaContents,
ExpandablePanel* panel = new ExpandablePanel(displayScrollAreaContents);
displayScrollAreaLayout->insertWidget(idx++, panel);
panel->SetTitle("Display Mesh Materials");
+ panel->setVisible(false);
return true;
}
bool BlastPlugin::AppMainWindow_InitPluginTab(QTabWidget* sideBarTab)
{
+ QWidget *tabMaterial;
{
- QWidget *tabMaterial;
QGridLayout *gridLayoutMaterial;
QFrame *materialEditorArea;
QVBoxLayout *materialEditorAreaLayout;
@@ -1213,10 +2060,6 @@ bool BlastPlugin::AppMainWindow_InitPluginTab(QTabWidget* sideBarTab)
gridLayoutMaterial->addWidget(materialScrollArea, 0, 0, 1, 1);
- sideBarTab->addTab(tabMaterial, QString());
-
- sideBarTab->setTabText(sideBarTab->indexOf(tabMaterial), QApplication::translate("AppMainWindowClass", "Materials", 0));
-
ExpandablePanel* panel = 0;
int pannelCnt = 0;
@@ -1233,8 +2076,8 @@ bool BlastPlugin::AppMainWindow_InitPluginTab(QTabWidget* sideBarTab)
panel->SetTitle("Material Assignments");
}
+ QWidget *tabBlast;
{
- QWidget *tabBlast;
QGridLayout *gridLayout;
QFrame *blastMaterialEditorArea;
QVBoxLayout *blastMaterialEditorAreaLayout;
@@ -1280,10 +2123,6 @@ bool BlastPlugin::AppMainWindow_InitPluginTab(QTabWidget* sideBarTab)
gridLayout->addWidget(blastScrollArea, 0, 0, 1, 1);
- sideBarTab->addTab(tabBlast, QString());
-
- sideBarTab->setTabText(sideBarTab->indexOf(tabBlast), QApplication::translate("AppMainWindowClass", "Blast", 0));
-
ExpandablePanel* panel = 0;
int pannelCnt = 0;
@@ -1306,50 +2145,42 @@ bool BlastPlugin::AppMainWindow_InitPluginTab(QTabWidget* sideBarTab)
panel->SetTitle("Support");
panel = new ExpandablePanel(blastScrollAreaContents);
- _blastCompositePanel = new BlastCompositePanel(panel);
- panel->AddContent(_blastCompositePanel);
- blastScrollAreaLayout->insertWidget(pannelCnt++, panel);
- panel->SetTitle("Blast Composite");
-
- panel = new ExpandablePanel(blastScrollAreaContents);
_fractureGeneralPanel = new FractureGeneralPanel(panel);
panel->AddContent(_fractureGeneralPanel);
blastScrollAreaLayout->insertWidget(pannelCnt++, panel);
panel->SetTitle("Fracture General");
panel = new ExpandablePanel(blastScrollAreaContents);
- _fractureCutoutSettingsPanel = new FractureCutoutSettingsPanel(panel);
- panel->AddContent(_fractureCutoutSettingsPanel);
- blastScrollAreaLayout->insertWidget(pannelCnt++, panel);
- panel->SetTitle("Cutout Projection Settings");
-
- panel = new ExpandablePanel(blastScrollAreaContents);
- _fractureShellCutSettingPanel = new FractureShellCutSettingsPanel(panel);
- panel->AddContent(_fractureShellCutSettingPanel);
+ _fractureVoronoiSettingsExpandlePanel = panel;
+ _fractureVoronoiSettingsPanel = new FractureVoronoiSettingsPanel(panel);
+ panel->AddContent(_fractureVoronoiSettingsPanel);
blastScrollAreaLayout->insertWidget(pannelCnt++, panel);
- panel->SetTitle("Shell Cut Settings");
+ panel->SetTitle("Voronoi Settings");
+ _fractureVoronoiSettingsExpandlePanel->setVisible(true);
panel = new ExpandablePanel(blastScrollAreaContents);
+ _fractureSliceSettingsExpandlePanel = panel;
_fractureSliceSettingsPanel = new FractureSliceSettingsPanel(panel);
panel->AddContent(_fractureSliceSettingsPanel);
blastScrollAreaLayout->insertWidget(pannelCnt++, panel);
panel->SetTitle("Slice Settings");
-
- panel = new ExpandablePanel(blastScrollAreaContents);
- _fractureVoronoiSettingsPanel = new FractureVoronoiSettingsPanel(panel);
- panel->AddContent(_fractureVoronoiSettingsPanel);
- blastScrollAreaLayout->insertWidget(pannelCnt++, panel);
- panel->SetTitle("Voronoi Settings");
+ _fractureSliceSettingsExpandlePanel->setVisible(false);
panel = new ExpandablePanel(blastScrollAreaContents);
_fractureVisualizersPanel = new FractureVisualizersPanel(panel);
panel->AddContent(_fractureVisualizersPanel);
blastScrollAreaLayout->insertWidget(pannelCnt++, panel);
panel->SetTitle("Visualizers");
+
+ _fractureGeneralPanel->setFracturePanels(_fractureVoronoiSettingsPanel, _fractureSliceSettingsPanel, _fractureVisualizersPanel);
+ _fractureGeneralPanel->setFractureExpandablePanels(_fractureVoronoiSettingsExpandlePanel, _fractureSliceSettingsExpandlePanel);
+ _fractureVoronoiSettingsPanel->setFractureGeneralPanel(_fractureGeneralPanel);
+ _fractureSliceSettingsPanel->setFractureGeneralPanel(_fractureGeneralPanel);
+ _fractureVisualizersPanel->setFractureGeneralPanel(_fractureGeneralPanel);
}
+ QWidget *tabDamage;
{
- QWidget *tabDamage;
QGridLayout *gridLayoutDamage;
QFrame *damageEditorArea;
QVBoxLayout *damageEditorAreaLayout;
@@ -1395,10 +2226,22 @@ bool BlastPlugin::AppMainWindow_InitPluginTab(QTabWidget* sideBarTab)
gridLayoutDamage->addWidget(damageScrollArea, 0, 0, 1, 1);
- sideBarTab->addTab(tabDamage, QString());
+ // GWDCC-523 Blast Tool - Tabs should be arranged Blast/Damage/Materials/Settings
+ sideBarTab->insertTab(0, tabBlast, QString());
+
+ sideBarTab->setTabText(sideBarTab->indexOf(tabBlast), QApplication::translate("AppMainWindowClass", "Blast", 0));
+
+ sideBarTab->insertTab(1, tabDamage, QString());
sideBarTab->setTabText(sideBarTab->indexOf(tabDamage), QApplication::translate("AppMainWindowClass", "Damage", 0));
+ sideBarTab->insertTab(2, tabMaterial, QString());
+
+ sideBarTab->setTabText(sideBarTab->indexOf(tabMaterial), QApplication::translate("AppMainWindowClass", "Materials", 0));
+
+ // make Blast page as current selected
+ sideBarTab->setCurrentIndex(0);
+
ExpandablePanel* panel = 0;
int pannelCnt = 0;
@@ -1430,6 +2273,7 @@ bool BlastPlugin::AppMainWindow_InitUI()
_blastSceneTree->setFeatures(_blastSceneTree->features()&~QDockWidget::DockWidgetClosable);
_blastSceneTree->addObserver(_defaultDamagePanel);
_blastSceneTree->addObserver(_supportPanel);
+ _blastSceneTree->addObserver(_generalPanel);
mainWindow->addDockWidget(Qt::LeftDockWidgetArea, _blastSceneTree);
return true;
}
@@ -1443,7 +2287,10 @@ bool BlastPlugin::AppMainWindow_updateUI()
_filtersDockWidget->updateValues();
if (_blastSceneTree)
+ {
_blastSceneTree->updateValues();
+ //SampleManager::ins()->m_bNeedRefreshTree = true;
+ }
if (_materialLibraryPanel)
_materialLibraryPanel->updateValues();
@@ -1457,18 +2304,9 @@ bool BlastPlugin::AppMainWindow_updateUI()
if (_generalPanel)
_generalPanel->updateValues();
- if (_blastCompositePanel)
- _blastCompositePanel->updateValues();
-
- if (_fractureCutoutSettingsPanel)
- _fractureCutoutSettingsPanel->updateValues();
-
if (_fractureGeneralPanel)
_fractureGeneralPanel->updateValues();
- if (_fractureShellCutSettingPanel)
- _fractureShellCutSettingPanel->updateValues();
-
if (_fractureSliceSettingsPanel)
_fractureSliceSettingsPanel->updateValues();
@@ -1518,9 +2356,15 @@ bool BlastPlugin::AppMainWindow_InitToolbar(QWidget *pQWidget, QVBoxLayout* pLay
bool BlastPlugin::AppMainWindow_shortcut_expert(bool mode)
{
- if (_mainToolbar)
- _mainToolbar->setVisible(mode);
+ //if (_mainToolbar)
+ // _mainToolbar->setVisible(mode);
+ if (_filtersDockWidget)
+ _filtersDockWidget->setVisible(mode);
+ if (_blastSceneTree)
+ _blastSceneTree->setVisible(mode);
+ // set FPS display
+ GlobalSettings::Inst().m_showFPS = mode;
return true;
}
@@ -1532,6 +2376,27 @@ bool BlastPlugin::AppMainWindow_updateMainToolbar()
return true;
}
+bool BlastPlugin::AppMainWindow_menu_item_triggered(QAction* action)
+{
+ bool clickRecent = false;
+ for (int i = 0; i < _recentProjectActions.count(); ++i)
+ {
+ if (_recentProjectActions.at(i) == action)
+ {
+ clickRecent = true;
+ break;
+ }
+ }
+
+ if (clickRecent)
+ {
+ bool ret = _openProject(action->text());
+ _resetRecentProject(action->text());
+ return ret;
+ }
+ return false;
+}
+
bool BlastPlugin::AppMainWindow_menu_about()
{
return true;
@@ -1580,7 +2445,9 @@ bool BlastPlugin::menu_openProject()
QString lastDir = window._lastFilePath;
QString fileName = QFileDialog::getOpenFileName(&window, "Open Blast Project File", lastDir, "Blast Project File (*.blastProj)");
- return window.openProject(fileName);
+ _addRecentProject(fileName);
+
+ return _openProject(fileName);
}
bool BlastPlugin::menu_saveProject()
@@ -1636,6 +2503,7 @@ bool BlastPlugin::menu_saveProjectAs()
QString lastDir = window._lastFilePath;
QString fileName = QFileDialog::getSaveFileName(&window, "Save Blast Project File", lastDir, "Blast Project File (*.blastProj)");
+ _addRecentProject(fileName);
if (!fileName.isEmpty())
{
QFileInfo fileInfo(fileName);
@@ -1652,7 +2520,7 @@ bool BlastPlugin::menu_saveProjectAs()
return false;
}
- sprintf(message, "Project file %s was saved.", (const char*)file);
+ sprintf(message, "Project file %s was saved.", (const char*)fileName.toUtf8().data());
/*
QMessageBox messageBox;
@@ -1662,6 +2530,9 @@ bool BlastPlugin::menu_saveProjectAs()
viewer_msg(message);
+ // show project path in toolbar
+ BlastPlugin::Inst().GetMainToolbar()->updateValues();
+
window._lastFilePath = fileInfo.absoluteDir().absolutePath();
return true;
}
@@ -1670,46 +2541,78 @@ bool BlastPlugin::menu_saveProjectAs()
bool BlastPlugin::shortcut_damagetool()
{
- SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
- sampleManager.setBlastToolType(BTT_Damage);
+ BlastPlugin::Inst().GetMainToolbar()->on_btnDamage_clicked();
return true;
}
bool BlastPlugin::shortcut_selecttool()
{
- SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
- sampleManager.setBlastToolType(BTT_Select);
+ BlastPlugin::Inst().GetMainToolbar()->on_btnSelectTool_clicked();
+ BlastPlugin::Inst().GetMainToolbar()->updateCheckIconsStates();
return true;
}
bool BlastPlugin::shortcut_Translate()
{
- SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
- sampleManager.setBlastToolType(BTT_Translate);
+ BlastPlugin::Inst().GetMainToolbar()->on_Translate_clicked();
+ BlastPlugin::Inst().GetMainToolbar()->updateCheckIconsStates();
return true;
}
bool BlastPlugin::shortcut_Rotation()
{
- SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
- sampleManager.setBlastToolType(BTT_Rotation);
+ BlastPlugin::Inst().GetMainToolbar()->on_Rotation_clicked();
+ BlastPlugin::Inst().GetMainToolbar()->updateCheckIconsStates();
return true;
}
bool BlastPlugin::shortcut_Scale()
{
- SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
- sampleManager.setBlastToolType(BTT_Scale);
+ BlastPlugin::Inst().GetMainToolbar()->on_Scale_clicked();
+ BlastPlugin::Inst().GetMainToolbar()->updateCheckIconsStates();
return true;
}
bool BlastPlugin::shortcut_edittool()
{
SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
- sampleManager.setBlastToolType(BTT_Edit);
+ sampleManager.EnableSimulating(false);
return true;
}
+bool BlastPlugin::shortcut_addFamily()
+{
+ SampleManager* pSampleManager = SampleManager::ins();
+ BlastAsset* pBlastAsset = pSampleManager->getCurBlastAsset();
+ if (pBlastAsset == nullptr)
+ {
+ viewer_warn("please select asset first to create family !");
+ return false;
+ }
+
+ SourceAssetOpenDlg dlg(2, &AppMainWindow::Inst());
+ if (dlg.exec() != QDialog::Accepted)
+ return false;
+
+ 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);
+ }
+ bool res = pSampleManager->addBlastFamily(pBlastAsset, t);
+ if(res)
+ AppMainWindow::Inst().updateUI();
+ return res;
+}
+
bool BlastPlugin::slot_Make_Support()
{
BlastSceneTree::ins()->makeSupport();
@@ -1745,3 +2648,123 @@ bool BlastPlugin::slot_Remove_all_Bonds()
BlastSceneTree::ins()->removeAllBonds();
return true;
}
+
+bool BlastPlugin::_openProject(const QString project)
+{
+ AppMainWindow& window = AppMainWindow::Inst();
+ bool ret = window.openProject(project);
+ if (ret)
+ {
+ SampleManager* pSampleManager = SampleManager::ins();
+ SelectionToolController& selectionToolController = pSampleManager->getSelectionToolController();
+ GizmoToolController& gizmoToolController = pSampleManager->getGizmoToolController();
+ gizmoToolController.showAxisRenderables(false);
+ if (selectionToolController.IsEnabled() || gizmoToolController.IsEnabled())
+ {
+ // do nothing here
+ }
+ else
+ {
+ // turn on selection tool
+ selectionToolController.EnableController();
+ BlastPlugin::Inst().GetMainToolbar()->updateCheckIconsStates();
+ }
+ }
+ return ret;
+}
+
+void BlastPlugin::_addRecentProject(const QString project)
+{
+ if (project.isEmpty())
+ return;
+
+ if (_recentProjectRecordFile.getItems().count() > 0 && _recentProjectRecordFile.getItems().first() == project)
+ return;
+
+ if (_recentProjectActions.count() == 8)
+ {
+ QAction* act = _recentProjectActions.last();
+ _recentProjectMenu->removeAction(act);
+
+ _recentProjectRecordFile.getItems().pop_back();
+ _recentProjectActions.pop_back();
+ }
+
+ if (_recentProjectRecordFile.isItemExist(project))
+ {
+ _resetRecentProject(project);
+ return;
+ }
+
+ QAction* act = new QAction(project, _recentProjectMenu);
+ if (_recentProjectActions.count() > 0)
+ _recentProjectMenu->insertAction(_recentProjectActions.first(), act);
+ else
+ _recentProjectMenu->addAction(act);
+
+ _recentProjectActions.push_front(act);
+
+ _recentProjectRecordFile.getItems().push_front(project);
+
+ _saveRecentProject();
+}
+
+void BlastPlugin::_resetRecentProject(const QString project)
+{
+ if (project.isEmpty())
+ return;
+
+ if (_recentProjectRecordFile.getItems().count() > 0 && _recentProjectRecordFile.getItems().first() == project)
+ return;
+
+ if (!_recentProjectRecordFile.isItemExist(project))
+ return;
+
+ QList<QAction*> actions;
+ for (int i = 0; i < _recentProjectActions.count(); ++i)
+ {
+ QAction* act = _recentProjectActions.at(i);
+ if (act->text() == project)
+ actions.push_front(act);
+ else
+ actions.push_back(act);
+ }
+
+ _recentProjectMenu->addActions(actions);
+ _recentProjectActions = actions;
+
+ QList<QString> projectsTMP;
+ QList<QString>& projectsCurrent = _recentProjectRecordFile.getItems();
+ for (int i = 0; i < projectsCurrent.count(); ++i)
+ {
+ QString item = projectsCurrent.at(i);
+ if (item == project)
+ projectsTMP.push_front(item);
+ else
+ projectsTMP.push_back(item);
+ }
+ projectsCurrent.clear();
+ projectsCurrent = projectsTMP;
+
+ _saveRecentProject();
+}
+
+void BlastPlugin::_loadRecentProject()
+{
+ QString recentProjectRecordFile = QCoreApplication::applicationDirPath() + "/RecentBlastProjects.rbp";
+ _recentProjectRecordFile.load(recentProjectRecordFile);
+
+ QList<QString> recentProjects = _recentProjectRecordFile.getItems();
+ _recentProjectRecordFile.getItems().clear();
+
+ for (int i = recentProjects.count() - 1; i >= 0; --i)
+ {
+ _addRecentProject(recentProjects.at(i));
+ }
+}
+
+void BlastPlugin::_saveRecentProject()
+{
+ QString recentProjectRecordFile = QCoreApplication::applicationDirPath() + "/RecentBlastProjects.rbp";
+ _recentProjectRecordFile.save(recentProjectRecordFile);
+}
diff --git a/tools/ArtistTools/source/BlastPlugin/BlastPlugin.h b/tools/ArtistTools/source/BlastPlugin/BlastPlugin.h
index 21a5499..59fc49a 100644
--- a/tools/ArtistTools/source/BlastPlugin/BlastPlugin.h
+++ b/tools/ArtistTools/source/BlastPlugin/BlastPlugin.h
@@ -5,6 +5,7 @@
#include <QtCore/QtPlugin>
#include "PluginInterface.h"
#include "UIGlobal.h"
+#include "XMLHelper.h"
class QMenu;
class QAction;
@@ -13,15 +14,13 @@ class QComboBox;
class QCheckBox;
class QVBoxLayout;
class BlastToolbar;
+class ExpandablePanel;
class FileReferencesPanel;
class GeneralPanel;
-class BlastCompositePanel;
class DefaultDamagePanel;
class MaterialLibraryPanel;
class MaterialAssignmentsPanel;
-class FractureCutoutSettingsPanel;
class FractureGeneralPanel;
-class FractureShellCutSettingsPanel;
class FractureSliceSettingsPanel;
class FractureVisualizersPanel;
class FractureVoronoiSettingsPanel;
@@ -47,6 +46,8 @@ class BlastPlugin : public QObject, public PluginInterface
Q_INTERFACES(PluginInterface)
public:
+ BlastPlugin();
+ ~BlastPlugin();
virtual QString GetPluginName();
virtual bool CoreLib_RunApp();
@@ -69,7 +70,7 @@ public:
virtual bool Gamepad_ToggleSimulation();
virtual bool Gamepad_LoadSamples(QString fn);
virtual bool Gamepad_ResetScene();
- virtual bool Gamepad_StartAnimation();
+ virtual bool Gamepad_PlaySample();
virtual bool GamepadHandler_ShowHair();
virtual bool GamepadHandler_SpinWindStrength(float windStrength);
virtual bool Gamepad_ResetAnimation();
@@ -78,6 +79,7 @@ public:
virtual bool Light_loadParameters(NvParameterized::Handle& handle, Light* pLight);
virtual bool Light_saveParameters(NvParameterized::Handle& handle, Light* pLight);
+ virtual void SimpleScene_OpenFilesByDrop(const QStringList& fileNames);
virtual bool SimpleScene_SimpleScene();
virtual bool SimpleScene_Initialize(int backdoor);
virtual bool SimpleScene_Shutdown();
@@ -85,6 +87,7 @@ public:
virtual bool SimpleScene_Draw_DX12();
virtual bool SimpleScene_Draw_DX11();
virtual bool SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents);
+ virtual bool SimpleScene_UpdateCamera();
virtual bool SimpleScene_DrawGround();
virtual bool SimpleScene_DrawWind();
virtual bool SimpleScene_DrawAxis();
@@ -125,6 +128,7 @@ public:
virtual bool AppMainWindow_shortcut_expert(bool mode);
virtual bool AppMainWindow_updateMainToolbar();
+ virtual bool AppMainWindow_menu_item_triggered(QAction* action);
virtual bool AppMainWindow_menu_about();
virtual bool AppMainWindow_menu_opendoc();
#if USE_CURVE_EDITOR
@@ -139,11 +143,18 @@ public:
public:
static void DrawHUD();
+ static BlastPlugin& Inst();
+
/////////////////////////////////////////////////////////////////////
// profiler and timer
static void ResetFrameTimer();
-
+ static void OpenBpxa(const char* dir, const char* fn);
+
+ FileReferencesPanel* GetFileReferencesPanel() { return _fileReferencesPanel; }
+
public slots:
+ void slot_Gamepad_PlaySample();
+
bool menu_openProject();
bool menu_saveProject();
bool menu_saveProjectAs();
@@ -153,6 +164,7 @@ public slots:
bool shortcut_Rotation();
bool shortcut_Scale();
bool shortcut_edittool();
+ bool shortcut_addFamily();
bool slot_Make_Support();
bool slot_Make_Static_Support();
@@ -162,25 +174,34 @@ public slots:
bool slot_Remove_all_Bonds();
private:
+ bool _openProject(const QString project);
+ void _addRecentProject(const QString project);
+ void _resetRecentProject(const QString project);
+ void _loadRecentProject();
+ void _saveRecentProject();
+
+private:
BlastToolbar* _mainToolbar;
MaterialLibraryPanel* _materialLibraryPanel;
MaterialAssignmentsPanel* _materialAssignmentsPanel;
FileReferencesPanel* _fileReferencesPanel;
GeneralPanel* _generalPanel;
- BlastCompositePanel* _blastCompositePanel;
DefaultDamagePanel* _defaultDamagePanel;
- FractureCutoutSettingsPanel* _fractureCutoutSettingsPanel;
FractureGeneralPanel* _fractureGeneralPanel;
- FractureShellCutSettingsPanel* _fractureShellCutSettingPanel;
+ FractureVoronoiSettingsPanel* _fractureVoronoiSettingsPanel;
FractureSliceSettingsPanel* _fractureSliceSettingsPanel;
FractureVisualizersPanel* _fractureVisualizersPanel;
- FractureVoronoiSettingsPanel* _fractureVoronoiSettingsPanel;
SupportPanel* _supportPanel;
+ ExpandablePanel* _fractureVoronoiSettingsExpandlePanel;
+ ExpandablePanel* _fractureSliceSettingsExpandlePanel;
BlastSceneTree* _blastSceneTree;
FiltersDockWidget* _filtersDockWidget;
- QMenu* _chunkContextMenu;
- QMenu* _bondContextMenu;
+ QMenu* _recentProjectMenu;
+ QList<QAction*> _recentProjectActions;
+ SingleItemKindFile _recentProjectRecordFile;
+
+ QMenu* _contextMenu;
QAction* action_Make_Support;
QAction* action_Make_Static_Support;
QAction* action_Remove_Support;
diff --git a/tools/ArtistTools/source/BlastPlugin/Parameters/BlastProjectParams.pl b/tools/ArtistTools/source/BlastPlugin/Parameters/BlastProjectParams.pl
new file mode 100644
index 0000000..bb22204
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/Parameters/BlastProjectParams.pl
@@ -0,0 +1,1514 @@
+{
+ header =>
+ {
+ className => 'BlastProjectParameters',
+ implementStorage => 1,
+
+ # Version history
+ # 0.0 Initial Version
+ classVersion => '0.0',
+
+ hints =>
+ {
+ },
+ },
+
+ structs =>
+ [
+ {
+ name => 'GraphicsMaterial',
+ parameters =>
+ [
+ {
+ name => 'ID',
+ type => 'I32',
+ defaultValue => '-1',
+ hints => { shortDescription => "ID of this material" },
+ },
+ {
+ name => 'name',
+ type => 'STRING',
+ hints => { shortDescription => 'Name of this material' },
+ },
+ {
+ name => 'useTextures',
+ type => 'BOOL',
+ hints => { shortDescription => 'Use textures'},
+ },
+ {
+ name => 'diffuseTextureFilePath',
+ type => 'STRING',
+ hints => { shortDescription => 'Diffuse texture file path' },
+ },
+ {
+ name => 'specularTextureFilePath',
+ type => 'STRING',
+ hints => { shortDescription => 'Specular texture file path' },
+ },
+ {
+ name => 'normalTextureFilePath',
+ type => 'STRING',
+ hints => { shortDescription => 'Normal texture file path' },
+ },
+ {
+ name => 'diffuseColor',
+ type => 'VEC4',
+ defaultValue => '0',
+ hints => { shortDescription => "Diffuse color" },
+ },
+ {
+ name => 'specularColor',
+ type => 'VEC4',
+ defaultValue => '0',
+ hints => { shortDescription => "Specular color" },
+ },
+ {
+ name => 'specularShininess',
+ type => 'F32',
+ defaultValue => '1.0f',
+ hints => { shortDescription => 'Specular shininess' },
+ },
+ ]
+ },
+ {
+ name => 'MaterialAssignments',
+ parameters =>
+ [
+ {
+ name => 'libraryMaterialID',
+ type => 'I32',
+ defaultValue => '-1',
+ hints =>
+ {
+ shortDescription => "ID of the material in material library",
+ },
+ },
+ {
+ name => 'faceMaterialID',
+ type => 'I32',
+ defaultValue => '-1',
+ hints =>
+ {
+ shortDescription => "ID of the material for face, which are generated in graphics mesh range",
+ },
+ },
+ ]
+ },
+ {
+ name => 'GraphicsMesh',
+ parameters =>
+ [
+ {
+ name => 'materialAssignments',
+ type => 'MaterialAssignments',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "MaterialAssignments",
+ },
+ },
+ {
+ name => 'positions',
+ type => 'VEC3',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Position data array",
+ },
+ },
+ {
+ name => 'normals',
+ type => 'VEC3',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Normal data array",
+ },
+ },
+ {
+ name => 'tangents',
+ type => 'VEC3',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Tangent data array",
+ },
+ },
+ {
+ name => 'texcoords',
+ type => 'VEC2',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Texcoord data array",
+ },
+ },
+ {
+ name => 'vertextCountInFace',
+ type => 'U32',
+ defaultValue => '3',
+ hints =>
+ {
+ shortDescription => "Count of vertextes of one face",
+ },
+ },
+ {
+ name => 'positionIndexes',
+ type => 'I32',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Indexes of the positions of each face",
+ },
+ },
+ {
+ name => 'normalIndexes',
+ type => 'I32',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Indexes of the normal of each face",
+ },
+ },
+ {
+ name => 'tangentIndexes',
+ type => 'I32',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Indexes of the tangents of each face",
+ },
+ },
+ {
+ name => 'texcoordIndexes',
+ type => 'I32',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Indexes of the texcoords of each face",
+ },
+ },
+ {
+ name => 'materialIDs',
+ type => 'I32',
+ isArray => 1,
+ arraySize => '-1',
+ hints => { shortDescription => "IDs of the material specified for each face " },
+ },
+ ]
+ },
+ {
+ name => 'Light',
+ parameters =>
+ [
+ {
+ name => 'name',
+ type => 'STRING',
+ defaultValue => '',
+ hints => { shortDescription => 'name of light' },
+ },
+ {
+ name => 'enable',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "enable this light" },
+ },
+ {
+ name => 'useShadows',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "use shadows for this light" },
+ },
+ {
+ name => 'lockToRoot',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "lock this light to the root bone" },
+ },
+ {
+ name => 'visualize',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "visualize this light" },
+ },
+ {
+ name => 'type',
+ type => 'I32',
+ defaultValue => '0',
+ hints =>
+ {
+ shortDescription => "Type of this light",
+ },
+ },
+ {
+ name => 'shadowMapResolution',
+ type => 'I32',
+ defaultValue => '0',
+ hints =>
+ {
+ shortDescription => "shadow resolution",
+ },
+ },
+ {
+ name => 'color',
+ type => 'VEC3',
+ defaultValue => '1.0f',
+ hints => { shortDescription => "Light color for visualization" },
+ },
+ {
+ name => 'diffuseColor',
+ type => 'VEC3',
+ defaultValue => '1.0f',
+ hints => { shortDescription => "Light diffuse color" },
+ },
+ {
+ name => 'ambientColor',
+ type => 'VEC3',
+ defaultValue => '1.0f',
+ hints => { shortDescription => "Light ambient color" },
+ },
+ {
+ name => 'specularColor',
+ type => 'VEC3',
+ defaultValue => '1.0f',
+ hints => { shortDescription => "Light specular color" },
+ },
+ {
+ name => 'intensity',
+ type => 'F32',
+ defaultValue => '1.0f',
+ hints => { shortDescription => "Light intensity" },
+ },
+ {
+ name => 'distance',
+ type => 'F32',
+ defaultValue => '100.0f',
+ hints => { shortDescription => "Light distance (for position based lights)" },
+ },
+ {
+ name => 'spotFalloffStart',
+ type => 'F32',
+ defaultValue => '20.0f',
+ hints => { shortDescription => "Fall off start angle for spot light" },
+ },
+ {
+ name => 'spotFalloffEnd',
+ type => 'F32',
+ defaultValue => '30.0f',
+ hints => { shortDescription => "Fall off end angle for spot light" },
+ },
+ {
+ name => 'lightAxisX',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints =>
+ {
+ shortDescription => "X axis of light matrix",
+ },
+ },
+ {
+ name => 'lightAxisY',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints =>
+ {
+ shortDescription => "Y axis of light matrix",
+ },
+ },
+ {
+ name => 'lightAxisZ',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints =>
+ {
+ shortDescription => "Z axis of light matrix",
+ },
+ },
+ {
+ name => 'lightPos',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints =>
+ {
+ shortDescription => "light position",
+ },
+ },
+ ]
+ },
+ {
+ name => 'Camera',
+ parameters =>
+ [
+ {
+ name => 'flags',
+ type => 'U16',
+ defaultValue => '0',
+ hints => { shortDescription => "Y Up(1) or Z Up(2)" },
+ },
+ {
+ name => 'fov',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "FOV" },
+ },
+ {
+ name => 'aspectRatio',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "FOV" },
+ },
+ {
+ name => 'znear',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Near Z" },
+ },
+ {
+ name => 'zfar',
+ type => 'F32',
+ defaultValue => '1.0f',
+ hints => { shortDescription => "Far Z" },
+ },
+ {
+ name => 'width',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Width for Ortho" },
+ },
+ {
+ name => 'height',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Height for Ortho" },
+ },
+ {
+ name => 'isPerspective',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "Camera Eye Position" },
+ },
+ {
+ name => 'eye',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Camera Eye Position" },
+ },
+ {
+ name => 'at',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Camera At Position" },
+ },
+ {
+ name => 'xAxis',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "X Axis" },
+ },
+ {
+ name => 'yAxis',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Y Axis" },
+ },
+ {
+ name => 'zAxis',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Z Axis" },
+ },
+ {
+ name => 'viewDirection',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "View Direction" },
+ },
+ {
+ name => 'lookDistance',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Look Distance" },
+ },
+ {
+ name => 'orientation',
+ type => 'VEC4',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Orientation Quaternion" },
+ },
+ {
+ name => 'viewMatrix',
+ type => 'MAT44',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "View Matrix" },
+ },
+ {
+ name => 'projectionMatrix',
+ type => 'MAT44',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "View Matrix" },
+ },
+ ]
+ },
+ {
+ name => 'CameraBookmark',
+ parameters =>
+ [
+ {
+ name => 'name',
+ type => 'STRING',
+ hints => { shortDescription => "Name of the bookmark" },
+ },
+ {
+ name => 'camera',
+ type => 'Camera',
+ hints => { shortDescription => "Camera information" },
+ },
+ ]
+ },
+ {
+ name => 'Scene',
+ parameters =>
+ [
+ {
+ name => 'repeatAnimation',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "Repeat animation" },
+ },
+ {
+ name => 'animationSpeed',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Animation speed" },
+ },
+ {
+ name => 'showGrid',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "Show grid" },
+ },
+ {
+ name => 'showAxis',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "Show axis" },
+ },
+ {
+ name => 'upAxis',
+ type => 'U32',
+ defaultValue => '0',
+ hints => { shortDescription => "Up axis" },
+ },
+ {
+ name => 'sceneUnitIndex',
+ type => 'U32',
+ defaultValue => '0',
+ hints => { shortDescription => "Scene Unit" },
+ },
+ ]
+ },
+ {
+ name => 'Renderer',
+ parameters =>
+ [
+ {
+ name => 'renderFps',
+ type => 'F32',
+ defaultValue => '60.0f',
+ hints =>
+ {
+ shortDescription => "Render Play Rate FPS",
+ },
+ },
+ {
+ name => 'frameStartTime',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints =>
+ {
+ shortDescription => "Frame start time",
+ },
+ },
+ {
+ name => 'frameEndTime',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints =>
+ {
+ shortDescription => "Frame end time",
+ },
+ },
+ {
+ name => 'animationFps',
+ type => 'F32',
+ defaultValue => '24.0f',
+ hints =>
+ {
+ shortDescription => "Animation FPS",
+ },
+ },
+ {
+ name => 'animate',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints =>
+ {
+ shortDescription => "Is animated",
+ },
+ },
+ {
+ name => 'simulate',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints =>
+ {
+ shortDescription => "Is simulated",
+ },
+ },
+ {
+ name => 'resetSimulationOnLoop',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints =>
+ {
+ shortDescription => "Reset simulation state on loop",
+ },
+ },
+ {
+ name => 'simulationFps',
+ type => 'F32',
+ defaultValue => '60.0f',
+ hints =>
+ {
+ shortDescription => "Simulation Rate FPS",
+ },
+ },
+ {
+ name => 'showGraphicsMesh',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints =>
+ {
+ shortDescription => "Show graphics mesh",
+ },
+ },
+ {
+ name => 'visualizeGrowthMesh',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints =>
+ {
+ shortDescription => "Visualize growth mesh",
+ },
+ },
+ {
+ name => 'visualizeLight',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints =>
+ {
+ shortDescription => "Visualize light",
+ },
+ },
+ {
+ name => 'visualizeWind',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints =>
+ {
+ shortDescription => "Visualize wind",
+ },
+ },
+ {
+ name => 'showStatistics',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints =>
+ {
+ shortDescription => "Show statistics",
+ },
+ },
+ {
+ name => 'renderStyle',
+ type => 'I32',
+ defaultValue => '2',
+ hints =>
+ {
+ shortDescription => "Render style",
+ },
+ },
+ {
+ name => 'colorizeOption',
+ type => 'I32',
+ defaultValue => '0',
+ hints =>
+ {
+ shortDescription => "Colorize option",
+ },
+ },
+ {
+ name => 'showWireframe',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints =>
+ {
+ shortDescription => "Show wireframe",
+ },
+ },
+ {
+ name => 'lockRootBone',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints =>
+ {
+ shortDescription => "Lock root bone",
+ },
+ },
+ {
+ name => 'controlTextureOption',
+ type => 'I32',
+ defaultValue => '0',
+ hints =>
+ {
+ shortDescription => "Control texture option",
+ },
+ },
+ {
+ name => 'useLighting',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints =>
+ {
+ shortDescription => "Use lighting",
+ },
+ },
+ {
+ name => 'showSkinnedMeshOnly',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints =>
+ {
+ shortDescription => "Show skinned mesh only",
+ },
+ },
+ {
+ name => 'lightDir',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints =>
+ {
+ shortDescription => "Light direction",
+ },
+ },
+ {
+ name => 'ambientColor',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints =>
+ {
+ shortDescription => "Scene ambient color",
+ },
+ },
+ {
+ name => 'windDir',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints =>
+ {
+ shortDescription => "Wind direction",
+ },
+ },
+ {
+ name => 'windStrength',
+ type => 'F32',
+ defaultValue => '1.0f',
+ hints =>
+ {
+ shortDescription => "Wind strength",
+ },
+ },
+ {
+ name => 'lightIntensity',
+ type => 'F32',
+ defaultValue => '1.0f',
+ hints =>
+ {
+ shortDescription => "Light intensity",
+ },
+ },
+ {
+ name => 'gravityDir',
+ type => 'VEC3',
+ defaultValue => '0.0f',
+ hints =>
+ {
+ shortDescription => "Gravity direction",
+ },
+ },
+ {
+ name => 'gravityScale',
+ type => 'F32',
+ defaultValue => '1.0f',
+ hints =>
+ {
+ shortDescription => "Gravity scale",
+ },
+ },
+ {
+ name => 'textureFilePath',
+ type => 'STRING',
+ hints =>
+ {
+ shortDescription => "Texture file path",
+ },
+ },
+ {
+ name => 'lights',
+ type => 'Light',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Light data",
+ },
+ },
+ ]
+ },
+ {
+ name => 'BlastFileReferences',
+ parameters =>
+ [
+ {
+ name => 'fbxSourceAsset',
+ type => 'STRING',
+ hints => { shortDescription => "FBX source asset path" },
+ },
+ ]
+ },
+ {
+ name => 'StressSolver',
+ parameters =>
+ [
+ {
+ name => 'hardness',
+ type => 'F32',
+ defaultValue => '1000.0f',
+ hints => { shortDescription => "Hardness of bond's material" },
+ },
+ {
+ name => 'linearFactor',
+ type => 'F32',
+ defaultValue => '0.25f',
+ hints => { shortDescription => "Linear stress on bond multiplier" },
+ },
+ {
+ name => 'angularFactor',
+ type => 'F32',
+ defaultValue => '0.75f',
+ hints => { shortDescription => "Angular stress on bond multiplier" },
+ },
+ {
+ name => 'bondIterationsPerFrame',
+ type => 'U32',
+ defaultValue => '18000',
+ hints => { shortDescription => "Number of bond iterations to perform per frame" },
+ },
+ {
+ name => 'graphReductionLevel',
+ type => 'U32',
+ defaultValue => '3',
+ hints => { shortDescription => "Graph reduction level" },
+ },
+ ]
+ },
+ {
+ name => 'SupportStructure',
+ parameters =>
+ [
+ {
+ name => 'healthMask',
+ type => 'STRING',
+ hints =>
+ {
+ shortDescription => "Name of active health mask",
+ },
+ },
+ {
+ name => 'bondStrength',
+ type => 'F32',
+ defaultValue => '1.0',
+ hints => { shortDescription => "Bond strength" },
+ },
+ {
+ name => 'enableJoint',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints => { shortDescription => "Whether have a joint or not" },
+ },
+ ]
+ },
+ {
+ name => 'Bond',
+ parameters =>
+ [
+ {
+ name => 'name',
+ type => 'STRING',
+ hints =>
+ {
+ shortDescription => "Name of bond",
+ },
+ },
+ {
+ name => 'asset',
+ type => 'I32',
+ hints =>
+ {
+ shortDescription => "ID of the blast asset this bond belongs to",
+ },
+ },
+ {
+ name => 'visible',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "Is this bond visible" },
+ },
+ {
+ name => 'fromChunk',
+ type => 'I32',
+ defaultValue => '-1',
+ hints => { shortDescription => "ID of the chunk this bond is from" },
+ },
+ {
+ name => 'toChunk',
+ type => 'I32',
+ defaultValue => '-1',
+ hints => { shortDescription => "ID of the chunk this bond is to" },
+ },
+ {
+ name => 'support',
+ type => 'SupportStructure',
+ },
+ ]
+ },
+ {
+ name => 'Chunk',
+ parameters =>
+ [
+ {
+ name => 'ID',
+ type => 'I32',
+ defaultValue => '-1',
+ hints => { shortDescription => "ID of this chunk" },
+ },
+ {
+ name => 'parentID',
+ type => 'I32',
+ defaultValue => '-1',
+ hints => { shortDescription => "ID of parent chunk" },
+ },
+ {
+ name => 'name',
+ type => 'STRING',
+ hints =>
+ {
+ shortDescription => "Name of chunk",
+ },
+ },
+ {
+ name => 'asset',
+ type => 'I32',
+ hints =>
+ {
+ shortDescription => "ID of the blast asset this chunk belongs to",
+ },
+ },
+ {
+ name => 'visible',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "Is this chunk visible" },
+ },
+ {
+ name => 'support',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "Is this chunk a support chunk" },
+ },
+ {
+ name => 'staticFlag',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints => { shortDescription => "Is this chunk static" },
+ },
+ {
+ name => 'graphicsMesh',
+ type => 'GraphicsMesh',
+ hints => { shortDescription => "Graphics mesh of this chunk" },
+ },
+ ]
+ },
+ {
+ name => 'DamageStruct',
+ parameters =>
+ [
+ {
+ name => 'damageRadius',
+ type => 'F32',
+ defaultValue => '5.0f',
+ hints => { shortDescription => "Damage radius (Mouse WH)" },
+ },
+ {
+ name => 'continuously',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints => { shortDescription => "Damage continuously" },
+ },
+ ]
+ },
+ {
+ name => 'DefaultDamage',
+ parameters =>
+ [
+ {
+ name => 'damageAmount',
+ type => 'F32',
+ defaultValue => '100.0f',
+ hints => { shortDescription => "Damage Amount" },
+ },
+ {
+ name => 'explosiveImpulse',
+ type => 'F32',
+ defaultValue => '100.0f',
+ hints => { shortDescription => "Explosive impulse" },
+ },
+ {
+ name => 'stressDamageForce',
+ type => 'F32',
+ defaultValue => '1.0f',
+ hints => { shortDescription => "Stress damage force" },
+ },
+ {
+ name => 'damageProfile',
+ type => 'U32',
+ defaultValue => '0',
+ hints => { shortDescription => "FallOff" },
+ },
+ {
+ name => 'damageStructs',
+ type => 'DamageStruct',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Damage Structs",
+ },
+ },
+ ]
+ },
+ {
+ name => 'BlastAsset',
+ parameters =>
+ [
+ {
+ name => 'ID',
+ type => 'I32',
+ defaultValue => '-1',
+ hints => { shortDescription => "ID of this asset" },
+ },
+ {
+ name => 'name',
+ type => 'STRING',
+ hints =>
+ {
+ shortDescription => "Name of this blast asset",
+ },
+ },
+ {
+ name => 'visible',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "Is this blast asset visible" },
+ },
+ {
+ name => 'stressSolver',
+ type => 'StressSolver',
+ },
+ {
+ name => 'activeUserPreset',
+ type => 'STRING',
+ hints => { shortDescription => "Name of active user preset" },
+ },
+ {
+ name => 'fbx',
+ type => 'STRING',
+ hints => { shortDescription => "FBX export asset path" },
+ },
+ {
+ name => 'exportFBX',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints => { shortDescription => "Is this blast asset export FBX" },
+ },
+ {
+ name => 'obj',
+ type => 'STRING',
+ hints => { shortDescription => "OBJ export asset path" },
+ },
+ {
+ name => 'exportOBJ',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints => { shortDescription => "Is this blast asset export OBJ" },
+ },
+ {
+ name => 'collision',
+ type => 'STRING',
+ hints => { shortDescription => "Collision export asset path" },
+ },
+ {
+ name => 'exportCollision',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints => { shortDescription => "Is this blast asset export Collision" },
+ },
+ {
+ name => 'llasset',
+ type => 'STRING',
+ hints => { shortDescription => "LLAsset export asset path" },
+ },
+ {
+ name => 'exportLLAsset',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints => { shortDescription => "Is this blast asset export LLAsset" },
+ },
+ {
+ name => 'tkasset',
+ type => 'STRING',
+ hints => { shortDescription => "TKAsset export asset path" },
+ },
+ {
+ name => 'exportTKAsset',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints => { shortDescription => "Is this blast asset export TKAsset" },
+ },
+ {
+ name => 'bpxa',
+ type => 'STRING',
+ hints => { shortDescription => "Blast export asset path" },
+ },
+ {
+ name => 'exportBPXA',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints => { shortDescription => "Is this blast asset export BPXA" },
+ },
+ ]
+ },
+ {
+ name => 'Transform',
+ parameters =>
+ [
+ {
+ name => 'position',
+ type => 'VEC3',
+ defaultValue => '0',
+ hints =>
+ {
+ shortDescription => "Position"
+ },
+ },
+ {
+ name => 'rotation',
+ type => 'VEC4',
+ defaultValue => '0',
+ hints =>
+ {
+ shortDescription => "Rotation"
+ },
+ },
+ ]
+ },
+ {
+ name => 'BlastAssetInstance',
+ parameters =>
+ [
+ {
+ name => 'name',
+ type => 'STRING',
+ hints =>
+ {
+ shortDescription => "Name of blast asset instance",
+ },
+ },
+ {
+ name => 'visible',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints => { shortDescription => "Is this bond visible" },
+ },
+ {
+ name => 'asset',
+ type => 'I32',
+ hints =>
+ {
+ shortDescription => "ID of the blast asset this instance created by",
+ },
+ },
+ {
+ name => 'transform',
+ type => 'Transform',
+ hints =>
+ {
+ shortDescription => "Transform of blast asset instance",
+ },
+ },
+ {
+ name => 'exMaterial',
+ type => 'STRING',
+ defaultValue => '',
+ hints => { shortDescription => "External material of blast asset instance" },
+ },
+ {
+ name => 'inMaterial',
+ type => 'STRING',
+ defaultValue => '',
+ hints => { shortDescription => "Internal material of blast asset instance" },
+ },
+ ]
+ },
+ {
+ name => 'Blast',
+ parameters =>
+ [
+ {
+ name => 'fileReferences',
+ type => 'BlastFileReferences',
+ },
+ {
+ name => 'blastAssets',
+ type => 'BlastAsset',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Blast assets",
+ },
+ },
+ {
+ name => 'blastAssetInstances',
+ type => 'BlastAssetInstance',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Blast asset instances",
+ },
+ },
+ {
+ name => 'chunks',
+ type => 'Chunk',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Chunks",
+ },
+ },
+ {
+ name => 'bonds',
+ type => 'Bond',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Bonds",
+ },
+ },
+ {
+ name => 'healthMask',
+ type => 'STRING',
+ hints =>
+ {
+ shortDescription => "Health mask file path",
+ },
+ },
+ ]
+ },
+ {
+ name => 'FractureGeneral',
+ parameters =>
+ [
+ {
+ name => 'fracturePreset',
+ type => 'STRING',
+ hints => { shortDescription => "Name of fracture preset" },
+ },
+ {
+ name => 'fractureType',
+ type => 'I32',
+ defaultValue => '-1',
+ hints => { shortDescription => "Index of fracture type" },
+ },
+ {
+ name => 'applyMaterial',
+ type => 'I32',
+ defaultValue => '-1',
+ hints => { shortDescription => "Apply material" },
+ },
+ {
+ name => 'autoSelectNewChunks',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints => { shortDescription => "Auto Select New Chunks" },
+ },
+ {
+ name => 'selectionDepthTest',
+ type => 'BOOL',
+ defaultValue => 'true',
+ hints =>
+ {
+ shortDescription => "Selection Depth Test",
+ },
+ },
+ ]
+ },
+ {
+ name => 'FractureVisualization',
+ parameters =>
+ [
+ {
+ name => 'fracturePreview',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints =>
+ {
+ shortDescription => "Show fracture preview",
+ },
+ },
+ {
+ name => 'displayFractureWidget',
+ type => 'BOOL',
+ defaultValue => 'false',
+ hints =>
+ {
+ shortDescription => "Display fracture widget",
+ },
+ },
+ ]
+ },
+ {
+ name => 'Voronoi',
+ parameters =>
+ [
+ {
+ name => 'siteGeneration',
+ type => 'I32',
+ defaultValue => '-1',
+ hints => { shortDescription => "Index of site generation" },
+ },
+ {
+ name => 'numSites',
+ type => 'U32',
+ defaultValue => '5',
+ hints => { shortDescription => "Number of generated sites for uniform site generation method" },
+ },
+ {
+ name => 'numberOfClusters',
+ type => 'U32',
+ defaultValue => '1',
+ hints => { shortDescription => "Number of generated clusters" },
+ },
+ {
+ name => 'sitesPerCluster',
+ type => 'U32',
+ defaultValue => '1.0f',
+ hints => { shortDescription => "Number of sites in each cluster" },
+ },
+ {
+ name => 'clusterRadius',
+ type => 'F32',
+ defaultValue => '1.0f',
+ hints => { shortDescription => "Voronoi cells cluster radius" },
+ },
+ ]
+ },
+ {
+ name => 'Slice',
+ parameters =>
+ [
+ {
+ name => 'numSlicesX',
+ type => 'U32',
+ defaultValue => '1',
+ hints => { shortDescription => "Number of slices along X axis" },
+ },
+ {
+ name => 'numSlicesY',
+ type => 'U32',
+ defaultValue => '1',
+ hints => { shortDescription => "Number of slices along Z axis" },
+ },
+ {
+ name => 'numSlicesZ',
+ type => 'U32',
+ defaultValue => '1',
+ hints => { shortDescription => "Number of slices along Z axis" },
+ },
+ {
+ name => 'offsetVariation',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Offset of variation" },
+ },
+ {
+ name => 'rotationVariation',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Rotation of variation" },
+ },
+ {
+ name => 'noiseAmplitude',
+ type => 'F32',
+ defaultValue => '0.0f',
+ hints => { shortDescription => "Noise of amplitude" },
+ },
+ {
+ name => 'noiseFrequency',
+ type => 'F32',
+ defaultValue => '1.0f',
+ hints => { shortDescription => "Noise of frequency" },
+ },
+ {
+ name => 'noiseOctaveNumber',
+ type => 'U32',
+ defaultValue => '1',
+ hints => { shortDescription => "Noise octave number, which declares how many octaves of noise will be summed to form final noise function" },
+ },
+ {
+ name => 'noiseSeed',
+ type => 'U32',
+ defaultValue => '1',
+ hints => { shortDescription => "Noise of seed" },
+ },
+ {
+ name => 'surfaceResolution',
+ type => 'I32',
+ defaultValue => '1',
+ hints => { shortDescription => "Cutting surface resolution" },
+ },
+ ]
+ },
+ {
+ name => 'Fracture',
+ parameters =>
+ [
+ {
+ name => 'general',
+ type => 'FractureGeneral',
+ },
+ {
+ name => 'visualization',
+ type => 'FractureVisualization',
+ },
+ {
+ name => 'voronoi',
+ type => 'Voronoi',
+ },
+ {
+ name => 'slice',
+ type => 'Slice',
+ },
+ ]
+ },
+ {
+ name => 'Filter',
+ parameters =>
+ [
+ {
+ name => 'activeFilter',
+ type => 'STRING',
+ hints => { shortDescription => "Name of active filter preset" },
+ },
+ {
+ name => 'filterRestrictions',
+ type => 'STRING',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Filter restrictions",
+ },
+ },
+ ]
+ },
+ ],
+
+ parameters =>
+ [
+ {
+ name => 'camera',
+ type => 'Camera',
+ },
+ {
+ name => 'cameraBookmarks',
+ type => 'CameraBookmark',
+ isArray => 1,
+ arraySize => '-1',
+ hints => { shortDescription => "All camera bookmarks" },
+ },
+ {
+ name => 'lightCamera',
+ type => 'Camera',
+ },
+ {
+ name => 'windCamera',
+ type => 'Camera',
+ },
+ {
+ name => 'graphicsMaterials',
+ type => 'GraphicsMaterial',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "Graphics materials",
+ },
+ },
+ {
+ name => 'scene',
+ type => 'Scene',
+ },
+ {
+ name => 'renderer',
+ type => 'Renderer',
+ },
+ {
+ name => 'blast',
+ type => 'Blast',
+ },
+ {
+ name => 'fracture',
+ type => 'Fracture',
+ },
+ {
+ name => 'defaultDamage',
+ type => 'DefaultDamage',
+ },
+ {
+ name => 'filter',
+ type => 'Filter',
+ },
+ ]
+}
diff --git a/tools/ArtistTools/source/BlastPlugin/Parameters/HackNvParamBug.cpp b/tools/ArtistTools/source/BlastPlugin/Parameters/HackNvParamBug.cpp
new file mode 100644
index 0000000..6017a75
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/Parameters/HackNvParamBug.cpp
@@ -0,0 +1,25 @@
+#include <string.h>
+#include "BlastProjectParameters.h"
+
+int GetHackElementSize(const char* data)
+{
+ if (strstr(data, "graphicsMesh.materialAssignments") != nullptr)
+ return sizeof(nvidia::parameterized::BlastProjectParametersNS::MaterialAssignments_Type);
+ if (strstr(data, "graphicsMesh.positions") != nullptr)
+ return sizeof(nvidia::NvVec3);
+ if (strstr(data, "graphicsMesh.normals") != nullptr)
+ return sizeof(nvidia::NvVec3);
+ if (strstr(data, "graphicsMesh.texcoords") != nullptr)
+ return sizeof(nvidia::NvVec2);
+ if (strstr(data, "graphicsMesh.positionIndexes") != nullptr)
+ return sizeof(int32_t);
+ if (strstr(data, "graphicsMesh.normalIndexes") != nullptr)
+ return sizeof(int32_t);
+ if (strstr(data, "graphicsMesh.texcoordIndexes") != nullptr)
+ return sizeof(int32_t);
+ if (strstr(data, "graphicsMesh.materialIDs") != nullptr)
+ return sizeof(int32_t);
+ if (strstr(data, "filter.filters[0].depthFilters") != nullptr)
+ return sizeof(uint32_t);
+ return 0;
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.cpp b/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.cpp
index 36d78cc..ebe8f3d 100644
--- a/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.cpp
@@ -42,13 +42,17 @@
#include <QtWidgets/QMessageBox>
#include "AppMainWindow.h"
#include "FoundationHolder.h"
+#include <limits>
+#include "BlastSceneTree.h"
using namespace nvidia;
using namespace nvidia::parameterized;
-
+using namespace nvidia::parameterized::BlastProjectParametersNS;
struct ProjectParamsContext* g_projectParamsContext = nullptr;
-const char* USER_PRESET_PATH = ".\\BlastUserPreset.userPreset";
+const char* USER_PRESET = "UserPreset.userPreset";
+const char* FRACTURE_PRESET = "FracturePreset.fracturePreset";
+const char* FILTER_PRESET = "FilterPreset.filterPreset";
struct ProjectParamsContext
{
@@ -65,75 +69,110 @@ void freeString(NvParameterized::DummyStringStruct& str)
void freeBlast(BPPGraphicsMesh& data)
{
- freeString(data.name);
+ delete[] data.materialAssignments.buf;
+ data.materialAssignments.buf = nullptr;
+ data.materialAssignments.arraySizes[0] = 0;
+
+ delete[] data.positions.buf;
+ data.positions.buf = nullptr;
+ data.positions.arraySizes[0] = 0;
+
+ delete[] data.normals.buf;
+ data.normals.buf = nullptr;
+ data.normals.arraySizes[0] = 0;
+
+ delete[] data.tangents.buf;
+ data.tangents.buf = nullptr;
+ data.tangents.arraySizes[0] = 0;
+
+ delete[] data.texcoords.buf;
+ data.texcoords.buf = nullptr;
+ data.texcoords.arraySizes[0] = 0;
+
+ delete data.positions.buf;
+ data.positions.buf = nullptr;
+ data.positions.arraySizes[0] = 0;
+
+ delete[] data.positionIndexes.buf;
+ data.positionIndexes.buf = nullptr;
+ data.positionIndexes.arraySizes[0] = 0;
+
+ delete[] data.normalIndexes.buf;
+ data.normalIndexes.buf = nullptr;
+ data.normalIndexes.arraySizes[0] = 0;
+
+ delete[] data.tangentIndexes.buf;
+ data.tangentIndexes.buf = nullptr;
+ data.tangentIndexes.arraySizes[0] = 0;
+
+ delete[] data.texcoordIndexes.buf;
+ data.texcoordIndexes.buf = nullptr;
+ data.texcoordIndexes.arraySizes[0] = 0;
+
+ delete[] data.materialIDs.buf;
+ data.materialIDs.buf = nullptr;
+ data.materialIDs.arraySizes[0] = 0;
}
void freeBlast(BPPChunk& data)
{
freeString(data.name);
- freeString(data.asset);
+ freeBlast(data.graphicsMesh);
}
void freeBlast(BPPBond& data)
{
freeString(data.name);
- freeString(data.asset);
}
void freeBlast(BPPAsset& data)
{
- freeString(data.path);
+ freeString(data.name);
+ freeString(data.fbx);
+ freeString(data.obj);
+ freeString(data.collision);
+ freeString(data.llasset);
+ freeString(data.tkasset);
+ freeString(data.bpxa);
}
void freeBlast(BPPAssetInstance& data)
{
freeString(data.name);
- freeString(data.source);
-}
-
-void freeBlast(BPPComposite& data)
-{
- freeString(data.composite);
-
- freeBlast(data.blastAssetInstances);
- freeBlast(data.landmarks);
+ freeString(data.exMaterial);
+ freeString(data.inMaterial);
}
void freeBlast(BPPBlast& data)
{
freeString(data.fileReferences.fbxSourceAsset);
- freeString(data.fileReferences.fbx);
- freeString(data.fileReferences.blast);
- freeString(data.fileReferences.collision);
- freeBlast(data.composite);
freeBlast(data.blastAssets);
+ freeBlast(data.blastAssetInstances);
freeBlast(data.chunks);
freeBlast(data.bonds);
}
-void freeBlast(BPPLandmark& data)
+void freeBlast(BPPGraphicsMaterial& data)
{
freeString(data.name);
+ freeString(data.diffuseTextureFilePath);
+ freeString(data.specularTextureFilePath);
+ freeString(data.normalTextureFilePath);
}
-void freeBlast(BPPStringArray& data)
+void freeBlast(BPPDefaultDamage& data)
{
- for (int i = 0; i < data.arraySizes[0]; ++i)
- {
- freeString(data.buf[i]);
- }
-
- delete[] data.buf;
- data.buf = nullptr;
- data.arraySizes[0] = 0;
+ delete[] data.damageStructs.buf;
+ data.damageStructs.buf = nullptr;
+ data.damageStructs.arraySizes[0] = 0;
}
-void freeBlast(BPPGraphicsMeshArray& data)
+void freeBlast(BPPStringArray& data)
{
for (int i = 0; i < data.arraySizes[0]; ++i)
{
- freeBlast(data.buf[i]);
+ freeString(data.buf[i]);
}
delete[] data.buf;
@@ -189,7 +228,7 @@ void freeBlast(BPPAssetInstanceArray& data)
data.arraySizes[0] = 0;
}
-void freeBlast(BPPLandmarkArray& data)
+void freeBlast(BPPGraphicsMaterialArray& data)
{
for (int i = 0; i < data.arraySizes[0]; ++i)
{
@@ -220,6 +259,70 @@ void copy(NvParameterized::DummyStringStruct& dest, NvParameterized::DummyString
copy(dest, source.buf);
}
+bool isItemExist(BPPStringArray& dest, const char* item)
+{
+ if (nullptr == item || 0 == strlen(item))
+ {
+ return false;
+ }
+
+ for (int i = 0; i < dest.arraySizes[0]; ++i)
+ {
+ NvParameterized::DummyStringStruct& curItem = dest.buf[i];
+
+ if (nvidia::shdfnd::strcmp(curItem.buf, item) == 0)
+ return true;
+ }
+
+ return false;
+}
+
+void addItem(BPPStringArray& dest, const char* item)
+{
+ if (nullptr == item || 0 == strlen(item))
+ {
+ return;
+ }
+
+ NvParameterized::DummyStringStruct* oldBuf = dest.buf;
+ dest.buf = new NvParameterized::DummyStringStruct[dest.arraySizes[0] + 1];
+ int i = 0;
+ for (; i < dest.arraySizes[0]; ++i)
+ {
+ copy(dest.buf[i], oldBuf[i]);
+ }
+
+ NvParameterized::DummyStringStruct& newItem = dest.buf[i];
+ copy(newItem, item);
+ dest.arraySizes[0] += 1;
+
+ delete[] oldBuf;
+}
+
+void removeItem(BPPStringArray& dest, const char* item)
+{
+ if (!isItemExist(dest, item))
+ {
+ return;
+ }
+
+ NvParameterized::DummyStringStruct* oldBuf = dest.buf;
+ dest.buf = new NvParameterized::DummyStringStruct[dest.arraySizes[0] - 1];
+
+ int index = 0;
+ for (int i = 0; i < dest.arraySizes[0]; ++i)
+ {
+ if (nvidia::shdfnd::strcmp(oldBuf[i].buf, item) != 0)
+ {
+ NvParameterized::DummyStringStruct& newItem = dest.buf[index++];
+ NvParameterized::DummyStringStruct& oldItem = oldBuf[i];
+ copy(newItem, oldItem);
+ }
+ }
+ dest.arraySizes[0] -= 1;
+ delete[] oldBuf;
+}
+
void copy(BPPStringArray& dest, BPPStringArray& source)
{
{
@@ -272,7 +375,7 @@ void copy(BPPGraphicsMaterialArray& dest, BPPGraphicsMaterialArray& source)
}
}
-void copy(BPPGraphicsMeshArray& dest, BPPGraphicsMeshArray& source)
+void copy(BPPMaterialAssignmentsArray& dest, BPPMaterialAssignmentsArray& source)
{
delete[] dest.buf;
dest.buf = nullptr;
@@ -280,17 +383,13 @@ void copy(BPPGraphicsMeshArray& dest, BPPGraphicsMeshArray& source)
if (source.arraySizes[0] > 0)
{
- dest.buf = new BPPGraphicsMesh[source.arraySizes[0]];
+ dest.buf = new BPPMaterialAssignments[source.arraySizes[0]];
for (int i = 0; i < source.arraySizes[0]; ++i)
{
- BPPGraphicsMesh& destItem = dest.buf[i];
- BPPGraphicsMesh& sourceItem = source.buf[i];
-
- destItem.name.buf = nullptr;
+ BPPMaterialAssignments& destItem = dest.buf[i];
+ BPPMaterialAssignments& sourceItem = source.buf[i];
- copy(destItem.name, sourceItem.name);
- destItem.visible = sourceItem.visible;
- copy(destItem.materialAssignments, sourceItem.materialAssignments);
+ copy(destItem, sourceItem);
}
dest.arraySizes[0] = source.arraySizes[0];
}
@@ -364,8 +463,7 @@ void copy(BPPChunkArray& dest, BPPChunkArray& source)
BPPChunk& destItem = dest.buf[i];
BPPChunk& sourceItem = source.buf[i];
- destItem.name.buf = nullptr;
- destItem.asset.buf = nullptr;
+ init(destItem);
copy(destItem, sourceItem);
}
@@ -385,31 +483,7 @@ void copy(BPPBondArray& dest, BPPBondArray& source)
BPPBond& destItem = dest.buf[i];
BPPBond& sourceItem = source.buf[i];
- destItem.name.buf = nullptr;
- destItem.asset.buf = nullptr;
- destItem.support.healthMask.buf = nullptr;
-
- copy(destItem, sourceItem);
- }
- dest.arraySizes[0] = source.arraySizes[0];
- }
-}
-
-void copy(BPPProjectileArray& dest, BPPProjectileArray& source)
-{
- delete[] dest.buf;
- dest.buf = nullptr;
- dest.arraySizes[0] = 0;
-
- if (source.arraySizes[0] > 0)
- {
- dest.buf = new BPPProjectile[source.arraySizes[0]];
- for (int i = 0; i < source.arraySizes[0]; ++i)
- {
- BPPProjectile& destItem = dest.buf[i];
- BPPProjectile& sourceItem = source.buf[i];
-
- destItem.name.buf = nullptr;
+ init(destItem);
copy(destItem, sourceItem);
}
@@ -431,8 +505,7 @@ void copy(BPPAssetArray& dest, BPPAssetArray& source)
BPPAsset& destItem = dest.buf[i];
BPPAsset& sourceItem = source.buf[i];
- destItem.path.buf = nullptr;
- destItem.activePreset.buf = nullptr;
+ init(destItem);
copy(destItem, sourceItem);
}
@@ -454,8 +527,7 @@ void copy(BPPAssetInstanceArray& dest, BPPAssetInstanceArray& source)
BPPAssetInstance& destItem = dest.buf[i];
BPPAssetInstance& sourceItem = source.buf[i];
- destItem.name.buf = nullptr;
- destItem.source.buf = nullptr;
+ init(destItem);
copy(destItem, sourceItem);
}
@@ -463,7 +535,7 @@ void copy(BPPAssetInstanceArray& dest, BPPAssetInstanceArray& source)
}
}
-void copy(BPPLandmarkArray& dest, BPPLandmarkArray& source)
+void copy(BPPI32Array& dest, BPPI32Array& source)
{
delete[] dest.buf;
dest.buf = nullptr;
@@ -471,21 +543,19 @@ void copy(BPPLandmarkArray& dest, BPPLandmarkArray& source)
if (source.arraySizes[0] > 0)
{
- dest.buf = new BPPLandmark[source.arraySizes[0]];
+ dest.buf = new int32_t[source.arraySizes[0]];
for (int i = 0; i < source.arraySizes[0]; ++i)
{
- BPPLandmark& destItem = dest.buf[i];
- BPPLandmark& sourceItem = source.buf[i];
-
- destItem.name.buf = nullptr;
+ int32_t& destItem = dest.buf[i];
+ int32_t& sourceItem = source.buf[i];
- copy(destItem, sourceItem);
+ destItem = sourceItem;
}
dest.arraySizes[0] = source.arraySizes[0];
}
}
-void copy(BPPU32Array& dest, BPPU32Array& source)
+void copy(BPPVEC3Array& dest, BPPVEC3Array& source)
{
delete[] dest.buf;
dest.buf = nullptr;
@@ -493,11 +563,11 @@ void copy(BPPU32Array& dest, BPPU32Array& source)
if (source.arraySizes[0] > 0)
{
- dest.buf = new uint32_t[source.arraySizes[0]];
+ dest.buf = new nvidia::NvVec3[source.arraySizes[0]];
for (int i = 0; i < source.arraySizes[0]; ++i)
{
- uint32_t& destItem = dest.buf[i];
- uint32_t& sourceItem = source.buf[i];
+ nvidia::NvVec3& destItem = dest.buf[i];
+ nvidia::NvVec3& sourceItem = source.buf[i];
destItem = sourceItem;
}
@@ -505,7 +575,7 @@ void copy(BPPU32Array& dest, BPPU32Array& source)
}
}
-void copy(BPPFilterPresetArray& dest, BPPFilterPresetArray& source)
+void copy(BPPVEC2Array& dest, BPPVEC2Array& source)
{
delete[] dest.buf;
dest.buf = nullptr;
@@ -513,16 +583,13 @@ void copy(BPPFilterPresetArray& dest, BPPFilterPresetArray& source)
if (source.arraySizes[0] > 0)
{
- dest.buf = new BPPFilterPreset[source.arraySizes[0]];
+ dest.buf = new nvidia::NvVec2[source.arraySizes[0]];
for (int i = 0; i < source.arraySizes[0]; ++i)
{
- BPPFilterPreset& destItem = dest.buf[i];
- BPPFilterPreset& sourceItem = source.buf[i];
-
- destItem.name.buf = nullptr;
- destItem.depthFilters.buf = nullptr;
+ nvidia::NvVec2& destItem = dest.buf[i];
+ nvidia::NvVec2& sourceItem = source.buf[i];
- copy(destItem, sourceItem);
+ destItem = sourceItem;
}
dest.arraySizes[0] = source.arraySizes[0];
}
@@ -565,23 +632,23 @@ void copy(BPPGraphicsMaterial& dest, BPPGraphicsMaterial& source)
void copy(BPPGraphicsMesh& dest, BPPGraphicsMesh& source)
{
- copy(dest.name, source.name);
- dest.visible = source.visible;
copy(dest.materialAssignments, source.materialAssignments);
+ copy(dest.positions, source.positions);
+ copy(dest.normals, source.normals);
+ copy(dest.tangents, source.tangents);
+ copy(dest.texcoords, source.texcoords);
+ dest.vertextCountInFace = source.vertextCountInFace;
+ copy(dest.positionIndexes, source.positionIndexes);
+ copy(dest.normalIndexes, source.normalIndexes);
+ copy(dest.tangentIndexes, source.tangentIndexes);
+ copy(dest.texcoordIndexes, source.texcoordIndexes);
+ copy(dest.materialIDs, source.materialIDs);
}
void copy(BPPMaterialAssignments& dest, BPPMaterialAssignments& source)
{
- dest.materialIndexes[0] = source.materialIndexes[0];
- dest.materialIndexes[1] = source.materialIndexes[1];
- dest.materialIndexes[2] = source.materialIndexes[2];
- dest.materialIndexes[3] = source.materialIndexes[3];
-}
-
-void copy(BPPProjectile& dest, BPPProjectile& source)
-{
- copy(dest.name, source.name);
- dest.visible = source.visible;
+ dest.libraryMaterialID = source.libraryMaterialID;
+ dest.faceMaterialID = source.faceMaterialID;
}
void copy(BPPSupportStructure& dest, BPPSupportStructure& source)
@@ -596,30 +663,23 @@ void copy(BPPChunk& dest, BPPChunk& source)
dest.ID = source.ID;
dest.parentID = source.parentID;
copy(dest.name, source.name);
- copy(dest.asset, source.asset);
+ dest.asset = source.asset;
dest.visible = source.visible;
dest.support = source.support;
dest.staticFlag = source.staticFlag;
+ copy(dest.graphicsMesh, source.graphicsMesh);
}
void copy(BPPBond& dest, BPPBond& source)
{
copy(dest.name, source.name);
- copy(dest.asset, source.asset);
+ dest.asset = source.asset;
dest.visible = source.visible;
dest.fromChunk = source.fromChunk;
dest.toChunk = source.toChunk;
copy(dest.support, source.support);
}
-void copy(BPPLandmark& dest, BPPLandmark& source)
-{
- copy(dest.name, source.name);
- dest.visible = source.visible;
- dest.enable = source.enable;
- dest.radius = source.radius;
-}
-
void copy(BPPRenderer& dest, BPPRenderer& source)
{
dest.renderFps = source.renderFps;
@@ -656,110 +716,120 @@ void copy(BPPRenderer& dest, BPPRenderer& source)
void copy(BPPStressSolver& dest, BPPStressSolver& source)
{
- dest.solverMode = source.solverMode;
+ dest.hardness = source.hardness;
dest.linearFactor = source.linearFactor;
dest.angularFactor = source.angularFactor;
- dest.meanError = source.meanError;
- dest.varianceError = source.varianceError;
- dest.bondsPerFrame = source.bondsPerFrame;
- dest.bondsIterations = source.bondsIterations;
+ dest.bondIterationsPerFrame = source.bondIterationsPerFrame;
+ dest.graphReductionLevel = source.graphReductionLevel;
}
void copy(BPPAsset& dest, BPPAsset& source)
{
- copy(dest.path, source.path);
+ dest.ID = source.ID;
+ copy(dest.name, source.name);
dest.visible = source.visible;
dest.stressSolver = source.stressSolver;
- copy(dest.activePreset, source.activePreset);
- dest.defaultDamage = source.defaultDamage;
+ copy(dest.activeUserPreset, source.activeUserPreset);
+ copy(dest.fbx, source.fbx);
+ copy(dest.obj, source.obj);
+ copy(dest.collision, source.collision);
+ copy(dest.llasset, source.llasset);
+ copy(dest.tkasset, source.tkasset);
+ copy(dest.bpxa, source.bpxa);
+ dest.exportFBX = source.exportFBX;
+ dest.exportOBJ = source.exportOBJ;
+ dest.exportCollision = source.exportCollision;
+ dest.exportLLAsset = source.exportLLAsset;
+ dest.exportTKAsset = source.exportTKAsset;
+ dest.exportBPXA = source.exportBPXA;
}
void copy(BPPAssetInstance& dest, BPPAssetInstance& source)
{
copy(dest.name, source.name);
dest.visible = source.visible;
- copy(dest.source, source.source);
+ dest.asset = source.asset;
dest.transform = source.transform;
-}
-
-void copy(BPPComposite& dest, BPPComposite& source)
-{
- copy(dest.composite, source.composite);
- dest.visible = source.visible;
- copy(dest.blastAssetInstances, source.blastAssetInstances);
- dest.bondThreshold = source.bondThreshold;
- dest.bondStrength = source.bondStrength;
- copy(dest.landmarks, source.landmarks);
+ copy(dest.exMaterial, source.exMaterial);
+ copy(dest.inMaterial, source.inMaterial);
}
void copy(BPPBlast& dest, BPPBlast& source)
{
copy(dest.fileReferences.fbxSourceAsset, source.fileReferences.fbxSourceAsset);
- copy(dest.fileReferences.fbx, source.fileReferences.fbx);
- copy(dest.fileReferences.blast, source.fileReferences.blast);
- copy(dest.fileReferences.collision, source.fileReferences.collision);
- copy(dest.composite, source.composite);
copy(dest.blastAssets, source.blastAssets);
+ copy(dest.blastAssetInstances, source.blastAssetInstances);
copy(dest.chunks, source.chunks);
copy(dest.bonds, source.bonds);
- copy(dest.projectiles, source.projectiles);
- copy(dest.graphicsMeshes, source.graphicsMeshes);
-
- copy(dest.userPreset, source.userPreset);
copy(dest.healthMask, source.healthMask);
}
-void copy(BPPFilter& dest, BPPFilter& source)
+void copy(BPPFractureGeneral& dest, BPPFractureGeneral& source)
{
- dest.activeFilter = source.activeFilter;
- copy(dest.filters, source.filters);
+ copy(dest.fracturePreset, source.fracturePreset);
+ dest.fractureType = source.fractureType;
+ dest.applyMaterial = source.applyMaterial;
+ dest.autoSelectNewChunks = source.autoSelectNewChunks;
+ dest.selectionDepthTest = source.selectionDepthTest;
}
void copy(BPPVoronoi& dest, BPPVoronoi& source)
{
- dest.numSites = source.numSites;
dest.siteGeneration = source.siteGeneration;
- dest.gridSize = source.gridSize;
- dest.gridScale = source.gridScale;
- dest.amplitude = source.amplitude;
-
- dest.frequency = source.frequency;
- copy(dest.paintMasks, source.paintMasks);
- dest.activePaintMask = source.activePaintMask;
- copy(dest.meshCutters, source.meshCutters);
- dest.activeMeshCutter = source.activeMeshCutter;
- dest.fractureInsideCutter = source.fractureInsideCutter;
- dest.fractureOutsideCutter = source.fractureOutsideCutter;
- copy(dest.textureSites, source.textureSites);
- dest.numTextureSites = source.numTextureSites;
-}
-
-void copy(BPPCutoutProjection& dest, BPPCutoutProjection& source)
-{
- copy(dest.textures, source.textures);
- dest.cutoutType = source.cutoutType;
- dest.pixelThreshold = source.pixelThreshold;
- dest.tiled = source.tiled;
- dest.invertU = source.invertU;
- dest.invertV = source.invertV;
+ dest.numSites = source.numSites;
+ dest.numberOfClusters = source.numberOfClusters;
+ dest.sitesPerCluster = source.sitesPerCluster;
+ dest.clusterRadius = source.clusterRadius;
}
void copy(BPPFracture& dest, BPPFracture& source)
{
- dest.activeFractureMethod = source.activeFractureMethod;
- dest.general = source.general;
+ copy(dest.general, source.general);
dest.visualization = source.visualization;
- dest.shellCut = source.shellCut;
copy(dest.voronoi, source.voronoi);
dest.slice = source.slice;
- copy(dest.cutoutProjection, source.cutoutProjection);
}
-void copy(BPPFilterPreset& dest, BPPFilterPreset& source)
+void copy(BPPDefaultDamage& dest, BPPDefaultDamage& source)
{
- copy(dest.name, source.name);
- copy(dest.depthFilters, source.depthFilters);
+ dest.damageAmount = source.damageAmount;
+ dest.explosiveImpulse = source.explosiveImpulse;
+ dest.stressDamageForce = source.stressDamageForce;
+ dest.damageProfile = source.damageProfile;
+
+ int count = source.damageStructs.arraySizes[0];
+
+ if(dest.damageStructs.buf != nullptr && dest.damageStructs.arraySizes[0] != count)
+ {
+ delete[] dest.damageStructs.buf;
+ dest.damageStructs.buf = nullptr;
+ dest.damageStructs.arraySizes[0] = 0;
+ }
+
+ if (count == 0)
+ return;
+
+ if (dest.damageStructs.buf == nullptr)
+ {
+ dest.damageStructs.buf = new BPPDamageStruct[count];
+ dest.damageStructs.arraySizes[0] = count;
+ }
+
+ for (int i = 0; i < count; ++i)
+ {
+ BPPDamageStruct& destItem = dest.damageStructs.buf[i];
+ BPPDamageStruct& sourceItem = source.damageStructs.buf[i];
+
+ destItem.damageRadius = sourceItem.damageRadius;
+ destItem.continuously = sourceItem.continuously;
+ }
+}
+
+void copy(BPPFilter& dest, BPPFilter& source)
+{
+ copy(dest.activeFilter, source.activeFilter);
+ copy(dest.filterRestrictions, source.filterRestrictions);
}
void copy(BPParams& dest, BPParams& source)
@@ -772,10 +842,83 @@ void copy(BPParams& dest, BPParams& source)
dest.scene = source.scene;
copy(dest.renderer, source.renderer);
copy(dest.blast, source.blast);
- copy(dest.filter, source.filter);
copy(dest.fracture, source.fracture);
+ copy(dest.defaultDamage, source.defaultDamage);
+ copy(dest.filter, source.filter);
+}
+
+void merge(BPPAssetArray& dest, BPPAssetArray& source)
+{
+ if (source.arraySizes[0] > 0)
+ {
+ BPPAsset* oriDestArray = dest.buf;
+ int oriCount = dest.arraySizes[0];
+ int srcCount = source.arraySizes[0];
+ dest.buf = new BPPAsset[oriCount + srcCount];
+ int i = 0;
+// std::map<BPPAsset*, BPPAsset*> changeMap;
+ for (; i < oriCount; ++i)
+ {
+ BPPAsset& destItem = dest.buf[i];
+ BPPAsset& oriItem = oriDestArray[i];
+
+ init(destItem);
+ copy(destItem, oriItem);
+// changeMap[&oriItem] = &destItem;
+ }
+// BlastTreeData::ins().refreshProjectDataToNodeMap(changeMap);
+ for (int j = 0; j < srcCount; ++j, ++i)
+ {
+ BPPAsset& destItem = dest.buf[i];
+ BPPAsset& sourceItem = source.buf[j];
+
+ init(destItem);
+ copy(destItem, sourceItem);
+ }
+ for (int m = 0; m < oriCount; ++m)
+ {
+ freeBlast(oriDestArray[m]);
+ }
+ delete[] oriDestArray;
+ dest.arraySizes[0] = oriCount + srcCount;
+ }
+}
+
+void merge(BPPAssetInstanceArray& dest, BPPAssetInstanceArray& source)
+{
+ if (source.arraySizes[0] > 0)
+ {
+ BPPAssetInstance* oriDestArray = dest.buf;
+ int oriCount = dest.arraySizes[0];
+ int srcCount = source.arraySizes[0];
+ dest.buf = new BPPAssetInstance[oriCount + srcCount];
+ int i = 0;
+// std::map<BPPAssetInstance*, BPPAssetInstance*> changeMap;
+ for (; i < oriCount; ++i)
+ {
+ BPPAssetInstance& destItem = dest.buf[i];
+ BPPAssetInstance& oriItem = oriDestArray[i];
+
+ init(destItem);
+ copy(destItem, oriItem);
+// changeMap[&oriItem] = &destItem;
+ }
+// BlastTreeData::ins().refreshProjectDataToNodeMap(changeMap);
+ for (int j = 0; j < srcCount; ++j, ++i)
+ {
+ BPPAssetInstance& destItem = dest.buf[i];
+ BPPAssetInstance& sourceItem = source.buf[j];
- copy(dest.blast.userPreset, USER_PRESET_PATH);
+ init(destItem);
+ copy(destItem, sourceItem);
+ }
+ for (int m = 0; m < oriCount; ++m)
+ {
+ freeBlast(oriDestArray[m]);
+ }
+ delete[] oriDestArray;
+ dest.arraySizes[0] = oriCount + srcCount;
+ }
}
void merge(BPPChunkArray& dest, BPPChunkArray& source)
@@ -792,8 +935,7 @@ void merge(BPPChunkArray& dest, BPPChunkArray& source)
BPPChunk& destItem = dest.buf[i];
BPPChunk& oriItem = oriDestArray[i];
- destItem.name.buf = nullptr;
- destItem.asset.buf = nullptr;
+ init(destItem);
copy(destItem, oriItem);
}
for (int j = 0; j < srcCount; ++j, ++i)
@@ -801,8 +943,7 @@ void merge(BPPChunkArray& dest, BPPChunkArray& source)
BPPChunk& destItem = dest.buf[i];
BPPChunk& sourceItem = source.buf[j];
- destItem.name.buf = nullptr;
- destItem.asset.buf = nullptr;
+ init(destItem);
copy(destItem, sourceItem);
}
for (int m = 0; m < oriCount; ++m)
@@ -828,9 +969,7 @@ void merge(BPPBondArray& dest, BPPBondArray& source)
BPPBond& destItem = dest.buf[i];
BPPBond& oriItem = oriDestArray[i];
- destItem.name.buf = nullptr;
- destItem.asset.buf = nullptr;
- destItem.support.healthMask.buf = nullptr;
+ init(destItem);
copy(destItem, oriItem);
}
for (int j = 0; j < srcCount; ++j, ++i)
@@ -838,9 +977,7 @@ void merge(BPPBondArray& dest, BPPBondArray& source)
BPPBond& destItem = dest.buf[i];
BPPBond& sourceItem = source.buf[j];
- destItem.name.buf = nullptr;
- destItem.asset.buf = nullptr;
- destItem.support.healthMask.buf = nullptr;
+ init(destItem);
copy(destItem, sourceItem);
}
for (int m = 0; m < oriCount; ++m)
@@ -852,25 +989,536 @@ void merge(BPPBondArray& dest, BPPBondArray& source)
}
}
+/*
+void apart(BPPAssetArray& dest, BPPAssetArray& source)
+{
+ if (source.arraySizes[0] == 0)
+ return;
+
+ int destCount = dest.arraySizes[0];
+ int srcCount = source.arraySizes[0];
+ std::vector<int> indexes;
+ for (int i = 0; i < destCount; ++i)
+ {
+ bool find = false;
+ for (int j = 0; j < srcCount; ++j)
+ {
+ if (dest.buf[i].ID == source.buf[j].ID)
+ {
+ find = true;
+ break;
+ }
+ }
+
+ if (!find)
+ {
+ indexes.push_back(i);
+ }
+ }
+
+ int newSize = indexes.size();
+ BPPAsset* newArray = nullptr;
+ if (newSize > 0)
+ {
+ newArray = new BPPAsset[newSize];
+ std::map<BPPAsset*, BPPAsset*> changeMap;
+ for (int n = 0; n < newSize; ++n)
+ {
+ BPPAsset& newItem = newArray[n];
+ BPPAsset& oriItem = dest.buf[indexes[n]];
+ init(newItem);
+ copy(newItem, oriItem);
+ changeMap[&oriItem] = &newItem;
+ }
+ BlastTreeData::ins().refreshProjectDataToNodeMap(changeMap);
+ }
+
+ freeBlast(dest);
+ dest.buf = newArray;
+ dest.arraySizes[0] = newSize;
+}
+
+void apart(BPPAssetInstanceArray& dest, BPPAssetInstanceArray& source)
+{
+ if (source.arraySizes[0] == 0)
+ return;
+
+ int destCount = dest.arraySizes[0];
+ int srcCount = source.arraySizes[0];
+ std::vector<int> indexes;
+ for (int i = 0; i < destCount; ++i)
+ {
+ bool find = false;
+ for (int j = 0; j < srcCount; ++j)
+ {
+ if (::strcmp(dest.buf[i].name.buf, source.buf[j].name.buf) == 0
+ && dest.buf[i].asset == source.buf[j].asset)
+ {
+ find = true;
+ break;
+ }
+ }
+
+ if (!find)
+ {
+ indexes.push_back(i);
+ }
+ }
+
+ int newSize = indexes.size();
+ BPPAssetInstance* newArray = nullptr;
+ if (newSize > 0)
+ {
+ newArray = new BPPAssetInstance[newSize];
+ std::map<BPPAssetInstance*, BPPAssetInstance*> changeMap;
+ for (int n = 0; n < newSize; ++n)
+ {
+ BPPAssetInstance& newItem = newArray[n];
+ BPPAssetInstance& oriItem = dest.buf[indexes[n]];
+ init(newItem);
+ copy(newItem, oriItem);
+ changeMap[&oriItem] = &newItem;
+ }
+ BlastTreeData::ins().refreshProjectDataToNodeMap(changeMap);
+ }
+
+ freeBlast(dest);
+ dest.buf = newArray;
+ dest.arraySizes[0] = newSize;
+}
+
+void apart(BPPChunkArray& dest, BPPChunkArray& source)
+{
+ if (source.arraySizes[0] == 0)
+ return;
+
+ int destCount = dest.arraySizes[0];
+ int srcCount = source.arraySizes[0];
+ std::vector<int> indexes;
+ for (int i = 0; i < destCount; ++i)
+ {
+ bool find = false;
+ for (int j = 0; j < srcCount; ++j)
+ {
+ if (::strcmp(dest.buf[i].name.buf, source.buf[j].name.buf) == 0
+ && dest.buf[i].asset == source.buf[j].asset)
+ {
+ find = true;
+ break;
+ }
+ }
+
+ if (!find)
+ {
+ indexes.push_back(i);
+ }
+ }
+
+ int newSize = indexes.size();
+ BPPChunk* newArray = nullptr;
+ if (newSize > 0)
+ {
+ newArray = new BPPChunk[newSize];
+
+ for (int n = 0; n < newSize; ++n)
+ {
+ BPPChunk& newItem = newArray[n];
+ init(newItem);
+ copy(newItem, dest.buf[indexes[n]]);
+ }
+ }
+
+ freeBlast(dest);
+ dest.buf = newArray;
+ dest.arraySizes[0] = newSize;
+}
+
+void apart(BPPBondArray& dest, BPPBondArray& source)
+{
+ if (source.arraySizes[0] == 0)
+ return;
+
+ int destCount = dest.arraySizes[0];
+ int srcCount = source.arraySizes[0];
+ std::vector<int> indexes;
+ for (int i = 0; i < destCount; ++i)
+ {
+ bool find = false;
+ for (int j = 0; j < srcCount; ++j)
+ {
+ if (::strcmp(dest.buf[i].name.buf, source.buf[j].name.buf) == 0
+ && dest.buf[i].asset == source.buf[j].asset)
+ {
+ find = true;
+ break;
+ }
+ }
+
+ if (!find)
+ {
+ indexes.push_back(i);
+ }
+ }
+
+ int newSize = indexes.size();
+ BPPBond* newArray = nullptr;
+ if (newSize > 0)
+ {
+ newArray = new BPPBond[newSize];
+
+ for (int n = 0; n < newSize; ++n)
+ {
+ BPPBond& newItem = newArray[n];
+ init(newItem);
+ copy(newItem, dest.buf[indexes[n]]);
+ }
+ }
+
+ freeBlast(dest);
+ dest.buf = newArray;
+ dest.arraySizes[0] = newSize;
+}
+
+*/
+void apart(BPPAssetArray& dest, int32_t assetId)
+{
+ if (assetId < 0)
+ {
+ return;
+ }
+
+ int destCount = dest.arraySizes[0];
+ std::vector<int> indexes;
+ for (int i = 0; i < destCount; ++i)
+ {
+ if (dest.buf[i].ID == assetId)
+ {
+ continue;
+ }
+
+ indexes.push_back(i);
+ }
+
+ int newSize = indexes.size();
+ BPPAsset* newArray = nullptr;
+ if (newSize > 0)
+ {
+ newArray = new BPPAsset[newSize];
+// std::map<BPPAsset*, BPPAsset*> changeMap;
+ for (int n = 0; n < newSize; ++n)
+ {
+ BPPAsset& newItem = newArray[n];
+ BPPAsset& oriItem = dest.buf[indexes[n]];
+ init(newItem);
+ copy(newItem, oriItem);
+// changeMap[&oriItem] = &newItem;
+ }
+// BlastTreeData::ins().refreshProjectDataToNodeMap(changeMap);
+ }
+
+ freeBlast(dest);
+ dest.buf = newArray;
+ dest.arraySizes[0] = newSize;
+}
+
+void apart(BPPAssetInstanceArray& dest, int32_t assetId)
+{
+ if (assetId < 0)
+ {
+ return;
+ }
+
+ int destCount = dest.arraySizes[0];
+ std::vector<int> indexes;
+ for (int i = 0; i < destCount; ++i)
+ {
+ if (dest.buf[i].asset == assetId)
+ {
+ continue;
+ }
+
+ indexes.push_back(i);
+ }
+
+ int newSize = indexes.size();
+ BPPAssetInstance* newArray = nullptr;
+ if (newSize > 0)
+ {
+ newArray = new BPPAssetInstance[newSize];
+// std::map<BPPAssetInstance*, BPPAssetInstance*> changeMap;
+ for (int n = 0; n < newSize; ++n)
+ {
+ BPPAssetInstance& newItem = newArray[n];
+ BPPAssetInstance& oriItem = dest.buf[indexes[n]];
+ init(newItem);
+ copy(newItem, oriItem);
+// changeMap[&oriItem] = &newItem;
+ }
+// BlastTreeData::ins().refreshProjectDataToNodeMap(changeMap);
+ }
+
+ freeBlast(dest);
+ dest.buf = newArray;
+ dest.arraySizes[0] = newSize;
+}
+
+void apart(BPPAssetInstanceArray& dest, int32_t assetId, const char* instanceName)
+{
+ if (assetId < 0 || instanceName == nullptr)
+ {
+ return;
+ }
+
+ int destCount = dest.arraySizes[0];
+ std::vector<int> indexes;
+ for (int i = 0; i < destCount; ++i)
+ {
+ if (dest.buf[i].asset == assetId &&
+ ::strcmp(dest.buf[i].name.buf, instanceName) == 0)
+ {
+ continue;
+ }
+
+ indexes.push_back(i);
+ }
+
+ int newSize = indexes.size();
+ BPPAssetInstance* newArray = nullptr;
+ if (newSize > 0)
+ {
+ newArray = new BPPAssetInstance[newSize];
+// std::map<BPPAssetInstance*, BPPAssetInstance*> changeMap;
+ for (int n = 0; n < newSize; ++n)
+ {
+ BPPAssetInstance& newItem = newArray[n];
+ BPPAssetInstance& oriItem = dest.buf[indexes[n]];
+ init(newItem);
+ copy(newItem, oriItem);
+// changeMap[&oriItem] = &newItem;
+ }
+// BlastTreeData::ins().refreshProjectDataToNodeMap(changeMap);
+ }
+
+ freeBlast(dest);
+ dest.buf = newArray;
+ dest.arraySizes[0] = newSize;
+}
+
+void apart(BPPChunkArray& dest, int32_t assetId)
+{
+ if (assetId < 0)
+ {
+ return;
+ }
+
+ int destCount = dest.arraySizes[0];
+ std::vector<int> indexes;
+ for (int i = 0; i < destCount; ++i)
+ {
+ if (dest.buf[i].asset == assetId)
+ {
+ continue;
+ }
+
+ indexes.push_back(i);
+ }
+
+ int newSize = indexes.size();
+ BPPChunk* newArray = nullptr;
+ if (newSize > 0)
+ {
+ newArray = new BPPChunk[newSize];
+// std::map<BPPChunk*, BPPChunk*> changeMap;
+ for (int n = 0; n < newSize; ++n)
+ {
+ BPPChunk& newItem = newArray[n];
+ BPPChunk& oriItem = dest.buf[indexes[n]];
+ init(newItem);
+ copy(newItem, oriItem);
+// changeMap[&oriItem] = &newItem;
+ }
+// BlastTreeData::ins().refreshProjectDataToNodeMap(changeMap);
+ }
+
+ freeBlast(dest);
+ dest.buf = newArray;
+ dest.arraySizes[0] = newSize;
+}
+
+void apart(BPPBondArray& dest, int32_t assetId)
+{
+ if (assetId < 0)
+ {
+ return;
+ }
+
+ int destCount = dest.arraySizes[0];
+ std::vector<int> indexes;
+ for (int i = 0; i < destCount; ++i)
+ {
+ if (dest.buf[i].asset == assetId)
+ {
+ continue;
+ }
+
+ indexes.push_back(i);
+ }
+
+ int newSize = indexes.size();
+ BPPBond* newArray = nullptr;
+ if (newSize > 0)
+ {
+ newArray = new BPPBond[newSize];
+// std::map<BPPBond*, BPPBond*> changeMap;
+ for (int n = 0; n < newSize; ++n)
+ {
+ BPPBond& newItem = newArray[n];
+ BPPBond& oriItem = dest.buf[indexes[n]];
+ init(newItem);
+ copy(newItem, oriItem);
+// changeMap[&oriItem] = &newItem;
+ }
+// BlastTreeData::ins().refreshProjectDataToNodeMap(changeMap);
+ }
+
+ freeBlast(dest);
+ dest.buf = newArray;
+ dest.arraySizes[0] = newSize;
+}
+
void init(BPPStressSolver& param)
{
- param.solverMode = -1;
- param.linearFactor = 0;
- param.angularFactor = 0;
- param.meanError = 0;
- param.varianceError = 0;
- param.bondsPerFrame = 0;
- param.bondsIterations = 0;
+ param.hardness = 1000.0f;
+ param.linearFactor = 0.25f;
+ param.angularFactor = 0.75f;
+ param.bondIterationsPerFrame = 18000;
+ param.graphReductionLevel = 3;
}
void init(BPPGraphicsMaterial& param)
{
+ param.ID = -1;
param.name.buf = nullptr;
param.useTextures = false;
param.diffuseTextureFilePath.buf = nullptr;
param.specularTextureFilePath.buf = nullptr;
param.normalTextureFilePath.buf = nullptr;
- param.specularShininess = 0.0;
+ param.specularShininess = 20.0;
+}
+
+void init(BPPGraphicsMesh& param)
+{
+ param.materialAssignments.buf = 0;
+ param.materialAssignments.arraySizes[0];
+
+ param.positions.buf = nullptr;
+ param.positions.arraySizes[0] = 0;
+
+ param.normals.buf = nullptr;
+ param.normals.arraySizes[0] = 0;
+
+ param.tangents.buf = nullptr;
+ param.tangents.arraySizes[0] = 0;
+
+ param.texcoords.buf = nullptr;
+ param.texcoords.arraySizes[0] = 0;
+
+ init<I32_DynamicArray1D_Type>(param.positionIndexes);
+ init<I32_DynamicArray1D_Type>(param.normalIndexes);
+ init<I32_DynamicArray1D_Type>(param.tangentIndexes);
+ init<I32_DynamicArray1D_Type>(param.texcoordIndexes);
+ init<I32_DynamicArray1D_Type>(param.materialIDs);
+}
+
+void init(BPPBond& param)
+{
+ param.name.buf = nullptr;
+ param.asset = -1;
+ param.visible = true;
+ param.support.healthMask.buf = nullptr;
+ param.support.bondStrength = 1.0;
+ param.support.enableJoint = false;
+}
+
+void init(BPPChunk& param)
+{
+ param.name.buf = nullptr;
+ param.asset = -1;
+ param.visible = true;
+
+ init(param.graphicsMesh);
+}
+
+void init(BPPDefaultDamage& param)
+{
+ /*
+ param.compressiveDamage = 1.0f;
+ param.explosiveImpulse = 100.0f;
+ param.damageRadius = 5.0f;
+ param.stressDamageForce = 1.0f;
+ param.damageProfile = 0;
+ */
+ param.damageStructs.buf = nullptr;
+ param.damageStructs.arraySizes[0] = 0;
+ param.damageProfile = -1;
+}
+
+void init(BPPAsset& param)
+{
+ param.ID = -1;
+ param.name.buf = nullptr;
+ param.activeUserPreset.buf = nullptr;
+ init(param.stressSolver);
+ param.obj.buf = nullptr;
+ param.fbx.buf = nullptr;
+ param.collision.buf = nullptr;
+ param.llasset.buf = nullptr;
+ param.tkasset.buf = nullptr;
+ param.bpxa.buf = nullptr;
+ param.exportFBX = false;
+ param.exportOBJ = false;
+ param.exportCollision = false;
+ param.exportLLAsset = false;
+ param.exportTKAsset = false;
+ param.exportBPXA = false;
+}
+
+void init(BPPAssetInstance& param)
+{
+ param.name.buf = nullptr;
+ param.asset = -1;
+ param.visible = true;
+ param.exMaterial.buf = nullptr;
+ param.inMaterial.buf = nullptr;
+}
+
+void init(BPPVoronoi& param)
+{
+ param.siteGeneration = 0;
+ param.numSites = 5;
+ param.numberOfClusters = 1;
+ param.sitesPerCluster = 1.0f;
+ param.clusterRadius = 1.0f;
+}
+
+void init(BPPSlice& param)
+{
+ param.numSlicesX = 1;
+ param.numSlicesY = 1;
+ param.numSlicesZ = 1;
+ param.offsetVariation = 0.0f;
+ param.rotationVariation = 0.0f;
+ param.noiseAmplitude = 0.0f;
+ param.noiseFrequency = 1.0f;
+ param.noiseOctaveNumber = 1;
+ param.noiseSeed = 1;
+ param.surfaceResolution = 1;
+}
+
+void init(BPPFractureVisualization& param)
+{
+ param.displayFractureWidget = false;
+ param.fracturePreview = false;
}
void init(BPParams& params)
@@ -882,17 +1530,134 @@ void init(BPParams& params)
// params.renderer.lights.buf[i].name.buf =
}
+const char* convertFilterRestrictionToString(EFilterRestriction& restriction)
+{
+ switch (restriction)
+ {
+ case eFilterRestriction_AllDescendants:
+ return "AllDescendants";
+ case eFilterRestriction_AllParents:
+ return "AllParents";
+ case eFilterRestriction_DepthAll:
+ return "DepthAll";
+ case eFilterRestriction_Depth0:
+ return "Depth0";
+ case eFilterRestriction_Depth1:
+ return "Depth1";
+ case eFilterRestriction_Depth2:
+ return "Depth2";
+ case eFilterRestriction_Depth3:
+ return "Depth3";
+ case eFilterRestriction_Depth4:
+ return "Depth4";
+ case eFilterRestriction_Depth5:
+ return "Depth5";
+ case eFilterRestriction_ItemTypeAll:
+ return "ItemTypeAll";
+ case eFilterRestriction_Chunk:
+ return "Chunk";
+ case eFilterRestriction_SupportChunk:
+ return "SupportChunk";
+ case eFilterRestriction_StaticSupportChunk:
+ return "StaticSupportChunk";
+ case eFilterRestriction_Bond:
+ return "Bond";
+ case eFilterRestriction_WorldBond:
+ return "WorldBond";
+ case eFilterRestriction_EqualTo:
+ return "EqualTo";
+ case eFilterRestriction_NotEquaTo:
+ return "NotEqualTo";
+ }
+
+ return "";
+}
+
+EFilterRestriction convertStringToFilterRestriction(const char* restriction)
+{
+ static std::map<std::string, EFilterRestriction> stringRestrictionMap;
+ if (0 == stringRestrictionMap.size())
+ {
+ stringRestrictionMap["AllDescendants"] = eFilterRestriction_AllDescendants;
+ stringRestrictionMap["AllParents"] = eFilterRestriction_AllParents;
+ stringRestrictionMap["DepthAll"] = eFilterRestriction_DepthAll;
+ stringRestrictionMap["Depth0"] = eFilterRestriction_Depth0;
+ stringRestrictionMap["Depth1"] = eFilterRestriction_Depth1;
+ stringRestrictionMap["Depth2"] = eFilterRestriction_Depth2;
+ stringRestrictionMap["Depth3"] = eFilterRestriction_Depth3;
+ stringRestrictionMap["Depth4"] = eFilterRestriction_Depth4;
+ stringRestrictionMap["Depth5"] = eFilterRestriction_Depth5;
+ stringRestrictionMap["ItemTypeAll"] = eFilterRestriction_ItemTypeAll;
+ stringRestrictionMap["Chunk"] = eFilterRestriction_Chunk;
+ stringRestrictionMap["SupportChunk"] = eFilterRestriction_SupportChunk;
+ stringRestrictionMap["StaticSupportChunk"] = eFilterRestriction_StaticSupportChunk;
+ stringRestrictionMap["Bond"] = eFilterRestriction_Bond;
+ stringRestrictionMap["WorldBond"] = eFilterRestriction_WorldBond;
+ stringRestrictionMap["EqualTo"] = eFilterRestriction_EqualTo;
+ stringRestrictionMap["NotEqualTo"] = eFilterRestriction_NotEquaTo;
+ }
+
+ if (nullptr == restriction || 0 == strlen(restriction))
+ return eFilterRestriction_Invalid;
+
+ for (std::map<std::string, EFilterRestriction>::iterator itr = stringRestrictionMap.begin(); itr != stringRestrictionMap.end(); ++itr)
+ {
+ if (0 == nvidia::shdfnd::stricmp(itr->first.c_str(), restriction))
+ return itr->second;
+ }
+
+ return eFilterRestriction_Invalid;
+}
+
+FilterPreset::FilterPreset(const char* inName)
+{
+ name = inName;
+}
+
StressSolverUserPreset::StressSolverUserPreset(const char* inName)
: name(inName)
{
name = name;
- stressSolver.solverMode = -1;
- stressSolver.linearFactor = 0;
- stressSolver.angularFactor = 0;
- stressSolver.meanError = 0;
- stressSolver.varianceError = 0;
- stressSolver.bondsPerFrame = 0;
- stressSolver.bondsIterations = 0;
+ init(stressSolver);
+}
+
+FracturePreset::FracturePreset(const char* inName, FractureType inType)
+ : name(inName)
+ , type(inType)
+{
+ init();
+}
+
+void FracturePreset::setType(FractureType inType)
+{
+ type = inType;
+
+ if (eFractureType_Voronoi == type)
+ {
+ BPPVoronoi& voronoi = fracture.voronoi;
+ ::init(voronoi);
+ }
+ else if (eFractureType_Slice == type)
+ {
+ BPPSlice& slice = fracture.slice;
+ ::init(slice);
+ }
+}
+
+void FracturePreset::init()
+{
+ if (eFractureType_Voronoi == type)
+ {
+ BPPVoronoi& voronoi = fracture.voronoi;
+ ::init(voronoi);
+ }
+ else if (eFractureType_Slice == type)
+ {
+ BPPSlice& slice = fracture.slice;
+ ::init(slice);
+ }
+
+ ::init(visualization);
}
BlastProject& BlastProject::ins()
@@ -909,6 +1674,78 @@ BlastProject::~BlastProject()
void BlastProject::clear()
{
freeBlast(_projectParams.blast);
+ freeBlast(_projectParams.graphicsMaterials);
+ _projectParams.fracture.general.applyMaterial = -1;
+ _projectParams.fracture.general.autoSelectNewChunks = false;
+ _projectParams.fracture.general.selectionDepthTest = true;
+}
+
+std::string BlastProject::getAseetNameByID(int assetID)
+{
+ BPPAssetArray& assetArray = _projectParams.blast.blastAssets;
+ for (int i = 0; i < assetArray.arraySizes[0]; ++i)
+ {
+ if (assetArray.buf[i].ID == assetID)
+ return assetArray.buf[i].name.buf;
+ }
+ return "";
+}
+
+int BlastProject::getAssetIDByName(const char* name)
+{
+ if (name == nullptr || strlen(name) == 0)
+ return -1;
+
+ BPPAssetArray& assetArray = _projectParams.blast.blastAssets;
+ for (int i = 0; i < assetArray.arraySizes[0]; ++i)
+ {
+ if (nvidia::shdfnd::strcmp(assetArray.buf[i].name, name) == 0)
+ return assetArray.buf[i].ID;
+ }
+ return -1;
+}
+
+BPPAsset* BlastProject::getAsset(const char* name)
+{
+ if (name == nullptr || strlen(name) == 0)
+ return nullptr;
+
+ BPPAssetArray& assetArray = _projectParams.blast.blastAssets;
+ for (int i = 0; i < assetArray.arraySizes[0]; ++i)
+ {
+ if (nvidia::shdfnd::strcmp(assetArray.buf[i].name, name) == 0)
+ return assetArray.buf + i;
+ }
+ return nullptr;
+}
+
+int BlastProject::generateNewAssetID()
+{
+ int id = 0;
+ for (; id < (std::numeric_limits<int>::max)(); ++id)
+ {
+ BPPAssetArray& assetArray = _projectParams.blast.blastAssets;
+ bool find = false;
+
+ if (assetArray.arraySizes[0] == 0)
+ find = false;
+
+ for (int i = 0; i < assetArray.arraySizes[0]; ++i)
+ {
+ if (assetArray.buf[i].ID == id)
+ {
+ find = true;
+ break;
+ }
+ }
+
+ if (!find)
+ {
+ break;
+ }
+ }
+
+ return id;
}
bool BlastProject::isGraphicsMaterialNameExist(const char* name)
@@ -927,7 +1764,7 @@ bool BlastProject::isGraphicsMaterialNameExist(const char* name)
return false;
}
-BPPGraphicsMaterial* BlastProject::addGraphicsMaterial(const char* name, const char* diffuseTexture)
+BPPGraphicsMaterial* BlastProject::addGraphicsMaterial(const char* name)
{
if (name == nullptr || strlen(name) == 0)
return nullptr;
@@ -941,27 +1778,13 @@ BPPGraphicsMaterial* BlastProject::addGraphicsMaterial(const char* name, const c
{
BPPGraphicsMaterial& newItem = theArray.buf[i];
BPPGraphicsMaterial& oldItem = oldBuf[i];
- newItem.useTextures = false;
- newItem.name.buf = nullptr;
- newItem.diffuseTextureFilePath.buf = nullptr;
- newItem.specularTextureFilePath.buf = nullptr;
- newItem.normalTextureFilePath.buf = nullptr;
- newItem.specularShininess = 0.0;
+ init(newItem);
copy(newItem, oldItem);
}
BPPGraphicsMaterial& newItem = theArray.buf[i];
- newItem.name.buf = nullptr;
- newItem.useTextures = false;
- newItem.diffuseTextureFilePath.buf = nullptr;
- newItem.specularTextureFilePath.buf = nullptr;
- newItem.normalTextureFilePath.buf = nullptr;
- newItem.specularShininess = 0.0;
+ init(newItem);
copy(newItem.name, name);
- if (diffuseTexture != nullptr)
- {
- copy(newItem.diffuseTextureFilePath, diffuseTexture);
- }
theArray.arraySizes[0] += 1;
delete[] oldBuf;
@@ -985,11 +1808,7 @@ void BlastProject::removeGraphicsMaterial(const char* name)
{
BPPGraphicsMaterial& newItem = theArray.buf[index++];
BPPGraphicsMaterial& oldItem = oldBuf[i];
- newItem.useTextures = false;
- newItem.name.buf = nullptr;
- newItem.diffuseTextureFilePath.buf = nullptr;
- newItem.specularTextureFilePath.buf = nullptr;
- newItem.normalTextureFilePath.buf = nullptr;
+ init(newItem);
copy(newItem, oldItem);
}
}
@@ -1014,10 +1833,167 @@ void BlastProject::renameGraphicsMaterial(const char* oldName, const char* newNa
}
}
-std::vector<BPPAsset*> BlastProject::getSelectedBlastAssets(void)
+void BlastProject::reloadDiffuseColor(const char* name, float r, float g, float b, float a)
+{
+ if (name == nullptr)
+ return;
+
+ BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials;
+
+ for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ {
+ if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, name) == 0)
+ {
+ theArray.buf[i].diffuseColor[0] = r;
+ theArray.buf[i].diffuseColor[1] = g;
+ theArray.buf[i].diffuseColor[2] = b;
+ theArray.buf[i].diffuseColor[3] = a;
+ return;
+ }
+ }
+}
+
+void BlastProject::reloadSpecularColor(const char* name, float r, float g, float b, float a)
+{
+ if (name == nullptr)
+ return;
+
+ BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials;
+
+ for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ {
+ if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, name) == 0)
+ {
+ theArray.buf[i].specularColor[0] = r;
+ theArray.buf[i].specularColor[1] = g;
+ theArray.buf[i].specularColor[2] = b;
+ theArray.buf[i].specularColor[3] = a;
+ return;
+ }
+ }
+}
+
+void BlastProject::reloadSpecularShininess(const char* name, float specularShininess)
+{
+ if (name == nullptr)
+ return;
+
+ BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials;
+
+ for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ {
+ if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, name) == 0)
+ {
+ theArray.buf[i].specularShininess = specularShininess;
+ return;
+ }
+ }
+}
+
+void BlastProject::reloadDiffuseTexture(const char* name, const char* diffuseTexture)
+{
+ if (name == nullptr)
+ return;
+
+ BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials;
+
+ for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ {
+ if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, name) == 0)
+ {
+ copy(theArray.buf[i].diffuseTextureFilePath, diffuseTexture);
+ return;
+ }
+ }
+}
+
+void BlastProject::reloadSpecularTexture(const char* name, const char* specularTexture)
{
- std::vector<BPPAsset*> assets;
- return assets;
+ if (name == nullptr)
+ return;
+
+ BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials;
+
+ for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ {
+ if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, name) == 0)
+ {
+ copy(theArray.buf[i].specularTextureFilePath, specularTexture);
+ return;
+ }
+ }
+}
+
+void BlastProject::reloadNormalTexture(const char* name, const char* normalTexture)
+{
+ if (name == nullptr)
+ return;
+
+ BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials;
+
+ for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ {
+ if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, name) == 0)
+ {
+ copy(theArray.buf[i].normalTextureFilePath, normalTexture);
+ return;
+ }
+ }
+}
+
+void BlastProject::reloadEnvTexture(const char* name, const char* envTexture)
+{
+ // to do
+}
+
+BPPGraphicsMaterial* BlastProject::getGraphicsMaterial(const char* name)
+{
+ if (name == nullptr || strlen(name) == 0)
+ return nullptr;
+
+ BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials;
+
+ for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ {
+ if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, name) == 0)
+ {
+ return &theArray.buf[i];
+ }
+ }
+
+ return nullptr;
+}
+
+std::string BlastProject::generateNewMaterialName(const char* name)
+{
+ std::string nName = "";
+ if (name != nullptr)
+ nName = name;
+
+ char materialName[MAX_PATH];
+
+ BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials;
+ for (int m = 0; ;m++)
+ {
+ sprintf(materialName, "%s_%d", nName.c_str(), m);
+
+ bool exist = false;
+ for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ {
+ BPPGraphicsMaterial& item = theArray.buf[i];
+ if (nvidia::shdfnd::strcmp(item.name.buf, materialName) == 0)
+ {
+ exist = true;
+ break;
+ }
+ }
+ if (!exist)
+ {
+ break;
+ }
+ }
+
+ return materialName;
}
bool BlastProject::isAssetInstanceNameExist(const char* name)
@@ -1025,7 +2001,7 @@ bool BlastProject::isAssetInstanceNameExist(const char* name)
if (name == nullptr || strlen(name) == 0)
return false;
- BPPAssetInstanceArray& theArray = _projectParams.blast.composite.blastAssetInstances;
+ BPPAssetInstanceArray& theArray = _projectParams.blast.blastAssetInstances;
for (int i = 0; i < theArray.arraySizes[0]; ++i)
{
@@ -1036,22 +2012,77 @@ bool BlastProject::isAssetInstanceNameExist(const char* name)
return false;
}
-BPPAssetInstance* BlastProject::getAssetInstance(const char* assetPath, int instanceIndex)
+int BlastProject::getAssetInstanceCount(int assetID)
+{
+ std::vector<BPPAssetInstance*> instances;
+ getAssetInstances(assetID, instances);
+ return instances.size();
+}
+
+void BlastProject::getAssetInstances(int assetID, std::vector<BPPAssetInstance*>& instances)
{
- if (assetPath == nullptr || strlen(assetPath) == 0 || instanceIndex < 0)
+ instances.clear();
+
+ if (assetID < 0)
+ {
+ return;
+ }
+
+ /*
+ assetID may not less than assetArray.arraySizes[0]
+ for example : there is only one asset and its id is two
+
+ BPPAssetArray& assetArray = _projectParams.blast.blastAssets;
+ if (assetID >= assetArray.arraySizes[0])
+ {
+ return;
+ }
+ */
+
+ BPPAssetInstanceArray& instanceArray = _projectParams.blast.blastAssetInstances;
+ for (int i = 0; i < instanceArray.arraySizes[0]; i++)
+ {
+ BPPAssetInstance& instance = instanceArray.buf[i];
+ if (assetID == instance.asset)
+ instances.push_back(&instance);
+ }
+}
+
+BPPAssetInstance* BlastProject::getAssetInstance(int assetID, int instanceIndex)
+{
+ std::vector<BPPAssetInstance*> instances;
+ getAssetInstances(assetID, instances);
+
+ int instanceSize = instances.size();
+ if (instanceSize == 0 || instanceSize <= instanceIndex)
{
return nullptr;
}
- BPPAssetInstanceArray& instanceArray = _projectParams.blast.composite.blastAssetInstances;
- if (instanceIndex < instanceArray.arraySizes[0])
+ return instances[instanceIndex];
+}
+
+BPPAssetInstance* BlastProject::getAssetInstance(int assetID, const char* instanceName)
+{
+ std::vector<BPPAssetInstance*> instances;
+ getAssetInstances(assetID, instances);
+
+ int instanceSize = instances.size();
+ if (instanceSize == 0)
{
- BPPAssetInstance& assetInstance = instanceArray.buf[instanceIndex];
- if (nvidia::shdfnd::strcmp(assetPath, assetInstance.source.buf) == 0)
- return &assetInstance;
+ return nullptr;
}
- return nullptr;
+ BPPAssetInstance* instance = nullptr;
+ for (int is = 0; is < instanceSize; is++)
+ {
+ if (::strcmp(instanceName, instances[is]->name.buf) == 0)
+ {
+ instance = instances[is];
+ break;
+ }
+ }
+ return instance;
}
BPPAssetInstance* BlastProject::addAssetInstance(int blastAssetIndex, const char* instanceName)
@@ -1063,8 +2094,7 @@ BPPAssetInstance* BlastProject::addAssetInstance(int blastAssetIndex, const char
if (blastAssetIndex < 0 && blastAssetIndex > assetArray.arraySizes[0])
return nullptr;
- BPPComposite& composite = _projectParams.blast.composite;
- BPPAssetInstanceArray& theArray = composite.blastAssetInstances;
+ BPPAssetInstanceArray& theArray = _projectParams.blast.blastAssetInstances;
BPPAssetInstance* oldBuf = theArray.buf;
theArray.buf = new BPPAssetInstance[theArray.arraySizes[0] + 1];
@@ -1075,16 +2105,14 @@ BPPAssetInstance* BlastProject::addAssetInstance(int blastAssetIndex, const char
BPPAssetInstance& newItem = theArray.buf[i];
BPPAssetInstance& oldItem = oldBuf[i];
- newItem.name.buf = nullptr;
- newItem.source.buf = nullptr;
+ init(newItem);
copy(newItem, oldItem);
}
BPPAssetInstance& newItem = theArray.buf[i];
- newItem.name.buf = nullptr;
- newItem.source.buf = nullptr;
+ init(newItem);
copy(newItem.name, instanceName);
- copy(newItem.source, assetArray.buf[blastAssetIndex].path);
+ newItem.asset = -1;
newItem.visible = true;
delete[] oldBuf;
@@ -1097,7 +2125,7 @@ void BlastProject::removeAssetInstance(const char* name)
if (name == nullptr || strlen(name) == 0 || !isAssetInstanceNameExist(name))
return;
- BPPAssetInstanceArray& theArray = _projectParams.blast.composite.blastAssetInstances;
+ BPPAssetInstanceArray& theArray = _projectParams.blast.blastAssetInstances;
BPPAssetInstance* oldBuf = theArray.buf;
theArray.buf = new BPPAssetInstance[theArray.arraySizes[0] - 1];
@@ -1108,8 +2136,7 @@ void BlastProject::removeAssetInstance(const char* name)
{
BPPAssetInstance& newItem = theArray.buf[index++];
BPPAssetInstance& oldItem = oldBuf[i];
- newItem.name.buf = nullptr;
- newItem.source.buf = nullptr;
+ init(newItem);
copy(newItem, oldItem);
}
}
@@ -1117,7 +2144,7 @@ void BlastProject::removeAssetInstance(const char* name)
delete[] oldBuf;
}
-BPPChunk* BlastProject::getChunk(BPPAsset& asset, int id)
+BPPChunk* BlastProject::getChunk(BPPAsset& asset, int chunkID)
{
BPPChunkArray& chunkArray = _projectParams.blast.chunks;
@@ -1125,7 +2152,7 @@ BPPChunk* BlastProject::getChunk(BPPAsset& asset, int id)
for (int i = 0; i < count; ++i)
{
BPPChunk& chunk = chunkArray.buf[i];
- if (chunk.ID == id && (nvidia::shdfnd::strcmp(chunk.asset.buf, asset.path.buf) == 0))
+ if (chunk.ID == chunkID && chunk.asset == asset.ID)
return &chunk;
}
@@ -1142,7 +2169,7 @@ std::vector<BPPChunk*> BlastProject::getChildrenChunks(BPPAsset& asset, int pare
for (int i = 0; i < count; ++i)
{
BPPChunk& chunk = chunkArray.buf[i];
- if (chunk.parentID == parentID && (nvidia::shdfnd::strcmp(chunk.asset.buf, asset.path.buf) == 0))
+ if (chunk.parentID == parentID && chunk.asset == asset.ID)
chunks.push_back(&chunk);
}
@@ -1151,6 +2178,11 @@ std::vector<BPPChunk*> BlastProject::getChildrenChunks(BPPAsset& asset, int pare
std::vector<BPPChunk*> BlastProject::getChildrenChunks(BPPAsset& asset)
{
+ return getChildrenChunks(asset.ID);
+}
+
+std::vector<BPPChunk*> BlastProject::getChildrenChunks(int assetID)
+{
std::vector<BPPChunk*> chunks;
BPPChunkArray& chunkArray = _projectParams.blast.chunks;
@@ -1159,7 +2191,7 @@ std::vector<BPPChunk*> BlastProject::getChildrenChunks(BPPAsset& asset)
for (int i = 0; i < count; ++i)
{
BPPChunk& chunk = chunkArray.buf[i];
- if (nvidia::shdfnd::strcmp(chunk.asset.buf, asset.path.buf) == 0)
+ if (chunk.asset == assetID)
chunks.push_back(&chunk);
}
@@ -1174,7 +2206,7 @@ std::vector<BPPBond*> BlastProject::getBondsByChunk(BPPAsset& asset, int chunkID
for (int i = 0; i < count; ++i)
{
BPPBond& bond = bondArray.buf[i];
- if ((nvidia::shdfnd::strcmp(bond.asset.buf, asset.path.buf) == 0))
+ if (bond.asset == asset.ID)
{
if (bond.fromChunk == chunkID)
bonds.push_back(&bond);
@@ -1186,119 +2218,120 @@ std::vector<BPPBond*> BlastProject::getBondsByChunk(BPPAsset& asset, int chunkID
return bonds;
}
-bool BlastProject::isLandmarkNameExist(const char* name)
+std::vector<BPPBond*> BlastProject::getChildrenBonds(BPPAsset& asset)
{
- if (name == nullptr || strlen(name) == 0)
- return false;
+ std::vector<BPPBond*> bonds;
- BPPLandmarkArray& theArray = _projectParams.blast.composite.landmarks;
+ BPPBondArray& bondArray = _projectParams.blast.bonds;
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ int count = bondArray.arraySizes[0];
+ for (int i = 0; i < count; ++i)
{
- BPPLandmark& item = theArray.buf[i];
- if (nvidia::shdfnd::strcmp(item.name.buf, name) == 0)
- return true;
+ BPPBond& bond = bondArray.buf[i];
+ if (bond.asset == asset.ID)
+ bonds.push_back(&bond);
}
- return false;
+
+ return bonds;
}
-BPPLandmark* BlastProject::addLandmark(const char* name)
+bool BlastProject::isUserPresetNameExist(const char* name)
{
- if (name == nullptr)
- return nullptr;
-
- BPPLandmarkArray& theArray = _projectParams.blast.composite.landmarks;
- BPPLandmark* oldBuf = theArray.buf;
- theArray.buf = new BPPLandmark[theArray.arraySizes[0] + 1];
+ if (name == nullptr || strlen(name) == 0)
+ return false;
- int i = 0;
- for (; i < theArray.arraySizes[0]; ++i)
+ for (size_t i = 0; i < _userPresets.size(); ++i)
{
- BPPLandmark& newItem = theArray.buf[i];
- BPPLandmark& oldItem = oldBuf[i];
-
- newItem.name.buf = nullptr;
- copy(newItem, oldItem);
+ StressSolverUserPreset& item = _userPresets[i];
+ if (item.name == name)
+ return true;
}
- BPPLandmark& newItem = theArray.buf[i];
- newItem.name.buf = nullptr;
- copy(newItem.name, name);
- newItem.visible = true;
- newItem.enable = true;
- newItem.radius = 0.0;
- theArray.arraySizes[0] += 1;
+ return false;
+}
- delete[] oldBuf;
+std::vector<StressSolverUserPreset>& BlastProject::getUserPresets()
+{
+ return _userPresets;
+}
- return &newItem;
+void BlastProject::addUserPreset(const char* name)
+{
+ _userPresets.push_back(StressSolverUserPreset(name));
}
-void BlastProject::removeLandmark(const char* name)
+void BlastProject::saveUserPreset()
{
- if (name == nullptr || strlen(name) == 0 || !isLandmarkNameExist(name))
- return ;
+ QString presetFolder = QCoreApplication::applicationDirPath() + "/Preset/";
+ QDir presetDir(presetFolder);
+ QString presetFilePath = presetFolder + USER_PRESET;
+ if (!presetDir.exists())
+ {
+ if (!presetDir.mkdir(presetFolder))
+ return;
+ }
+ QFile file(presetFilePath);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ {
+ return;
+ }
+ QTextStream out(&file);
- BPPLandmarkArray& theArray = _projectParams.blast.composite.landmarks;
- BPPLandmark* oldBuf = theArray.buf;
-
- theArray.buf = new BPPLandmark[theArray.arraySizes[0] - 1];
- int index = 0;
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ QDomDocument xmlDoc;
+ QDomElement rootElm = xmlDoc.createElement(QObject::tr("UserPreset"));
+ xmlDoc.appendChild(rootElm);
+
+ for (size_t i = 0; i < _userPresets.size(); ++i)
{
- if (nvidia::shdfnd::strcmp(oldBuf[i].name.buf, name) != 0)
- {
- BPPLandmark& newItem = theArray.buf[index++];
- BPPLandmark& oldItem = oldBuf[i];
- newItem.name.buf = nullptr;
- copy(newItem, oldItem);
- }
+ _saveStressSolverPreset(rootElm, _userPresets[i]);
}
- theArray.arraySizes[0] -= 1;
- delete[] oldBuf;
+
+ // 4 is count of indent
+ xmlDoc.save(out, 4);
}
-BPPLandmark* BlastProject::getLandmark(const char* name)
+void BlastProject::loadUserPreset()
{
- if (name == nullptr)
- return nullptr;
+ QString presetFilePath = QCoreApplication::applicationDirPath() + "/Preset/" + USER_PRESET;
- BPPLandmarkArray& theArray = _projectParams.blast.composite.landmarks;
+ QFile file(presetFilePath);
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ if (!file.open(QIODevice::ReadOnly))
{
- if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, name) == 0)
- return &theArray.buf[i];
+ return;
}
- return nullptr;
-}
-
-void BlastProject::renameLandmark(const char* oldName, const char* newName)
-{
- if (oldName == nullptr || newName == nullptr)
- return ;
+ QDomDocument xmlDoc;
+ if (!xmlDoc.setContent(&file))
+ {
+ file.close();
+ return;
+ }
+ file.close();
- BPPLandmarkArray& theArray = _projectParams.blast.composite.landmarks;
+ if (xmlDoc.isNull() || xmlDoc.documentElement().tagName() != QObject::tr("UserPreset"))
+ {
+ QMessageBox::warning(&AppMainWindow::Inst(), QObject::tr("Warning"), QObject::tr("The file you selected is empty or not a blast user preset file."));
+ return;
+ }
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ QDomNodeList elms = xmlDoc.documentElement().elementsByTagName(QObject::tr("StressSolverPreset"));
+ for (int i = 0; i < elms.count(); ++i)
{
- if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, oldName) == 0)
- {
- copy(theArray.buf[i].name, newName);
- return;
- }
+ StressSolverUserPreset preset("");
+ _userPresets.push_back(preset);
+ _loadStressSolverPreset(elms.at(i).toElement(), _userPresets[i]);
}
}
-bool BlastProject::isUserPresetNameExist(const char* name)
+bool BlastProject::isFracturePresetNameExist(const char* name)
{
if (name == nullptr || strlen(name) == 0)
return false;
- for (size_t i = 0; i < _userPresets.size(); ++i)
+ for (size_t i = 0; i < _fracturePresets.size(); ++i)
{
- StressSolverUserPreset& item = _userPresets[i];
+ FracturePreset& item = _fracturePresets[i];
if (item.name == name)
return true;
}
@@ -1306,19 +2339,27 @@ bool BlastProject::isUserPresetNameExist(const char* name)
return false;
}
-std::vector<StressSolverUserPreset>& BlastProject::getUserPresets()
+std::vector<FracturePreset>& BlastProject::getFracturePresets()
{
- return _userPresets;
+ return _fracturePresets;
}
-void BlastProject::addUserPreset(const char* name)
+void BlastProject::addFracturePreset(const char* name, FractureType type)
{
- _userPresets.push_back(StressSolverUserPreset(name));
+ _fracturePresets.push_back(FracturePreset(name, type));
}
-void BlastProject::saveUserPreset()
+void BlastProject::saveFracturePreset()
{
- QFile file(_projectParams.blast.userPreset.buf);
+ QString presetFolder = QCoreApplication::applicationDirPath() + "/Preset/";
+ QDir presetDir(presetFolder);
+ QString presetFilePath = presetFolder + FRACTURE_PRESET;
+ if (!presetDir.exists())
+ {
+ if (!presetDir.mkdir(presetFolder))
+ return;
+ }
+ QFile file(presetFilePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
return;
@@ -1326,21 +2367,22 @@ void BlastProject::saveUserPreset()
QTextStream out(&file);
QDomDocument xmlDoc;
- QDomElement rootElm = xmlDoc.createElement(QObject::tr("UserPreSet"));
+ QDomElement rootElm = xmlDoc.createElement(QObject::tr("FracturePresets"));
xmlDoc.appendChild(rootElm);
- for (size_t i = 0; i < _userPresets.size(); ++i)
+ for (size_t i = 0; i < _fracturePresets.size(); ++i)
{
- _saveStressSolverPreset(rootElm, _userPresets[i]);
+ _saveFracturePreset(rootElm, _fracturePresets[i]);
}
// 4 is count of indent
xmlDoc.save(out, 4);
}
-void BlastProject::loadUserPreset()
+void BlastProject::loadFracturePreset()
{
- QFile file(_projectParams.blast.userPreset.buf);
+ QString presetFilePath = QCoreApplication::applicationDirPath() + "/Preset/" + FRACTURE_PRESET;
+ QFile file(presetFilePath);
if (!file.open(QIODevice::ReadOnly))
{
@@ -1355,20 +2397,19 @@ void BlastProject::loadUserPreset()
}
file.close();
- if (xmlDoc.isNull() || xmlDoc.documentElement().tagName() != QObject::tr("UserPreSet"))
+ if (xmlDoc.isNull() || xmlDoc.documentElement().tagName() != QObject::tr("FracturePresets"))
{
QMessageBox::warning(&AppMainWindow::Inst(), QObject::tr("Warning"), QObject::tr("The file you selected is empty or not a blast user preset file."));
return;
}
- QDomNodeList elms = xmlDoc.documentElement().elementsByTagName(QObject::tr("StressSolverPreset"));
+ QDomNodeList elms = xmlDoc.documentElement().elementsByTagName(QObject::tr("FracturePreset"));
for (int i = 0; i < elms.count(); ++i)
{
- StressSolverUserPreset preset("");
- _userPresets.push_back(preset);
- _loadStressSolverPreset(elms.at(i).toElement(), _userPresets[i]);
+ FracturePreset preset("", eFractureType_Voronoi);
+ _fracturePresets.push_back(preset);
+ _loadFracturePreset(elms.at(i).toElement(), _fracturePresets[i]);
}
-
}
bool BlastProject::isFilterPresetNameExist(const char* name)
@@ -1376,21 +2417,18 @@ bool BlastProject::isFilterPresetNameExist(const char* name)
if (name == nullptr || strlen(name) == 0)
return false;
- BPPFilterPresetArray& theArray = _projectParams.filter.filters;
-
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ for (FilterPreset preset : _filterPresets)
{
- BPPFilterPreset& item = theArray.buf[i];
- if (nvidia::shdfnd::strcmp(item.name.buf, name) == 0)
+ if (preset.name == name)
return true;
}
+
return false;
}
-std::vector<BPPFilterPreset*> BlastProject::getFilterPresets()
+std::vector<FilterPreset>& BlastProject::getFilterPresets()
{
- std::vector<BPPFilterPreset*> presets;
- return presets;
+ return _filterPresets;
}
void BlastProject::addFilterPreset(const char* name)
@@ -1398,30 +2436,7 @@ void BlastProject::addFilterPreset(const char* name)
if (name == nullptr)
return;
- BPPFilterPresetArray& theArray = _projectParams.filter.filters;
- BPPFilterPreset* oldBuf = theArray.buf;
- theArray.buf = new BPPFilterPreset[theArray.arraySizes[0] + 1];
-
- int i = 0;
- for (; i < theArray.arraySizes[0]; ++i)
- {
- BPPFilterPreset& newItem = theArray.buf[i];
- BPPFilterPreset& oldItem = oldBuf[i];
-
- newItem.name.buf = nullptr;
- newItem.depthFilters.buf = nullptr;
- newItem.depthFilters.arraySizes[0] = 0;
- copy(newItem, oldItem);
- }
-
- BPPFilterPreset& newItem = theArray.buf[i];
- newItem.name.buf = nullptr;
- newItem.depthFilters.buf = nullptr;
- newItem.depthFilters.arraySizes[0] = 0;
- copy(newItem.name, name);
- theArray.arraySizes[0] += 1;
-
- delete[] oldBuf;
+ _filterPresets.push_back(FilterPreset(name));
}
void BlastProject::removeFilterPreset(const char* name)
@@ -1429,38 +2444,27 @@ void BlastProject::removeFilterPreset(const char* name)
if (name == nullptr || strlen(name) == 0 || !isFilterPresetNameExist(name))
return;
- BPPFilterPresetArray& theArray = _projectParams.filter.filters;
- BPPFilterPreset* oldBuf = theArray.buf;
-
- theArray.buf = new BPPFilterPreset[theArray.arraySizes[0] - 1];
- int index = 0;
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ for (std::vector<FilterPreset>::iterator itr = _filterPresets.begin(); itr != _filterPresets.end(); ++itr)
{
- if (nvidia::shdfnd::strcmp(oldBuf[i].name.buf, name) != 0)
+ if (itr->name == name)
{
- BPPFilterPreset& newItem = theArray.buf[index++];
- BPPFilterPreset& oldItem = oldBuf[i];
- newItem.name.buf = nullptr;
- newItem.depthFilters.buf = nullptr;
- newItem.depthFilters.arraySizes[0] = 0;
- copy(newItem, oldItem);
+ _filterPresets.erase(itr);
+ return;
}
}
- theArray.arraySizes[0] -= 1;
- delete[] oldBuf;
}
-BPPFilterPreset* BlastProject::getFilterPreset(const char* name)
+FilterPreset* BlastProject::getFilterPreset(const char* name)
{
if (name == nullptr)
return nullptr;
- BPPFilterPresetArray& theArray = _projectParams.filter.filters;
-
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ for (std::vector<FilterPreset>::iterator itr = _filterPresets.begin(); itr != _filterPresets.end(); ++itr)
{
- if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, name) == 0)
- return &theArray.buf[i];
+ if (itr->name == name)
+ {
+ return &(*itr);
+ }
}
return nullptr;
@@ -1471,244 +2475,112 @@ void BlastProject::renameFilterPreset(const char* oldName, const char* newName)
if (oldName == nullptr || newName == nullptr)
return;
- BPPFilterPresetArray& theArray = _projectParams.filter.filters;
-
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ for (std::vector<FilterPreset>::iterator itr = _filterPresets.begin(); itr != _filterPresets.end(); ++itr)
{
- if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, oldName) == 0)
+ if (itr->name == oldName)
{
- copy(theArray.buf[i].name, newName);
+ (*itr).name = newName;
return;
}
}
}
-void BlastProject::addFilterDepth(const char* filterName, int depth)
+void BlastProject::addFilterRestriction(const char* filterName, EFilterRestriction restriction)
{
- if (filterName == nullptr || depth < 0)
+ if (filterName == nullptr || strlen(filterName) == 0 || !isFilterPresetNameExist(filterName))
return;
- BPPFilterPresetArray& theArray = _projectParams.filter.filters;
-
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ for (std::vector<FilterPreset>::iterator itr = _filterPresets.begin(); itr != _filterPresets.end(); ++itr)
{
- if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, filterName) == 0)
+ if (itr->name == filterName)
{
- BPPU32Array& depthArray = theArray.buf[i].depthFilters;
- for (int j = 0; j < depthArray.arraySizes[0]; ++j)
- {
- if (depthArray.buf[j] == depth)
- return;
- }
-
- uint32_t* oldBuf = depthArray.buf;
- depthArray.buf = new uint32_t[theArray.arraySizes[0] + 1];
-
- int m = 0, n = 0;
- for (; n < depthArray.arraySizes[0];)
- {
- if (oldBuf[n] < depth)
- {
- depthArray.buf[m++] = oldBuf[n++];
- }
- else
- {
- if (m == n)
- depthArray.buf[m++] = depth;
- else
- depthArray.buf[m++] = oldBuf[n++];
- }
- }
-
- if (m == n)
- {
- depthArray.buf[m] = depth;
- }
- depthArray.arraySizes[0] += 1;
+ (*itr).filters.push_back(restriction);
return;
}
}
}
-void BlastProject::removeFilterDepth(const char* filterName, int depth)
+void BlastProject::removeFilterRestriction(const char* filterName, EFilterRestriction restriction)
{
- if (filterName == nullptr || depth < 0)
+ if (filterName == nullptr || strlen(filterName) == 0 || !isFilterPresetNameExist(filterName))
return;
- BPPFilterPresetArray& theArray = _projectParams.filter.filters;
-
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ for (std::vector<FilterPreset>::iterator itr = _filterPresets.begin(); itr != _filterPresets.end(); ++itr)
{
- if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, filterName) == 0)
+ if (itr->name == filterName)
{
- bool foundDepth = false;
- BPPU32Array& depthArray = theArray.buf[i].depthFilters;
- for (int j = 0; j < depthArray.arraySizes[0]; ++j)
- {
- if (depthArray.buf[j] == depth)
- {
- foundDepth = true;
- break;
- }
- }
-
- if (!foundDepth)
- return;
-
- uint32_t* oldBuf = depthArray.buf;
- depthArray.buf = new uint32_t[theArray.arraySizes[0] - 1];
-
- int m = 0, n = 0;
- for (; n < depthArray.arraySizes[0];)
- {
- if (oldBuf[n] != depth)
- {
- depthArray.buf[m++] = oldBuf[n++];
- }
- else
- {
- depthArray.buf[m] = depthArray.buf[n++];
- }
- }
-
- depthArray.arraySizes[0] -= 1;
+ std::vector<EFilterRestriction>& filters = (*itr).filters;
+ filters.erase(std::find(filters.begin(), filters.end(), restriction));
return;
}
}
}
-bool BlastProject::isCutoutTextureNameExist(const char* name)
+void BlastProject::saveFilterPreset()
{
- if (name == nullptr || strlen(name) == 0)
- return false;
-
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.cutoutProjection.textures;
-
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ QString presetFolder = QCoreApplication::applicationDirPath() + "/Preset/";
+ QDir presetDir(presetFolder);
+ QString presetFilePath = presetFolder + FILTER_PRESET;
+ if (!presetDir.exists())
{
- NvParameterized::DummyStringStruct& item = theArray.buf[i];
- if (nvidia::shdfnd::strcmp(item.buf, name) == 0)
- return true;
+ if (!presetDir.mkdir(presetFolder))
+ return;
}
- return false;
-}
-
-void BlastProject::addCutoutTexture(const char* name)
-{
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.cutoutProjection.textures;
- _addStringItem(theArray, name);
-}
-
-void BlastProject::removeCutoutTexture(const char* name)
-{
- if (name == nullptr || strlen(name) == 0 || !isCutoutTextureNameExist(name))
+ QFile file(presetFilePath);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ {
return;
+ }
+ QTextStream out(&file);
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.cutoutProjection.textures;
- _removeStringItem(theArray, name);
-}
-
-bool BlastProject::isPaintMaskNameExist(const char* name)
-{
- if (name == nullptr || strlen(name) == 0)
- return false;
-
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.paintMasks;
+ QDomDocument xmlDoc;
+ QDomElement rootElm = xmlDoc.createElement(QObject::tr("FilterPresets"));
+ xmlDoc.appendChild(rootElm);
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ for (size_t i = 0; i < _filterPresets.size(); ++i)
{
- NvParameterized::DummyStringStruct& item = theArray.buf[i];
- if (nvidia::shdfnd::strcmp(item.buf, name) == 0)
- return true;
+ _saveFilterPreset(rootElm, _filterPresets[i]);
}
- return false;
-}
-
-void BlastProject::addPaintMasks(const char* name)
-{
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.paintMasks;
- _addStringItem(theArray, name);
-}
-
-void BlastProject::removePaintMasks(const char* name)
-{
- if (name == nullptr || strlen(name) == 0 || !isPaintMaskNameExist(name))
- return;
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.paintMasks;
- _removeStringItem(theArray, name);
+ // 4 is count of indent
+ xmlDoc.save(out, 4);
}
-bool BlastProject::isMeshCutterNameExist(const char* name)
+void BlastProject::loadFilterPreset()
{
- if (name == nullptr || strlen(name) == 0)
- return false;
+ QString presetFilePath = QCoreApplication::applicationDirPath() + "/Preset/" + FILTER_PRESET;
+ QFile file(presetFilePath);
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.meshCutters;
-
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ if (!file.open(QIODevice::ReadOnly))
{
- NvParameterized::DummyStringStruct& item = theArray.buf[i];
- if (nvidia::shdfnd::strcmp(item.buf, name) == 0)
- return true;
- }
- return false;
-}
-
-void BlastProject::addMeshCutter(const char* name)
-{
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.meshCutters;
- _addStringItem(theArray, name);
-}
-
-void BlastProject::removeMeshCutter(const char* name)
-{
- if (name == nullptr || strlen(name) == 0 || !isMeshCutterNameExist(name))
return;
+ }
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.meshCutters;
- _removeStringItem(theArray, name);
-}
-
-bool BlastProject::isVoronoiTextureNameExist(const char* name)
-{
- if (name == nullptr || strlen(name) == 0)
- return false;
-
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.textureSites;
-
- for (int i = 0; i < theArray.arraySizes[0]; ++i)
+ QDomDocument xmlDoc;
+ if (!xmlDoc.setContent(&file))
{
- NvParameterized::DummyStringStruct& item = theArray.buf[i];
- if (nvidia::shdfnd::strcmp(item.buf, name) == 0)
- return true;
+ file.close();
+ return;
}
- return false;
-}
-
-void BlastProject::addVoronoiTexture(const char* name)
-{
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.textureSites;
- _addStringItem(theArray, name);
-}
+ file.close();
-void BlastProject::removeVoronoiTexture(const char* name)
-{
- if (name == nullptr || strlen(name) == 0 || !isVoronoiTextureNameExist(name))
+ if (xmlDoc.isNull() || xmlDoc.documentElement().tagName() != QObject::tr("FilterPresets"))
+ {
+ QMessageBox::warning(&AppMainWindow::Inst(), QObject::tr("Warning"), QObject::tr("The file you selected is empty or not a blast user preset file."));
return;
+ }
- BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.textureSites;
- _removeStringItem(theArray, name);
+ QDomNodeList elms = xmlDoc.documentElement().elementsByTagName(QObject::tr("FilterPreset"));
+ for (int i = 0; i < elms.count(); ++i)
+ {
+ FilterPreset preset("");
+ _filterPresets.push_back(preset);
+ _loadFilterPreset(elms.at(i).toElement(), _filterPresets[i]);
+ }
}
BlastProject::BlastProject()
{
- _projectParams.cameraBookmarks.buf = nullptr;
- _projectParams.cameraBookmarks.arraySizes[0] = 0;
-
- _projectParams.graphicsMaterials.buf = nullptr;
- _projectParams.graphicsMaterials.arraySizes[0] = 0;
-
_projectParams.renderer.textureFilePath.buf = nullptr;
_projectParams.renderer.lights.buf = new BPPLight[4];
@@ -1719,44 +2591,19 @@ BlastProject::BlastProject()
_projectParams.renderer.lights.buf[i].name.buf = nullptr;
}
- _projectParams.blast.fileReferences.blast.buf = nullptr;
- _projectParams.blast.fileReferences.fbx.buf = nullptr;
_projectParams.blast.fileReferences.fbxSourceAsset.buf = nullptr;
- _projectParams.blast.fileReferences.collision.buf = nullptr;
-
- _projectParams.blast.composite.composite.buf = nullptr;
- _projectParams.blast.composite.blastAssetInstances.buf = nullptr;
- _projectParams.blast.composite.blastAssetInstances.arraySizes[0] = 0;
-
- _projectParams.blast.composite.landmarks.buf = nullptr;
- _projectParams.blast.composite.landmarks.arraySizes[0] = 0;
- _projectParams.blast.blastAssets.buf = nullptr;
- _projectParams.blast.blastAssets.arraySizes[0] = 0;
-
- _projectParams.blast.projectiles.buf = nullptr;
- _projectParams.blast.projectiles.arraySizes[0] = 0;
-
- _projectParams.blast.graphicsMeshes.buf = nullptr;
- _projectParams.blast.graphicsMeshes.arraySizes[0] = 0;
-
- _projectParams.blast.userPreset.buf = nullptr;
_projectParams.blast.healthMask.buf = nullptr;
- _projectParams.filter.filters.buf = nullptr;
- _projectParams.filter.filters.arraySizes[0] = 0;
-
- _projectParams.fracture.voronoi.paintMasks.buf = nullptr;
- _projectParams.fracture.voronoi.paintMasks.arraySizes[0] = 0;
+ _projectParams.fracture.general.fracturePreset.buf = nullptr;
- _projectParams.fracture.voronoi.meshCutters.buf = nullptr;
- _projectParams.fracture.voronoi.meshCutters.arraySizes[0] = 0;
+ init(_projectParams.fracture.slice);
+ init(_projectParams.fracture.voronoi);
- _projectParams.fracture.voronoi.textureSites.buf = nullptr;
- _projectParams.fracture.voronoi.textureSites.arraySizes[0] = 0;
+ init(_projectParams.defaultDamage);
- _projectParams.fracture.cutoutProjection.textures.buf = nullptr;
- _projectParams.fracture.cutoutProjection.textures.arraySizes[0] = 0;
+ _projectParams.fracture.general.autoSelectNewChunks = false;
+ _projectParams.fracture.general.selectionDepthTest = true;
}
void BlastProject::_saveStressSolverPreset(QDomElement& parentElm, StressSolverUserPreset& stressSolverUserPreset)
@@ -1771,13 +2618,11 @@ void BlastProject::_saveStressSolver(QDomElement& parentElm, BPPStressSolver& st
{
QDomElement newElm = parentElm.ownerDocument().createElement(QObject::tr("StressSolver"));
parentElm.appendChild(newElm);
- newElm.setAttribute(QObject::tr("SolverMode"), stressSolver.solverMode);
+ newElm.setAttribute(QObject::tr("Hardness"), stressSolver.hardness);
newElm.setAttribute(QObject::tr("LinearFactor"), stressSolver.linearFactor);
newElm.setAttribute(QObject::tr("AngularFactor"), stressSolver.angularFactor);
- newElm.setAttribute(QObject::tr("MeanError"), stressSolver.meanError);
- newElm.setAttribute(QObject::tr("VarianceError"), stressSolver.varianceError);
- newElm.setAttribute(QObject::tr("BondsPerFrame"), stressSolver.bondsPerFrame);
- newElm.setAttribute(QObject::tr("BondsIterations"), stressSolver.bondsIterations);
+ newElm.setAttribute(QObject::tr("BondIterationsPerFrame"), stressSolver.bondIterationsPerFrame);
+ newElm.setAttribute(QObject::tr("GraphReductionLevel"), stressSolver.graphReductionLevel);
}
void BlastProject::_loadStressSolverPreset(QDomElement& parentElm, StressSolverUserPreset& stressSolverUserPreset)
@@ -1790,13 +2635,153 @@ void BlastProject::_loadStressSolverPreset(QDomElement& parentElm, StressSolverU
void BlastProject::_loadStressSolver(QDomElement& parentElm, BPPStressSolver& stressSolver)
{
- stressSolver.solverMode = parentElm.attribute(QObject::tr("SolverMode")).toInt();
+ stressSolver.hardness = parentElm.attribute(QObject::tr("Hardness")).toFloat();
stressSolver.linearFactor = parentElm.attribute(QObject::tr("LinearFactor")).toFloat();
stressSolver.angularFactor = parentElm.attribute(QObject::tr("AngularFactor")).toFloat();
- stressSolver.meanError = parentElm.attribute(QObject::tr("MeanError")).toFloat();
- stressSolver.varianceError = parentElm.attribute(QObject::tr("VarianceError")).toFloat();
- stressSolver.bondsPerFrame = parentElm.attribute(QObject::tr("BondsPerFrame")).toUInt();
- stressSolver.bondsIterations = parentElm.attribute(QObject::tr("BondsIterations")).toUInt();
+ stressSolver.bondIterationsPerFrame = parentElm.attribute(QObject::tr("BondIterationsPerFrame")).toUInt();
+ stressSolver.graphReductionLevel = parentElm.attribute(QObject::tr("GraphReductionLevel")).toUInt();
+}
+
+void BlastProject::_saveFracturePreset(QDomElement& parentElm, FracturePreset& fracturePreset)
+{
+ QDomElement newElm = parentElm.ownerDocument().createElement(QObject::tr("FracturePreset"));
+ parentElm.appendChild(newElm);
+ newElm.setAttribute(QObject::tr("Name"), fracturePreset.name.c_str());
+
+ if (eFractureType_Voronoi == fracturePreset.type)
+ {
+ _saveFracture(newElm, fracturePreset.fracture.voronoi);
+ }
+ else if (eFractureType_Slice == fracturePreset.type)
+ {
+ _saveFracture(newElm, fracturePreset.fracture.slice);
+ }
+
+ QDomElement visualizationElm = parentElm.ownerDocument().createElement(QObject::tr("Visualization"));
+ newElm.appendChild(visualizationElm);
+ visualizationElm.setAttribute(QObject::tr("FracturePreview"), fracturePreset.visualization.fracturePreview);
+ visualizationElm.setAttribute(QObject::tr("DisplayFractureWidget"), fracturePreset.visualization.displayFractureWidget);
+}
+
+void BlastProject::_saveFracture(QDomElement& parentElm, BPPVoronoi& voronoi)
+{
+ QDomElement newElm = parentElm.ownerDocument().createElement(QObject::tr("Voronoi"));
+ parentElm.appendChild(newElm);
+ newElm.setAttribute(QObject::tr("SiteGeneration"), voronoi.siteGeneration);
+ newElm.setAttribute(QObject::tr("NumSites"), voronoi.numSites);
+ newElm.setAttribute(QObject::tr("NumberOfClusters"), voronoi.numberOfClusters);
+ newElm.setAttribute(QObject::tr("SitesPerCluster"), voronoi.sitesPerCluster);
+ newElm.setAttribute(QObject::tr("ClusterRadius"), voronoi.clusterRadius);
+}
+
+void BlastProject::_saveFracture(QDomElement& parentElm, BPPSlice& slice)
+{
+ QDomElement newElm = parentElm.ownerDocument().createElement(QObject::tr("Slice"));
+ parentElm.appendChild(newElm);
+ newElm.setAttribute(QObject::tr("NumSlicesX"), slice.numSlicesX);
+ newElm.setAttribute(QObject::tr("NumSlicesY"), slice.numSlicesY);
+ newElm.setAttribute(QObject::tr("NumSlicesZ"), slice.numSlicesZ);
+ newElm.setAttribute(QObject::tr("OffsetVariation"), slice.offsetVariation);
+ newElm.setAttribute(QObject::tr("RotationVariation"), slice.rotationVariation);
+ newElm.setAttribute(QObject::tr("NoiseAmplitude"), slice.noiseAmplitude);
+ newElm.setAttribute(QObject::tr("NoiseFrequency"), slice.noiseFrequency);
+ newElm.setAttribute(QObject::tr("NoiseOctaveNumber"), slice.noiseOctaveNumber);
+ newElm.setAttribute(QObject::tr("NoiseSeed"), slice.noiseSeed);
+ newElm.setAttribute(QObject::tr("SurfaceResolution"), slice.surfaceResolution);
+}
+
+void BlastProject::_loadFracturePreset(QDomElement& parentElm, FracturePreset& fracturePreset)
+{
+ fracturePreset.name = parentElm.attribute(QObject::tr("Name")).toUtf8().data();
+
+ QDomElement elm = parentElm.firstChildElement(QObject::tr("Voronoi"));
+ if (!elm.isNull())
+ {
+ fracturePreset.type = eFractureType_Voronoi;
+ _loadFracture(elm, fracturePreset.fracture.voronoi);
+ }
+ elm = parentElm.firstChildElement(QObject::tr("Slice"));
+ if (!elm.isNull())
+ {
+ fracturePreset.type = eFractureType_Slice;
+ _loadFracture(elm, fracturePreset.fracture.slice);
+ }
+
+ elm = parentElm.firstChildElement(QObject::tr("Visualization"));
+ if (!elm.isNull())
+ {
+ /*
+ std::string str0 = parentElm.attribute(QObject::tr("FracturePreview")).toStdString();
+ std::string str1 = parentElm.attribute(QObject::tr("DisplayFractureWidget")).toStdString();
+ uint val0 = parentElm.attribute(QObject::tr("FracturePreview")).toUInt();
+ uint val1 = parentElm.attribute(QObject::tr("DisplayFractureWidget")).toUInt();
+ */
+ fracturePreset.visualization.fracturePreview = elm.attribute(QObject::tr("FracturePreview")).toUInt();
+ fracturePreset.visualization.displayFractureWidget = elm.attribute(QObject::tr("DisplayFractureWidget")).toUInt();
+ }
+}
+
+void BlastProject::_loadFracture(QDomElement& parentElm, BPPVoronoi& voronoi)
+{
+ voronoi.siteGeneration = parentElm.attribute(QObject::tr("SiteGeneration")).toInt();
+ voronoi.numSites = parentElm.attribute(QObject::tr("NumSites")).toUInt();
+ voronoi.numberOfClusters = parentElm.attribute(QObject::tr("NumberOfClusters")).toUInt();
+ voronoi.sitesPerCluster = parentElm.attribute(QObject::tr("SitesPerCluster")).toFloat();
+ voronoi.clusterRadius = parentElm.attribute(QObject::tr("ClusterRadius")).toFloat();
+}
+
+void BlastProject::_loadFracture(QDomElement& parentElm, BPPSlice& slice)
+{
+ slice.numSlicesX = parentElm.attribute(QObject::tr("NumSlicesX")).toUInt();
+ slice.numSlicesY = parentElm.attribute(QObject::tr("NumSlicesY")).toUInt();
+ slice.numSlicesZ = parentElm.attribute(QObject::tr("NumSlicesZ")).toUInt();
+ slice.offsetVariation = parentElm.attribute(QObject::tr("OffsetVariation")).toFloat();
+ slice.rotationVariation = parentElm.attribute(QObject::tr("RotationVariation")).toFloat();
+ slice.noiseAmplitude = parentElm.attribute(QObject::tr("NoiseAmplitude")).toFloat();
+ slice.noiseFrequency = parentElm.attribute(QObject::tr("NoiseFrequency")).toFloat();
+ slice.noiseOctaveNumber = parentElm.attribute(QObject::tr("NoiseOctaveNumber")).toUInt();
+ slice.noiseSeed = parentElm.attribute(QObject::tr("NoiseSeed")).toUInt();
+ slice.surfaceResolution = parentElm.attribute(QObject::tr("SurfaceResolution")).toUInt();
+}
+
+void BlastProject::_saveFilterPreset(QDomElement& parentElm, FilterPreset& filterPreset)
+{
+ QDomElement newElm = parentElm.ownerDocument().createElement(QObject::tr("FilterPreset"));
+ parentElm.appendChild(newElm);
+ newElm.setAttribute(QObject::tr("Name"), filterPreset.name.c_str());
+
+ for (EFilterRestriction restriction : filterPreset.filters)
+ _saveRestriction(newElm, restriction);
+}
+
+void BlastProject::_saveRestriction(QDomElement& parentElm, EFilterRestriction& restriction)
+{
+ QDomElement newElm = parentElm.ownerDocument().createElement(QObject::tr("Restriction"));
+ parentElm.appendChild(newElm);
+ newElm.setAttribute(QObject::tr("Value"), convertFilterRestrictionToString(restriction));
+}
+
+void BlastProject::_loadFilterPreset(QDomElement& parentElm, FilterPreset& filterPreset)
+{
+ filterPreset.name = parentElm.attribute(QObject::tr("Name")).toUtf8().data();
+
+ QDomNodeList nodeList = parentElm.childNodes();
+ for (int i = 0; i < nodeList.count(); ++i)
+ {
+ QDomNode& node = nodeList.at(i);
+ QDomElement elm = node.toElement();
+ if (elm.isNull() || elm.nodeName() != "Restriction")
+ continue;
+
+ EFilterRestriction restriction;
+ _loadRestriction(elm, restriction);
+ filterPreset.filters.push_back(restriction);
+ }
+}
+
+void BlastProject::_loadRestriction(QDomElement& parentElm, EFilterRestriction& restriction)
+{
+ restriction = (EFilterRestriction)(convertStringToFilterRestriction(parentElm.attribute(QObject::tr("Value")).toUtf8().data()));
}
void BlastProject::_addStringItem(BPPStringArray& theArray, const char* name)
@@ -2101,7 +3086,7 @@ bool ProjectParamsLoad(const char* filePath,
return false;
}
- scene->Clear();
+// scene->Clear();
for (int idx = 0; idx < (int)data.size(); ++idx) {
NvParameterized::Interface* iface = data[idx];
diff --git a/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.h b/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.h
index fa7adf7..cfc0b7f 100644
--- a/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.h
+++ b/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.h
@@ -2,7 +2,7 @@
#include "BlastProjectParameters.h"
#include <QtCore/QVector>
-
+#include <set>
class QDomElement;
typedef nvidia::parameterized::BlastProjectParametersNS::ParametersStruct BPParams;
@@ -19,36 +19,30 @@ typedef nvidia::parameterized::BlastProjectParametersNS::StressSolver_Type BPPSt
typedef nvidia::parameterized::BlastProjectParametersNS::SupportStructure_Type BPPSupportStructure;
typedef nvidia::parameterized::BlastProjectParametersNS::Bond_Type BPPBond;
typedef nvidia::parameterized::BlastProjectParametersNS::Chunk_Type BPPChunk;
+typedef nvidia::parameterized::BlastProjectParametersNS::DamageStruct_Type BPPDamageStruct;
typedef nvidia::parameterized::BlastProjectParametersNS::DefaultDamage_Type BPPDefaultDamage;
typedef nvidia::parameterized::BlastProjectParametersNS::BlastAsset_Type BPPAsset;
typedef nvidia::parameterized::BlastProjectParametersNS::BlastAssetInstance_Type BPPAssetInstance;
-typedef nvidia::parameterized::BlastProjectParametersNS::Projectile_Type BPPProjectile;
-typedef nvidia::parameterized::BlastProjectParametersNS::Landmark_Type BPPLandmark;
-typedef nvidia::parameterized::BlastProjectParametersNS::BlastComposite_Type BPPComposite;
typedef nvidia::parameterized::BlastProjectParametersNS::Blast_Type BPPBlast;
typedef nvidia::parameterized::BlastProjectParametersNS::FractureGeneral_Type BPPFractureGeneral;
typedef nvidia::parameterized::BlastProjectParametersNS::FractureVisualization_Type BPPFractureVisualization;
-typedef nvidia::parameterized::BlastProjectParametersNS::ShellCut_Type BPPShellCut;
typedef nvidia::parameterized::BlastProjectParametersNS::Voronoi_Type BPPVoronoi;
typedef nvidia::parameterized::BlastProjectParametersNS::Slice_Type BPPSlice;
-typedef nvidia::parameterized::BlastProjectParametersNS::CutoutProjection_Type BPPCutoutProjection;
typedef nvidia::parameterized::BlastProjectParametersNS::Fracture_Type BPPFracture;
-typedef nvidia::parameterized::BlastProjectParametersNS::FilterPreset_Type BPPFilterPreset;
typedef nvidia::parameterized::BlastProjectParametersNS::Filter_Type BPPFilter;
typedef nvidia::parameterized::BlastProjectParametersNS::CameraBookmark_DynamicArray1D_Type BPPBookmarkArray;
typedef nvidia::parameterized::BlastProjectParametersNS::STRING_DynamicArray1D_Type BPPStringArray;
typedef nvidia::parameterized::BlastProjectParametersNS::GraphicsMaterial_DynamicArray1D_Type BPPGraphicsMaterialArray;
-typedef nvidia::parameterized::BlastProjectParametersNS::GraphicsMesh_DynamicArray1D_Type BPPGraphicsMeshArray;
+typedef nvidia::parameterized::BlastProjectParametersNS::MaterialAssignments_DynamicArray1D_Type BPPMaterialAssignmentsArray;
typedef nvidia::parameterized::BlastProjectParametersNS::Light_DynamicArray1D_Type BPPLightArray;
typedef nvidia::parameterized::BlastProjectParametersNS::Chunk_DynamicArray1D_Type BPPChunkArray;
typedef nvidia::parameterized::BlastProjectParametersNS::Bond_DynamicArray1D_Type BPPBondArray;
-typedef nvidia::parameterized::BlastProjectParametersNS::Projectile_DynamicArray1D_Type BPPProjectileArray;
typedef nvidia::parameterized::BlastProjectParametersNS::BlastAsset_DynamicArray1D_Type BPPAssetArray;
typedef nvidia::parameterized::BlastProjectParametersNS::BlastAssetInstance_DynamicArray1D_Type BPPAssetInstanceArray;
-typedef nvidia::parameterized::BlastProjectParametersNS::Landmark_DynamicArray1D_Type BPPLandmarkArray;
-typedef nvidia::parameterized::BlastProjectParametersNS::FilterPreset_DynamicArray1D_Type BPPFilterPresetArray;
-typedef nvidia::parameterized::BlastProjectParametersNS::U32_DynamicArray1D_Type BPPU32Array;
+typedef nvidia::parameterized::BlastProjectParametersNS::I32_DynamicArray1D_Type BPPI32Array;
+typedef nvidia::parameterized::BlastProjectParametersNS::VEC3_DynamicArray1D_Type BPPVEC3Array;
+typedef nvidia::parameterized::BlastProjectParametersNS::VEC2_DynamicArray1D_Type BPPVEC2Array;
void freeString(NvParameterized::DummyStringStruct& str);
void freeBlast(BPPGraphicsMesh& data);
@@ -56,33 +50,34 @@ void freeBlast(BPPChunk& data);
void freeBlast(BPPBond& data);
void freeBlast(BPPAsset& data);
void freeBlast(BPPAssetInstance& data);
-void freeBlast(BPPComposite& data);
void freeBlast(BPPBlast& data);
-void freeBlast(BPPLandmark& data);
+void freeBlast(BPPGraphicsMaterial& data);
+void freeBlast(BPPDefaultDamage& data);
void freeBlast(BPPStringArray& data);
-void freeBlast(BPPGraphicsMeshArray& data);
void freeBlast(BPPChunkArray& data);
void freeBlast(BPPBondArray& data);
void freeBlast(BPPAssetArray& data);
void freeBlast(BPPAssetInstanceArray& data);
-void freeBlast(BPPLandmarkArray& data);
+void freeBlast(BPPGraphicsMaterialArray& data);
void copy(NvParameterized::DummyStringStruct& dest, const char* source);
void copy(NvParameterized::DummyStringStruct& dest, NvParameterized::DummyStringStruct& source);
+bool isItemExist(BPPStringArray& dest, const char* item);
+void addItem(BPPStringArray& dest, const char* item);
+void removeItem(BPPStringArray& dest, const char* item);
void copy(BPPStringArray& dest, BPPStringArray& source);
void copy(BPPGraphicsMaterialArray& dest, BPPGraphicsMaterialArray& source);
-void copy(BPPGraphicsMeshArray& dest, BPPGraphicsMeshArray& source);
+void copy(BPPMaterialAssignmentsArray& dest, BPPMaterialAssignmentsArray& source);
void copy(BPPBookmarkArray& dest, BPPBookmarkArray& source);
void copy(BPPLightArray& dest, BPPLightArray& source);
void copy(BPPChunkArray& dest, BPPChunkArray& source);
void copy(BPPBondArray& dest, BPPBondArray& source);
-void copy(BPPProjectileArray& dest, BPPProjectileArray& source);
void copy(BPPAssetArray& dest, BPPAssetArray& source);
void copy(BPPAssetInstanceArray& dest, BPPAssetInstanceArray& source);
-void copy(BPPLandmarkArray& dest, BPPLandmarkArray& source);
-void copy(BPPU32Array& dest, BPPU32Array& source);
-void copy(BPPFilterPresetArray& dest, BPPFilterPresetArray& source);
+void copy(BPPI32Array& dest, BPPI32Array& source);
+void copy(BPPVEC3Array& dest, BPPVEC3Array& source);
+void copy(BPPVEC2Array& dest, BPPVEC2Array& source);
void copy(BPPLight& dest, BPPLight& source);
void copy(BPPRenderer& dest, BPPRenderer& source);
@@ -91,28 +86,87 @@ void copy(BPPGraphicsMesh& dest, BPPGraphicsMesh& source);
void copy(BPPMaterialAssignments& dest, BPPMaterialAssignments& source);
void copy(BPPChunk& dest, BPPChunk& source);
void copy(BPPBond& dest, BPPBond& source);
-void copy(BPPProjectile& dest, BPPProjectile& source);
void copy(BPPSupportStructure& dest, BPPSupportStructure& source);
-void copy(BPPLandmark& dest, BPPLandmark& source);
void copy(BPPStressSolver& dest, BPPStressSolver& source);
void copy(BPPAsset& dest, BPPAsset& source);
void copy(BPPAssetInstance& dest, BPPAssetInstance& source);
-void copy(BPPComposite& dest, BPPComposite& source);
void copy(BPPBlast& dest, BPPBlast& source);
-void copy(BPPFilter& dest, BPPFilter& source);
+void copy(BPPFractureGeneral& dest, BPPFractureGeneral& source);
void copy(BPPVoronoi& dest, BPPVoronoi& source);
-void copy(BPPCutoutProjection& dest, BPPCutoutProjection& source);
void copy(BPPFracture& dest, BPPFracture& source);
-void copy(BPPFilterPreset& dest, BPPFilterPreset& source);
+void copy(BPPDefaultDamage& dest, BPPDefaultDamage& source);
+void copy(BPPFilter& dest, BPPFilter& source);
void copy(BPParams& dest, BPParams& source);
+void merge(BPPAssetArray& dest, BPPAssetArray& source);
+void merge(BPPAssetInstanceArray& dest, BPPAssetInstanceArray& source);
void merge(BPPChunkArray& dest, BPPChunkArray& source);
void merge(BPPBondArray& dest, BPPBondArray& source);
+/*
+void apart(BPPAssetArray& dest, BPPAssetArray& source);
+void apart(BPPAssetInstanceArray& dest, BPPAssetInstanceArray& source);
+void apart(BPPChunkArray& dest, BPPChunkArray& source);
+void apart(BPPBondArray& dest, BPPBondArray& source);
+*/
+void apart(BPPAssetArray& dest, int32_t assetId);
+void apart(BPPAssetInstanceArray& dest, int32_t assetId);
+void apart(BPPAssetInstanceArray& dest, int32_t assetId, const char* instanceName);
+void apart(BPPChunkArray& dest, int32_t assetId);
+void apart(BPPBondArray& dest, int32_t assetId);
+
+template <class T>
+void init(T& param)
+{
+ param.buf = nullptr;
+ param.arraySizes[0] = 0;
+}
void init(BPPStressSolver& param);
void init(BPPGraphicsMaterial& param);
+void init(BPPGraphicsMesh& param);
+void init(BPPBond& param);
+void init(BPPChunk& param);
+void init(BPPDefaultDamage& param);
+void init(BPPAsset& param);
+void init(BPPAssetInstance& param);
+void init(BPPVoronoi& param);
+void init(BPPSlice& param);
+void init(BPPFractureVisualization& param);
void init(BPParams& params);
+enum EFilterRestriction
+{
+ eFilterRestriction_Invalid = 0x0000,
+ eFilterRestriction_AllDescendants = 0x0001 << 0,
+ eFilterRestriction_AllParents = 0x0001 << 1,
+ eFilterRestriction_DepthAll = 0x0001 << 2,
+ eFilterRestriction_Depth0 = 0x0001 << 3,
+ eFilterRestriction_Depth1 = 0x0001 << 4,
+ eFilterRestriction_Depth2 = 0x0001 << 5,
+ eFilterRestriction_Depth3 = 0x0001 << 6,
+ eFilterRestriction_Depth4 = 0x0001 << 7,
+ eFilterRestriction_Depth5 = 0x0001 << 8,
+ eFilterRestriction_ItemTypeAll = 0x0001 << 9,
+ eFilterRestriction_Chunk = 0x0001 << 10,
+ eFilterRestriction_SupportChunk = 0x0001 << 11,
+ eFilterRestriction_StaticSupportChunk = 0x0001 << 12,
+ eFilterRestriction_Bond = 0x0001 << 13,
+ eFilterRestriction_WorldBond = 0x0001 << 14,
+ eFilterRestriction_EqualTo = 0x0001 << 15,
+ eFilterRestriction_NotEquaTo = 0x0001 << 16,
+
+};
+
+const char* convertFilterRestrictionToString(EFilterRestriction& restriction);
+EFilterRestriction convertStringToFilterRestriction(const char* restriction);
+
+struct FilterPreset
+{
+ FilterPreset(const char* inName);
+ std::string name;
+ std::vector<EFilterRestriction> filters;
+};
+
struct StressSolverUserPreset
{
StressSolverUserPreset(const char* inName);
@@ -120,6 +174,30 @@ struct StressSolverUserPreset
BPPStressSolver stressSolver;
};
+enum FractureType
+{
+ eFractureType_Voronoi,
+ eFractureType_Slice,
+};
+struct FracturePreset
+{
+ FracturePreset(const char* inName, FractureType inType);
+
+ void setType(FractureType inType);
+
+ FractureType type;
+ std::string name;
+
+ void init();
+ union
+ {
+ BPPVoronoi voronoi;
+ BPPSlice slice;
+ } fracture;
+
+ BPPFractureVisualization visualization;
+};
+
class BlastProject
{
public:
@@ -131,28 +209,39 @@ public:
void clear();
+ std::string getAseetNameByID(int assetID);
+ int getAssetIDByName(const char* name);
+ BPPAsset* getAsset(const char* name);
+ int generateNewAssetID();
+
bool isGraphicsMaterialNameExist(const char* name);
- BPPGraphicsMaterial* addGraphicsMaterial(const char* name, const char* diffuseTexture);
+ BPPGraphicsMaterial* addGraphicsMaterial(const char* name);
void removeGraphicsMaterial(const char* name);
void renameGraphicsMaterial(const char* oldName, const char* newName);
-
- std::vector<BPPAsset*> getSelectedBlastAssets(void);
+ void reloadDiffuseColor(const char* name, float r, float g, float b, float a = 1.0);
+ void reloadSpecularColor(const char* name, float r, float g, float b, float a = 1.0);
+ void reloadSpecularShininess(const char* name, float specularShininess);
+ void reloadDiffuseTexture(const char* name, const char* diffuseTexture);
+ void reloadSpecularTexture(const char* name, const char* specularTexture);
+ void reloadNormalTexture(const char* name, const char* normalTexture);
+ void reloadEnvTexture(const char* name, const char* envTexture);
+ BPPGraphicsMaterial* getGraphicsMaterial(const char* name);
+ std::string generateNewMaterialName(const char* name);
bool isAssetInstanceNameExist(const char* name);
- BPPAssetInstance* getAssetInstance(const char* assetPath, int instanceIndex);
+ int getAssetInstanceCount(int assetID);
+ void getAssetInstances(int assetID, std::vector<BPPAssetInstance*>& instances);
+ BPPAssetInstance* getAssetInstance(int assetID, int instanceIndex);
+ BPPAssetInstance* getAssetInstance(int assetID, const char* instanceName);
BPPAssetInstance* addAssetInstance(int blastAssetIndex, const char* instanceName);
void removeAssetInstance(const char* name);
- BPPChunk* getChunk(BPPAsset& asset, int id);
+ BPPChunk* getChunk(BPPAsset& asset, int chunkID);
std::vector<BPPChunk*> getChildrenChunks(BPPAsset& asset, int parentID);
std::vector<BPPChunk*> getChildrenChunks(BPPAsset& asset);
+ std::vector<BPPChunk*> getChildrenChunks(int assetID);
std::vector<BPPBond*> getBondsByChunk(BPPAsset& asset, int chunkID);
-
- bool isLandmarkNameExist(const char* name);
- BPPLandmark* addLandmark(const char* name);
- void removeLandmark(const char* name);
- BPPLandmark* getLandmark(const char* name);
- void renameLandmark(const char* oldName, const char* newName);
+ std::vector<BPPBond*> getChildrenBonds(BPPAsset& asset);
bool isUserPresetNameExist(const char* name);
std::vector<StressSolverUserPreset>& getUserPresets();
@@ -160,30 +249,22 @@ public:
void saveUserPreset();
void loadUserPreset();
+ bool isFracturePresetNameExist(const char* name);
+ std::vector<FracturePreset>& getFracturePresets();
+ void addFracturePreset(const char* name, FractureType type);
+ void saveFracturePreset();
+ void loadFracturePreset();
+
bool isFilterPresetNameExist(const char* name);
- std::vector<BPPFilterPreset*> getFilterPresets();
+ std::vector<FilterPreset>& getFilterPresets();
void addFilterPreset(const char* name);
void removeFilterPreset(const char* name);
- BPPFilterPreset* getFilterPreset(const char* name);
+ FilterPreset* getFilterPreset(const char* name);
void renameFilterPreset(const char* oldName, const char* newName);
- void addFilterDepth(const char* filterName, int depth);
- void removeFilterDepth(const char* filterName, int depth);
-
- bool isCutoutTextureNameExist(const char* name);
- void addCutoutTexture(const char* name);
- void removeCutoutTexture(const char* name);
-
- bool isPaintMaskNameExist(const char* name);
- void addPaintMasks(const char* name);
- void removePaintMasks(const char* name);
-
- bool isMeshCutterNameExist(const char* name);
- void addMeshCutter(const char* name);
- void removeMeshCutter(const char* name);
-
- bool isVoronoiTextureNameExist(const char* name);
- void addVoronoiTexture(const char* name);
- void removeVoronoiTexture(const char* name);
+ void addFilterRestriction(const char* filterName, EFilterRestriction restriction);
+ void removeFilterRestriction(const char* filterName, EFilterRestriction restriction);
+ void saveFilterPreset();
+ void loadFilterPreset();
private:
BlastProject();
@@ -192,12 +273,26 @@ private:
void _loadStressSolverPreset(QDomElement& parentElm, StressSolverUserPreset& stressSolverUserPreset);
void _loadStressSolver(QDomElement& parentElm, BPPStressSolver& stressSolver);
+ void _saveFracturePreset(QDomElement& parentElm, FracturePreset& fracturePreset);
+ void _saveFracture(QDomElement& parentElm, BPPVoronoi& voronoi);
+ void _saveFracture(QDomElement& parentElm, BPPSlice& slice);
+ void _loadFracturePreset(QDomElement& parentElm, FracturePreset& fracturePreset);
+ void _loadFracture(QDomElement& parentElm, BPPVoronoi& voronoi);
+ void _loadFracture(QDomElement& parentElm, BPPSlice& slice);
+
+ void _saveFilterPreset(QDomElement& parentElm, FilterPreset& filterPreset);
+ void _saveRestriction(QDomElement& parentElm, EFilterRestriction& restriction);
+ void _loadFilterPreset(QDomElement& parentElm, FilterPreset& filterPreset);
+ void _loadRestriction(QDomElement& parentElm, EFilterRestriction& restriction);
+
void _addStringItem(BPPStringArray& theArray, const char* name);
void _removeStringItem(BPPStringArray& theArray, const char* name);
private:
BPParams _projectParams;
std::vector<StressSolverUserPreset> _userPresets;
+ std::vector<FracturePreset> _fracturePresets;
+ std::vector<FilterPreset> _filterPresets;
};
bool CreateProjectParamsContext();
diff --git a/tools/ArtistTools/source/BlastPlugin/Parameters/go.bat b/tools/ArtistTools/source/BlastPlugin/Parameters/go.bat
new file mode 100644
index 0000000..4a5b6c9
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/Parameters/go.bat
@@ -0,0 +1,3 @@
+@if "%PERL%"=="" set PERL=..\..\..\..\..\..\..\external\perl\5.8.8_822\bin\perl.exe
+@%PERL% ..\..\..\..\..\..\..\external\NvParameterized\1.1\trunk\build\scripts\GenParameterized.pl -force BlastProjectParams.pl . .
+
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/Sample.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/Sample.h
index c9fa503..2499deb 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/Sample.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/Sample.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef SAMPLE_H
#define SAMPLE_H
@@ -21,7 +39,7 @@ struct AssetList
struct BoxAsset
{
BoxAsset() : staticHeight(-std::numeric_limits<float>().infinity()),
- jointAllBonds(false), extents(20, 20, 20)
+ jointAllBonds(false), extents(20, 20, 20), bondFlags(7)
{}
struct Level
@@ -38,6 +56,7 @@ struct AssetList
float staticHeight;
bool jointAllBonds;
std::vector<Level> levels;
+ uint32_t bondFlags;
};
struct ModelAsset
@@ -48,6 +67,7 @@ struct AssetList
std::string id;
std::string file;
std::string name;
+ std::string fullpath;
physx::PxTransform transform;
bool isSkinned;
};
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.cpp
index 01f8fd6..c39d927 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.cpp
@@ -1,25 +1,117 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "BlastAsset.h"
#include "NvBlastExtPxAsset.h"
#include "NvBlastTkAsset.h"
#include <map>
+#include <algorithm>
+// Add By Lixu Begin
+#include "BlastSceneTree.h"
+#include "SampleManager.h"
+// Add By Lixu End
+
BlastAsset::BlastAsset(Renderer& renderer)
- : m_renderer(renderer)
+ : m_renderer(renderer), m_bondHealthMax(1.0f), m_supportChunkHealthMax(1.0f)
{
}
-void BlastAsset::validate()
+void BlastAsset::initialize()
{
+// Add By Lixu Begin
+ BPPBlast& blast = BlastProject::ins().getParams().blast;
+ BPPChunkArray& chunks = blast.chunks;
+ BPPBondArray& bonds = blast.bonds;
+
+ std::vector<float> BondHealths;
+ SampleManager* pSampleManager = SampleManager::ins();
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itASM = AssetDescMap.find(this);
+ AssetList::ModelAsset m;
+ if (itASM != AssetDescMap.end())
+ {
+ m = itASM->second;
+ }
+
+ int assetID = BlastProject::ins().getAssetIDByName(m.name.c_str());
+ for (int bc = 0; bc < bonds.arraySizes[0]; bc++)
+ {
+ BPPBond& bond = bonds.buf[bc];
+ if (bond.asset == assetID)
+ {
+ BondHealths.push_back(bond.support.bondStrength);
+ }
+ }
+
+ const TkAsset& tkAsset = m_pxAsset->getTkAsset();
+ uint32_t bondCount = tkAsset.getBondCount();
+
+ const float* pBondHealths = nullptr;
+ if (bondCount == BondHealths.size())
+ {
+ pBondHealths = BondHealths.data();
+ }
+
+ const NvBlastActorDesc& defaultActorDesc = m_pxAsset->getDefaultActorDesc();
+ NvBlastActorDesc newActorDesc = defaultActorDesc;
+ newActorDesc.initialBondHealths = pBondHealths;
+// Add By Lixu End
+
+ // calc max healths
+ const NvBlastActorDesc& actorDesc = newActorDesc;
+ if (actorDesc.initialBondHealths)
+ {
+ m_bondHealthMax = FLT_MIN;
+ const uint32_t bondCount = m_pxAsset->getTkAsset().getBondCount();
+ for (uint32_t i = 0; i < bondCount; ++i)
+ {
+ m_bondHealthMax = std::max<float>(m_bondHealthMax, actorDesc.initialBondHealths[i]);
+ }
+ }
+ else
+ {
+ m_bondHealthMax = actorDesc.uniformInitialBondHealth;
+ }
+
+ if(actorDesc.initialSupportChunkHealths)
+ {
+ m_supportChunkHealthMax = FLT_MIN;
+ const uint32_t nodeCount = m_pxAsset->getTkAsset().getGraph().nodeCount;
+ for (uint32_t i = 0; i < nodeCount; ++i)
+ {
+ m_supportChunkHealthMax = std::max<float>(m_supportChunkHealthMax, actorDesc.initialSupportChunkHealths[i]);
+ }
+ }
+ else
+ {
+ m_supportChunkHealthMax = actorDesc.uniformInitialLowerSupportChunkHealth;
+ }
}
size_t BlastAsset::getBlastAssetSize() const
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.h
index b2e2f38..5502c5c 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_ASSET_H
#define BLAST_ASSET_H
@@ -16,6 +34,7 @@
#include "PxTransform.h"
#include "NvBlastTypes.h"
+
using namespace physx;
class Renderer;
@@ -77,11 +96,22 @@ public:
size_t getBlastAssetSize() const;
std::vector<uint32_t> getChunkIndexesByDepth(uint32_t depth) const;
+
+ float getBondHealthMax() const
+ {
+ return m_bondHealthMax;
+ }
+
+ float getSupportChunkHealthMax() const
+ {
+ return m_bondHealthMax;
+ }
+
+ void initialize();
protected:
//////// internal operations ////////
- void validate();
//////// input data ////////
@@ -92,6 +122,8 @@ protected:
//////// internal data ////////
ExtPxAsset* m_pxAsset;
+ float m_bondHealthMax;
+ float m_supportChunkHealthMax;
};
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.cpp
index dfa0138..4bd9766 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "BlastAssetBoxes.h"
#include "BlastFamilyBoxes.h"
@@ -23,9 +41,9 @@ BlastAssetBoxes::BlastAssetBoxes(TkFramework& framework, PxPhysics& physics, PxC
// asset desc / tk asset
ExtPxAssetDesc assetDesc;
- assetDesc.chunkDescs = &m_generatorAsset.solverChunks[0];
+ assetDesc.chunkDescs = m_generatorAsset.solverChunks.data();
assetDesc.chunkCount = (uint32_t)m_generatorAsset.solverChunks.size();
- assetDesc.bondDescs = m_generatorAsset.solverBonds.size() > 0 ? &m_generatorAsset.solverBonds[0] : nullptr;
+ assetDesc.bondDescs = m_generatorAsset.solverBonds.data();
assetDesc.bondCount = (uint32_t)m_generatorAsset.solverBonds.size();
std::vector<uint8_t> bondFlags(assetDesc.bondCount);
std::fill(bondFlags.begin(), bondFlags.end(), desc.jointAllBonds ? 1 : 0);
@@ -67,7 +85,7 @@ BlastAssetBoxes::BlastAssetBoxes(TkFramework& framework, PxPhysics& physics, PxC
assetDesc.pxChunks = pxChunks.data();
m_pxAsset = ExtPxAsset::create(assetDesc, framework);
- validate();
+ initialize();
}
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.h
index 518e93d..d4f8dd2 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_ASSET_BOXES_H
#define BLAST_ASSET_BOXES_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.cpp
index 756b520..2c39824 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.cpp
@@ -1,69 +1,236 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "GlobalSettings.h"
+#include <QtCore/QFile>
#include "BlastAssetModel.h"
#include "Renderer.h"
#include "BlastController.h"
#include "Utils.h"
-#include "PsFileBuffer.h"
+#include "ResourceManager.h"
#include "NvBlastExtPxAsset.h"
-#include <QtCore/QFile>
#include <sstream>
+#include <fstream>
+#include "NvBlastExtExporterFbxReader.h"
+#include "PxPhysics.h"
+#include <NvBlastGlobals.h>
+#include "NvBlastExtAssetUtils.h"
+#include "NvBlastExtPxAsset.h"
+#include "NvBlastTkAsset.h"
+#include "NvBlastExtSerialization.h"
+#include "NvBlastExtLlSerialization.h"
+#include "NvBlastExtTkSerialization.h"
+#include "NvBlastExtPxSerialization.h"
-
-BlastAssetModel::BlastAssetModel(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName, const char* modelPath)
+BlastAssetModel::BlastAssetModel(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, ExtSerialization& serialization, Renderer& renderer, const char* modelName, const char* modelPath)
: BlastAsset(renderer)
{
- // Add By Lixu Begin
if (modelPath == NULL)
{
GlobalSettings& globalSettings = GlobalSettings::Inst();
modelPath = globalSettings.m_projectFileDir.c_str();
assert(globalSettings.m_projectFileDir.length() > 0);
}
- // Physics Asset
- std::string blastFileName = std::string(modelName) + ".bpxa";
- // Add By Lixu Begin
- std::string path = GlobalSettings::MakeFileName(modelPath, blastFileName.c_str());
- if (QFile::exists(path.c_str()))
- {
- PsFileBuffer fileBuf(path.c_str(), PxFileBuf::OPEN_READ_ONLY);
- m_pxAsset = ExtPxAsset::deserialize(fileBuf, framework, physics);
- ASSERT_PRINT(m_pxAsset != nullptr, "can't load bpxa file");
- }
- else
- {
- ASSERT_PRINT(false, "wrong blastFilename");
- }
+
+ const float unitConversion = 1.f;
+
+ const NvcVec3 inputScale = { unitConversion, unitConversion, unitConversion };
+
+ std::string path;
// load obj file
- std::string objFileName = std::string(modelName) + ".obj";
- // Add By Lixu Begin
- path = GlobalSettings::MakeFileName(modelPath, objFileName.c_str());
+ std::ostringstream objFileName;
+ objFileName << modelName << ".obj";
+
+ path = GlobalSettings::MakeFileName(modelPath, objFileName.str().c_str());
if (QFile::exists(path.c_str()))
{
m_model = BlastModel::loadFromFileTinyLoader(path.c_str());
if (!m_model)
{
ASSERT_PRINT(false, "obj load failed");
+ }
+ }
+ else // Obj is not found, try FBX
+ {
+ objFileName.clear();
+ objFileName.str("");
+ objFileName << modelName << ".fbx";
+ path = GlobalSettings::MakeFileName(modelPath, objFileName.str().c_str());
+ if (QFile::exists(path.c_str()))
+ {
+ m_model = BlastModel::loadFromFbxFile(path.c_str());
+ if (!m_model)
+ {
+ ASSERT_PRINT(false, "fbx load failed");
+ }
+
+ }
+ else
+ {
+ ASSERT_PRINT(false, "mesh file not found");
}
}
- else
+
+ for (auto& chunk : m_model->chunks)
{
- ASSERT_PRINT(false, "wrong objFileName");
+ for (auto& mesh : chunk.meshes)
+ {
+ SimpleMesh& smesh = const_cast<SimpleMesh&>(mesh.mesh);
+ smesh.center *= unitConversion;
+ smesh.extents *= unitConversion;
+ for (auto& vertex : smesh.vertices)
+ {
+ vertex.position *= unitConversion;
+ }
+ }
}
- validate();
+ // Physics Asset
+
+ // Read file into buffer
+ std::ostringstream blastFileName;
+ blastFileName << modelName << ".blast";
+ path = GlobalSettings::MakeFileName(modelPath, blastFileName.str().c_str());
+ if (QFile::exists(path.c_str()))
+ {
+ std::ifstream stream(path.c_str(), std::ios::binary);
+ std::streampos size = stream.tellg();
+ stream.seekg(0, std::ios::end);
+ size = stream.tellg() - size;
+ stream.seekg(0, std::ios::beg);
+ std::vector<char> buffer(size);
+ stream.read(buffer.data(), buffer.size());
+ stream.close();
+ uint32_t objectTypeID;
+ void* asset = serialization.deserializeFromBuffer(buffer.data(), buffer.size(), &objectTypeID);
+ if (asset == nullptr)
+ {
+ ASSERT_PRINT(asset != nullptr, "can't load .blast file.");
+ }
+ else
+ if (objectTypeID == Nv::Blast::ExtPxObjectTypeID::Asset)
+ {
+ m_pxAsset = reinterpret_cast<ExtPxAsset*>(asset);
+ const TkAsset& tkAsset = m_pxAsset->getTkAsset();
+ NvBlastAsset* llasset = const_cast<NvBlastAsset*>(tkAsset.getAssetLL());
+ NvBlastExtAssetTransformInPlace(llasset, &inputScale, nullptr, nullptr);
+ ExtPxSubchunk* subchunks = const_cast<ExtPxSubchunk*>(m_pxAsset->getSubchunks());
+ for (uint32_t i = 0; i < m_pxAsset->getSubchunkCount(); ++i)
+ {
+ subchunks[i].geometry.scale.scale = PxVec3(unitConversion);
+ }
+ }
+ else
+ {
+ TkAsset* tkAsset = nullptr;
+ if (objectTypeID == Nv::Blast::TkObjectTypeID::Asset)
+ {
+ tkAsset = reinterpret_cast<TkAsset*>(asset);
+ NvBlastAsset* llasset = const_cast<NvBlastAsset*>(tkAsset->getAssetLL());
+ NvBlastExtAssetTransformInPlace(llasset, &inputScale, nullptr, nullptr);
+ }
+ else
+ if (objectTypeID == Nv::Blast::LlObjectTypeID::Asset)
+ {
+ NvBlastAsset* llasset = reinterpret_cast<NvBlastAsset*>(asset);
+ NvBlastExtAssetTransformInPlace(llasset, &inputScale, nullptr, nullptr);
+ tkAsset = framework.createAsset(llasset, nullptr, 0, true);
+ }
+ else
+ {
+ ASSERT_PRINT(false, ".blast file contains unknown object.");
+ }
+
+ if (tkAsset != nullptr)
+ {
+ std::vector<ExtPxAssetDesc::ChunkDesc> physicsChunks;
+ std::vector<std::vector<ExtPxAssetDesc::SubchunkDesc> > physicsSubchunks;
+ /**
+ Try find FBX and check whether it contains collision geometry.
+ */
+ objFileName.str("");
+ objFileName << modelName << ".fbx";
+ path = GlobalSettings::MakeFileName(modelPath, objFileName.str().c_str());
+ if (QFile::exists(path.c_str()))
+ {
+ FbxFileReader rdr;
+ rdr.loadFromFile(path);
+ if (rdr.isCollisionLoaded() == 0)
+ {
+ ASSERT_PRINT(false, "fbx doesn't contain collision geometry");
+ }
+ std::vector<std::vector<CollisionHull> > hulls;
+ rdr.getCollision(hulls);
+
+ /**
+ Create physics meshes;
+ */
+ Nv::Blast::ConvexMeshBuilder collisionBuilder(&cooking, &physics.getPhysicsInsertionCallback());
+ physicsChunks.resize(hulls.size());
+ physicsSubchunks.resize(hulls.size());
+
+ for (uint32_t i = 0; i < hulls.size(); ++i)
+ {
+ for (uint32_t sbHulls = 0; sbHulls < hulls[i].size(); ++sbHulls)
+ {
+ PxConvexMeshGeometry temp = physx::PxConvexMeshGeometry(collisionBuilder.buildConvexMesh(hulls[i][sbHulls]));
+ if (temp.isValid())
+ {
+ physicsSubchunks[i].push_back(ExtPxAssetDesc::SubchunkDesc());
+ physicsSubchunks[i].back().geometry = temp;
+ physicsSubchunks[i].back().transform = physx::PxTransform(physx::PxIdentity);
+ }
+ }
+ }
+ for (uint32_t i = 0; i < hulls.size(); ++i)
+ {
+ physicsChunks[i].isStatic = false;
+ physicsChunks[i].subchunkCount = (uint32_t)physicsSubchunks[i].size();
+ physicsChunks[i].subchunks = physicsSubchunks[i].data();
+ }
+ }
+ m_pxAsset = ExtPxAsset::create(tkAsset, physicsChunks.data(), (uint32_t)physicsChunks.size());
+ ASSERT_PRINT(m_pxAsset != nullptr, "can't create asset");
+ }
+ }
+ }
}
+BlastAssetModel::BlastAssetModel(ExtPxAsset* pExtPxAsset, BlastModel* pBlastModel, Renderer& renderer)
+ : BlastAsset(renderer)
+{
+ m_pxAsset = pExtPxAsset;
+ ASSERT_PRINT(m_pxAsset != nullptr, "m_pxAsset is nullptr");
+
+ m_model = pBlastModel;
+ ASSERT_PRINT(m_model != nullptr, "m_model is nullptr");
+}
BlastAssetModel::~BlastAssetModel()
{
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.h
index 334c8aa..9e13674 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_ASSET_MODEL_H
#define BLAST_ASSET_MODEL_H
@@ -26,6 +44,7 @@ namespace Nv
namespace Blast
{
class TkFramework;
+class ExtSerialization;
}
}
@@ -35,7 +54,8 @@ class BlastAssetModel : public BlastAsset
public:
//////// ctor ////////
- BlastAssetModel(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName, const char* modelPath = NULL);
+ BlastAssetModel(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, ExtSerialization& serialization, Renderer& renderer, const char* modelName, const char* modelPath = NULL);
+ BlastAssetModel(ExtPxAsset* pExtPxAsset, BlastModel* pBlastModel, Renderer& renderer);
virtual ~BlastAssetModel();
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.cpp
index 56c7441..c3db31d 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.cpp
@@ -1,12 +1,29 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
#include "BlastAssetModelSimple.h"
@@ -19,37 +36,38 @@
// BlastAssetModelSimple
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-BlastAssetModelSimple::BlastAssetModelSimple(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName)
- : BlastAssetModel(framework, physics, cooking, renderer, modelName)
+BlastAssetModelSimple::BlastAssetModelSimple(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, ExtSerialization& serialization, Renderer& renderer, const char* modelName)
+ : BlastAssetModel(framework, physics, cooking, serialization, renderer, modelName)
{
- // prepare materials
-// Add By Lixu Begin
- for (const BlastModel::Material& material : getModel().materials)
- {
- if (material.diffuseTexture.empty())
- m_renderMaterials.push_back(RenderMaterial::getDefaultRenderMaterial());
- else
- m_renderMaterials.push_back(new RenderMaterial(material.name.c_str(), renderer.getResourceManager(), "model_simple_textured_ex", material.diffuseTexture.c_str()));
- }
-// Add By Lixu End
- validate();
+ _init(renderer);
}
+BlastAssetModelSimple::BlastAssetModelSimple(ExtPxAsset* pExtPxAsset, BlastModel* pBlastModel, Renderer& renderer)
+ : BlastAssetModel(pExtPxAsset, pBlastModel, renderer)
+{
+ _init(renderer);
+}
BlastAssetModelSimple::~BlastAssetModelSimple()
{
- // release materials
- for (RenderMaterial* r : m_renderMaterials)
+ m_renderMaterialNames.clear();
+}
+
+void BlastAssetModelSimple::_init(Renderer& renderer)
+{
+ for (const BlastModel::Material& material : getModel().materials)
{
- if (r == RenderMaterial::getDefaultRenderMaterial())
+ std::string name = material.name;
+ if (name != "" && !BlastProject::ins().isGraphicsMaterialNameExist(name.c_str()))
{
- continue;
+ BlastProject::ins().addGraphicsMaterial(name.c_str());
+ BlastProject::ins().reloadDiffuseTexture(name.c_str(), material.diffuseTexture.c_str());
+ BlastProject::ins().reloadDiffuseColor(name.c_str(), material.r, material.g, material.b, material.a);
}
- SAFE_DELETE(r);
+ m_renderMaterialNames.push_back(name);
}
}
-
BlastFamilyPtr BlastAssetModelSimple::createFamily(PhysXController& physXConroller, ExtPxManager& pxManager, const ActorDesc& desc)
{
return BlastFamilyPtr(new BlastFamilyModelSimple(physXConroller, pxManager, m_renderer, *this, desc));
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.h
index 7e61616..ca3d995 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_ASSET_MODEL_SIMPLE_H
#define BLAST_ASSET_MODEL_SIMPLE_H
@@ -14,14 +32,14 @@
#include "BlastAssetModel.h"
-class RenderMaterial;
class BlastAssetModelSimple : public BlastAssetModel
{
public:
//////// ctor ////////
- BlastAssetModelSimple(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName);
+ BlastAssetModelSimple(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, ExtSerialization& serialization, Renderer& renderer, const char* modelName);
+ BlastAssetModelSimple(ExtPxAsset* pExtPxAsset, BlastModel* pBlastModel, Renderer& renderer);
virtual ~BlastAssetModelSimple();
@@ -32,16 +50,17 @@ public:
//////// data getters ////////
- const std::vector<RenderMaterial*>& getRenderMaterials() const
+ const std::vector<std::string>& getRenderMaterials() const
{
- return m_renderMaterials;
+ return m_renderMaterialNames;
}
private:
//////// private internal data ////////
+ void _init(Renderer& renderer);
- std::vector<RenderMaterial*> m_renderMaterials;
+ std::vector<std::string> m_renderMaterialNames;
};
#endif //BLAST_ASSET_MODEL_SIMPLE_H \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.cpp
index 5cf3a0d..747c2f4 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "BlastAssetModelSkinned.h"
#include "BlastFamilyModelSkinned.h"
@@ -14,8 +32,8 @@
#include "Renderer.h"
-BlastAssetModelSkinned::BlastAssetModelSkinned(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName)
- : BlastAssetModel(framework, physics, cooking, renderer, modelName)
+BlastAssetModelSkinned::BlastAssetModelSkinned(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, ExtSerialization& serialization, Renderer& renderer, const char* modelName)
+ : BlastAssetModel(framework, physics, cooking, serialization, renderer, modelName)
{
// Add By Lixu Begin
int index = 0;
@@ -30,7 +48,7 @@ BlastAssetModelSkinned::BlastAssetModelSkinned(TkFramework& framework, PxPhysics
m_renderMaterials.push_back(new RenderMaterial(modelName, renderer.getResourceManager(), "model_skinned_textured", material.diffuseTexture.c_str()));
}
// Add By Lixu End
- validate();
+ initialize();
}
BlastAssetModelSkinned::~BlastAssetModelSkinned()
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.h
index 149c8e8..e9c6784 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_ASSET_MODEL_SKINNED_H
#define BLAST_ASSET_MODEL_SKINNED_H
@@ -20,7 +38,7 @@ class BlastAssetModelSkinned : public BlastAssetModel
public:
//////// ctor ////////
- BlastAssetModelSkinned(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName);
+ BlastAssetModelSkinned(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, ExtSerialization& serialization, Renderer& renderer, const char* modelName);
virtual ~BlastAssetModelSkinned();
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.cpp
index 9cf4d3b..8df665e 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "BlastController.h"
#include "BlastFamily.h"
@@ -18,10 +36,16 @@
#include "Utils.h"
#include "Renderer.h"
+#include "NvBlastExtPxTask.h"
+
#include "NvBlast.h"
+#include "NvBlastPxCallbacks.h"
#include "NvBlastExtPxManager.h"
#include "NvBlastExtPxFamily.h"
#include "NvBlastExtPxActor.h"
+#include "NvBlastExtSerialization.h"
+#include "NvBlastExtTkSerialization.h"
+#include "NvBlastExtPxSerialization.h"
#include "NvBlastTkFramework.h"
@@ -43,65 +67,6 @@
#include "BlastSceneTree.h"
// Add By Lixu End
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// AllocatorCallback
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-class BlastAllocatorCallback : public PxAllocatorCallback
-{
-public:
- virtual void* allocate(size_t size, const char* typeName, const char* filename, int line) override
- {
- NV_UNUSED(typeName);
- NV_UNUSED(filename);
- NV_UNUSED(line);
- return malloc(size);
- }
-
- virtual void deallocate(void* ptr) override
- {
- free(ptr);
- }
-};
-BlastAllocatorCallback g_allocatorCallback;
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// ErrorCallback
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-class BlastErrorCallback : public PxErrorCallback
-{
-public:
- virtual void reportError(PxErrorCode::Enum code, const char* msg, const char* file, int line) override
- {
- std::stringstream str;
- str << "NvBlastTk ";
- bool critical = false;
- switch (code)
- {
- case PxErrorCode::eNO_ERROR: critical = false; break;
- case PxErrorCode::eDEBUG_INFO: str << "[Debug Info]"; critical = false; break;
- case PxErrorCode::eDEBUG_WARNING: str << "[Debug Warning]"; critical = false; break;
- case PxErrorCode::eINVALID_PARAMETER: str << "[Invalid Parameter]"; critical = true; break;
- case PxErrorCode::eINVALID_OPERATION: str << "[Invalid Operation]"; critical = true; break;
- case PxErrorCode::eOUT_OF_MEMORY: str << "[Out of] Memory"; critical = true; break;
- case PxErrorCode::eINTERNAL_ERROR: str << "[Internal Error]"; critical = true; break;
- case PxErrorCode::eABORT: str << "[Abort]"; critical = true; break;
- case PxErrorCode::ePERF_WARNING: str << "[Perf Warning]"; critical = false; break;
- default: PX_ALWAYS_ASSERT();
- }
- str << file << "(" << line << "): " << msg << "\n";
-
- std::string message = str.str();
- shdfnd::printString(message.c_str());
- PX_ASSERT_WITH_MESSAGE(!critical, message.c_str());
- }
-};
-BlastErrorCallback g_errorCallback;
-
-
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Joint creation
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -120,10 +85,9 @@ static physx::PxJoint* createPxJointCallback(ExtPxActor* actor0, const physx::Px
BlastController::BlastController()
: m_eventCallback(nullptr), debugRenderMode(BlastFamily::DEBUG_RENDER_DISABLED), m_impactDamageEnabled(true),
-m_impactDamageToStressEnabled(false), m_rigidBodyLimitEnabled(true), m_rigidBodyLimit(40000), m_blastAssetsSize(0), debugRenderScale(0.01f)
+m_impactDamageToStressEnabled(false), m_rigidBodyLimitEnabled(true), m_rigidBodyLimit(40000), m_blastAssetsSize(0), debugRenderScale(0.01f),
+m_taskManager(nullptr), m_extGroupTaskManager(nullptr)
{
- m_extImpactDamageManagerSettings.fragility = 500.0f;
-
m_impactDamageToStressFactor = 0.01f;
m_draggingToStressFactor = 100.0f;
}
@@ -141,17 +105,14 @@ void BlastController::reinitialize()
void BlastController::onSampleStart()
{
- TkFrameworkDesc desc;
- desc.allocatorCallback = &g_allocatorCallback;
- desc.errorCallback = &g_errorCallback;
- m_tkFramework = NvBlastTkFrameworkCreate(desc);
+ m_tkFramework = NvBlastTkFrameworkCreate();
m_replay = new BlastReplay();
- m_taskManager = PxTaskManager::createTaskManager(g_errorCallback, getPhysXController().getCPUDispatcher(), 0);
+ m_taskManager = PxTaskManager::createTaskManager(NvBlastGetPxErrorCallback(), getPhysXController().getCPUDispatcher(), 0);
TkGroupDesc gdesc;
- gdesc.pxTaskManager = m_taskManager;
+ gdesc.workerCount = m_taskManager->getCpuDispatcher()->getWorkerCount();
m_tkGroup = m_tkFramework->createGroup(gdesc);
m_extPxManager = ExtPxManager::create(getPhysXController().getPhysics(), *m_tkFramework, createPxJointCallback);
@@ -159,12 +120,24 @@ void BlastController::onSampleStart()
m_extImpactDamageManager = ExtImpactDamageManager::create(m_extPxManager, m_extImpactDamageManagerSettings);
m_eventCallback = new EventCallback(m_extImpactDamageManager);
+ m_extGroupTaskManager = ExtGroupTaskManager::create(*m_taskManager);
+ m_extGroupTaskManager->setGroup(m_tkGroup);
+
setImpactDamageEnabled(m_impactDamageEnabled, true);
+
+ m_extSerialization = NvBlastExtSerializationCreate();
+ if (m_extSerialization != nullptr)
+ {
+ NvBlastExtTkSerializerLoadSet(*m_tkFramework, *m_extSerialization);
+ NvBlastExtPxSerializerLoadSet(*m_tkFramework, getPhysXController().getPhysics(), getPhysXController().getCooking(), *m_extSerialization);
+ }
}
void BlastController::onSampleStop()
{
+ getPhysXController().simualtionSyncEnd();
+
removeAllFamilies();
m_extImpactDamageManager->release();
@@ -177,20 +150,54 @@ void BlastController::onSampleStop()
m_tkFramework->release();
- m_taskManager->release();
+ if (m_extGroupTaskManager != nullptr)
+ {
+ m_extGroupTaskManager->release();
+ m_extGroupTaskManager = nullptr;
+ }
+
+ if (m_taskManager != nullptr)
+ {
+ m_taskManager->release();
+ }
+}
+
+
+void BlastController::notifyPhysXControllerRelease()
+{
+ if (m_extGroupTaskManager != nullptr)
+ {
+ m_extGroupTaskManager->release();
+ m_extGroupTaskManager = nullptr;
+ }
+
+ if (m_taskManager != nullptr)
+ {
+ m_taskManager->release();
+ m_taskManager = nullptr;
+ }
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Impact damage
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void BlastController::updateImpactDamage()
+{
+ if (m_impactDamageUpdatePending)
+ {
+ getPhysXController().getPhysXScene().setSimulationEventCallback(m_impactDamageEnabled ? m_eventCallback : nullptr);
+ refreshImpactDamageSettings();
+ m_impactDamageUpdatePending = false;
+ }
+}
+
void BlastController::setImpactDamageEnabled(bool enabled, bool forceUpdate)
{
if (m_impactDamageEnabled != enabled || forceUpdate)
{
m_impactDamageEnabled = enabled;
- getPhysXController().getPhysXScene().setSimulationEventCallback(m_impactDamageEnabled ? m_eventCallback : nullptr);
- refreshImpactDamageSettings();
+ m_impactDamageUpdatePending = true;
}
}
@@ -206,8 +213,8 @@ bool BlastController::stressDamage(ExtPxActor *actor, physx::PxVec3 position, ph
void* userData = actor->getFamily().userData;
if (userData)
{
- ExtStressSolver* solver = reinterpret_cast<ExtStressSolver*>(userData);
- solver->applyImpulse(*actor, position, force * m_impactDamageToStressFactor);
+ ExtPxStressSolver* solver = reinterpret_cast<ExtPxStressSolver*>(userData);
+ solver->getSolver().addForce(*actor->getTkActor().getActorLL(), position, force * m_impactDamageToStressFactor);
return true;
}
}
@@ -222,6 +229,78 @@ void BlastController::refreshImpactDamageSettings()
m_extImpactDamageManager->setSettings(m_extImpactDamageManagerSettings);
}
+// Add By Lixu Begin
+BlastFamily* BlastController::getFamilyByPxActor(const PxActor& actor)
+{
+ for (BlastFamilyPtr family : m_families)
+ {
+ if (family->find(actor))
+ {
+ return family;
+ }
+ }
+ return nullptr;
+}
+
+std::vector<PxActor*> BlastController::getActor(BlastAsset* asset, int chunkId)
+{
+ std::vector<PxActor*> actors;
+ for (BlastFamilyPtr family : m_families)
+ {
+ if (&(family->getBlastAsset()) == asset)
+ {
+ PxActor* actor = nullptr;
+ family->getPxActorByChunkIndex(chunkId, &actor);
+ if (actor)
+ actors.push_back(actor);
+ }
+ }
+ return actors;
+}
+
+void BlastController::updateActorRenderableTransform(const PxActor& actor, physx::PxTransform& pos, bool local)
+{
+ BlastFamily* family = getFamilyByPxActor(actor);
+ if (family == nullptr)
+ return;
+
+ family->updateActorRenderableTransform(actor, pos, local);
+}
+
+bool BlastController::isActorVisible(const PxActor& actor)
+{
+ BlastFamily* family = getFamilyByPxActor(actor);
+ if (family == nullptr)
+ return false;
+
+ return family->isActorVisible(actor);
+}
+
+bool BlastController::isAssetFractrued(const PxActor& actor)
+{
+ BlastFamily* family = getFamilyByPxActor(actor);
+ if (family == nullptr)
+ return false;
+
+ const BlastAsset& asset = family->getBlastAsset();
+ if (asset.getChunkIndexesByDepth(1).size() > 0)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+void BlastController::updateModelMeshToProjectParam(const PxActor& actor)
+{
+ BlastFamily* family = getFamilyByPxActor(actor);
+ if (family == nullptr)
+ return;
+
+ const BlastAsset& asset = family->getBlastAsset();
+ SampleManager::ins()->updateModelMeshToProjectParam(const_cast<BlastAsset*>(&asset));
+}
+// Add By Lixu End
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Stress
@@ -239,11 +318,11 @@ void BlastController::updateDraggingStress()
void* userData = pxActor->getFamily().userData;
if (userData)
{
- ExtStressSolver* solver = reinterpret_cast<ExtStressSolver*>(userData);
+ ExtPxStressSolver* solver = reinterpret_cast<ExtPxStressSolver*>(userData);
PxTransform t(pxActor->getPhysXActor().getGlobalPose().getInverse());
PxVec3 dragVector = t.rotate(physxController.getDragVector());
const float factor = dragVector.magnitudeSquared() * m_draggingToStressFactor;
- solver->applyImpulse(*pxActor, physxController.getDragActorHookLocalPoint(), dragVector.getNormalized() * factor);
+ solver->getSolver().addForce(*pxActor->getTkActor().getActorLL(), physxController.getDragActorHookLocalPoint(), dragVector.getNormalized() * factor);
}
}
}
@@ -300,7 +379,11 @@ void BlastController::Animate(double dt)
updateDraggingStress();
- m_replay->update();
+ fillDebugRender();
+
+ getPhysXController().simualtionSyncEnd();
+
+ updateImpactDamage();
Time blastTime;
for (uint32_t i = 0; i < m_families.size(); ++i)
@@ -311,13 +394,25 @@ void BlastController::Animate(double dt)
}
}
- fillDebugRender();
+ m_replay->update();
PROFILER_BEGIN("Tk Group Process/Sync");
+
+#if 1
+
+ m_extGroupTaskManager->process();
+ m_extGroupTaskManager->wait();
+
+#else // process group on main thread
+
m_tkGroup->process();
- m_tkGroup->sync(true);
+
+#endif
+
PROFILER_END();
+ getPhysXController().simulationBegin(dt);
+
TkGroupStats gstats;
m_tkGroup->getStats(gstats);
@@ -365,7 +460,8 @@ void BlastController::Animate(double dt)
if (needUpdateUI)
{
- pBlastSceneTree->updateValues(false);
+ //pBlastSceneTree->updateValues(false);
+ SampleManager::ins()->m_bNeedRefreshTree = true;
}
// Add By Lixu End
}
@@ -379,15 +475,20 @@ void BlastController::drawUI()
{
setImpactDamageEnabled(impactEnabled);
}
-
- if (ImGui::DragFloat("Fragility", &m_extImpactDamageManagerSettings.fragility))
- {
- refreshImpactDamageSettings();
- }
-
- if (ImGui::Checkbox("Impact Damage To Stress Solver", &m_impactDamageToStressEnabled))
{
- refreshImpactDamageSettings();
+ bool refresh = false;
+ refresh |= ImGui::Checkbox("Use Shear Damage", &m_extImpactDamageManagerSettings.shearDamage);
+ refresh |= ImGui::DragFloat("Impulse Threshold (Min)", &m_extImpactDamageManagerSettings.impulseMinThreshold);
+ refresh |= ImGui::DragFloat("Impulse Threshold (Max)", &m_extImpactDamageManagerSettings.impulseMaxThreshold);
+ refresh |= ImGui::DragFloat("Damage (Max)", &m_extImpactDamageManagerSettings.damageMax);
+ refresh |= ImGui::DragFloat("Damage Radius (Max)", &m_extImpactDamageManagerSettings.damageRadiusMax);
+ refresh |= ImGui::DragFloat("Damage Attenuation", &m_extImpactDamageManagerSettings.damageAttenuation, 1.0f, 0.0f, 1.0f);
+ refresh |= ImGui::Checkbox("Impact Damage To Stress Solver", &m_impactDamageToStressEnabled);
+
+ if (refresh)
+ {
+ refreshImpactDamageSettings();
+ }
}
ImGui::DragFloat("Impact Damage To Stress Factor", &m_impactDamageToStressFactor, 0.001f, 0.0f, 1000.0f, "%.4f");
@@ -435,45 +536,8 @@ void BlastController::removeAllFamilies()
m_replay->reset();
}
-// Add By Lixu Begin
-#include "SceneController.h"
-// Add By Lixu End
void BlastController::recalculateAssetsSize()
{
-
-// Add By Lixu Begin
- std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = getManager()->getAssetFamiliesMap();
- std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = getManager()->getAssetDescMap();
- std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator it;
- for (it = AssetFamiliesMap.begin(); it != AssetFamiliesMap.end(); it++)
- {
- std::vector<BlastFamily*>& fs = it->second;
- fs.clear();
- }
- AssetFamiliesMap.clear();
- AssetDescMap.clear();
-
- SceneController& sceneController = getManager()->getSceneController();
- int familiesSize = m_families.size();
- for (int i = 0; i < familiesSize; i++)
- {
- BlastFamilyPtr pBlastFamily = m_families[i];
- BlastAsset* pBlastAsset = (BlastAsset*)&pBlastFamily->getBlastAsset();
- AssetFamiliesMap[pBlastAsset].push_back(&*m_families[i]);
- if (AssetDescMap.find(pBlastAsset) == AssetDescMap.end())
- {
- AssetList::ModelAsset desc;
- if (sceneController.GetAssetDesc(pBlastAsset, desc))
- {
- AssetDescMap[pBlastAsset] = desc;
- }
- }
-
- AssetList::ModelAsset& m = AssetDescMap[pBlastAsset];
- pBlastFamily->initTransform(m.transform);
- }
-// Add By Lixu End
-
std::set<const BlastAsset*> uniquedAssets;
m_blastAssetsSize = 0;
for (uint32_t i = 0; i < m_families.size(); ++i)
@@ -486,40 +550,19 @@ void BlastController::recalculateAssetsSize()
}
}
-void BlastController::blast(PxVec3 worldPos, float damageRadius, float explosiveImpulse, std::function<void(ExtPxActor*)> damageFunction)
+bool BlastController::overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*)> hitCall)
{
PROFILER_SCOPED_FUNCTION();
+ bool anyHit = false;
for (uint32_t i = 0; i < m_families.size(); ++i)
{
if (m_families[i])
{
- m_families[i]->blast(worldPos, damageRadius, explosiveImpulse, damageFunction);
+ anyHit |= m_families[i]->overlap(geometry, pose, hitCall);
}
}
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// context/log
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void BlastController::blastLog(int type, const char* msg, const char* file, int line)
-{
- std::stringstream str;
- bool critical = false;
- switch (type)
- {
- case NvBlastMessage::Error: str << "[NvBlast ERROR] "; critical = true; break;
- case NvBlastMessage::Warning: str << "[NvBlast WARNING] "; critical = true; break;
- case NvBlastMessage::Info: str << "[NvBlast INFO] "; critical = false; break;
- case NvBlastMessage::Debug: str << "[NvBlast DEBUG] "; critical = false; break;
- }
- str << file << "(" << line << "): " << msg << "\n";
-
- std::string message = str.str();
- shdfnd::printString(message.c_str());
- PX_ASSERT_WITH_MESSAGE(!critical, message.c_str());
+ return anyHit;
}
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.h
index 98f5c24..5e4d269 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_CONTROLLER_H
#define BLAST_CONTROLLER_H
@@ -31,6 +49,8 @@ namespace Nv
namespace Blast
{
class TkFramework;
+class ExtGroupTaskManager;
+class ExtSerialization;
}
}
@@ -68,7 +88,7 @@ public:
//////// public API ////////
- void blast(PxVec3 worldPos, float damageRadius, float explosiveImpulse, std::function<void(ExtPxActor*)> damageFunction);
+ bool overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*)> hitCall);
bool stressDamage(ExtPxActor *actor, PxVec3 position, PxVec3 force);
@@ -77,11 +97,6 @@ public:
void removeAllFamilies();
- //////// public static ////////
-
- static void blastLog(int type, const char* msg, const char* file, int line);
-
-
//////// public getters/setters ////////
TkFramework& getTkFramework() const
@@ -142,10 +157,29 @@ public:
{
return m_families;
}
+
+ BlastFamily* getFamilyByPxActor(const PxActor& actor);
+ std::vector<PxActor*> getActor(BlastAsset* asset, int chunkId);
+
+ void updateActorRenderableTransform(const PxActor& actor, physx::PxTransform& pos, bool local = false);
+
+ bool isActorVisible(const PxActor& actor);
+
+ bool isAssetFractrued(const PxActor& actor);
+
+ // only update unfractured mode mesh
+ void updateModelMeshToProjectParam(const PxActor& actor);
// Add By Lixu End
float getLastStressDelta() const;
+ void notifyPhysXControllerRelease();
+
+ ExtSerialization* getExtSerialization() const
+ {
+ return m_extSerialization;
+ }
+
//////// public variables for UI ////////
BlastFamily::DebugRenderMode debugRenderMode;
@@ -190,6 +224,8 @@ private:
void updateDraggingStress();
+ void updateImpactDamage();
+
void refreshImpactDamageSettings();
void fillDebugRender();
@@ -222,11 +258,14 @@ private:
ExtImpactSettings m_extImpactDamageManagerSettings;
EventCallback* m_eventCallback;
ExtStressSolverSettings m_extStressSolverSettings;
+ ExtGroupTaskManager* m_extGroupTaskManager;
+ ExtSerialization* m_extSerialization;
std::vector<BlastFamilyPtr> m_families;
DebugRenderBuffer m_debugRenderBuffer;
bool m_impactDamageEnabled;
+ bool m_impactDamageUpdatePending;
bool m_impactDamageToStressEnabled;
float m_impactDamageToStressFactor;
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.cpp
index f947cbd..b5afc82 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "BlastFamily.h"
#include "SampleProfiler.h"
@@ -28,12 +46,13 @@
#include "PxRigidDynamic.h"
#include "PxScene.h"
#include "PxJoint.h"
+// Add By Lixu Begin
+#include "BlastSceneTree.h"
+// Add By Lixu End
const float RIGIDBODY_DENSITY = 2000.0f;
-const float BlastFamily::BOND_HEALTH_MAX = 1.0f;
-
BlastFamily::BlastFamily(PhysXController& physXController, ExtPxManager& pxManager, const BlastAsset& blastAsset)
: m_physXController(physXController)
, m_pxManager(pxManager)
@@ -41,11 +60,10 @@ BlastFamily::BlastFamily(PhysXController& physXController, ExtPxManager& pxManag
, m_listener(this)
, m_totalVisibleChunkCount(0)
, m_stressSolver(nullptr)
+ , m_spawned(false)
{
m_settings.stressSolverEnabled = false;
m_settings.stressDamageEnabled = false;
-
- m_settings.material = { 3.0f, 0.1f, 0.2f, 1.5f + 1e-5f, 0.95f };;
}
BlastFamily::~BlastFamily()
@@ -62,11 +80,44 @@ BlastFamily::~BlastFamily()
void BlastFamily::initialize(const BlastAsset::ActorDesc& desc)
{
+// Add By Lixu Begin
+ BPPBlast& blast = BlastProject::ins().getParams().blast;
+ BPPBondArray& bonds = blast.bonds;
+ BlastTreeData& blastTreeData = BlastTreeData::ins();
+
+ std::vector<float> BondHealths;
+ BlastAsset* pThis = (BlastAsset*)&m_blastAsset;
+ SampleManager* pSampleManager = SampleManager::ins();
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ AssetList::ModelAsset m = AssetDescMap[pThis];
+ int assetID = BlastProject::ins().getAssetIDByName(m.name.c_str());
+
+ for (int bc = 0; bc < bonds.arraySizes[0]; bc++)
+ {
+ BPPBond& bond = bonds.buf[bc];
+ if (bond.asset == assetID)
+ {
+ BondHealths.push_back(bond.support.bondStrength);
+ }
+ }
+
+ const ExtPxAsset* pExtPxAsset = m_blastAsset.getPxAsset();
+ const TkAsset& tkAsset = pExtPxAsset->getTkAsset();
+ uint32_t bondCount = tkAsset.getBondCount();
+
+ const float* pBondHealths = nullptr;
+ if (bondCount == BondHealths.size())
+ {
+ pBondHealths = BondHealths.data();
+ }
+
+ const NvBlastActorDesc& defaultActorDesc = m_blastAsset.getPxAsset()->getDefaultActorDesc();
+ NvBlastActorDesc newActorDesc = defaultActorDesc;
+ newActorDesc.initialBondHealths = pBondHealths;
+// Add By Lixu End
+
ExtPxFamilyDesc familyDesc;
- familyDesc.actorDesc.initialBondHealths = nullptr;
- familyDesc.actorDesc.initialSupportChunkHealths = nullptr;
- familyDesc.actorDesc.uniformInitialBondHealth = BOND_HEALTH_MAX;
- familyDesc.actorDesc.uniformInitialLowerSupportChunkHealth = 1.0f;
+ familyDesc.actorDesc = (const NvBlastActorDesc*)&newActorDesc; // if you use it one day, consider changing code which needs getBondHealthMax() from BlastAsset.
familyDesc.group = desc.group;
familyDesc.pxAsset = m_blastAsset.getPxAsset();
m_pxFamily = m_pxManager.createFamily(familyDesc);
@@ -79,28 +130,27 @@ void BlastFamily::initialize(const BlastAsset::ActorDesc& desc)
m_pxFamily->subscribe(m_listener);
- ExtPxSpawnSettings spawnSettings = {
- &m_physXController.getPhysXScene(),
- m_physXController.getDefaultMaterial(),
- RIGIDBODY_DENSITY
- };
- m_pxFamily->spawn(desc.transform, PxVec3(1.0f), spawnSettings);
+ m_initialTransform = desc.transform;
- reloadStressSolver();
+ updatePreSplit(0);
+ m_VisibleChangedChunks.clear();
}
void BlastFamily::updatePreSplit(float dt)
{
- PROFILER_BEGIN("Stress Solver");
- // update stress
- m_stressSolveTime = 0;
- if (m_stressSolver)
+ if (!m_spawned)
{
- Time t;
- m_stressSolver->update(m_settings.stressDamageEnabled);
- m_stressSolveTime += t.getElapsedSeconds();
+ ExtPxSpawnSettings spawnSettings = {
+ &m_physXController.getPhysXScene(),
+ m_physXController.getDefaultMaterial(),
+ RIGIDBODY_DENSITY
+ };
+
+ m_pxFamily->spawn(m_initialTransform, PxVec3(1.0f), spawnSettings);
+ reloadStressSolver();
+
+ m_spawned = true;
}
- PROFILER_END();
// collect potential actors to health update
m_actorsToUpdateHealth.clear();
@@ -128,6 +178,17 @@ void BlastFamily::updateAfterSplit(float dt)
}
PROFILER_END();
+ PROFILER_BEGIN("Stress Solver");
+ // update stress
+ m_stressSolveTime = 0;
+ if (m_stressSolver)
+ {
+ Time t;
+ m_stressSolver->update(m_settings.stressDamageEnabled);
+ m_stressSolveTime += t.getElapsedSeconds();
+ }
+ PROFILER_END();
+
PROFILER_BEGIN("Actor Misc Update");
onUpdate();
PROFILER_END();
@@ -173,11 +234,9 @@ void BlastFamily::drawUI()
// Blast Material
ImGui::Spacing();
ImGui::Text("Blast Material:");
- ImGui::DragFloat("singleChunkThreshold", &m_settings.material.singleChunkThreshold);
- ImGui::DragFloat("graphChunkThreshold", &m_settings.material.graphChunkThreshold);
- ImGui::DragFloat("bondNormalThreshold", &m_settings.material.bondNormalThreshold);
- ImGui::DragFloat("bondTangentialThreshold", &m_settings.material.bondTangentialThreshold);
- ImGui::DragFloat("damageAttenuation", &m_settings.material.damageAttenuation);
+ ImGui::DragFloat("Health", &m_settings.material.health);
+ ImGui::DragFloat("Min Damage Threshold", &m_settings.material.minDamageThreshold, 0.01f, 0.f, m_settings.material.maxDamageThreshold);
+ ImGui::DragFloat("Max Damage Threshold", &m_settings.material.maxDamageThreshold, 0.01f, m_settings.material.minDamageThreshold, 1.f);
ImGui::Spacing();
@@ -193,8 +252,9 @@ void BlastFamily::drawUI()
bool changed = false;
changed |= ImGui::DragInt("Bond Iterations Per Frame", (int*)&m_settings.stressSolverSettings.bondIterationsPerFrame, 100, 0, 500000);
- changed |= ImGui::DragFloat("Stress Linear Factor", &m_settings.stressSolverSettings.stressLinearFactor, 0.00001f, 0.0f, 10.0f, "%.6f");
- changed |= ImGui::DragFloat("Stress Angular Factor", &m_settings.stressSolverSettings.stressAngularFactor, 0.00001f, 0.0f, 10.0f, "%.6f");
+ changed |= ImGui::DragFloat("Material Hardness", &m_settings.stressSolverSettings.hardness, 10.0f, 0.01f, 100000.0f, "%.2f");
+ changed |= ImGui::DragFloat("Stress Linear Factor", &m_settings.stressSolverSettings.stressLinearFactor, 0.01f, 0.0f, 100.0f, "%.2f");
+ changed |= ImGui::DragFloat("Stress Angular Factor", &m_settings.stressSolverSettings.stressAngularFactor, 0.01f, 0.0f, 100.0f, "%.2f");
changed |= ImGui::SliderInt("Graph Reduction Level", (int*)&m_settings.stressSolverSettings.graphReductionLevel, 0, 32);
if (changed)
{
@@ -213,22 +273,22 @@ void BlastFamily::drawUI()
void BlastFamily::drawStatsUI()
{
ImGui::PushStyleColor(ImGuiCol_Text, ImColor(10, 255, 10, 255));
- const ExtStressSolver* stressSolver = m_stressSolver;
- if (stressSolver)
+ if (m_stressSolver)
{
- const float errorLinear = stressSolver->getStressErrorLinear();
- const float errorAngular = stressSolver->getStressErrorAngular();
+ const ExtStressSolver& stressSolver = m_stressSolver->getSolver();
+ const float errorLinear = stressSolver.getStressErrorLinear();
+ const float errorAngular = stressSolver.getStressErrorAngular();
- ImGui::Text("Stress Bond Count: %d", stressSolver->getBondCount());
- ImGui::Text("Stress Iterations: %d (+%d)", stressSolver->getIterationCount(), stressSolver->getIterationsPerFrame());
- ImGui::Text("Stress Frames: %d", stressSolver->getFrameCount());
+ ImGui::Text("Stress Bond Count: %d", stressSolver.getBondCount());
+ ImGui::Text("Stress Frame Iter: %d", stressSolver.getIterationsPerFrame());
+ ImGui::Text("Stress Frames: %d", stressSolver.getFrameCount());
ImGui::Text("Stress Error Lin / Ang: %.4f / %.4f", errorLinear, errorAngular);
ImGui::Text("Stress Solve Time: %.3f ms", m_stressSolveTime * 1000);
// plot errors
{
static float scale = 1.0f;
- scale = stressSolver->getFrameCount() <= 1 ? 1.0f : scale;
+ scale = stressSolver.getFrameCount() <= 1 ? 1.0f : scale;
scale = std::max<float>(scale, errorLinear);
scale = std::max<float>(scale, errorAngular);
@@ -263,19 +323,24 @@ void BlastFamily::setSettings(const Settings& settings)
}
m_tkFamily->setMaterial(&m_settings.material);
+ initTransform(m_settings.transform);
+ m_initialTransform = m_settings.transform;
}
void BlastFamily::refreshStressSolverSettings()
{
if (m_stressSolver)
{
- m_stressSolver->setSettings(m_settings.stressSolverSettings);
+ m_stressSolver->getSolver().setSettings(m_settings.stressSolverSettings);
}
}
void BlastFamily::resetStress()
{
- m_stressSolver->reset();
+ if (m_stressSolver)
+ {
+ m_stressSolver->getSolver().reset();
+ }
}
void BlastFamily::reloadStressSolver()
@@ -288,7 +353,7 @@ void BlastFamily::reloadStressSolver()
if (m_settings.stressSolverEnabled)
{
- m_stressSolver = ExtStressSolver::create(*m_pxFamily, m_settings.stressSolverSettings);
+ m_stressSolver = ExtPxStressSolver::create(*m_pxFamily, m_settings.stressSolverSettings);
m_pxFamily->userData = m_stressSolver;
}
}
@@ -351,6 +416,8 @@ void BlastFamily::fillDebugRender(DebugRenderBuffer& debugRenderBuffer, DebugRen
const NvBlastChunk* chunks = m_tkFamily->getAsset()->getChunks();
const NvBlastBond* bonds = m_tkFamily->getAsset()->getBonds();
const NvBlastSupportGraph graph = m_tkFamily->getAsset()->getGraph();
+ const float bondHealthMax = m_blastAsset.getBondHealthMax();
+ const uint32_t chunkCount = m_tkFamily->getAsset()->getChunkCount();
for (const ExtPxActor* pxActor : m_actors)
{
@@ -361,7 +428,7 @@ void BlastFamily::fillDebugRender(DebugRenderBuffer& debugRenderBuffer, DebugRen
if (nodeCount == 0) // subsupport chunks don't have graph nodes
continue;
- std::vector<uint32_t> nodes(actor.getGraphNodeCount());
+ std::vector<uint32_t> nodes(nodeCount);
actor.getGraphNodeIndices(nodes.data(), static_cast<uint32_t>(nodes.size()));
if (DEBUG_RENDER_HEALTH_GRAPH <= mode && mode <= DEBUG_RENDER_HEALTH_GRAPH_CENTROIDS)
@@ -385,11 +452,11 @@ void BlastFamily::fillDebugRender(DebugRenderBuffer& debugRenderBuffer, DebugRen
if (node0 > node1)
continue;
- bool invisibleBond = assetChunk0.subchunkCount == 0 || assetChunk1.subchunkCount == 0;
+ bool invisibleBond = chunkIndex0 >= chunkCount || chunkIndex1 >= chunkCount || assetChunk0.subchunkCount == 0 || assetChunk1.subchunkCount == 0;
// health
uint32_t bondIndex = graph.adjacentBondIndices[adjacencyIndex];
- float healthVal = PxClamp(bondHealths[bondIndex] / BOND_HEALTH_MAX, 0.0f, 1.0f);
+ float healthVal = PxClamp(bondHealths[bondIndex] / bondHealthMax, 0.0f, 1.0f);
DirectX::XMFLOAT4 color = bondHealthColor(healthVal);
@@ -419,7 +486,12 @@ void BlastFamily::fillDebugRender(DebugRenderBuffer& debugRenderBuffer, DebugRen
{
if (m_stressSolver)
{
- m_stressSolver->fillDebugRender(nodes, debugRenderBuffer.m_lines, (ExtStressSolver::DebugRenderMode)(mode - DEBUG_RENDER_STRESS_GRAPH), renderScale);
+ const auto buffer = m_stressSolver->getSolver().fillDebugRender(nodes.data(), (uint32_t)nodes.size(), (ExtStressSolver::DebugRenderMode)(mode - DEBUG_RENDER_STRESS_GRAPH), renderScale);
+ if (buffer.lineCount)
+ {
+ const auto lines = reinterpret_cast<const PxDebugLine*>(buffer.lines);
+ debugRenderBuffer.m_lines.insert(debugRenderBuffer.m_lines.end(), lines, lines + buffer.lineCount);
+ }
}
}
@@ -497,7 +569,7 @@ private:
PxOverlapHit m_hitBuffer[1000];
};
-void BlastFamily::blast(PxVec3 worldPos, float damageRadius, float explosiveImpulse, std::function<void(ExtPxActor*)> damageFunction)
+bool BlastFamily::overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*)> hitCall)
{
// Add By Lixu Begin
const ExtPxAsset* pExtPxAsset = m_blastAsset.getPxAsset();
@@ -505,14 +577,14 @@ void BlastFamily::blast(PxVec3 worldPos, float damageRadius, float explosiveImpu
uint32_t bondCount = tkAsset.getBondCount();
if (bondCount == 0)
{
- return;
+ return false;
}
// Add By Lixu End
std::set<ExtPxActor*> actorsToDamage;
#if 1
BlastOverlapCallback overlapCallback(m_pxManager, actorsToDamage);
- m_physXController.getPhysXScene().overlap(PxSphereGeometry(damageRadius), PxTransform(worldPos), overlapCallback);
+ m_physXController.getPhysXScene().overlap(geometry, pose, overlapCallback);
#else
for (std::map<NvBlastActor*, PhysXController::Actor*>::iterator it = m_actorsMap.begin(); it != m_actorsMap.end(); it++)
{
@@ -522,67 +594,9 @@ void BlastFamily::blast(PxVec3 worldPos, float damageRadius, float explosiveImpu
for (auto actor : actorsToDamage)
{
- damageFunction(actor);
- }
-
- if (explosiveImpulse > 0.0f)
- {
- explode(worldPos, damageRadius, explosiveImpulse);
- }
-}
-
-
-class ExplodeOverlapCallback : public PxOverlapCallback
-{
-public:
- ExplodeOverlapCallback(PxVec3 worldPos, float radius, float explosiveImpulse)
- : m_worldPos(worldPos)
- , m_radius(radius)
- , m_explosiveImpulse(explosiveImpulse)
- , PxOverlapCallback(m_hitBuffer, sizeof(m_hitBuffer) / sizeof(m_hitBuffer[0])) {}
-
- PxAgain processTouches(const PxOverlapHit* buffer, PxU32 nbHits)
- {
- for (PxU32 i = 0; i < nbHits; ++i)
- {
- PxRigidActor* actor = buffer[i].actor;
- PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>();
- if (rigidDynamic && !(rigidDynamic->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC))
- {
- if (m_actorBuffer.find(rigidDynamic) == m_actorBuffer.end())
- {
- m_actorBuffer.insert(rigidDynamic);
- PxVec3 dr = rigidDynamic->getGlobalPose().transform(rigidDynamic->getCMassLocalPose()).p - m_worldPos;
- float distance = dr.magnitude();
- float factor = PxClamp(1.0f - (distance * distance) / (m_radius * m_radius), 0.0f, 1.0f);
- float impulse = factor * m_explosiveImpulse * RIGIDBODY_DENSITY;
- PxVec3 vel = dr.getNormalized() * impulse / rigidDynamic->getMass();
- rigidDynamic->setLinearVelocity(rigidDynamic->getLinearVelocity() + vel);
- }
- }
- }
- return true;
+ hitCall(actor);
}
-private:
- PxOverlapHit m_hitBuffer[1000];
- float m_explosiveImpulse;
- std::set<PxRigidDynamic*> m_actorBuffer;
- PxVec3 m_worldPos;
- float m_radius;
-};
-
-void BlastFamily::explode(PxVec3 worldPos, float damageRadius, float explosiveImpulse)
-{
- ExplodeOverlapCallback overlapCallback(worldPos, damageRadius, explosiveImpulse);
- m_physXController.getPhysXScene().overlap(PxSphereGeometry(damageRadius), PxTransform(worldPos), overlapCallback);
-
+ return !actorsToDamage.empty();
}
-// Add By Lixu Begin
-bool BlastFamily::find(ExtPxActor* actor)
-{
- std::set<ExtPxActor*>::iterator it = m_actors.find(actor);
- return it != m_actors.end();
-}
-// Add By Lixu End
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.h
index b4611a9..356e0c5 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.h
@@ -1,19 +1,37 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_FAMILY_H
#define BLAST_FAMILY_H
#include "BlastAsset.h"
#include "NvBlastExtPxListener.h"
-#include "NvBlastExtStressSolver.h"
+#include "NvBlastExtPxStressSolver.h"
#include "NvBlastExtDamageShaders.h"
#include <functional>
#include <set>
@@ -23,6 +41,11 @@
class DebugRenderBuffer;
// Add By Lixu Begin
class RenderMaterial;
+namespace physx
+{
+ class PxActor;
+}
+using namespace physx;
// Add By Lixu End
namespace Nv
@@ -34,6 +57,13 @@ class ExtPxManager;
}
}
+namespace physx
+{
+class PxGeometry;
+class PxTransform;
+}
+
+
/**
BlastFamily class represents 1 spawned BlastAsset, contains and manipulates all physx/blast actors spawned by fracturing it.
@@ -45,8 +75,7 @@ public:
//////// public API ////////
- void blast(PxVec3 worldPos, float damageRadius, float explosiveImpulse, std::function<void(ExtPxActor*)> damageFunction);
- void explode(PxVec3 worldPos, float damageRadius, float explosiveImpulse);
+ bool overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*)> hitCall);
void updatePreSplit(float dt);
void updateAfterSplit(float dt);
@@ -55,22 +84,29 @@ public:
void drawStatsUI();
// Add By Lixu Begin
- bool find(ExtPxActor* actor);
- virtual void setActorSelected(const ExtPxActor& actor, bool selected) {}
+ virtual bool find(const PxActor& actor) { return false; }
+ virtual void updateActorRenderableTransform(const PxActor& actor, PxTransform& pos, bool local) {}
+ virtual uint32_t getChunkIndexByPxActor(const PxActor& actor) { return -1; }
+ virtual bool getPxActorByChunkIndex(uint32_t chunkIndex, PxActor** ppActor) { return false; }
+ virtual void setActorSelected(const PxActor& actor, bool selected) {}
+ virtual bool isActorSelected(const PxActor& actor) { return false; }
+ virtual void setActorVisible(const PxActor& actor, bool visible) {}
+ virtual bool isActorVisible(const PxActor& actor) { return false; }
virtual std::vector<uint32_t> getSelectedChunks() { return std::vector<uint32_t>(); }
virtual void clearChunksSelected() {}
virtual void setChunkSelected(uint32_t chunk, bool selected) {}
virtual void setChunkSelected(std::vector<uint32_t> depths, bool selected) {}
- virtual bool getChunkSelected(uint32_t chunk) { return false; }
- virtual void setActorScale(const ExtPxActor& actor, PxMat44& scale, bool replace) {}
+ virtual bool isChunkSelected(uint32_t chunk) { return false; }
+ virtual void setActorScale(const PxActor& actor, PxMat44& scale, bool replace) {}
virtual bool isChunkVisible(uint32_t chunkIndex) { return false; }
virtual void setChunkVisible(uint32_t chunkIndex, bool bVisible) {}
virtual void setChunkVisible(std::vector<uint32_t> depths, bool bVisible) {}
- virtual void initTransform(physx::PxTransform t) {}
+ virtual void initTransform(physx::PxTransform t) { m_settings.transform = t; }
std::map<uint32_t, bool>& getVisibleChangedChunks() { return m_VisibleChangedChunks; }
void clearVisibleChangedChunks() { m_VisibleChangedChunks.clear(); }
virtual void getMaterial(RenderMaterial** ppRenderMaterial, bool externalSurface) {}
virtual void setMaterial(RenderMaterial* pRenderMaterial, bool externalSurface) {}
+ virtual void highlightChunks() {}
// Add By Lixu End
enum DebugRenderMode
@@ -122,11 +158,6 @@ public:
void reloadStressSolver();
- //////// consts ////////
-
- static const float BOND_HEALTH_MAX;
-
-
//////// settings ////////
struct Settings
@@ -135,6 +166,7 @@ public:
ExtStressSolverSettings stressSolverSettings;
bool stressDamageEnabled;
NvBlastExtMaterial material;
+ physx::PxTransform transform;
};
void setSettings(const Settings& settings);
@@ -171,7 +203,7 @@ protected:
//////// protected data ////////
PhysXController& m_physXController;
- ExtPxManager& m_pxManager;
+ ExtPxManager& m_pxManager;
const BlastAsset& m_blastAsset;
std::map<uint32_t, bool> m_VisibleChangedChunks;
@@ -209,15 +241,20 @@ private:
//////// private data ////////
TkFamily* m_tkFamily;
- ExtPxFamily* m_pxFamily;
- PxManagerListener m_listener;
+ ExtPxFamily* m_pxFamily;
+ PxManagerListener m_listener;
Settings m_settings;
+ PxTransform m_initialTransform;
+ bool m_spawned;
size_t m_familySize;
uint32_t m_totalVisibleChunkCount;
- ExtStressSolver* m_stressSolver;
+ ExtPxStressSolver* m_stressSolver;
double m_stressSolveTime;
- std::set<ExtPxActor*> m_actors;
- std::set<const ExtPxActor*> m_actorsToUpdateHealth;
+ std::set<const ExtPxActor*> m_actorsToUpdateHealth;
+ // Add By Lixu Begin
+protected:
+ std::set<ExtPxActor*> m_actors;
+ // Add By Lixu End
};
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.cpp
index e8b7b27..7011612 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.cpp
@@ -1,12 +1,29 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
#include "BlastFamilyBoxes.h"
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.h
index 1f70451..b67ec31 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_FAMILY_BOXES
#define BLAST_FAMILY_BOXES
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.cpp
index e692547..01559da 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "BlastFamilyModelSimple.h"
#include "RenderUtils.h"
@@ -19,8 +37,119 @@
#include "PxRigidDynamic.h"
#include "MaterialLibraryPanel.h"
+// Add By Lixu Begin
+#include "NvBlastExtPxManager.h"
+#include "SceneController.h"
+#include "PhysXController.h"
+#include "SampleManager.h"
+#include "BlastModel.h"
+#include "PxPhysics.h"
+#include "PxScene.h"
+#include "GizmoToolController.h"
+// Add By Lixu End
+
using namespace physx;
+#include "ViewerOutput.h"
+// print out all shapes for debug purpose. check actor/shape releasing.
+void PrintActors(PhysXController& physXController)
+{
+ PxPhysics& physx = physXController.getPhysics();
+ static int convexNum = 0, shapeNum = 0;
+ int convexNumNew = physx.getNbConvexMeshes();
+ int shapeNumNew = physx.getNbShapes();
+ if (shapeNum != shapeNumNew && shapeNumNew > 0)
+ {
+ // print shapes
+ std::vector<PxShape*> shapes(shapeNumNew);
+ physx.getShapes(shapes.data(), shapeNumNew);
+ shapeNum = shapeNumNew;
+ for (PxU32 u = 0; u < shapeNumNew; ++u)
+ {
+ PxShape& shape = *shapes[u];
+ PxRigidActor* pActor = shape.getActor();
+ const char* pName = pActor ? pActor->getName() : nullptr;
+ char buf[256];
+ if (pName)
+ {
+ sprintf(buf, "Actor %x shape %x %s", pActor, &shape, pName);
+ }
+ else
+ {
+ sprintf(buf, "Actor %x shape %x", pActor, &shape);
+ }
+ viewer_msg(buf);
+ }
+ }
+}
+
+// only modify unfractured mode mesh
+void modifyModelByLocalWay(BlastModel& model, PxTransform& gp_old, PxTransform& gp_new)
+{
+ BlastModel::Chunk& chunk = model.chunks[0];//unfracture model only has one chunk
+
+ std::vector<BlastModel::Chunk::Mesh>& meshes = chunk.meshes;
+ int meshSize = meshes.size();
+
+ if (meshSize == 0)
+ {
+ return;
+ }
+
+ PxTransform gp_newInv = gp_new.getInverse();
+ for (int ms = 0; ms < meshSize; ms++)
+ {
+ BlastModel::Chunk::Mesh& mesh = meshes[ms];
+ SimpleMesh& simpleMesh = mesh.mesh;
+ std::vector<SimpleMesh::Vertex>& vertices = simpleMesh.vertices;
+
+ int NumVertices = vertices.size();
+ for (uint32_t i = 0; i < NumVertices; ++i)
+ {
+ PxTransform v_old(vertices[i].position);
+ PxTransform v_new = gp_newInv * gp_old * v_old;
+ physx::PxVec3 pos = v_new.p;
+
+ SimpleMesh::Vertex& vertex = vertices[i];
+ vertex.position.x = pos.x;
+ vertex.position.y = pos.y;
+ vertex.position.z = pos.z;
+ }
+ }
+}
+
+
+void scaleModel(BlastModel& model, PxMat44& scale)
+{
+ BlastModel::Chunk& chunk = model.chunks[0];//unfracture model only has one chunk
+
+ std::vector<BlastModel::Chunk::Mesh>& meshes = chunk.meshes;
+ int meshSize = meshes.size();
+
+ if (meshSize == 0)
+ {
+ return;
+ }
+
+ for (int ms = 0; ms < meshSize; ms++)
+ {
+ BlastModel::Chunk::Mesh& mesh = meshes[ms];
+ SimpleMesh& simpleMesh = mesh.mesh;
+ std::vector<SimpleMesh::Vertex>& vertices = simpleMesh.vertices;
+
+ int NumVertices = vertices.size();
+ for (uint32_t i = 0; i < NumVertices; ++i)
+ {
+ SimpleMesh::Vertex& vertex = vertices[i];
+ physx::PxVec3 pos = scale.transform(vertices[i].position);
+
+ vertex.position.x = pos.x;
+ vertex.position.y = pos.y;
+ vertex.position.z = pos.z;
+ }
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SimpleRenderMesh
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -34,7 +163,8 @@ public:
m_inputDesc.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 });
m_inputDesc.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 });
- m_inputDesc.push_back({ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+ m_inputDesc.push_back({ "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 });
+ m_inputDesc.push_back({ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, 0 });
m_inputDesc.push_back({ "TEXCOORD", 1, DXGI_FORMAT_R32_FLOAT, 1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 });
m_numVertices = static_cast<uint32_t>(mesh->vertices.size());
@@ -200,10 +330,20 @@ private:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// BlastFamilyModelSimple
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
BlastFamilyModelSimple::BlastFamilyModelSimple(PhysXController& physXController, ExtPxManager& pxManager, Renderer& renderer, const BlastAssetModelSimple& blastAsset, const BlastAsset::ActorDesc& desc)
: BlastFamily(physXController, pxManager, blastAsset), m_renderer(renderer)
{
+ // Add By Lixu Begin
+ SampleManager* pSampleManager = SampleManager::ins();
+ std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = pSampleManager->getAssetFamiliesMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+
+ BlastAsset* pBlastAsset = (BlastAsset*)&getBlastAsset();
+ AssetFamiliesMap[pBlastAsset].push_back(this);
+
+ AssetList::ModelAsset& m = AssetDescMap[pBlastAsset];
+ // Add By Lixu End
+
// materials
auto materials = blastAsset.getRenderMaterials();
@@ -223,6 +363,10 @@ BlastFamilyModelSimple::BlastFamilyModelSimple(PhysXController& physXController,
ex_Renderables.clear();
std::vector<Renderable*>& in_Renderables = m_chunks[chunkIndex].in_Renderables;
in_Renderables.clear();
+
+ PxActor* actor = pSampleManager->getPhysXController().createEditPhysXActor(meshes, desc.transform);
+ m_editActorChunkMap.insert(std::make_pair(actor, chunkIndex));
+ m_chunkEditActorMap.insert(std::make_pair(chunkIndex, actor));
// Add By Lixu End
renderMeshes.resize(meshes.size());
renderables.resize(meshes.size());
@@ -231,8 +375,11 @@ BlastFamilyModelSimple::BlastFamilyModelSimple(PhysXController& physXController,
renderMeshes[i] = new SimpleRenderMesh(&meshes[i].mesh);
uint32_t materialIndex = model.chunks[chunkIndex].meshes[i].materialIndex;
- Renderable* renderable = renderer.createRenderable(*renderMeshes[i], *materials[materialIndex]);
- renderable->setHidden(true);
+
+ RenderMaterial* pRenderMaterial = pSampleManager->getRenderMaterial(materials[materialIndex]);
+
+ Renderable* renderable = renderer.createRenderable(*renderMeshes[i], *pRenderMaterial);
+ renderable->setHidden(!_getBPPChunkVisible(chunkIndex));
renderables[i] = renderable;
// Add By Lixu Begin
if (materialIndex == 0)
@@ -247,6 +394,10 @@ BlastFamilyModelSimple::BlastFamilyModelSimple(PhysXController& physXController,
}
}
+// Add By Lixu Begin
+ initTransform(desc.transform);
+// Add By Lixu End
+
// initialize in position
initialize(desc);
}
@@ -254,21 +405,63 @@ BlastFamilyModelSimple::BlastFamilyModelSimple(PhysXController& physXController,
BlastFamilyModelSimple::~BlastFamilyModelSimple()
{
// Add By Lixu Begin
+ // remove from AssetFamiliesMap
+ SampleManager* pSampleManager = SampleManager::ins();
+ std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = pSampleManager->getAssetFamiliesMap();
+ BlastAsset* pBlastAsset = (BlastAsset*)&getBlastAsset();
+ std::vector<BlastFamily*>& families = AssetFamiliesMap[pBlastAsset];
+ std::vector<BlastFamily*>::iterator itBF;
+ for (itBF = families.begin(); itBF != families.end(); itBF++)
+ {
+ if ((*itBF) == this)
+ {
+ families.erase(itBF);
+ break;
+ }
+ }
+ if (families.size() == 0)
+ {
+ AssetFamiliesMap.erase(AssetFamiliesMap.find(pBlastAsset));
+ }
+
// disconnect the material and relative renderable
const BlastAssetModelSimple& blastAsset = *(BlastAssetModelSimple*)&m_blastAsset;
- const std::vector<RenderMaterial*>& materials = blastAsset.getRenderMaterials();
+ const std::vector<std::string>& materials = blastAsset.getRenderMaterials();
int materialSize = materials.size();
for (int ms = 0; ms < materialSize; ms++)
{
- RenderMaterial* pRenderMaterial = materials[ms];
+ RenderMaterial* pRenderMaterial = pSampleManager->getRenderMaterial(materials[ms]);
pRenderMaterial->clearRelatedRenderables();
}
- std::map<std::string, RenderMaterial*>& RenderMaterialMap = MaterialLibraryPanel::ins()->getRenderMaterials();
- std::map<std::string, RenderMaterial*>::iterator it;
- for (it = RenderMaterialMap.begin(); it != RenderMaterialMap.end(); it++)
+
+ // remove physx actor for edit mode
+ PxScene& editScene = pSampleManager->getPhysXController().getEditPhysXScene();
+
+ for (std::map<PxActor*, uint32_t>::iterator itr = m_editActorChunkMap.begin(); itr != m_editActorChunkMap.end(); ++itr)
{
- RenderMaterial* pRenderMaterial = it->second;
- pRenderMaterial->clearRelatedRenderables();
+ editScene.removeActor(*(itr->first));
+ PxRigidDynamic* rigidDynamic = (itr->first)->is<PxRigidDynamic>();
+ if (rigidDynamic == nullptr)
+ {
+ itr->first->release();
+ continue;
+ }
+
+ PxU32 shapeCount = rigidDynamic->getNbShapes();
+ std::vector<PxShape*> shapes;
+ shapes.resize(shapeCount);
+ rigidDynamic->getShapes(shapes.data(), shapeCount);
+ for (PxU32 u = 0; u < shapeCount; ++u)
+ {
+ PxShape& shape = *shapes[u];
+ rigidDynamic->detachShape(shape);
+ PxConvexMeshGeometry geometry;
+ shape.getConvexMeshGeometry(geometry);
+ geometry.convexMesh->release();
+ shape.release();
+ }
+
+ rigidDynamic->release();
}
// Add By Lixu End
@@ -282,6 +475,9 @@ BlastFamilyModelSimple::~BlastFamilyModelSimple()
SAFE_DELETE(m_chunks[chunkIndex].renderMeshes[i]);
}
}
+ // Add By Lixu Begin
+ //PrintActors(SampleManager::ins()->getPhysXController());
+ // Add By Lixu End
}
void BlastFamilyModelSimple::onActorCreated(const ExtPxActor& actor)
@@ -299,9 +495,15 @@ void BlastFamilyModelSimple::onActorCreated(const ExtPxActor& actor)
{
if (colors.size() <= r)
colors.push_back(getRandomPastelColor());
-
- renderables[r]->setHidden(false);
- renderables[r]->setColor(colors[r]);
+ if (SampleManager::ins()->IsSimulating())
+ {
+ renderables[r]->setHidden(false);
+ }
+ else
+ {
+ renderables[r]->setHidden(!_getBPPChunkVisible(chunkIndex));
+ }
+// renderables[r]->setColor(colors[r]);
m_VisibleChangedChunks[chunkIndex] = true;
}
@@ -311,6 +513,9 @@ void BlastFamilyModelSimple::onActorCreated(const ExtPxActor& actor)
void BlastFamilyModelSimple::onActorUpdate(const ExtPxActor& actor)
{
// Add By Lixu Begin
+ if (!SampleManager::ins()->IsSimulating())
+ return;
+
uint32_t shapesCount = actor.getPhysXActor().getNbShapes();
PxTransform lp;
if (shapesCount > 0)
@@ -336,6 +541,12 @@ void BlastFamilyModelSimple::onActorUpdate(const ExtPxActor& actor)
r->setTransform(actor.getPhysXActor().getGlobalPose() * lp * subChunks[chunks[chunkIndex].firstSubchunkIndex].transform);
// Add By Lixu End
}
+
+ // Add By Lixu Begin
+ PxActor* editActor = m_chunkEditActorMap[chunkIndex];
+ PxRigidDynamic* rigidDynamic = editActor->is<PxRigidDynamic>();
+ rigidDynamic->setGlobalPose(actor.getPhysXActor().getGlobalPose() * lp * subChunks[chunks[chunkIndex].firstSubchunkIndex].transform);
+ // Add By Lixu End
}
}
@@ -373,6 +584,7 @@ void BlastFamilyModelSimple::onActorHealthUpdate(const ExtPxActor& actor)
const NvBlastBond* bonds = tkAsset->getBonds();
const NvBlastSupportGraph graph = tkAsset->getGraph();
+ const float bondHealthMax = m_blastAsset.getBondHealthMax();
std::vector<float> healthBuffer;
@@ -405,7 +617,7 @@ void BlastFamilyModelSimple::onActorHealthUpdate(const ExtPxActor& actor)
{
uint32_t node1 = graph.adjacentNodeIndices[adjacencyIndex];
uint32_t bondIndex = graph.adjacentBondIndices[adjacencyIndex];
- float bondHealth = PxClamp(bondHealths[bondIndex] / BOND_HEALTH_MAX, 0.0f, 1.0f);
+ float bondHealth = PxClamp(bondHealths[bondIndex] / bondHealthMax, 0.0f, 1.0f);
const NvBlastBond& solverBond = bonds[bondIndex];
const PxVec3& centroid = reinterpret_cast<const PxVec3&>(solverBond.centroid);
@@ -424,30 +636,167 @@ void BlastFamilyModelSimple::onActorHealthUpdate(const ExtPxActor& actor)
}
// Add By Lixu Begin
-void BlastFamilyModelSimple::setActorSelected(const ExtPxActor& actor, bool selected)
+bool BlastFamilyModelSimple::find(const PxActor& actor)
{
- const uint32_t* chunkIndices = actor.getChunkIndices();
- uint32_t chunkCount = actor.getChunkCount();
- for (uint32_t i = 0; i < chunkCount; i++)
+ return -1 != getChunkIndexByPxActor(actor);
+}
+
+void BlastFamilyModelSimple::updateActorRenderableTransform(const PxActor& actor, PxTransform& pos, bool local)
+{
+ uint32_t chunkIndex = getChunkIndexByPxActor(actor);
+ if (-1 == chunkIndex)
+ return;
+
+ std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables;
+ for (Renderable* r : renderables)
{
- uint32_t chunkIndex = chunkIndices[i];
- std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables;
- for (Renderable* r : renderables)
+ if (!local)
+ {
+ r->setTransform(pos);
+
+ // in edit mode, if change root chunk's orientation in edit physx scene, also change root physx actor in blast physx scene
+ if (0 == chunkIndex && !SampleManager::ins()->IsSimulating())
+ {
+ (*m_actors.begin())->getPhysXActor().setGlobalPose(pos);
+ }
+ }
+ else
{
- r->setSelected(selected);
+ if (0 == chunkIndex)
+ {
+ PxActor& blastActor = (*m_actors.begin())->getPhysXActor();
+ PxRigidDynamic* rigidDynamic = blastActor.is<PxRigidDynamic>();
+ if (NULL != rigidDynamic)
+ {
+ PxTransform gp_new = pos;
+ PxTransform gp_old = rigidDynamic->getGlobalPose();
+ rigidDynamic->setGlobalPose(pos);
+ PxScene& pxScene = SampleManager::ins()->getPhysXController().getPhysXScene();
+ modifyPxActorByLocalWay(pxScene, *rigidDynamic, gp_old, gp_new);
+ const BlastModel& model = dynamic_cast<BlastAssetModelSimple*>(const_cast<BlastAsset*>(&m_blastAsset))->getModel();
+ // update model mesh
+ modifyModelByLocalWay(*(const_cast<BlastModel*>(&model)), gp_old, gp_new);
+ // update blast asset instance's transform
+ BPPAssetInstance* assetInstance = SampleManager::ins()->getInstanceByFamily(this);
+ assetInstance->transform.position = nvidia::NvVec3(gp_new.p.x, gp_new.p.y, gp_new.p.z);
+ assetInstance->transform.rotation = nvidia::NvVec4(gp_new.q.x, gp_new.q.y, gp_new.q.z, gp_new.q.w);
+ }
+ }
}
}
}
+uint32_t BlastFamilyModelSimple::getChunkIndexByPxActor(const PxActor& actor)
+{
+ std::map<PxActor*, uint32_t>::iterator itr = m_editActorChunkMap.find(const_cast<PxActor*>(&actor));
+
+ if (itr != m_editActorChunkMap.end())
+ {
+ return itr->second;
+ }
+ else
+ {
+ for (ExtPxActor* extPxActor : m_actors)
+ {
+ if (&(extPxActor->getPhysXActor()) == (&actor)->is<physx::PxRigidDynamic>())
+ {
+ return extPxActor->getChunkIndices()[0];
+ }
+ }
+ }
+ return -1;
+}
+
+bool BlastFamilyModelSimple::getPxActorByChunkIndex(uint32_t chunkIndex, PxActor** ppActor)
+{
+ *ppActor = nullptr;
+ std::map<uint32_t, PxActor*>::iterator it = m_chunkEditActorMap.find(chunkIndex);
+ if (it == m_chunkEditActorMap.end())
+ {
+ return false;
+ }
+
+ *ppActor = it->second;
+ return true;
+}
+
+void BlastFamilyModelSimple::setActorSelected(const PxActor& actor, bool selected)
+{
+ uint32_t chunkIndex = getChunkIndexByPxActor(actor);
+ if (-1 == chunkIndex)
+ return;
+
+ bool selectionDepthTest = BlastProject::ins().getParams().fracture.general.selectionDepthTest;
+
+ std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables;
+ for (Renderable* r : renderables)
+ {
+ r->setSelected(selected);
+
+ if (!selectionDepthTest && selected)
+ {
+ r->setDepthTest(false);
+ }
+ else
+ {
+ r->setDepthTest(true);
+ }
+ }
+}
+
+bool BlastFamilyModelSimple::isActorSelected(const PxActor& actor)
+{
+ uint32_t chunkIndex = getChunkIndexByPxActor(actor);
+ if (-1 == chunkIndex)
+ return false;
+
+ std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables;
+ return renderables[0]->isSelected();
+}
+
+void BlastFamilyModelSimple::setActorVisible(const PxActor& actor, bool visible)
+{
+ uint32_t chunkIndex = getChunkIndexByPxActor(actor);
+ if (-1 == chunkIndex)
+ return;
+
+ std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables;
+ for (Renderable* r : renderables)
+ {
+ r->setHidden(!visible);
+ }
+}
+
+bool BlastFamilyModelSimple::isActorVisible(const PxActor& actor)
+{
+ uint32_t chunkIndex = getChunkIndexByPxActor(actor);
+ if (-1 == chunkIndex)
+ return false;
+
+ std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables;
+ return !renderables[0]->isHidden();
+}
+
void BlastFamilyModelSimple::setChunkSelected(uint32_t chunk, bool selected)
{
if (chunk > m_chunks.size())
return;
+ bool selectionDepthTest = BlastProject::ins().getParams().fracture.general.selectionDepthTest;
+
std::vector<Renderable*>& renderables = m_chunks[chunk].renderables;
for (Renderable* r : renderables)
{
r->setSelected(select);
+
+ if (!selectionDepthTest && selected)
+ {
+ r->setDepthTest(false);
+ }
+ else
+ {
+ r->setDepthTest(true);
+ }
}
}
@@ -472,11 +821,13 @@ void BlastFamilyModelSimple::clearChunksSelected()
for (Renderable* r : renderables)
{
r->setSelected(false);
+ r->setDepthTest(true);
+ r->setHighlight(false);
}
}
}
-bool BlastFamilyModelSimple::getChunkSelected(uint32_t chunk)
+bool BlastFamilyModelSimple::isChunkSelected(uint32_t chunk)
{
if (chunk > m_chunks.size())
return false;
@@ -515,17 +866,31 @@ std::vector<uint32_t> BlastFamilyModelSimple::getSelectedChunks()
return selectedChunks;
}
-void BlastFamilyModelSimple::setActorScale(const ExtPxActor& actor, PxMat44& scale, bool replace)
+void BlastFamilyModelSimple::setActorScale(const PxActor& actor, PxMat44& scale, bool replace)
{
- const uint32_t* chunkIndices = actor.getChunkIndices();
- uint32_t chunkCount = actor.getChunkCount();
- for (uint32_t i = 0; i < chunkCount; i++)
+ uint32_t chunkIndex = getChunkIndexByPxActor(actor);
+ if (-1 == chunkIndex)
+ return;
+ std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables;
+ for (Renderable* r : renderables)
{
- uint32_t chunkIndex = chunkIndices[i];
- std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables;
- for (Renderable* r : renderables)
+ r->setMeshScale(scale, replace);
+ }
+
+ if (0 == chunkIndex)
+ {
+ PxActor& blastActor = (*m_actors.begin())->getPhysXActor();
+ PxRigidDynamic* rigidDynamic = blastActor.is<PxRigidDynamic>();
+ if (NULL != rigidDynamic)
{
- r->setMeshScale(scale, replace);
+ PxScene& pxScene = SampleManager::ins()->getPhysXController().getPhysXScene();
+ scalePxActor(pxScene, *rigidDynamic, scale);
+
+ if (replace)
+ {
+ const BlastModel& model = dynamic_cast<BlastAssetModelSimple*>(const_cast<BlastAsset*>(&m_blastAsset))->getModel();
+ scaleModel(*(const_cast<BlastModel*>(&model)), scale);
+ }
}
}
}
@@ -574,6 +939,7 @@ void BlastFamilyModelSimple::setChunkVisible(std::vector<uint32_t> depths, bool
void BlastFamilyModelSimple::initTransform(physx::PxTransform t)
{
+ BlastFamily::initTransform(t);
int chunkSize = m_chunks.size();
for (int i = 0; i < chunkSize; i++)
{
@@ -583,6 +949,12 @@ void BlastFamilyModelSimple::initTransform(physx::PxTransform t)
r->setTransform(t);
}
}
+
+ for (std::map<PxActor*, uint32_t>::iterator itr = m_editActorChunkMap.begin(); itr != m_editActorChunkMap.end(); ++itr)
+ {
+ PxRigidDynamic* rigidDynamic = itr->first->is<PxRigidDynamic>();
+ rigidDynamic->setGlobalPose(t);
+ }
}
void BlastFamilyModelSimple::getMaterial(RenderMaterial** ppRenderMaterial, bool externalSurface)
@@ -655,4 +1027,39 @@ void BlastFamilyModelSimple::setMaterial(RenderMaterial* pRenderMaterial, bool e
}
}
}
+
+void BlastFamilyModelSimple::highlightChunks()
+{
+ bool selectionDepthTest = BlastProject::ins().getParams().fracture.general.selectionDepthTest;
+
+ for (Chunk chunk : m_chunks)
+ {
+ std::vector<Renderable*>& renderables = chunk.renderables;
+ for (Renderable* r : renderables)
+ {
+ r->setHighlight(true);
+ r->setDepthTest(selectionDepthTest);
+ }
+ }
+}
+
+bool BlastFamilyModelSimple::_getBPPChunkVisible(uint32_t chunkIndex)
+{
+ std::map<BlastAsset*, AssetList::ModelAsset>& assetDescMap = SampleManager::ins()->getAssetDescMap();
+ BlastAsset* blastAsset = (BlastAsset*)&getBlastAsset();
+ AssetList::ModelAsset& m = assetDescMap[blastAsset];
+
+ BlastProject& project = BlastProject::ins();
+ BPPAsset& bppAsset = *(project.getAsset(m.name.c_str()));
+
+ BPPChunk* bppChunk = project.getChunk(bppAsset, chunkIndex);
+ if (bppChunk)
+ {
+ return bppChunk->visible;
+ }
+ else
+ {
+ return true;
+ }
+}
// Add By Lixu End \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.h
index ed51133..c86242a 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_FAMILY_MODEL_SIMPLE_H
#define BLAST_FAMILY_MODEL_SIMPLE_H
@@ -17,6 +35,13 @@
class SimpleRenderMesh;
class Renderable;
class Renderer;
+// Add By Lixu Begin
+namespace physx
+{
+ class PxActor;
+}
+using namespace physx;
+// Add By Lixu End
class BlastFamilyModelSimple : public BlastFamily
{
@@ -27,19 +52,27 @@ public:
virtual ~BlastFamilyModelSimple();
// Add By Lixu Begin
- virtual void setActorSelected(const ExtPxActor& actor, bool selected);
+ virtual bool find(const PxActor& actor);
+ virtual void updateActorRenderableTransform(const PxActor& actor, PxTransform& pos, bool local);
+ virtual uint32_t getChunkIndexByPxActor(const PxActor& actor);
+ virtual bool getPxActorByChunkIndex(uint32_t chunkIndex, PxActor** ppActor);
+ virtual void setActorSelected(const PxActor& actor, bool selected);
+ virtual bool isActorSelected(const PxActor& actor);
+ virtual void setActorVisible(const PxActor& actor, bool visible);
+ virtual bool isActorVisible(const PxActor& actor);
virtual void clearChunksSelected();
virtual void setChunkSelected(uint32_t chunk, bool selected);
virtual void setChunkSelected(std::vector<uint32_t> depths, bool selected);
- virtual bool getChunkSelected(uint32_t chunk);
+ virtual bool isChunkSelected(uint32_t chunk);
virtual std::vector<uint32_t> getSelectedChunks();
- virtual void setActorScale(const ExtPxActor& actor, PxMat44& scale, bool replace);
+ virtual void setActorScale(const PxActor& actor, PxMat44& scale, bool replace);
virtual bool isChunkVisible(uint32_t chunkIndex);
virtual void setChunkVisible(uint32_t chunkIndex, bool bVisible);
virtual void setChunkVisible(std::vector<uint32_t> depths, bool bVisible);
virtual void initTransform(physx::PxTransform t);
virtual void getMaterial(RenderMaterial** ppRenderMaterial, bool externalSurface);
virtual void setMaterial(RenderMaterial* pRenderMaterial, bool externalSurface);
+ virtual void highlightChunks();
// Add By Lixu End
protected:
@@ -51,6 +84,10 @@ protected:
virtual void onActorHealthUpdate(const ExtPxActor& pxActor);
private:
+ // Add By Lixu Begin
+ bool _getBPPChunkVisible(uint32_t chunkIndex);
+ // Add By Lixu End
+
//////// internal data ////////
Renderer& m_renderer;
@@ -66,6 +103,8 @@ private:
};
std::vector<Chunk> m_chunks;
+ std::map<PxActor*, uint32_t> m_editActorChunkMap;// only for edit mode
+ std::map<uint32_t, PxActor*> m_chunkEditActorMap;// only for edit mode
};
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.cpp
index c0731d5..a0319ff 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "BlastFamilyModelSkinned.h"
#include "RenderUtils.h"
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.h
index aeb9353..d76b18e 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_FAMILY_MODEL_SKINNED_H
#define BLAST_FAMILY_MODEL_SKINNED_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.cpp
index aa738b9..5051534 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "BlastFractureTool.h"
#include <BlastAssetModel.h>
@@ -126,8 +144,72 @@ void BlastFractureTool::setSourceAsset(const BlastAsset* pBlastAsset)
for (uint32_t i = 0; i < supportGraph.nodeCount; ++i)
{
const uint32_t chunkIndex = supportGraph.chunkIndices[i];
- isLeafs[chunkIndex] = true;
+ if (chunkIndex < chunkSize)
+ {
+ isLeafs[chunkIndex] = true;
+ }
+ }
+ }
+
+ setSourceMesh(chunkMeshes[0]);
+
+ mChunkData.resize(chunkSize);
+ mChunkData[0].parent = parentIds[0];
+ mChunkData[0].isLeaf = isLeafs[0];
+ mChunkData[0].chunkId = 0;
+ Nv::Blast::Mesh* mesh = nullptr;
+ for (int cs = 1; cs < chunkSize; cs++)
+ {
+ if (chunkMeshes[cs] == nullptr)
+ continue;
+ mChunkData[cs].meshData = new Nv::Blast::Mesh(*chunkMeshes[cs]);
+ mChunkData[cs].parent = parentIds[cs];
+ mChunkData[cs].chunkId = mChunkIdCounter++;
+ mChunkData[cs].isLeaf = isLeafs[cs];
+
+ mesh = mChunkData[cs].meshData;
+ Nv::Blast::Vertex* verticesBuffer = mesh->getVertices();
+ for (uint32_t i = 0; i < mesh->getVerticesCount(); ++i)
+ {
+ verticesBuffer[i].p = (verticesBuffer[i].p - mOffset) * (1.0f / mScaleFactor);
+ }
+ mesh->getBoundingBox().minimum = (mesh->getBoundingBox().minimum - mOffset) * (1.0f / mScaleFactor);
+ mesh->getBoundingBox().maximum = (mesh->getBoundingBox().maximum - mOffset) * (1.0f / mScaleFactor);
+ for (uint32_t i = 0; i < mesh->getFacetCount(); ++i)
+ {
+ mesh->getFacet(i)->userData = chunkMeshes[cs]->getFacet(i)->userData;
+ }
+ }
+}
+
+void BlastFractureTool::setSourceMeshes(std::vector<Nv::Blast::Mesh*>& meshes, std::vector<int32_t>& parentIds)
+{
+ free();
+
+ int chunkSize = meshes.size();
+ if (chunkSize == 0)
+ {
+ return;
+ }
+
+ chunkMeshes.resize(chunkSize, nullptr);
+ for (int cs = 0; cs < chunkSize; cs++)
+ {
+ Nv::Blast::Mesh* pMesh = new Nv::Blast::Mesh(*meshes[cs]);
+ chunkMeshes[cs] = pMesh;
+ }
+
+ std::vector<bool> isLeafs;
+ isLeafs.resize(chunkSize, true);
+ for (int cs = 0; cs < chunkSize; cs++)
+ {
+ int32_t parentId = parentIds[cs];
+ if (parentId == -1)
+ {
+ continue;
}
+
+ isLeafs[parentId] = false;
}
setSourceMesh(chunkMeshes[0]);
@@ -143,7 +225,7 @@ void BlastFractureTool::setSourceAsset(const BlastAsset* pBlastAsset)
continue;
mChunkData[cs].meshData = new Nv::Blast::Mesh(*chunkMeshes[cs]);
mChunkData[cs].parent = parentIds[cs];
- mChunkData[cs].chunkId = cs;
+ mChunkData[cs].chunkId = mChunkIdCounter++;
mChunkData[cs].isLeaf = isLeafs[cs];
mesh = mChunkData[cs].meshData;
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.h
index b50ccf3..42ff78f 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_FRACTURETOOL_H
#define BLAST_FRACTURETOOL_H
@@ -25,11 +43,13 @@ namespace Nv
class BlastFractureTool : public Nv::Blast::FractureTool
{
public:
- BlastFractureTool(NvBlastLog logCallback = nullptr) : FractureTool(logCallback) {}
+ BlastFractureTool() {}
~BlastFractureTool() { free(); }
void setSourceAsset(const BlastAsset* pBlastAsset);
+ void setSourceMeshes(std::vector<Nv::Blast::Mesh*>& meshes, std::vector<int32_t>& parentIds);
+
Nv::Blast::Mesh* getSourceMesh(int32_t chunkId);
private:
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.cpp
index d231a6c..1e45003 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "BlastModel.h"
@@ -14,14 +32,101 @@
//#define TINYOBJLOADER_IMPLEMENTATION
// Add By Lixu End
#include "tiny_obj_loader.h"
-
+#include "MathUtil.h"
+#include "NvBlastExtExporterFbxReader.h"
using namespace physx;
+void computeTangentByPositionAndTexcoord(
+ physx::PxVec3 p0, physx::PxVec3 p1, physx::PxVec3 p2,
+ physx::PxVec2 r0, physx::PxVec2 r1, physx::PxVec2 r2,
+ physx::PxVec3& tangent)
+{
+ float x1 = p1.x - p0.x;
+ float x2 = p2.x - p0.x;
+ float y1 = p1.y - p0.y;
+ float y2 = p2.y - p0.y;
+ float z1 = p1.z - p0.z;
+ float z2 = p2.z - p0.z;
+
+ float s1 = r1.x - r0.x;
+ float s2 = r2.x - r0.x;
+ float t1 = r1.y - r0.y;
+ float t2 = r2.y - r0.y;
+
+ float r = 1.0f / (s1 * t2 - s2 * t1);
+
+ tangent = PxVec3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
+}
+
+BlastModelPtr BlastModel::loadFromFbxFile(const char* path)
+{
+// Add By Lixu Begin
+ BlastModel* model = new BlastModel();
+ model->bbMin = PxVec3(FLT_MAX, FLT_MAX, FLT_MAX);
+ model->bbMax = PxVec3(FLT_MIN, FLT_MIN, FLT_MIN);
+// Add By Lixu End
+
+ FbxFileReader rdr;
+ rdr.loadFromFile(path);
+ if (rdr.getBoneCount() == 0)
+ {
+ return nullptr;
+ }
+
+ model->chunks.resize(rdr.getBoneCount());
+
+ model->materials.push_back(BlastModel::Material());
+
+
+ /**
+ Produce buffers of appropriate for AssetViewer format
+ */
+ std::vector<uint32_t> infl;
+ rdr.getBoneInfluences(infl);
+ for (uint32_t i = 0; i < rdr.getBoneCount(); ++i)
+ {
+ std::vector<int32_t> indRemap(rdr.getPositionArray().size(), -1);
+ std::vector<uint32_t> indices;
+ SimpleMesh cmesh;
+ for (uint32_t j = 0; j < rdr.getPositionArray().size(); ++j)
+ {
+ if (i == infl[j])
+ {
+ indRemap[j] = (int32_t)cmesh.vertices.size();
+ cmesh.vertices.push_back(SimpleMesh::Vertex());
+ cmesh.vertices.back().normal = rdr.getNormalsArray()[j];
+ cmesh.vertices.back().position = rdr.getPositionArray()[j];
+ cmesh.vertices.back().uv = rdr.getUvArray()[j];
+ }
+ }
+ for (uint32_t j = 0; j < rdr.getIndexArray().size(); j += 3)
+ {
+ if (i == infl[rdr.getIndexArray()[j]])
+ {
+ int32_t lind = rdr.getIndexArray()[j + 2];
+ cmesh.indices.push_back(indRemap[lind]);
+ lind = rdr.getIndexArray()[j + 1];
+ cmesh.indices.push_back(indRemap[lind]);
+ lind = rdr.getIndexArray()[j];
+ cmesh.indices.push_back(indRemap[lind]);
+ }
+ }
+
+ model->chunks[i].meshes.push_back(Chunk::Mesh());
+ model->chunks[i].meshes.back().materialIndex = 0;
+ model->chunks[i].meshes.back().mesh = cmesh;
+ }
+ return model;
+}
+
+
BlastModelPtr BlastModel::loadFromFileTinyLoader(const char* path)
{
// Add By Lixu Begin
BlastModel* model = new BlastModel();
+ model->bbMin = PxVec3(FLT_MAX, FLT_MAX, FLT_MAX);
+ model->bbMax = PxVec3(FLT_MIN, FLT_MIN, FLT_MIN);
// Add By Lixu End
std::vector<tinyobj::shape_t> shapes;
@@ -30,14 +135,14 @@ BlastModelPtr BlastModel::loadFromFileTinyLoader(const char* path)
std::string mtlPath;
for (size_t i = strnlen(path, 255) - 1; i >= 0; --i)
{
- if (path[i] == '\\')
+ if (path[i] == '\\' || path[i] == '/')
{
mtlPath.resize(i + 2, 0);
strncpy(&mtlPath[0], path, i + 1);
break;
}
}
-
+
bool ret = tinyobj::LoadObj(shapes, mats, err, path, mtlPath.data());
@@ -54,11 +159,24 @@ BlastModelPtr BlastModel::loadFromFileTinyLoader(const char* path)
{
tinyobj::material_t *pMaterial = &mats[i];
- if (!pMaterial->diffuse_texname.empty())
+ // Add By Lixu Begin
+ if (strcmp(pMaterial->name.c_str(), "neverMat123XABCnever") == 0)
+ {
+ model->materials[i].name.clear();
+ }
+ else
{
-// Add By Lixu Begin
model->materials[i].name = pMaterial->name;
-// Add By Lixu End
+ }
+ // Add By Lixu End
+
+ model->materials[i].r = pMaterial->diffuse[0];
+ model->materials[i].g = pMaterial->diffuse[1];
+ model->materials[i].b = pMaterial->diffuse[2];
+ model->materials[i].a = 1.0;
+
+ if (!pMaterial->diffuse_texname.empty())
+ {
model->materials[i].diffuseTexture = pMaterial->diffuse_texname;
}
}
@@ -154,12 +272,39 @@ BlastModelPtr BlastModel::loadFromFileTinyLoader(const char* path)
}
}
+ // compute tangent
+ if (pMesh.mesh.indices.size() > 0 && allTriangles)
+ {
+ for (uint32_t i = 0; i < pMesh.mesh.indices.size(); i += 3)
+ {
+ SimpleMesh::Vertex& v0 = chunkMesh.vertices[chunkMesh.indices[i + 0]];
+ SimpleMesh::Vertex& v1 = chunkMesh.vertices[chunkMesh.indices[i + 1]];
+ SimpleMesh::Vertex& v2 = chunkMesh.vertices[chunkMesh.indices[i + 2]];
+
+ physx::PxVec3 tangent;
+ computeTangentByPositionAndTexcoord(
+ v0.position, v1.position, v2.position, v0.uv, v1.uv, v2.uv, tangent);
+
+ v0.tangent += tangent;
+ v1.tangent += tangent;
+ v2.tangent += tangent;
+ }
+ for (uint32_t i = 0; i < chunkMesh.vertices.size(); i++)
+ {
+ chunkMesh.vertices[i].tangent = chunkMesh.vertices[i].tangent.getNormalized();
+ }
+ }
+
// assign extents
chunkMesh.extents = (emax - emin) * 0.5f;
// get the center
chunkMesh.center = emin + chunkMesh.extents;
+ atcore_float3 min = gfsdk_min(*(atcore_float3*)&emin, *(atcore_float3*)&(model->bbMin));
+ model->bbMin = *(physx::PxVec3*)&min;
+ atcore_float3 max = gfsdk_max(*(atcore_float3*)&emax, *(atcore_float3*)&(model->bbMax));
+ model->bbMax = *(physx::PxVec3*)&max;
}
}
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.h
index 683a343..82d2af8 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_MODEL_H
#define BLAST_MODEL_H
@@ -32,10 +50,9 @@ class BlastModel
public:
struct Material
{
-// Add By Lixu Begin
std::string name;
-// Add By Lixu End
std::string diffuseTexture;
+ float r, g, b, a;
};
struct Chunk
@@ -51,8 +68,11 @@ public:
std::vector<Material> materials;
std::vector<Chunk> chunks;
+ physx::PxVec3 bbMin;
+ physx::PxVec3 bbMax;
static BlastModelPtr loadFromFileTinyLoader(const char* path);
+ static BlastModelPtr loadFromFbxFile(const char* path);
private:
BlastModel() {}
};
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.cpp
index 13d2b33..678cec2 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "BlastReplay.h"
#include "NvBlastTk.h"
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.h
index a85c996..2c247a5 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef BLAST_REPLAY_H
#define BLAST_REPLAY_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.cpp
index 955d841..81754e4 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "Application.h"
#include <DirectXMath.h>
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.h
index f0e0601..3681eb3 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef APPLICATION_H
#define APPLICATION_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/DeviceManager.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/DeviceManager.cpp
index b29fb86..78eefe8 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/DeviceManager.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/DeviceManager.cpp
@@ -7,6 +7,7 @@
#include <sstream>
#include <algorithm>
#include <vector>
+#include "GlobalSettings.h"
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
@@ -333,14 +334,7 @@ DeviceManager::MessageLoop()
if (m_SwapChain && GetWindowState() != kWindowMinimized)
{
Animate(elapsedSeconds);
- // changed by Junma Lixu
- CoreLib* pCore = CoreLib::Inst();
- RenderInterface::SwitchToDX11();
- pCore->SimpleScene_Draw_DX11();
Render();
- RenderInterface::FlushDX11();
- RenderInterface::PresentRenderWindow();
- //m_SwapChain->Present(m_SyncInterval, 0);
Sleep(0);
}
else
@@ -486,7 +480,8 @@ DeviceManager::Render()
}
}
- m_ImmediateContext->OMSetRenderTargets(0, NULL, NULL);
+ m_ImmediateContext->OMSetRenderTargets(1, &m_BackBufferRTV, m_DepthStencilDSV);
+ GlobalSettings::Inst().m_renderFrameCnt++;
}
void
@@ -796,6 +791,6 @@ DeviceManager::SetWindowDeviceAndSwapChain(D3DHandles& deviceHandles)
m_DepthStencilBuffer = (ID3D11Texture2D*)deviceHandles.pD3D11DepthBuffer;
m_DepthStencilDSV = (ID3D11DepthStencilView*)deviceHandles.pD3D11DepthStencilView;
m_DepthStencilBuffer->GetDesc(&m_DepthStencilDesc);
- //m_DepthStencilDSV->GetDesc(&);
+
return S_OK;
}
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.cpp
index 163b3b4..cd8ea4c 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.cpp
@@ -1,18 +1,37 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "SampleController.h"
#include "SceneController.h"
#include "CommonUIController.h"
#include "BlastController.h"
#include "PhysXController.h"
+#include "Renderer.h"
#include "imgui.h"
@@ -45,9 +64,12 @@ void SampleController::setUseGPUPhysics(bool useGPUPhysics)
int assetNum = getSceneController().releaseAll();
+ getBlastController().notifyPhysXControllerRelease();
getPhysXController().setUseGPUPhysics(useGPUPhysics);
getBlastController().reinitialize();
+ getRenderer().clearQueue();
+
getSceneController().spawnAsset(assetNum);
}
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.h
index a52c2fe..6d478c1 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef SAMPLE_CONTROLLER_H
#define SAMPLE_CONTROLLER_H
@@ -48,6 +66,11 @@ private:
return getManager()->getCommonUIController();
}
+ Renderer& getRenderer() const
+ {
+ return getManager()->getRenderer();
+ }
+
//////// private methods ////////
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.cpp
index 63178fd..61a174a 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.cpp
@@ -1,16 +1,35 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
+
#include "AppMainWindow.h"
#include "GlobalSettings.h"
#include <QtCore/QFileInfo>
-
+#include <QtCore/QDir>
#include "NvBlastExtAuthoringTypes.h"
#include "NvBlastExtAuthoringFractureTool.h"
#include "NvBlastExtAuthoringBondGenerator.h"
@@ -26,6 +45,7 @@
#include "CommonUIController.h"
#include "DamageToolController.h"
#include "SelectionToolController.h"
+#include "ExplodeToolController.h"
#include "GizmoToolController.h"
#include "EditionToolController.h"
#include "SceneController.h"
@@ -41,9 +61,20 @@
#include <set>
#include "MaterialLibraryPanel.h"
#include "MaterialAssignmentsPanel.h"
+#include "ViewerOutput.h"
+
+#include "NvBlastTkAsset.h"
+#include "BlastAssetModelSimple.h"
+#include "CorelibUtils.h"
+#include "BlastAssetModel.h"
+#include "SimpleScene.h"
+#include "FileReferencesPanel.h"
+#include "BlastPlugin.h"
+#include "BlastToolBar.h"
using namespace physx;
+const uint32_t DEFAULT_VORONOI_UNIFORM_SITES_NUMBER = 5;
physx::PxFoundation* foundation = nullptr;
physx::PxPhysics* physics = nullptr;
physx::PxCooking* cooking = nullptr;
@@ -89,7 +120,7 @@ void loggingCallback(int type, const char* msg, const char* file, int line)
}
void buildPxChunks(const std::vector<std::vector<Triangle>>& chunkGeometry, std::vector<ExtPxAssetDesc::ChunkDesc>& pxChunks,
- std::vector<ExtPxAssetDesc::SubchunkDesc>& pxSubchunks)
+ std::vector<ExtPxAssetDesc::SubchunkDesc>& pxSubchunks, std::vector<bool>& statics)
{
ConvexMeshBuilder collisionBuilder(cooking, &physics->getPhysicsInsertionCallback());
@@ -107,7 +138,7 @@ void buildPxChunks(const std::vector<std::vector<Triangle>>& chunkGeometry, std:
}
pxSubchunks[i].transform = physx::PxTransform(physx::PxIdentity);
pxSubchunks[i].geometry = physx::PxConvexMeshGeometry(collisionBuilder.buildConvexMesh(vertices));
- pxChunks[i].isStatic = false;
+ pxChunks[i].isStatic = statics.size() == 0 ? false : statics[i];
pxChunks[i].subchunkCount = 1;
pxChunks[i].subchunks = &pxSubchunks[i];
}
@@ -118,10 +149,61 @@ void buildPxChunks(const std::vector<std::vector<Triangle>>& chunkGeometry, std:
void saveFractureToObj(std::vector<std::vector<Triangle> > chunksGeometry, std::string name, std::string path)
{
- MaterialAssignmentsPanel* pMaterialAssignmentsPanel = MaterialAssignmentsPanel::ins();
- std::vector<std::string> materialNames;
- std::vector<std::string> materialPaths;
- pMaterialAssignmentsPanel->getMaterialNameAndPaths(materialNames, materialPaths);
+ std::vector<std::string> materialNames(2);
+ std::vector<std::string> materialPaths(2);
+ float diffuseColor[2][4];
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ BlastAsset* pCurBlastAsset = nullptr;
+ int nCurIndex = -1;
+ pSampleManager->getCurrentSelectedInstance(&pCurBlastAsset, nCurIndex);
+ if (pCurBlastAsset != nullptr && nCurIndex != -1)
+ {
+ pSampleManager->getMaterialForCurrentFamily(materialNames[0], true);
+ pSampleManager->getMaterialForCurrentFamily(materialNames[1], false);
+
+ BPPGraphicsMaterial* pMaterialEx = BlastProject::ins().getGraphicsMaterial(materialNames[0].c_str());
+ BPPGraphicsMaterial* pMaterialIn = BlastProject::ins().getGraphicsMaterial(materialNames[1].c_str());
+
+ diffuseColor[0][0] = pMaterialEx->diffuseColor.x;
+ diffuseColor[0][1] = pMaterialEx->diffuseColor.y;
+ diffuseColor[0][2] = pMaterialEx->diffuseColor.z;
+ diffuseColor[0][3] = pMaterialEx->diffuseColor.w;
+ if (pMaterialEx->diffuseTextureFilePath != nullptr)
+ {
+ materialPaths[0] = pMaterialEx->diffuseTextureFilePath;
+ }
+
+ if (pMaterialIn == nullptr)
+ {
+ pMaterialIn = pMaterialEx;
+ }
+
+ diffuseColor[1][0] = pMaterialIn->diffuseColor.x;
+ diffuseColor[1][1] = pMaterialIn->diffuseColor.y;
+ diffuseColor[1][2] = pMaterialIn->diffuseColor.z;
+ diffuseColor[1][3] = pMaterialIn->diffuseColor.w;
+ if (pMaterialIn->diffuseTextureFilePath != nullptr)
+ {
+ materialPaths[1] = pMaterialIn->diffuseTextureFilePath;
+ }
+ }
+ else
+ {
+ MaterialAssignmentsPanel* pMaterialAssignmentsPanel = MaterialAssignmentsPanel::ins();
+ pMaterialAssignmentsPanel->getMaterialNameAndPaths(materialNames, materialPaths);
+
+ if (materialPaths[0] == "")
+ {
+ RenderMaterial* pMaterialEx = RenderMaterial::getDefaultRenderMaterial();
+ pMaterialEx->getDiffuseColor(diffuseColor[0][0], diffuseColor[0][1], diffuseColor[0][2], diffuseColor[0][3]);
+ }
+ if (materialPaths[1] == "")
+ {
+ RenderMaterial* pMaterialIn = RenderMaterial::getDefaultRenderMaterial();
+ pMaterialIn->getDiffuseColor(diffuseColor[1][0], diffuseColor[1][1], diffuseColor[1][2], diffuseColor[1][3]);
+ }
+ }
uint32_t submeshCount = 2;
// export materials (mtl file)
@@ -133,8 +215,12 @@ void saveFractureToObj(std::vector<std::vector<Triangle> > chunksGeometry, std::
for (uint32_t submeshIndex = 0; submeshIndex < submeshCount; ++submeshIndex)
{
- fprintf(f, "newmtl %s\n", materialNames[submeshIndex].c_str());
+ // Add By Lixu Begin
+ std::string& matName = materialNames[submeshIndex];
+ fprintf(f, "newmtl %s\n", matName.size()? matName.c_str() : "neverMat123XABCnever"); // this speical string is also used in another BlastModel.cpp.
+ // Add By Lixu End
fprintf(f, "\tmap_Kd %s\n", materialPaths[submeshIndex].c_str());
+ fprintf(f, "\tKd %f %f %f\n", diffuseColor[submeshIndex][0], diffuseColor[submeshIndex][1], diffuseColor[submeshIndex][2]);
fprintf(f, "\n");
}
@@ -217,81 +303,201 @@ void saveFractureToObj(std::vector<std::vector<Triangle> > chunksGeometry, std::
}
}
-void FractureExecutor::setSourceMesh(Nv::Blast::Mesh* mesh)
+#include "NvBlastExtLlSerialization.h"
+#include "NvBlastExtTkSerialization.h"
+#include "NvBlastExtPxSerialization.h"
+#include "NvBlastExtSerialization.h"
+
+bool saveBlastObject(const std::string& outputDir, const std::string& objectName, const void* object, uint32_t objectTypeID)
{
- assert(m_fractureTool);
- m_sourMesh = mesh;
- m_fractureTool->setSourceMesh(mesh);
+ ExtSerialization* mSerialization = SampleManager::ins()->getBlastController().getExtSerialization();
+
+ void* buffer;
+ const uint64_t bufferSize = mSerialization->serializeIntoBuffer(buffer, object, objectTypeID);
+ if (bufferSize == 0)
+ {
+ std::cerr << "saveBlastObject: Serialization failed.\n";
+ return false;
+ }
+
+ // Add By Lixu Begin
+ physx::PsFileBuffer fileBuf((outputDir + "/" + objectName).c_str(), physx::PxFileBuf::OPEN_WRITE_ONLY);
+ // Add By Lixu End
+
+ bool result = fileBuf.isOpen();
+
+ if (!result)
+ {
+ std::cerr << "Can't open output buffer.\n";
+ }
+ else
+ {
+ result = (bufferSize == (size_t)fileBuf.write(buffer, (uint32_t)bufferSize));
+ if (!result)
+ {
+ std::cerr << "Buffer write failed.\n";
+ }
+ fileBuf.close();
+ }
+
+ NVBLAST_FREE(buffer);
+
+ return result;
+}
+
+bool saveLlAsset(const std::string& outputDir, const std::string& objectName, const NvBlastAsset* assetLL)
+{
+ return saveBlastObject(outputDir, objectName, assetLL, LlObjectTypeID::Asset);
+}
+
+bool saveTkAsset(const std::string& outputDir, const std::string& objectName, const TkAsset* tkAsset)
+{
+ return saveBlastObject(outputDir, objectName, tkAsset, TkObjectTypeID::Asset);
}
-void FractureExecutor::setSourceAsset(const BlastAsset* blastAsset)
+bool saveExtAsset(const std::string& outputDir, const std::string& objectName, const ExtPxAsset* pxAsset)
+{
+ return saveBlastObject(outputDir, objectName, pxAsset, ExtPxObjectTypeID::Asset);
+}
+
+void FractureExecutor::setSourceAsset(BlastAsset* blastAsset)
{
assert(m_fractureTool);
m_fractureTool->setSourceAsset(blastAsset);
- m_sourMesh = nullptr;
+ m_pCurBlastAsset = blastAsset;
}
VoronoiFractureExecutor::VoronoiFractureExecutor()
-: m_cellsCount(5)
+: m_voronoi(nullptr)
{
if (sSampleManager)
m_fractureTool = sSampleManager->m_fTool;
}
-void VoronoiFractureExecutor::setCellsCount(uint32_t cellsCount)
-{
- m_cellsCount = cellsCount;
-}
-
bool VoronoiFractureExecutor::execute()
{
- Nv::Blast::Mesh* mesh = nullptr;
- if (m_sourMesh)
+ std::vector<uint32_t>::iterator it;
+ for (it = m_chunkIds.begin(); it != m_chunkIds.end(); it++)
{
- mesh = m_sourMesh;
+ Nv::Blast::Mesh* mesh = m_fractureTool->getSourceMesh(*it);
+ if (mesh == nullptr)
+ continue;
+
+ VoronoiSitesGenerator* siteGenerator = nullptr;
+ if (m_voronoi)
+ {
+ siteGenerator = new VoronoiSitesGenerator(mesh, m_randomGenerator == nullptr ? &sRandomGenerator : m_randomGenerator);
+ if (0 == m_voronoi->siteGeneration)
+ {
+ siteGenerator->uniformlyGenerateSitesInMesh(m_voronoi->numSites);
+ }
+ else if (1 == m_voronoi->siteGeneration)
+ {
+ siteGenerator->clusteredSitesGeneration(m_voronoi->numberOfClusters, m_voronoi->sitesPerCluster, m_voronoi->clusterRadius);
+ }
+ }
+ else
+ {
+ siteGenerator = new VoronoiSitesGenerator(mesh, m_randomGenerator == nullptr ? &sRandomGenerator : m_randomGenerator);
+ siteGenerator->uniformlyGenerateSitesInMesh(DEFAULT_VORONOI_UNIFORM_SITES_NUMBER);
+ }
+
+ m_fractureTool->voronoiFracturing(*it, siteGenerator->getVoronoiSites(), false);
+ delete siteGenerator;
}
- else
+ m_fractureTool->finalizeFracturing();
+
+ std::vector<bool> supports;
+ std::vector<bool> statics;
+ std::vector<uint8_t> joints;
+ std::vector<uint32_t> worlds;
+ BlastAsset* pNewBlastAsset = sSampleManager->_replaceAsset(m_pCurBlastAsset, supports, statics, joints, worlds);
+ if (nullptr == pNewBlastAsset)
{
- mesh = m_fractureTool->getSourceMesh(m_chunkId);
- }
- // Prevent crash Junma Added By Lixu
- if (mesh == nullptr)
return false;
+ }
- VoronoiSitesGenerator stGenerator(mesh, (m_randomGenerator == nullptr ? &sRandomGenerator : m_randomGenerator));
- stGenerator.uniformlyGenerateSitesInMesh(m_cellsCount);
- m_fractureTool->voronoiFracturing(m_chunkId, stGenerator.getVoronoiSites(), false);
- m_fractureTool->finalizeFracturing();
+ std::vector<uint32_t> NewChunkIndexes;
+ for (uint32_t ci = 0; ci < m_fractureTool->getChunkCount(); ci++)
+ {
+ for (uint32_t chunkId : m_chunkIds)
+ {
+ if (m_fractureTool->getChunkInfo(ci).parent == chunkId)
+ {
+ NewChunkIndexes.push_back(ci);
+ }
+ }
+ }
- return sSampleManager->postProcessCurrentAsset();
+ sSampleManager->ApplyAutoSelectNewChunks(pNewBlastAsset, NewChunkIndexes);
+
+ return true;
}
SliceFractureExecutor::SliceFractureExecutor()
-: m_config(new Nv::Blast::SlicingConfiguration())
+: m_slice(nullptr)
{
if (sSampleManager)
m_fractureTool = sSampleManager->m_fTool;
}
-void SliceFractureExecutor::applyNoise(float amplitude, float frequency, int32_t octaves, float falloff, int32_t relaxIterations, float relaxFactor, int32_t seed)
+bool SliceFractureExecutor::execute()
{
- m_fractureTool->applyNoise(amplitude, frequency, octaves, falloff, relaxIterations, relaxFactor, seed);
-}
+ SlicingConfiguration config;
+ if (m_slice)
+ {
+ config.x_slices = m_slice->numSlicesX;
+ config.y_slices = m_slice->numSlicesY;
+ config.z_slices = m_slice->numSlicesZ;
+ config.offset_variations = m_slice->offsetVariation;
+ config.angle_variations = m_slice->rotationVariation;
+ config.noiseAmplitude = m_slice->noiseAmplitude;
+ config.noiseFrequency = m_slice->noiseFrequency;
+ config.noiseOctaveNumber = m_slice->noiseOctaveNumber;
+ config.surfaceResolution = m_slice->surfaceResolution;
+ }
-void SliceFractureExecutor::applyConfig(int32_t xSlices, int32_t ySlices, int32_t zSlices, float offsetVariations, float angleVariations)
-{
- m_config->x_slices = xSlices;
- m_config->y_slices = ySlices;
- m_config->z_slices = zSlices;
- m_config->offset_variations = offsetVariations;
- m_config->angle_variations = angleVariations;
-}
+ if (m_randomGenerator == nullptr)
+ {
+ sRandomGenerator.seed(m_slice->noiseSeed);
+ }
+ else
+ {
+ m_randomGenerator->seed(m_slice->noiseSeed);
+ }
-bool SliceFractureExecutor::execute()
-{
- m_fractureTool->slicing(m_chunkId, *m_config, false, (m_randomGenerator == nullptr ? &sRandomGenerator : m_randomGenerator));
+ std::vector<uint32_t>::iterator it;
+ for (it = m_chunkIds.begin(); it != m_chunkIds.end(); it++)
+ {
+ m_fractureTool->slicing(*it, config, false, (m_randomGenerator == nullptr ? &sRandomGenerator : m_randomGenerator));
+ }
m_fractureTool->finalizeFracturing();
- return sSampleManager->postProcessCurrentAsset();
+
+ std::vector<bool> supports;
+ std::vector<bool> statics;
+ std::vector<uint8_t> joints;
+ std::vector<uint32_t> worlds;
+ BlastAsset* pNewBlastAsset = sSampleManager->_replaceAsset(m_pCurBlastAsset, supports, statics, joints, worlds);
+ if (nullptr == pNewBlastAsset)
+ {
+ return false;
+ }
+
+ std::vector<uint32_t> NewChunkIndexes;
+ for (uint32_t ci = 0; ci < m_fractureTool->getChunkCount(); ci++)
+ {
+ for (uint32_t chunkId : m_chunkIds)
+ {
+ if (m_fractureTool->getChunkInfo(ci).parent == chunkId)
+ {
+ NewChunkIndexes.push_back(ci);
+ }
+ }
+ }
+
+ sSampleManager->ApplyAutoSelectNewChunks(pNewBlastAsset, NewChunkIndexes);
+
+ return true;
}
static VoronoiFractureExecutor sVoronoiFracture;
@@ -302,9 +508,8 @@ SampleManager* SampleManager::ins()
}
SampleManager::SampleManager(DeviceManager* pDeviceManager)
-{
+{
sSampleManager = this;
- m_bNeedConfig = false;
m_bNeedRefreshTree = false;
m_renderer = new Renderer();
@@ -313,10 +518,11 @@ SampleManager::SampleManager(DeviceManager* pDeviceManager)
m_sceneController = new SceneController();
m_damageToolController = new DamageToolController();
m_selectionToolController = new SelectionToolController();
+ m_explodeToolController = new ExplodeToolController();
m_gizmoToolController = new GizmoToolController();
m_editionToolController = new EditionToolController();
m_sampleController = new SampleController();
-// m_commonUIController = new CommonUIController();
+ m_commonUIController = nullptr; // new CommonUIController();
m_pApplication = new Application(pDeviceManager);
@@ -328,8 +534,9 @@ SampleManager::SampleManager(DeviceManager* pDeviceManager)
app.addControllerToFront(m_sceneController);
app.addControllerToFront(m_damageToolController);
app.addControllerToFront(m_selectionToolController);
+ app.addControllerToFront(m_explodeToolController);
app.addControllerToFront(m_gizmoToolController);
- app.addControllerToFront(m_editionToolController);
+// app.addControllerToFront(m_editionToolController);
app.addControllerToFront(m_sampleController);
// app.addControllerToFront(m_commonUIController);
@@ -338,24 +545,14 @@ SampleManager::SampleManager(DeviceManager* pDeviceManager)
(static_cast<ISampleController*>(c))->setManager(this);
}
- m_config.sampleName = L"";
- m_config.assetsFile = "";
-
- m_config.additionalResourcesDir.clear();
- m_config.additionalResourcesDir.push_back("../resources");
- m_config.additionalResourcesDir.push_back("../../../../bin/resources");
-
- m_config.additionalAssetList.models.clear();
- m_config.additionalAssetList.boxes.clear();
- m_config.additionalAssetList.composites.clear();
-
- m_fTool = new BlastFractureTool(loggingCallback);
+ m_fTool = new BlastFractureTool();
m_fractureExecutor = nullptr;
setFractureExecutor(&sVoronoiFracture);
m_pCurBlastAsset = nullptr;
m_nCurFamilyIndex = -1;
+ EnableSimulating(false);
}
SampleManager::~SampleManager()
@@ -366,6 +563,7 @@ SampleManager::~SampleManager()
delete m_sceneController;
delete m_damageToolController;
delete m_selectionToolController;
+ delete m_explodeToolController;
delete m_gizmoToolController;
delete m_editionToolController;
delete m_sampleController;
@@ -378,34 +576,36 @@ int SampleManager::init()
Application& app = *m_pApplication;
app.init();
- m_ToolType = BTT_Num;
- setBlastToolType(BTT_Edit);
+ m_damageToolController->DisableController();
+ m_selectionToolController->EnableController();
+ m_explodeToolController->DisableController();
+ m_gizmoToolController->DisableController();
+ BlastPlugin::Inst().GetMainToolbar()->updateCheckIconsStates();
+
+ EnableSimulating(false);
return 0;
}
int SampleManager::run()
{
- if (m_bNeedConfig)
- {
- getSceneController().onSampleStop();
- getSceneController().onSampleStart();
-
- _setSourceAsset();
-
- m_bNeedConfig = false;
- m_bNeedRefreshTree = true;
- }
+ m_physXController->setPlaneVisible(AppMainWindow::Inst().m_bShowPlane);
Application& app = *m_pApplication;
app.run();
std::vector<std::string>::iterator itStr;
std::vector<Renderable*>::iterator itRenderable;
+ std::map<std::string, RenderMaterial*>::iterator itRenderMaterial;
for (itStr = m_NeedDeleteRenderMaterials.begin(); itStr != m_NeedDeleteRenderMaterials.end(); itStr++)
{
- std::string materialName = *itStr;
- RenderMaterial* pRenderMaterial = m_RenderMaterialMap[materialName];
+ itRenderMaterial = m_RenderMaterialMap.find(*itStr);
+ if (itRenderMaterial == m_RenderMaterialMap.end())
+ {
+ continue;
+ }
+ RenderMaterial* pRenderMaterial = itRenderMaterial->second;
+
std::vector<Renderable*>& renderables = pRenderMaterial->getRelatedRenderables();
for (itRenderable = renderables.begin(); itRenderable != renderables.end(); itRenderable++)
{
@@ -413,12 +613,12 @@ int SampleManager::run()
pRenderable->setMaterial(*RenderMaterial::getDefaultRenderMaterial());
}
- removeRenderMaterial(materialName);
+ delete pRenderMaterial;
+ pRenderMaterial = nullptr;
+ m_RenderMaterialMap.erase(itRenderMaterial);
}
m_NeedDeleteRenderMaterials.clear();
- MaterialLibraryPanel::ins()->deleteMaterials();
-
return 0;
}
@@ -436,161 +636,360 @@ int SampleManager::free()
Application& app = *m_pApplication;
app.free();
- /*
- std::vector<AssetList::ModelAsset>& modelAssets = m_config.additionalAssetList.models;
- std::vector<AssetList::ModelAsset>::iterator it;
- char filename[50];
- for (it = modelAssets.begin(); it != modelAssets.end(); it++)
+ return 0;
+}
+
+bool SampleManager::createAsset(
+ BlastAssetModelSimple** ppBlastAsset,
+ std::vector<Nv::Blast::Mesh*>& meshes,
+ std::vector<int32_t>& parentIds,
+ std::vector<bool>& supports,
+ std::vector<bool>& statics,
+ std::vector<uint8_t>& joints,
+ std::vector<uint32_t>& worlds)
+{
+ m_fTool->setSourceMeshes(meshes, parentIds);
+ m_fTool->finalizeFracturing();
+
+ _createAsset(ppBlastAsset, supports, statics, joints, worlds);
+
+ return true;
+}
+
+bool SampleManager::saveAsset(BlastAsset* pBlastAsset)
+{
+ if (pBlastAsset == nullptr)
{
- AssetList::ModelAsset& m = *it;
+ return false;
+ }
+
+ AssetList::ModelAsset& desc = m_AssetDescMap[pBlastAsset];
+
+ PhysXController& pc = getPhysXController();
+ BlastController& bc = getBlastController();
+ physics = &pc.getPhysics();
+ foundation = &physics->getFoundation();
+ cooking = &pc.getCooking();
+ physicsManager = &bc.getExtPxManager();
- sprintf(filename, "../../../../bin/resources/models/%s.bpxa", m.id.c_str());
- DeleteFileA(filename);
+ std::string outDir = GlobalSettings::Inst().m_projectFileDir;
+
+ std::string outBlastFilePath = GlobalSettings::MakeFileName(outDir.c_str(), std::string(desc.name + ".blast").c_str());
+ const ExtPxAsset* asset = pBlastAsset->getPxAsset();
+ if (asset == nullptr)
+ {
+ return false;
+ }
+ saveExtAsset(outDir, std::string(desc.name + ".blast"), asset);
- sprintf(filename, "../../../../bin/resources/models/%s.mtl", m.id.c_str());
- DeleteFileA(filename);
+ m_fTool->setSourceAsset(pBlastAsset);
+ m_fTool->finalizeFracturing();
- sprintf(filename, "../../../../bin/resources/models/%s.obj", m.id.c_str());
- DeleteFileA(filename);
+ size_t nChunkListSize = m_fTool->getChunkCount();
+ std::vector<std::shared_ptr<Triangle> > chunkMeshes(nChunkListSize);
+ std::vector<uint32_t> chunkMeshesTriangleCount(nChunkListSize);
+ std::vector<bool> isSupport(nChunkListSize);
+ for (uint32_t i = 0; i < nChunkListSize; ++i)
+ {
+ chunkMeshesTriangleCount[i] = m_fTool->getBaseMesh(i, chunkMeshes[i]);
+ isSupport[i] = m_fTool->getChunkInfo(i).isLeaf;
}
- */
- return 0;
-}
+ BlastBondGenerator bondGenerator(cooking, &physics->getPhysicsInsertionCallback());
+ BondGenerationConfig cnf;
+ cnf.bondMode = BondGenerationConfig::AVERAGE;
+ std::vector<NvBlastChunkDesc> chunkDesc;
+ std::vector<NvBlastBondDesc> bondDescs;
+ bondGenerator.buildDescFromInternalFracture(m_fTool, isSupport, bondDescs, chunkDesc);
+ const uint32_t chunkCount = static_cast<uint32_t>(chunkDesc.size());
+ const uint32_t bondCount = static_cast<uint32_t>(bondDescs.size());
+ if (bondCount == 0)
+ {
+ std::cout << "Can't create bonds descriptors..." << std::endl;
+ }
-void SampleManager::addModelAsset(std::string path, std::string file, bool isSkinned, physx::PxTransform transform, bool clear)
-{
- if (clear)
+ std::vector<uint32_t> chunkReorderInvMap;
{
- //m_config.additionalAssetList.models.clear();
- //clearScene();
- AppMainWindow::Inst().menu_clearScene();
- GlobalSettings::Inst().m_projectFileDir = path;
- GlobalSettings::Inst().m_projectFileName = file;
- QFileInfo fileInfo(file.c_str());
- std::string ext = fileInfo.suffix().toUtf8().data();
- if (ext.length() < 1)
- GlobalSettings::Inst().m_projectFileName += ".blastProj";
+ std::vector<uint32_t> chunkReorderMap(chunkCount);
+ std::vector<char> scratch(chunkCount * sizeof(NvBlastChunkDesc));
+ NvBlastEnsureAssetExactSupportCoverage(chunkDesc.data(), chunkCount, scratch.data(), loggingCallback);
+ NvBlastBuildAssetDescChunkReorderMap(chunkReorderMap.data(), chunkDesc.data(), chunkCount, scratch.data(), loggingCallback);
+ NvBlastApplyAssetDescChunkReorderMapInPlace(chunkDesc.data(), chunkCount, bondDescs.data(), bondCount, chunkReorderMap.data(), true, scratch.data(), loggingCallback);
+ chunkReorderInvMap.resize(chunkReorderMap.size());
+ Nv::Blast::invertMap(chunkReorderInvMap.data(), chunkReorderMap.data(), static_cast<unsigned int>(chunkReorderMap.size()));
}
- else
+
+ std::vector<std::vector<Triangle>> resultGeometry(nChunkListSize);
+ for (uint32_t i = 0; i < nChunkListSize; ++i)
{
- std::vector<AssetList::ModelAsset>& modelAssets = m_config.additionalAssetList.models;
- std::vector<AssetList::ModelAsset>::iterator it = modelAssets.begin();
- for (; it != modelAssets.end(); it++)
- {
- AssetList::ModelAsset& m = *it;
- if (m.id == file)
- {
- modelAssets.erase(it);
- break;
- }
- }
+ uint32_t chunkIndex = chunkReorderInvMap[i];
+ resultGeometry[chunkIndex].resize(chunkMeshesTriangleCount[i]);
+ memcpy(resultGeometry[chunkIndex].data(), chunkMeshes[i].get(), chunkMeshesTriangleCount[i] * sizeof(Triangle));
}
- AssetList::ModelAsset modelAsset;
- modelAsset.name = file;
- modelAsset.id = file;
- modelAsset.file = file;
- modelAsset.isSkinned = isSkinned;
- modelAsset.transform = transform;
+ saveFractureToObj(resultGeometry, desc.name, outDir);
- m_config.additionalAssetList.models.push_back(modelAsset);
+ char message[MAX_PATH];
+ sprintf(message, "Blast file %s was saved.", outBlastFilePath.c_str());
+ output(message);
- m_bNeedConfig = true;
+ return true;
}
-bool SampleManager::createAsset(
- std::string path,
- std::string assetName,
- std::vector<physx::PxVec3>& positions,
- std::vector<physx::PxVec3>& normals,
- std::vector<physx::PxVec2>& uv,
- std::vector<unsigned int>& indices,
- bool fracture)
+#include "fbxsdk.h"
+
+uint32_t currentDepth;
+bool bOutputFBXAscii = true;
+
+void PxVec3ToFbx(physx::PxVec3& inVector, FbxVector4& outVector)
{
- PhysXController& pc = getPhysXController();
- BlastController& bc = getBlastController();
+ outVector[0] = inVector.x;
+ outVector[1] = inVector.y;
+ outVector[2] = inVector.z;
+ outVector[3] = 0;
+}
- physics = &pc.getPhysics();
- foundation = &physics->getFoundation();
- cooking = &pc.getCooking();
- physicsManager = &bc.getExtPxManager();
+void PxVec2ToFbx(physx::PxVec2& inVector, FbxVector2& outVector)
+{
+ outVector[0] = inVector.x;
+ outVector[1] = inVector.y;
+}
- std::vector<Nv::Blast::Mesh* > meshes;
- PxVec3* nr = (!normals.empty()) ? normals.data() : 0;
- PxVec2* uvp = (!uv.empty()) ? uv.data() : 0;
- Nv::Blast::Mesh* sourceMesh = new Nv::Blast::Mesh(positions.data(), nr, uvp, static_cast<uint32_t>(positions.size()),
- indices.data(), static_cast<uint32_t>(indices.size()));
- meshes.push_back(sourceMesh);
+void VertexToFbx(Nv::Blast::Vertex& vert, FbxVector4& outVertex, FbxVector4& outNormal, FbxVector2& outUV)
+{
+ PxVec3ToFbx(vert.p, outVertex);
+ PxVec3ToFbx(vert.n, outNormal);
+ PxVec2ToFbx(vert.uv[0], outUV);
+}
- m_fractureExecutor->setSourceMesh(sourceMesh);
- if (fracture)
+uint32_t createChunkRecursive(FbxManager* sdkManager, uint32_t currentCpIdx, uint32_t chunkIndex, FbxNode *meshNode, FbxNode* parentNode, FbxSkin* skin, const NvBlastAsset* asset, std::vector<std::vector<Nv::Blast::Triangle>> chunksGeometry)
+{
+ currentDepth++;
+
+ auto chunks = NvBlastAssetGetChunks(asset, nullptr);
+ const NvBlastChunk* chunk = &chunks[chunkIndex];
+ auto triangles = chunksGeometry[chunkIndex];
+ physx::PxVec3 centroid = physx::PxVec3(chunk->centroid[0], chunk->centroid[1], chunk->centroid[2]);
+
+ std::ostringstream namestream;
+
+ //mesh->InitTextureUV(triangles.size() * 3);
+
+ std::ostringstream().swap(namestream); // Swap namestream with a default constructed ostringstream
+ namestream << "bone_" << chunkIndex;
+ std::string boneName = namestream.str();
+
+ FbxSkeleton* skelAttrib;
+ if (chunk->parentChunkIndex == UINT32_MAX)
{
- m_fractureExecutor->execute();
- m_fractureExecutor = &sVoronoiFracture;
+ skelAttrib = FbxSkeleton::Create(sdkManager, "SkelRootAttrib");
+ skelAttrib->SetSkeletonType(FbxSkeleton::eRoot);
+
+ // Change the centroid to origin
+ centroid = physx::PxVec3(0.0f);
}
else
{
- m_fTool->finalizeFracturing();
+ skelAttrib = FbxSkeleton::Create(sdkManager, boneName.c_str());
+ skelAttrib->SetSkeletonType(FbxSkeleton::eLimbNode);
}
- std::string outDir = path;
- _createAsset(assetName, outDir, meshes);
+ skelAttrib->Size.Set(1.0); // What's this for?
- delete sourceMesh;
- sourceMesh = 0;
- m_bNeedConfig = true;
+ FbxNode* boneNode = FbxNode::Create(sdkManager, boneName.c_str());
+ boneNode->SetNodeAttribute(skelAttrib);
- return true;
-}
+ auto mat = parentNode->EvaluateGlobalTransform().Inverse();
-bool SampleManager::createAsset(
- const std::string& path,
- const std::string& assetName,
- const std::vector<Nv::Blast::Mesh* >& meshes,
- bool fracture)
-{
- PhysXController& pc = getPhysXController();
- BlastController& bc = getBlastController();
+ FbxVector4 vec(centroid.x, centroid.y, centroid.z, 0);
+ FbxVector4 c2 = mat.MultT(vec);
- physics = &pc.getPhysics();
- foundation = &physics->getFoundation();
- cooking = &pc.getCooking();
- physicsManager = &bc.getExtPxManager();
+ boneNode->LclTranslation.Set(c2);
+
+ parentNode->AddChild(boneNode);
- if (meshes.size() == 1)
+ std::ostringstream().swap(namestream); // Swap namestream with a default constructed ostringstream
+ namestream << "cluster_" << std::setw(5) << std::setfill('0') << chunkIndex;
+ std::string clusterName = namestream.str();
+
+ FbxCluster* cluster = FbxCluster::Create(sdkManager, clusterName.c_str());
+ cluster->SetTransformMatrix(FbxAMatrix());
+ cluster->SetLink(boneNode);
+ cluster->SetLinkMode(FbxCluster::eTotalOne);
+
+ skin->AddCluster(cluster);
+
+ FbxMesh* mesh = static_cast<FbxMesh*>(meshNode->GetNodeAttribute());
+
+ FbxVector4* controlPoints = mesh->GetControlPoints();
+ auto geNormal = mesh->GetElementNormal();
+ auto geUV = mesh->GetElementUV("diffuseElement");
+ FbxGeometryElementMaterial* matElement = mesh->GetElementMaterial();
+
+ auto addVert = [&](Nv::Blast::Vertex vert, int controlPointIdx)
{
- Nv::Blast::Mesh* sourceMesh = meshes[0];
- m_fractureExecutor->setSourceMesh(sourceMesh);
- if (fracture)
+ FbxVector4 vertex;
+ FbxVector4 normal;
+ FbxVector2 uv;
+
+ VertexToFbx(vert, vertex, normal, uv);
+
+ controlPoints[controlPointIdx] = vertex;
+ geNormal->GetDirectArray().Add(normal);
+ geUV->GetDirectArray().Add(uv);
+ // Add this control point to the bone with weight 1.0
+ cluster->AddControlPointIndex(controlPointIdx, 1.0);
+ };
+
+ uint32_t cpIdx = 0;
+ uint32_t polyCount = mesh->GetPolygonCount();
+ for (auto tri : triangles)
+ {
+ addVert(tri.a, currentCpIdx + cpIdx + 0);
+ addVert(tri.b, currentCpIdx + cpIdx + 1);
+ addVert(tri.c, currentCpIdx + cpIdx + 2);
+
+ mesh->BeginPolygon();
+ mesh->AddPolygon(currentCpIdx + cpIdx + 0);
+ mesh->AddPolygon(currentCpIdx + cpIdx + 1);
+ mesh->AddPolygon(currentCpIdx + cpIdx + 2);
+ mesh->EndPolygon();
+ if (tri.userInfo == 0)
{
- m_fractureExecutor->execute();
- m_fractureExecutor = &sVoronoiFracture;
+ matElement->GetIndexArray().SetAt(polyCount, 0);
}
else
{
- m_fTool->finalizeFracturing();
+ matElement->GetIndexArray().SetAt(polyCount, 1);
}
+ polyCount++;
+ cpIdx += 3;
}
- std::string outDir = path;
- _createAsset(assetName, outDir, meshes);
+ mat = meshNode->EvaluateGlobalTransform();
+ cluster->SetTransformMatrix(mat);
+
+ mat = boneNode->EvaluateGlobalTransform();
+ cluster->SetTransformLinkMatrix(mat);
+
+ uint32_t addedCps = static_cast<uint32_t>(triangles.size() * 3);
+
+ for (uint32_t i = chunk->firstChildIndex; i < chunk->childIndexStop; i++)
+ {
+ addedCps += createChunkRecursive(sdkManager, currentCpIdx + addedCps, i, meshNode, boneNode, skin, asset, chunksGeometry);
+ }
+
+ return addedCps;
+}
- m_bNeedConfig = true;
+bool finalizeFbxAndSave(FbxManager* sdkManager, FbxScene* scene, FbxSkin* skin, const std::string& outputFilePath)
+{
+ // Store the bind pose
+
+ std::unordered_set<FbxNode*> clusterNodes;
+
+ std::function<void(FbxNode*)> addRecursively = [&](FbxNode* node)
+ {
+ if (node)
+ {
+ addRecursively(node->GetParent());
+
+ clusterNodes.insert(node);
+ }
+ };
+
+ for (uint32_t i = 0; i < (uint32_t)skin->GetClusterCount(); i++)
+ {
+ FbxNode* clusterNode = skin->GetCluster(i)->GetLink();
+
+ addRecursively(clusterNode);
+ }
+
+ assert(clusterNodes.size() > 0);
+
+ FbxPose* pose = FbxPose::Create(sdkManager, "BasePose");
+ pose->SetIsBindPose(true);
+
+ for (auto node : clusterNodes)
+ {
+ FbxMatrix bindMat = node->EvaluateGlobalTransform();
+
+ pose->Add(node, bindMat);
+ }
+
+ scene->AddPose(pose);
+
+ FbxExporter* exporter = FbxExporter::Create(sdkManager, "Scene Exporter");
+
+ int lFormat;
+
+ if (bOutputFBXAscii)
+ {
+ lFormat = sdkManager->GetIOPluginRegistry()->FindWriterIDByDescription("FBX ascii (*.fbx)");
+ }
+ else
+ {
+ lFormat = sdkManager->GetIOPluginRegistry()->FindWriterIDByDescription("FBX binary (*.fbx)");
+ }
+
+ bool exportStatus = exporter->Initialize(outputFilePath.c_str(), lFormat, sdkManager->GetIOSettings());
+
+ if (!exportStatus)
+ {
+ std::cerr << "Call to FbxExporter::Initialize failed" << std::endl;
+ std::cerr << "Error returned: " << exporter->GetStatus().GetErrorString() << std::endl;
+ return false;
+ }
+
+ exportStatus = exporter->Export(scene);
+
+ if (!exportStatus)
+ {
+ auto fbxStatus = exporter->GetStatus();
+
+ std::cerr << "Call to FbxExporter::Export failed" << std::endl;
+ std::cerr << "Error returned: " << fbxStatus.GetErrorString() << std::endl;
+ return false;
+ }
return true;
}
-bool SampleManager::saveAsset()
+bool SampleManager::exportAsset()
{
if (m_pCurBlastAsset == nullptr)
{
+ viewer_err("Please select one asset instance before saving!");
+ return false;
+ }
+
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = m_AssetDescMap.find(m_pCurBlastAsset);
+ if (itADM == m_AssetDescMap.end())
+ {
+ viewer_err("Fails to find out the selected asset instance in current project!");
+ return false;
+ }
+
+ BPParams& projectParams = BlastProject::ins().getParams();
+
+ AssetList::ModelAsset& desc = itADM->second;
+
+ BPPAssetArray& assetArray = projectParams.blast.blastAssets;
+ BPPAsset asset;
+ int aaas = 0;
+ for (; aaas < assetArray.arraySizes[0]; aaas++)
+ {
+ asset = assetArray.buf[aaas];
+ std::string assetname = asset.name;
+ if (assetname == desc.name)
+ break;
+ }
+ if (aaas == assetArray.arraySizes[0])
+ {
return false;
}
- AssetList::ModelAsset& desc = m_AssetDescMap[m_pCurBlastAsset];
-
PhysXController& pc = getPhysXController();
BlastController& bc = getBlastController();
physics = &pc.getPhysics();
@@ -600,29 +999,17 @@ bool SampleManager::saveAsset()
std::string outDir = GlobalSettings::Inst().m_projectFileDir;
- std::string outBlastFilePath = GlobalSettings::MakeFileName(outDir.c_str(), std::string(desc.name + ".bpxa").c_str());
- const ExtPxAsset* asset = m_pCurBlastAsset->getPxAsset();
- if (asset == nullptr)
- {
- return false;
- }
- physx::PsFileBuffer fileBuf(outBlastFilePath.c_str(), physx::PxFileBuf::OPEN_WRITE_ONLY);
- if (!asset->serialize(fileBuf, *cooking))
- {
- return false;
- }
- fileBuf.close();
-
m_fTool->setSourceAsset(m_pCurBlastAsset);
m_fTool->finalizeFracturing();
- size_t nChunkListSize = m_fTool->getChunkList().size();
- std::vector<std::vector<Triangle> > chunkMeshes(nChunkListSize);
+ size_t nChunkListSize = m_fTool->getChunkCount();
+ std::vector<std::shared_ptr<Triangle> > chunkMeshes(nChunkListSize);
+ std::vector<uint32_t> chunkMeshesTriangleCount(nChunkListSize);
std::vector<bool> isSupport(nChunkListSize);
for (uint32_t i = 0; i < nChunkListSize; ++i)
{
- m_fTool->getBaseMesh(i, chunkMeshes[i]);
- isSupport[i] = m_fTool->getChunkList()[i].isLeaf;
+ chunkMeshesTriangleCount[i] = m_fTool->getBaseMesh(i, chunkMeshes[i]);
+ isSupport[i] = m_fTool->getChunkInfo(i).isLeaf;
}
BlastBondGenerator bondGenerator(cooking, &physics->getPhysicsInsertionCallback());
@@ -644,27 +1031,212 @@ bool SampleManager::saveAsset()
std::vector<char> scratch(chunkCount * sizeof(NvBlastChunkDesc));
NvBlastEnsureAssetExactSupportCoverage(chunkDesc.data(), chunkCount, scratch.data(), loggingCallback);
NvBlastBuildAssetDescChunkReorderMap(chunkReorderMap.data(), chunkDesc.data(), chunkCount, scratch.data(), loggingCallback);
- NvBlastApplyAssetDescChunkReorderMapInplace(chunkDesc.data(), chunkCount, bondDescs.data(), bondCount, chunkReorderMap.data(), scratch.data(), loggingCallback);
+ NvBlastApplyAssetDescChunkReorderMapInPlace(chunkDesc.data(), chunkCount, bondDescs.data(), bondCount, chunkReorderMap.data(), true, scratch.data(), loggingCallback);
chunkReorderInvMap.resize(chunkReorderMap.size());
Nv::Blast::invertMap(chunkReorderInvMap.data(), chunkReorderMap.data(), static_cast<unsigned int>(chunkReorderMap.size()));
}
- std::vector<std::vector<Triangle>> resultGeometry(chunkMeshes.size());
- for (uint32_t i = 0; i < chunkMeshes.size(); ++i)
+ std::vector<std::vector<Triangle>> resultGeometry(nChunkListSize);
+ for (uint32_t i = 0; i < nChunkListSize; ++i)
{
uint32_t chunkIndex = chunkReorderInvMap[i];
- resultGeometry[chunkIndex] = chunkMeshes[i];
+ resultGeometry[chunkIndex].resize(chunkMeshesTriangleCount[i]);
+ memcpy(resultGeometry[chunkIndex].data(), chunkMeshes[i].get(), chunkMeshesTriangleCount[i] * sizeof(Triangle));
}
- saveFractureToObj(resultGeometry, desc.name, outDir);
+ if (asset.exportFBX)
+ {
+ FbxManager* sdkManager = FbxManager::Create();
+
+ FbxIOSettings* ios = FbxIOSettings::Create(sdkManager, IOSROOT);
+ // Set some properties on the io settings
+
+ sdkManager->SetIOSettings(ios);
+
+ sdkManager->GetIOSettings()->SetBoolProp(EXP_ASCIIFBX, bOutputFBXAscii);
+
+ FbxScene* scene = FbxScene::Create(sdkManager, "Export Scene");
+ /*
+ if (getConvertToUE4())
+ {
+ FbxAxisSystem::EFrontVector FrontVector = (FbxAxisSystem::EFrontVector) - FbxAxisSystem::eParityOdd;
+ const FbxAxisSystem UnrealZUp(FbxAxisSystem::eZAxis, FrontVector, FbxAxisSystem::eRightHanded);
+
+ scene->GetGlobalSettings().SetAxisSystem(UnrealZUp);
+ }
+ */
+ // Otherwise default to Maya defaults
+
+ FbxMesh* mesh = FbxMesh::Create(sdkManager, "meshgeo");
+
+ FbxGeometryElementNormal* geNormal = mesh->CreateElementNormal();
+ geNormal->SetMappingMode(FbxGeometryElement::eByControlPoint);
+ geNormal->SetReferenceMode(FbxGeometryElement::eDirect);
+
+ FbxGeometryElementUV* geUV = mesh->CreateElementUV("diffuseElement");
+ geUV->SetMappingMode(FbxGeometryElement::eByPolygonVertex);
+ geUV->SetReferenceMode(FbxGeometryElement::eDirect);
+
+ // Get the triangles count for all of the mesh parts
+
+ size_t triangleCount = 0;
+ for (auto triangles : resultGeometry)
+ {
+ triangleCount += triangles.size();
+ }
+
+ mesh->InitControlPoints((int)triangleCount * 3);
- std::string saveInfo = outBlastFilePath + " saved successfully\n";
- output(saveInfo.c_str());
+ FbxNode* meshNode = FbxNode::Create(scene, "meshnode");
+ meshNode->SetNodeAttribute(mesh);
+ meshNode->SetShadingMode(FbxNode::eTextureShading);
+
+ FbxNode* lRootNode = scene->GetRootNode();
+ lRootNode->AddChild(meshNode);
+
+ FbxSkin* skin = FbxSkin::Create(sdkManager, "Skin of the thing");
+ skin->SetGeometry(mesh);
+
+ mesh->AddDeformer(skin);
+
+ // Add a material otherwise UE4 freaks out on import
+
+ FbxGeometryElementMaterial* matElement = mesh->CreateElementMaterial();
+ matElement->SetMappingMode(FbxGeometryElement::eByPolygon);
+ matElement->SetReferenceMode(FbxGeometryElement::eIndexToDirect);
+
+ FbxSurfacePhong* material = FbxSurfacePhong::Create(sdkManager, "FirstExportMaterial");
+
+ material->Diffuse.Set(FbxDouble3(1.0, 1.0, 0));
+ material->DiffuseFactor.Set(1.0);
+
+ meshNode->AddMaterial(material);
+
+ FbxSurfacePhong* material2 = FbxSurfacePhong::Create(sdkManager, "SecondExportMaterial");
+
+ material2->Diffuse.Set(FbxDouble3(1.0, 0.0, 1.0));
+ material2->DiffuseFactor.Set(1.0);
+
+ meshNode->AddMaterial(material2);
+
+ const ExtPxAsset* pExtPxAsset = m_pCurBlastAsset->getPxAsset();
+ if (pExtPxAsset == nullptr)
+ {
+ return false;
+ }
+
+ const TkAsset& tkAsset = pExtPxAsset->getTkAsset();
+ const NvBlastAsset* pAssetLL = tkAsset.getAssetLL();
+ uint32_t chunkCount = NvBlastAssetGetChunkCount(pAssetLL, nullptr);
+
+ auto chunks = NvBlastAssetGetChunks(pAssetLL, nullptr);
+
+ currentDepth = 0;
+ uint32_t cpIdx = 0;
+ for (uint32_t i = 0; i < chunkCount; i++)
+ {
+ const NvBlastChunk* chunk = &chunks[i];
+
+ if (chunk->parentChunkIndex == UINT32_MAX)
+ {
+ uint32_t addedCps = createChunkRecursive(sdkManager, cpIdx, i, meshNode, lRootNode, skin, pAssetLL, resultGeometry);
+
+ cpIdx += addedCps;
+ }
+ }
+
+ std::string outputFilePath = GlobalSettings::MakeFileName(outDir.c_str(), asset.fbx.buf);
+ finalizeFbxAndSave(sdkManager, scene, skin, outputFilePath);
+
+ sdkManager->Destroy();
+ sdkManager = nullptr;
+
+ std::string info = outputFilePath + " is saved.";
+ viewer_info(info.c_str());
+ }
+
+ if (asset.exportOBJ)
+ {
+ std::string filename = asset.obj.buf;
+ filename = filename.substr(0, filename.find_last_of('.'));
+ saveFractureToObj(resultGeometry, filename, outDir);
+
+ std::string outputFilePath = GlobalSettings::MakeFileName(outDir.c_str(), asset.obj.buf);
+ std::string info = outputFilePath + " is saved.";
+ viewer_info(info.c_str());
+ }
+
+ if (asset.exportBPXA)
+ {
+ std::string outputFilePath = GlobalSettings::MakeFileName(outDir.c_str(), asset.bpxa.buf);
+ const ExtPxAsset* pExtPxAsset = m_pCurBlastAsset->getPxAsset();
+ if (pExtPxAsset == nullptr)
+ {
+ return false;
+ }
+ saveExtAsset(outDir, std::string(asset.bpxa.buf), pExtPxAsset);
+
+ std::string info = outputFilePath + " is saved.";
+ viewer_info(info.c_str());
+ }
+
+ if (asset.exportCollision)
+ {
+ SampleManager* pSampleManager = SampleManager::ins();
+ PhysXController& physXController = pSampleManager->getPhysXController();
+ PxPhysics& physics = physXController.getPhysics();
+ PxScene& scene = physXController.getPhysXScene();
+
+ std::string outputFilePath = GlobalSettings::MakeFileName(outDir.c_str(), asset.collision.buf);
+ physXController.ExportCollisionRepX(outputFilePath.c_str(), &physics, &scene, false);
+
+ std::string info = outputFilePath + " is saved.";
+ viewer_info(info.c_str());
+ }
+
+ if (asset.exportTKAsset)
+ {
+ std::string outputFilePath = GlobalSettings::MakeFileName(outDir.c_str(), asset.tkasset.buf);
+ const ExtPxAsset* pExtPxAsset = m_pCurBlastAsset->getPxAsset();
+ if (pExtPxAsset == nullptr)
+ {
+ return false;
+ }
+
+ const TkAsset& tkAsset = pExtPxAsset->getTkAsset();
+
+ saveTkAsset(outDir, std::string(asset.tkasset.buf), &tkAsset);
+
+ std::string info = outputFilePath + " is saved.";
+ viewer_info(info.c_str());
+ }
+
+ if (asset.exportLLAsset)
+ {
+ std::string outputFilePath = GlobalSettings::MakeFileName(outDir.c_str(), asset.llasset.buf);
+ const ExtPxAsset* pExtPxAsset = m_pCurBlastAsset->getPxAsset();
+ if (pExtPxAsset == nullptr)
+ {
+ return false;
+ }
+
+ const TkAsset& tkAsset = pExtPxAsset->getTkAsset();
+ const NvBlastAsset* pAssetLL = tkAsset.getAssetLL();
+
+ saveLlAsset(outDir, std::string(asset.llasset.buf), pAssetLL);
+
+ std::string info = outputFilePath + " is saved.";
+ viewer_info(info.c_str());
+ }
return true;
}
-bool SampleManager::fractureAsset(std::string& path, std::string& assetName, const BlastAsset* pBlastAsset, int32_t chunkId)
+void SampleManager::_createAsset(BlastAssetModelSimple** ppBlastAsset,
+ std::vector<bool>& supports,
+ std::vector<bool>& statics,
+ std::vector<uint8_t>& joints,
+ std::vector<uint32_t>& worlds)
{
PhysXController& pc = getPhysXController();
BlastController& bc = getBlastController();
@@ -673,35 +1245,38 @@ bool SampleManager::fractureAsset(std::string& path, std::string& assetName, con
foundation = &physics->getFoundation();
cooking = &pc.getCooking();
physicsManager = &bc.getExtPxManager();
-
- m_fractureExecutor->setSourceAsset(pBlastAsset);
- m_fractureExecutor->setTargetChunk(chunkId);
- m_fractureExecutor->execute();
- m_fractureExecutor = &sVoronoiFracture;
-
- std::string outDir = path;
-
- std::string outBlastFilePath = GlobalSettings::MakeFileName(outDir.c_str(), std::string(assetName + ".bpxa").c_str());
+ TkFramework& tk = bc.getTkFramework();
std::vector<NvBlastChunkDesc> chunkDesc;
std::vector<NvBlastBondDesc> bondDescs;
- std::vector<std::vector<Triangle> > chunkMeshes;
+ std::vector<std::shared_ptr<Triangle> > chunkMeshes;
+ std::vector<uint32_t> chunkMeshesTriangleCount(nChunkListSize);
std::vector<bool> isSupport;
- size_t nChunkListSize = m_fTool->getChunkList().size();
+ size_t nChunkListSize = m_fTool->getChunkCount();
chunkMeshes.resize(nChunkListSize);
isSupport.resize(nChunkListSize);
for (uint32_t i = 0; i < nChunkListSize; ++i)
{
- m_fTool->getBaseMesh(i, chunkMeshes[i]);
- isSupport[i] = m_fTool->getChunkList()[i].isLeaf;
+ chunkMeshesTriangleCount[i] = m_fTool->getBaseMesh(i, chunkMeshes[i]);
+ isSupport[i] = supports.size() == 0 ? m_fTool->getChunkInfo(i).isLeaf : supports[i];
}
BlastBondGenerator bondGenerator(cooking, &physics->getPhysicsInsertionCallback());
-
- BondGenerationConfig cnf;
- cnf.bondMode = BondGenerationConfig::AVERAGE;
bondGenerator.buildDescFromInternalFracture(m_fTool, isSupport, bondDescs, chunkDesc);
+ bondDescs.clear();
+ bondGenerator.bondsFromPrefractured(chunkMeshes, isSupport, bondDescs);
+ int bondDescsSize = bondDescs.size();
+ if (bondDescsSize == worlds.size())
+ {
+ for (int bds = 0; bds < bondDescsSize; bds++)
+ {
+ if (worlds[bds] == 0xFFFFFFFF)
+ {
+ bondDescs[bds].chunkIndices[1] = worlds[bds];
+ }
+ }
+ }
const uint32_t chunkCount = static_cast<uint32_t>(chunkDesc.size());
const uint32_t bondCount = static_cast<uint32_t>(bondDescs.size());
@@ -717,23 +1292,24 @@ bool SampleManager::fractureAsset(std::string& path, std::string& assetName, con
std::vector<char> scratch(chunkCount * sizeof(NvBlastChunkDesc));
NvBlastEnsureAssetExactSupportCoverage(chunkDesc.data(), chunkCount, scratch.data(), loggingCallback);
NvBlastBuildAssetDescChunkReorderMap(chunkReorderMap.data(), chunkDesc.data(), chunkCount, scratch.data(), loggingCallback);
- NvBlastApplyAssetDescChunkReorderMapInplace(chunkDesc.data(), chunkCount, bondDescs.data(), bondCount, chunkReorderMap.data(), scratch.data(), loggingCallback);
+ NvBlastApplyAssetDescChunkReorderMapInPlace(chunkDesc.data(), chunkCount, bondDescs.data(), bondCount, chunkReorderMap.data(), true, scratch.data(), loggingCallback);
chunkReorderInvMap.resize(chunkReorderMap.size());
Nv::Blast::invertMap(chunkReorderInvMap.data(), chunkReorderMap.data(), static_cast<unsigned int>(chunkReorderMap.size()));
}
// get result geometry
- std::vector<std::vector<Triangle>> resultGeometry(chunkMeshes.size());
- for (uint32_t i = 0; i < chunkMeshes.size(); ++i)
+ std::vector<std::vector<Triangle>> resultGeometry(nChunkListSize);
+ for (uint32_t i = 0; i < nChunkListSize; ++i)
{
uint32_t chunkIndex = chunkReorderInvMap[i];
- resultGeometry[chunkIndex] = chunkMeshes[i];
+ resultGeometry[chunkIndex].resize(chunkMeshesTriangleCount[i]);
+ memcpy(resultGeometry[chunkIndex].data(), chunkMeshes[i].get(), chunkMeshesTriangleCount[i] * sizeof(Triangle));
}
// prepare physics data (convexes)
std::vector<ExtPxAssetDesc::ChunkDesc> pxChunks(chunkCount);
std::vector<ExtPxAssetDesc::SubchunkDesc> pxSubchunks;
- buildPxChunks(resultGeometry, pxChunks, pxSubchunks);
+ buildPxChunks(resultGeometry, pxChunks, pxSubchunks, statics);
// build and serialize ExtPhysicsAsset
ExtPxAssetDesc descriptor;
@@ -741,45 +1317,83 @@ bool SampleManager::fractureAsset(std::string& path, std::string& assetName, con
descriptor.bondDescs = bondDescs.data();
descriptor.chunkCount = chunkCount;
descriptor.chunkDescs = chunkDesc.data();
- descriptor.bondFlags = nullptr;
+ descriptor.bondFlags = joints.data();
descriptor.pxChunks = pxChunks.data();
- ExtPxAsset* asset = ExtPxAsset::create(descriptor, bc.getTkFramework());
+ ExtPxAsset* asset = ExtPxAsset::create(descriptor, tk);
if (asset == nullptr)
{
- return false;
+ return;
}
- physx::PsFileBuffer fileBuf(outBlastFilePath.c_str(), physx::PxFileBuf::OPEN_WRITE_ONLY);
- if (!asset->serialize(fileBuf, *cooking))
+ std::string tempFilePath = utils::GetTempFilePath();
+ QFileInfo tempFileInfo(tempFilePath.c_str());
+ std::string tempdir = QDir::toNativeSeparators(tempFileInfo.absoluteDir().absolutePath()).toLocal8Bit();
+ std::string tempfile = tempFileInfo.fileName().toLocal8Bit();
+ saveFractureToObj(resultGeometry, tempfile, tempdir);
+ std::string objFilePath = tempFilePath + ".obj";
+ std::string mtlFilePath = tempFilePath + ".mtl";
+ BlastModel* pBlastModel = BlastModel::loadFromFileTinyLoader(objFilePath.c_str());
+ DeleteFileA(tempFilePath.c_str());
+ DeleteFileA(objFilePath.c_str());
+ DeleteFileA(mtlFilePath.c_str());
+
+ *ppBlastAsset = new BlastAssetModelSimple(asset, pBlastModel, getRenderer());
+}
+
+BlastAsset* SampleManager::_replaceAsset(BlastAsset* pBlastAsset,
+ std::vector<bool>& supports,
+ std::vector<bool>& statics,
+ std::vector<uint8_t>& joints,
+ std::vector<uint32_t>& worlds)
+{
+ if (pBlastAsset == nullptr)
{
return false;
}
- fileBuf.close();
- asset->release();
- saveFractureToObj(resultGeometry, assetName, outDir);
+ BlastAsset* pCurBlastAsset = nullptr;
+ int nFamilyIndex = -1;
+ getCurrentSelectedInstance(&pCurBlastAsset, nFamilyIndex);
- m_bNeedConfig = true;
+ std::vector<BlastFamily*> familiesOld = m_AssetFamiliesMap[pBlastAsset];
+ int familiesSize = familiesOld.size();
+ std::vector<physx::PxTransform> transforms(familiesSize);
+ std::vector<std::string> extMaterials(familiesSize);
+ std::vector<std::string> intMaterials(familiesSize);
+ for (int fs = 0; fs < familiesSize; fs++)
+ {
+ transforms[fs] = familiesOld[fs]->getSettings().transform;
- return true;
-}
+ setCurrentSelectedInstance(pBlastAsset, fs);
+ getMaterialForCurrentFamily(extMaterials[fs], true);
+ getMaterialForCurrentFamily(intMaterials[fs], false);
+ }
-bool SampleManager::postProcessCurrentAsset()
-{
- std::vector<AssetList::ModelAsset>& models = m_config.additionalAssetList.models;
- if (models.size() < 0)
+ BlastAssetModelSimple* pBlastAssetNew;
+ _createAsset(&pBlastAssetNew, supports, statics, joints, worlds);
+
+ BlastAssetModelSimple* pBlastAssetOld = (BlastAssetModelSimple*)pBlastAsset;
+ AssetList::ModelAsset desc = m_AssetDescMap[pBlastAsset];
+ removeBlastAsset(pBlastAssetOld);
+ addBlastAsset(pBlastAssetNew, desc);
+
+ for (int fs = 0; fs < familiesSize; fs++)
{
- return true;
- }
+ addBlastFamily(pBlastAssetNew, transforms[fs]);
- std::string assetName = models.at(models.size() - 1).file;
- std::string outDir = GlobalSettings::Inst().m_projectFileDir;
- std::vector<Nv::Blast::Mesh* > meshes;
- _createAsset(assetName, outDir, meshes);
+ setCurrentSelectedInstance(pBlastAssetNew, fs);
- m_bNeedConfig = true;
+ setMaterialForCurrentFamily(extMaterials[fs], true);
+ setMaterialForCurrentFamily(intMaterials[fs], false);
+ }
- return true;
+ if (pCurBlastAsset == pBlastAsset)
+ {
+ pCurBlastAsset = pBlastAssetNew;
+ }
+ setCurrentSelectedInstance(pCurBlastAsset, nFamilyIndex);
+
+ return pBlastAssetNew;
}
std::vector<uint32_t> SampleManager::getCurrentSelectedChunks()
@@ -880,405 +1494,1664 @@ void SampleManager::setFractureExecutor(FractureExecutor* executor)
}
}
-void SampleManager::setBlastToolType(BlastToolType type)
+void SampleManager::EnableStepforward(bool bStepforward)
+{
+ m_stepforward = bStepforward;
+}
+
+void SampleManager::EnableSimulating(bool bSimulating)
{
- if (m_ToolType == type)
+ m_simulating = bSimulating;
+ m_stepforward = false;
+ m_physXController->setPaused(!m_simulating);
+
+ if (!m_simulating)
{
- getPhysXController().setPaused(type != BTT_Damage);
- return;
+ m_damageToolController->DisableController();
+#if 0
+ BlastSceneTree* pBlastSceneTree = BlastSceneTree::ins();
+ if (pBlastSceneTree)
+ {
+ pBlastSceneTree->hideAllChunks();
+ // make sure chunk0 shows.
+ std::vector<uint32_t> depths(1, 0);
+ pBlastSceneTree->setChunkVisible(depths, true);
+ // refresh in scene tree and viewport
+ //pBlastSceneTree->updateValues(false);
+ SampleManager::ins()->m_bNeedRefreshTree = true;
+ }
+#endif
}
+}
- // refresh selection
- bool needClear = true;
- bool currentGizmo = (m_ToolType >= BTT_Translate && m_ToolType <= BTT_Rotation);
- bool switchToGizmo = (type >= BTT_Translate && type <= BTT_Rotation);
- if (currentGizmo && switchToGizmo)
+#include <ViewerOutput.h>
+void SampleManager::output(const char* str)
+{
+ viewer_msg("%s", str);
+}
+
+void SampleManager::output(float value)
+{
+ viewer_msg("%f", value);
+}
+
+void SampleManager::output(physx::PxVec3& vec)
+{
+ viewer_msg("%f,%f,%f", vec.x, vec.y, vec.z);
+}
+
+void SampleManager::clearScene()
+{
+ m_gizmoToolController->resetPos();
+ /*
+ BPPAssetArray& assets = BlastProject::ins().getParams().blast.blastAssets;
+ int assetSize = assets.arraySizes[0];
+ for (int as = 0; as < assetSize; as++)
{
- needClear = false;
+ BPPAsset& asset = assets.buf[as];
+ BlastSceneTree::ins()->removeBlastInstances(asset);
+ BlastSceneTree::ins()->removeBlastAsset(asset);
}
- if (needClear)
+ BlastSceneTree::ins()->clearProjectile();
+ */
+ m_sceneController->ClearScene();
+
+ EnableSimulating(false);
+
+ std::map<std::string, RenderMaterial*>::iterator itRenderMaterial;
+ for (itRenderMaterial = m_RenderMaterialMap.begin();
+ itRenderMaterial != m_RenderMaterialMap.end(); itRenderMaterial++)
{
- getSelectionToolController().clearSelect();
- getGizmoToolController().resetPos();
+ RenderMaterial* pRenderMaterial = itRenderMaterial->second;
+ delete pRenderMaterial;
+ pRenderMaterial = nullptr;
}
+ m_RenderMaterialMap.clear();
- getDamageToolController().getPickPointer()->setHidden(type != BTT_Damage);
- getGizmoToolController().showAxisRenderables(switchToGizmo);
- getPhysXController().setPaused(type != BTT_Damage);
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAssetFamilies;
+ for (itAssetFamilies = m_AssetFamiliesMap.begin();
+ itAssetFamilies != m_AssetFamiliesMap.end(); itAssetFamilies++)
+ {
+ std::vector<BlastFamily*>& fs = itAssetFamilies->second;
+ fs.clear();
+ }
+ m_AssetFamiliesMap.clear();
+ m_AssetDescMap.clear();
+ m_instanceFamilyMap.clear();
+
+ physx::PxVec3 zero(0.0f, 0.0f, 0.0f);
+ m_assetExtents = zero;
- getDamageToolController().DisableController();
- getSelectionToolController().DisableController();
- getGizmoToolController().DisableController();
- getEditionToolController().DisableController();
+ m_bNeedRefreshTree = true;
- switch (type)
+ m_pCurBlastAsset = nullptr;
+ m_nCurFamilyIndex = -1;
+
+ SimpleScene::Inst()->m_pCamera->SetDefaults();
+}
+
+void SampleManager::resetScene()
+{
+ std::map<BPPAssetInstance*, std::set<uint32_t>> selectChunks;
+
+ if (m_selectionToolController->IsEnabled())
{
- case BTT_Damage:
+ std::set<PxActor*> actors = m_selectionToolController->getTargetActors();
+ for (PxActor* actor : actors)
{
- getDamageToolController().EnableController();
+ BlastFamily* pBlastFamily = m_blastController->getFamilyByPxActor(*actor);
+ if (pBlastFamily)
+ {
+ BPPAssetInstance* assetInstance = getInstanceByFamily(pBlastFamily);
+ uint32_t chunkIndex = pBlastFamily->getChunkIndexByPxActor(*actor);
+ selectChunks[assetInstance].insert(chunkIndex);
+ }
}
- break;
- case BTT_Drag:
+ }
+ else if (m_gizmoToolController->IsEnabled())
+ {
+ PxActor* actor = m_gizmoToolController->getTargetActor();
+
+ if (actor)
{
- getDamageToolController().EnableController();
+ BlastFamily* pBlastFamily = m_blastController->getFamilyByPxActor(*actor);
+ if (pBlastFamily)
+ {
+ BPPAssetInstance* assetInstance = getInstanceByFamily(pBlastFamily);
+ uint32_t chunkIndex = pBlastFamily->getChunkIndexByPxActor(*actor);
+ selectChunks[assetInstance].insert(chunkIndex);
+ }
}
- break;
- case BTT_Select:
+ }
+
+ m_selectionToolController->clearSelect();
+ /*
+ std::map<BPPAssetInstance*, BlastFamily*>::iterator itIFM;
+ for (itIFM = m_instanceFamilyMap.begin(); itIFM != m_instanceFamilyMap.end(); itIFM++)
+ {
+ BPPAssetInstance* pInstance = itIFM->first;
+ BlastSceneTree::ins()->removeBlastInstance(*pInstance);
+ }
+ BlastSceneTree::ins()->clearProjectile();
+ */
+ getSceneController().ResetScene();
+ EnableSimulating(false);
+ /*
+ for (itIFM = m_instanceFamilyMap.begin(); itIFM != m_instanceFamilyMap.end(); itIFM++)
+ {
+ BPPAssetInstance* pInstance = itIFM->first;
+ BlastSceneTree::ins()->addBlastInstance(*pInstance);
+ }
+ */
+ std::set<PxActor*> actors;
+ for (std::map<BPPAssetInstance*, std::set<uint32_t>>::iterator itr = selectChunks.begin(); itr != selectChunks.end(); ++itr)
+ {
+ BlastFamily* family = getFamilyByInstance(itr->first);
+ std::set<uint32_t>& chunkIndexes = itr->second;
+
+ if (nullptr != family)
{
- getSelectionToolController().EnableController();
+ for (uint32_t chunkIndex : chunkIndexes)
+ {
+ PxActor* actor = nullptr;
+ family->getPxActorByChunkIndex(chunkIndex, &actor);
+
+ if (actor)
+ actors.insert(actor);
+ }
}
- break;
- case BTT_Translate:
+ }
+
+ if (m_selectionToolController->IsEnabled())
+ {
+ m_selectionToolController->setTargetActors(actors);
+ }
+ else if (m_gizmoToolController->IsEnabled())
+ {
+ if (actors.size() > 0)
+ m_gizmoToolController->setTargetActor(*actors.begin());
+ }
+
+ // reset scene should not restore camera
+ //SimpleScene::Inst()->m_pCamera->SetDefaults();
+}
+
+bool isChunkVisible(std::vector<BlastFamily*>& fs, uint32_t chunkIndex)
+{
+ int fsSize = fs.size();
+ if (fsSize == 0)
+ {
+ return true;
+ }
+
+ bool visible = false;
+ for (int i = 0; i < fsSize; i++)
+ {
+ if (fs[i]->isChunkVisible(chunkIndex))
{
- getGizmoToolController().EnableController();
- getGizmoToolController().setGizmoToolMode(GTM_Translate);
- }
+ visible = true;
break;
- case BTT_Scale:
+ }
+ }
+ return visible;
+}
+
+void SampleManager::_setSourceAsset()
+{
+ std::vector<BlastFamilyPtr>& families = m_blastController->getFamilies();
+ if (families.size() > 0)
+ {
+ BlastFamilyPtr spLastFamily = families.back();
+
+ m_fTool->setSourceAsset(&(spLastFamily->getBlastAsset()));
+ }
+}
+
+BlastFamily* SampleManager::getFamilyByInstance(BPPAssetInstance* instance)
+{
+ if (instance)
+ {
+ if (m_instanceFamilyMap.find(instance) != m_instanceFamilyMap.end())
{
- getGizmoToolController().EnableController();
- getGizmoToolController().setGizmoToolMode(GTM_Scale);
+ return m_instanceFamilyMap[instance];
}
- break;
- case BTT_Rotation:
+ }
+ return nullptr;
+}
+
+BPPAssetInstance* SampleManager::getInstanceByFamily(BlastFamily* family)
+{
+ if (family)
+ {
+ std::map<BPPAssetInstance*, BlastFamily*>::iterator itr = m_instanceFamilyMap.begin();
+ for (; itr != m_instanceFamilyMap.end(); ++itr)
{
- getGizmoToolController().EnableController();
- getGizmoToolController().setGizmoToolMode(GTM_Rotation);
+ if (itr->second == family)
+ {
+ return itr->first;
+ }
}
- break;
- case BTT_Edit:
+ }
+ return nullptr;
+}
+
+void SampleManager::updateFamily(BlastFamily* oldFamily, BlastFamily* newFamily)
+{
+ if (oldFamily)
+ {
+ BPPAssetInstance* instance = getInstanceByFamily(oldFamily);
+ if (instance)
{
- getEditionToolController().EnableController();
+ m_instanceFamilyMap[instance] = newFamily;
}
- break;
- default:
- break;
}
+}
- m_ToolType = type;
+void SampleManager::removeRenderMaterial(std::string name)
+{
+ if (name.empty())
+ {
+ return;
+ }
+
+ std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(name);
+ if (it != m_RenderMaterialMap.end())
+ {
+ m_NeedDeleteRenderMaterials.push_back(name);
+ }
}
-#include <ViewerOutput.h>
-void SampleManager::output(const char* str)
+void SampleManager::renameRenderMaterial(std::string oldName, std::string newName)
{
- viewer_msg("%s", str);
+ if (oldName.empty() || newName.empty())
+ {
+ return;
+ }
+
+ std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(oldName);
+ if (it != m_RenderMaterialMap.end())
+ {
+ RenderMaterial* pRenderMaterial = it->second;
+ m_RenderMaterialMap.erase(it);
+ pRenderMaterial->setMaterialName(newName);
+ m_RenderMaterialMap[newName] = pRenderMaterial;
+ }
}
-void SampleManager::output(float value)
+void SampleManager::reloadRenderMaterial(std::string name, float r, float g, float b, bool diffuse)
{
- viewer_msg("%f", value);
+ if (name.empty())
+ {
+ return;
+ }
+
+ std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(name);
+ if (it != m_RenderMaterialMap.end())
+ {
+ RenderMaterial* pRenderMaterial = it->second;
+ if (diffuse)
+ {
+ pRenderMaterial->setDiffuseColor(r, g, b);
+ }
+ else
+ {
+ pRenderMaterial->setSpecularColor(r, g, b);
+ }
+ }
}
-void SampleManager::output(physx::PxVec3& vec)
+void SampleManager::reloadRenderMaterial(std::string name, std::string texture, RenderMaterial::TextureType tt)
{
- viewer_msg("%f,%f,%f", vec.x, vec.y, vec.z);
+ if (name.empty())
+ {
+ return;
+ }
+
+ std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(name);
+ if (it != m_RenderMaterialMap.end())
+ {
+ RenderMaterial* pRenderMaterial = it->second;
+ pRenderMaterial->setTextureFileName(texture, tt);
+ }
}
-void SampleManager::clearScene()
+void SampleManager::reloadRenderMaterial(std::string name, float specularShininess)
{
- getSceneController().ClearScene();
- setBlastToolType(BTT_Edit);
+ if (name.empty())
+ {
+ return;
+ }
- MaterialLibraryPanel::ins()->deleteMaterialMap();
+ std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(name);
+ if (it != m_RenderMaterialMap.end())
+ {
+ RenderMaterial* pRenderMaterial = it->second;
+ pRenderMaterial->setSpecularShininess(specularShininess);
+ }
+}
- m_config.sampleName.clear();
- m_config.assetsFile.clear();
- m_config.additionalAssetList.models.clear();
- m_config.additionalAssetList.composites.clear();
- m_config.additionalAssetList.boxes.clear();
+RenderMaterial* SampleManager::getRenderMaterial(std::string name, bool create)
+{
+ if (name == "" || name == "None")
+ {
+ return RenderMaterial::getDefaultRenderMaterial();
+ }
- std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator it;
- for (it = m_AssetFamiliesMap.begin(); it != m_AssetFamiliesMap.end(); it++)
+ std::map<std::string, RenderMaterial*>::iterator itRenderMaterial = m_RenderMaterialMap.find(name);
+ RenderMaterial* pRenderMaterial = nullptr;
+ if (itRenderMaterial != m_RenderMaterialMap.end())
{
- std::vector<BlastFamily*>& fs = it->second;
- fs.clear();
+ pRenderMaterial = itRenderMaterial->second;
}
- m_AssetFamiliesMap.clear();
- m_AssetDescMap.clear();
+ else if(create)
+ {
+ ResourceManager* pResourceManager = ResourceManager::ins();
- m_bNeedRefreshTree = true;
+ BPPGraphicsMaterial* pBPPGraphicsMaterial = BlastProject::ins().getGraphicsMaterial(name.c_str());
+
+ if (pBPPGraphicsMaterial == nullptr)
+ {
+ return RenderMaterial::getDefaultRenderMaterial();
+ }
+ else if (pBPPGraphicsMaterial->diffuseTextureFilePath.buf != nullptr)
+ {
+ pRenderMaterial = new RenderMaterial(name.c_str(), *pResourceManager,
+ "model_simple_textured_ex",
+ pBPPGraphicsMaterial->diffuseTextureFilePath.buf);
+ pRenderMaterial->setDiffuseColor(
+ pBPPGraphicsMaterial->diffuseColor[0],
+ pBPPGraphicsMaterial->diffuseColor[1],
+ pBPPGraphicsMaterial->diffuseColor[2],
+ pBPPGraphicsMaterial->diffuseColor[3]);
+ }
+ else
+ {
+ pRenderMaterial = new RenderMaterial(name.c_str(), *pResourceManager,
+ "model_simple_textured_ex",
+ pBPPGraphicsMaterial->diffuseColor[0],
+ pBPPGraphicsMaterial->diffuseColor[1],
+ pBPPGraphicsMaterial->diffuseColor[2],
+ pBPPGraphicsMaterial->diffuseColor[3]);
+ }
+
+ m_RenderMaterialMap[name] = pRenderMaterial;
+ }
+ return pRenderMaterial;
}
-void SampleManager::resetScene()
+void SampleManager::getCurrentSelectedInstance(BlastAsset** ppBlastAsset, int& index)
{
- getSceneController().ResetScene();
- setBlastToolType(BTT_Edit);
+ *ppBlastAsset = m_pCurBlastAsset;
+ index = m_nCurFamilyIndex;
}
-bool SampleManager::_createAsset(
- const std::string& assetName,
- const std::string& outDir,
- const std::vector<Nv::Blast::Mesh* >& meshes)
+void SampleManager::setCurrentSelectedInstance(BlastAsset* pBlastAsset, int index)
{
- PhysXController& pc = getPhysXController();
- BlastController& bc = getBlastController();
+ m_pCurBlastAsset = pBlastAsset;
+ m_nCurFamilyIndex = index;
- physics = &pc.getPhysics();
- foundation = &physics->getFoundation();
- cooking = &pc.getCooking();
- physicsManager = &bc.getExtPxManager();
- TkFramework& tk = bc.getTkFramework();
+ MaterialAssignmentsPanel::ins()->updateValues();
+ FileReferencesPanel::ins()->updateValues();
+}
- std::string outBlastFilePath = GlobalSettings::MakeFileName(outDir.c_str(), std::string(assetName + ".bpxa").c_str());
+void SampleManager::getMaterialForCurrentFamily(std::string& name, bool externalSurface)
+{
+ name = "";
- std::vector<NvBlastChunkDesc> chunkDesc;
- std::vector<NvBlastBondDesc> bondDescs;
- std::vector<std::vector<Triangle> > chunkMeshes;
- std::vector<bool> isSupport;
+ if (m_pCurBlastAsset == nullptr || m_nCurFamilyIndex < 0)
+ {
+ return;
+ }
- if (meshes.size() <= 1)
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator it = m_AssetFamiliesMap.find(m_pCurBlastAsset);
+ if (it == m_AssetFamiliesMap.end())
{
- size_t nChunkListSize = m_fTool->getChunkList().size();
- chunkMeshes.resize(nChunkListSize);
- isSupport.resize(nChunkListSize);
- for (uint32_t i = 0; i < nChunkListSize; ++i)
+ return;
+ }
+
+ std::vector<BlastFamily*>& fs = it->second;
+ int fsSize = fs.size();
+ if (fsSize == 0 || fsSize <= m_nCurFamilyIndex)
+ {
+ return;
+ }
+
+ BlastFamily* pBlastFamily = fs[m_nCurFamilyIndex];
+ RenderMaterial* pRenderMaterial = nullptr;
+ pBlastFamily->getMaterial(&pRenderMaterial, externalSurface);
+ if (pRenderMaterial != nullptr)
+ {
+ name = pRenderMaterial->getMaterialName();
+ if (name != "")
{
- m_fTool->getBaseMesh(i, chunkMeshes[i]);
- isSupport[i] = m_fTool->getChunkList()[i].isLeaf;
+ return;
}
}
- // If there are more than one mesh, then it seems that it prefractured, lets consider first mesh in meshes as depth 0, other meshes as depth 1 chunks
- // we should just build Blast descriptors for such input.
+
+ AssetList::ModelAsset modelAsset = m_AssetDescMap[m_pCurBlastAsset];
+ int assetID = BlastProject::ins().getAssetIDByName(modelAsset.name.c_str());
+ BPPAssetInstance* instance = BlastProject::ins().getAssetInstance(assetID, m_nCurFamilyIndex);
+ if (externalSurface && instance->exMaterial.buf != nullptr)
+ {
+ name = instance->exMaterial.buf;
+ }
+ else if (!externalSurface && instance->inMaterial.buf != nullptr)
+ {
+ name = instance->inMaterial.buf;
+ }
+}
+
+void SampleManager::setMaterialForCurrentFamily(std::string name, bool externalSurface)
+{
+ if (m_pCurBlastAsset == nullptr || m_nCurFamilyIndex < 0)
+ {
+ return;
+ }
+
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator it = m_AssetFamiliesMap.find(m_pCurBlastAsset);
+ if (it == m_AssetFamiliesMap.end())
+ {
+ return;
+ }
+
+ std::vector<BlastFamily*>& fs = it->second;
+ int fsSize = fs.size();
+ if (fsSize == 0 || fsSize <= m_nCurFamilyIndex)
+ {
+ return;
+ }
+
+ RenderMaterial* pRenderMaterial = getRenderMaterial(name);
+
+ BlastFamily* pBlastFamily = fs[m_nCurFamilyIndex];
+ pBlastFamily->setMaterial(pRenderMaterial, externalSurface);
+
+ AssetList::ModelAsset modelAsset = m_AssetDescMap[m_pCurBlastAsset];
+ int assetID = BlastProject::ins().getAssetIDByName(modelAsset.name.c_str());
+ BPPAssetInstance* instance = BlastProject::ins().getAssetInstance(assetID, m_nCurFamilyIndex);
+ if (externalSurface)
+ {
+ copy(instance->exMaterial, name.c_str());
+ }
+ else
+ {
+ copy(instance->inMaterial, name.c_str());
+ }
+}
+
+#if 0
+void SampleManager::applyAssetToProjectParam(BlastAsset* pBlastAsset, bool addTo)
+{
+ BlastAssetModel* assetModel = dynamic_cast<BlastAssetModel*>(pBlastAsset);
+
+ BPPBlast& blast = BlastProject::ins().getParams().blast;
+
+ std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = getAssetFamiliesMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = getAssetDescMap();
+
+ AssetList::ModelAsset desc = AssetDescMap[pBlastAsset];
+ std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset];
+
+ BlastController& blastController = getBlastController();
+ SceneController& sceneController = getSceneController();
+
+ char str[MAX_PATH];
+
+ // asset array
+ BPPAssetArray assetArray;
+ assetArray.arraySizes[0] = 1;
+ assetArray.buf = new BPPAsset[1];
+ BPPAsset& asset = assetArray.buf[0];
+ ::init(asset);
+ copy(asset.name, desc.name.c_str());
+ if (addTo)
+ {
+ asset.ID = BlastProject::ins().generateNewAssetID();
+ merge(blast.blastAssets, assetArray);
+ }
else
{
- chunkMeshes.resize(meshes.size());
- std::vector<PxVec3> chunkCentroids(meshes.size(), PxVec3(0, 0, 0));
+ asset.ID = BlastProject::ins().getAssetIDByName(asset.name.buf);
+ apart(blast.blastAssets, assetArray);
+ }
+
+ 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;
+
+ std::vector<bool> isSupports(chunkCount);
+ isSupports.assign(chunkCount, false);
+ std::vector<uint32_t> fromIDs(bondCount);
+ std::vector<uint32_t> toIDs(bondCount);
+ fromIDs.assign(bondCount, -1);
+ toIDs.assign(bondCount, -1);
+
+ for (uint32_t node0 = 0; node0 < supportGraph.nodeCount; ++node0)
+ {
+ const uint32_t chunkIndex0 = supportGraph.chunkIndices[node0];
+ if (chunkIndex0 >= chunkCount)
+ {
+ continue;
+ }
+
+ isSupports[chunkIndex0] = true;
- for (uint32_t i = 0; i < meshes.size(); ++i)
+ for (uint32_t adjacencyIndex = adjacencyPartition[node0]; adjacencyIndex < adjacencyPartition[node0 + 1]; adjacencyIndex++)
{
- std::vector<Triangle>& chunk = chunkMeshes[i];
+ uint32_t node1 = supportGraph.adjacentNodeIndices[adjacencyIndex];
+
+ // add this condition if you don't want to iterate all bonds twice
+ if (node0 > node1)
+ continue;
- Vertex* vbf = meshes[i]->getVertices();
- Edge* ebf = meshes[i]->getEdges();
+ const uint32_t chunkIndex1 = supportGraph.chunkIndices[node1];
- for (uint32_t fc = 0; fc < meshes[i]->getFacetCount(); ++fc)
+ uint32_t bondIndex = supportGraph.adjacentBondIndices[adjacencyIndex];
+
+ if (chunkIndex0 < chunkIndex1)
{
- Facet* f = meshes[i]->getFacet(fc);
- Triangle tr;
- tr.a = vbf[ebf[f->firstEdgeNumber].s];
- tr.b = vbf[ebf[f->firstEdgeNumber + 1].s];
- tr.c = vbf[ebf[f->firstEdgeNumber + 2].s];
- chunk.push_back(tr);
-
- chunkCentroids[i] += tr.a.p + tr.b.p + tr.c.p;
+ fromIDs[bondIndex] = chunkIndex0;
+ toIDs[bondIndex] = chunkIndex1;
}
+ else
+ {
+ fromIDs[bondIndex] = chunkIndex1;
+ toIDs[bondIndex] = chunkIndex0;
+ }
+ }
+ }
+
+ // chunks
+ BPPChunkArray chunkArray;
+ {
+ chunkArray.buf = new BPPChunk[chunkCount];
+ chunkArray.arraySizes[0] = chunkCount;
+ char chunkname[10];
+ for (int cc = 0; cc < chunkCount; ++cc)
+ {
+ BPPChunk& chunk = chunkArray.buf[cc];
+ ::init(chunk);
+
+ 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());
+
+ chunk.asset = asset.ID;
+ chunk.ID = cc;
+ chunk.parentID = pNvBlastChunk[cc].parentChunkIndex;
+ chunk.staticFlag = pExtPxChunk[cc].isStatic;
+ chunk.visible = isChunkVisible(fs, cc);
+ chunk.support = isSupports[cc];
+
+ if (assetModel != nullptr)
+ {
+ const BlastModel& model = assetModel->getModel();
+
+ BPPGraphicsMesh& graphicsMesh = chunk.graphicsMesh;
+ ::init(graphicsMesh);
+
+ const BlastModel::Chunk& chunk = model.chunks[cc];
+
+ const std::vector<BlastModel::Chunk::Mesh>& meshes = chunk.meshes;
+ int meshSize = meshes.size();
+
+ if (meshSize == 0)
+ {
+ continue;
+ }
+
+ std::vector<physx::PxVec3> positions;
+ std::vector<physx::PxVec3> normals;
+ std::vector<physx::PxVec2> uv;
+ std::vector<uint32_t> ind;
+ std::vector<int> faceBreakPoint;
+ std::vector<uint32_t> materialIndexes;
+ uint16_t curIndex = 0;
+ for (int ms = 0; ms < meshSize; ms++)
+ {
+ const BlastModel::Chunk::Mesh& mesh = meshes[ms];
+ materialIndexes.push_back(mesh.materialIndex);
+ const SimpleMesh& simpleMesh = mesh.mesh;
+ const std::vector<SimpleMesh::Vertex>& vertices = simpleMesh.vertices;
+ const std::vector<uint16_t>& indices = simpleMesh.indices;
+
+ int NumVertices = vertices.size();
+ for (uint32_t i = 0; i < NumVertices; ++i)
+ {
+ positions.push_back(physx::PxVec3(vertices[i].position.x, vertices[i].position.y, vertices[i].position.z));
+ normals.push_back(physx::PxVec3(vertices[i].normal.x, vertices[i].normal.y, vertices[i].normal.z));
+ uv.push_back(physx::PxVec2(vertices[i].uv.x, vertices[i].uv.y));
+ }
+ int NumIndices = indices.size();
+ for (uint32_t i = 0; i < NumIndices; ++i)
+ {
+ ind.push_back(indices[i] + curIndex);
+ }
+ curIndex += NumIndices;
+ faceBreakPoint.push_back(NumIndices / 3);
+ }
+
+ graphicsMesh.materialAssignments.buf = new BPPMaterialAssignments[materialIndexes.size()];
+ graphicsMesh.materialAssignments.arraySizes[0] = materialIndexes.size();
+ for (size_t i = 0; i < materialIndexes.size(); ++i)
+ {
+ BPPMaterialAssignments& assignment = graphicsMesh.materialAssignments.buf[i];
+ assignment.libraryMaterialID = materialIndexes[i];
+ assignment.faceMaterialID = materialIndexes[i];
+ }
+
+ graphicsMesh.positions.buf = new nvidia::NvVec3[positions.size()];
+ graphicsMesh.positions.arraySizes[0] = positions.size();
+ for (size_t i = 0; i < positions.size(); ++i)
+ {
+ nvidia::NvVec3& item = graphicsMesh.positions.buf[i];
+ item.x = positions[i].x;
+ item.y = positions[i].y;
+ item.z = positions[i].z;
+ }
+
+ graphicsMesh.normals.buf = new nvidia::NvVec3[normals.size()];
+ graphicsMesh.normals.arraySizes[0] = normals.size();
+ for (size_t i = 0; i < normals.size(); ++i)
+ {
+ nvidia::NvVec3& item = graphicsMesh.normals.buf[i];
+ item.x = normals[i].x;
+ item.y = normals[i].y;
+ item.z = normals[i].z;
+ }
+
+ graphicsMesh.texcoords.buf = new nvidia::NvVec2[uv.size()];
+ graphicsMesh.texcoords.arraySizes[0] = uv.size();
+ for (size_t i = 0; i < uv.size(); ++i)
+ {
+ nvidia::NvVec2& item = graphicsMesh.texcoords.buf[i];
+ item.x = uv[i].x;
+ item.y = uv[i].y;
+ }
+
+ size_t indexCount = ind.size();
+ size_t faceCount = ind.size() / 3;
+
+ graphicsMesh.vertextCountInFace = 3;
- chunkCentroids[i] *= 1.0f / (3 * meshes[i]->getFacetCount());
+ graphicsMesh.positionIndexes.buf = new int32_t[indexCount];
+ graphicsMesh.positionIndexes.arraySizes[0] = indexCount;
+
+ graphicsMesh.normalIndexes.buf = new int32_t[indexCount];
+ graphicsMesh.normalIndexes.arraySizes[0] = indexCount;
+
+ graphicsMesh.texcoordIndexes.buf = new int32_t[indexCount];
+ graphicsMesh.texcoordIndexes.arraySizes[0] = indexCount;
+
+ graphicsMesh.materialIDs.buf = new int32_t[faceCount];
+ graphicsMesh.materialIDs.arraySizes[0] = faceCount;
+
+ for (size_t i = 0; i < indexCount; ++i)
+ {
+ graphicsMesh.positionIndexes.buf[i] = ind[i];
+ graphicsMesh.normalIndexes.buf[i] = ind[i];
+ graphicsMesh.texcoordIndexes.buf[i] = ind[i];
+ /*
+ size_t j = 0;
+ for (; j < faceBreakPoint.size(); ++j)
+ {
+ if (i < faceBreakPoint[j])
+ break;
+ }
+ graphicsMesh.materialIDs.buf[i / 3] = j;
+ */
+ }
+
+ for (size_t f = 0; f < faceCount; f++)
+ {
+ int32_t ex = f < faceBreakPoint[0] ? 0 : 1;
+ graphicsMesh.materialIDs.buf[f] = ex;
+ }
+ }
}
- isSupport.resize(chunkMeshes.size());
- chunkDesc.resize(chunkMeshes.size());
- isSupport[0] = false;
+ if (addTo)
+ {
+ merge(blast.chunks, chunkArray);
+ }
+ else
+ {
+ apart(blast.chunks, chunkArray);
+ }
+ }
- chunkDesc[0].centroid[0] = chunkCentroids[0].x;
- chunkDesc[0].centroid[1] = chunkCentroids[0].y;
- chunkDesc[0].centroid[2] = chunkCentroids[0].z;
- chunkDesc[0].parentChunkIndex = UINT32_MAX;
+ // bonds
+ BPPBondArray bondArray;
+ {
+ bondArray.buf = new BPPBond[bondCount];
+ bondArray.arraySizes[0] = bondCount;
+ char bondname[10];
+ bool visible;
+ for (int bc = 0; bc < bondCount; ++bc)
+ {
+ BPPBond& bond = bondArray.buf[bc];
+ bond.name.buf = nullptr;
+ ::init(bond);
+
+ visible = isChunkVisible(fs, fromIDs[bc]) || isChunkVisible(fs, toIDs[bc]);
+ bond.visible = visible;
+ bond.fromChunk = fromIDs[bc];
+ bond.toChunk = toIDs[bc];
+
+ sprintf(bondname, "Bond_%d_%d", bond.fromChunk, bond.toChunk);
+ copy(bond.name, bondname);
+ bond.asset = asset.ID;
+
+ bond.support.healthMask.buf = nullptr;
+ bond.support.bondStrength = 1.0;
+ bond.support.enableJoint = false;
+ }
- for (uint32_t i = 1; i < chunkDesc.size(); ++i)
+ if (addTo)
+ {
+ merge(blast.bonds, bondArray);
+ }
+ else
{
- chunkDesc[i].parentChunkIndex = 0;
- chunkDesc[i].flags = NvBlastChunkDesc::SupportFlag;
- chunkDesc[i].centroid[0] = chunkCentroids[i].x;
- chunkDesc[i].centroid[1] = chunkCentroids[i].y;
- chunkDesc[i].centroid[2] = chunkCentroids[i].z;
- isSupport[i] = true;
+ apart(blast.bonds, bondArray);
}
}
- BlastBondGenerator bondGenerator(cooking, &physics->getPhysicsInsertionCallback());
+ freeBlast(bondArray);
+ freeBlast(chunkArray);
+ freeBlast(assetArray);
- BondGenerationConfig cnf;
- cnf.bondMode = BondGenerationConfig::AVERAGE;
+ m_bNeedRefreshTree = true;
+}
+#endif
- if (meshes.size() > 1)
+void SampleManager::updateAssetFamilyStressSolver(BPPAsset* bppAsset, BPPStressSolver& stressSolver)
+{
+ if (nullptr == bppAsset || nullptr == bppAsset->name.buf || 0 == strlen(bppAsset->name.buf))
+ return;
+
+ BlastAsset* blastAsset = nullptr;
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itr = m_AssetDescMap.begin();
+ for (; itr != m_AssetDescMap.end(); ++itr)
{
- bondGenerator.bondsFromPrefractured(chunkMeshes, isSupport, bondDescs, cnf);
+ if (itr->second.name == bppAsset->name.buf)
+ {
+ blastAsset = itr->first;
+ break;
+ }
}
- else
+
+ if (nullptr == blastAsset)
+ return;
+
+ std::vector<BlastFamily*>& families = m_AssetFamiliesMap[blastAsset];
+
+ for (BlastFamily* family : families)
{
- bondGenerator.buildDescFromInternalFracture(m_fTool, isSupport, bondDescs, chunkDesc);
+ BlastFamily::Settings settings = family->getSettings();
+
+ ExtStressSolverSettings & stressSolverSettings = settings.stressSolverSettings;
+ stressSolverSettings.hardness = stressSolver.hardness;
+ stressSolverSettings.stressLinearFactor = stressSolver.linearFactor;
+ stressSolverSettings.stressAngularFactor = stressSolver.angularFactor;
+ stressSolverSettings.bondIterationsPerFrame = stressSolver.bondIterationsPerFrame;
+ stressSolverSettings.graphReductionLevel = stressSolver.graphReductionLevel;
+ family->setSettings(settings);
}
+}
- const uint32_t chunkCount = static_cast<uint32_t>(chunkDesc.size());
- const uint32_t bondCount = static_cast<uint32_t>(bondDescs.size());
- if (bondCount == 0)
+void SampleManager::updateModelMeshToProjectParam(BlastAsset* pBlastAsset)
+{
+ BlastProject& project = BlastProject::ins();
+ BlastAssetModel* assetModel = dynamic_cast<BlastAssetModel*>(pBlastAsset);
+ BPPBlast& blast = project.getParams().blast;
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = getAssetDescMap();
+ AssetList::ModelAsset desc = AssetDescMap[pBlastAsset];
+
+ int assetId = project.getAssetIDByName(desc.name.c_str());
+ if (-1 == assetId)
+ return;
+
+ std::vector<BPPChunk*> chunks = project.getChildrenChunks(assetId);
+
+ BPPChunk& chunk = *chunks[0];//unfracture model only has one chunk
+
+ if (assetModel != nullptr)
{
- std::cout << "Can't create bonds descriptors..." << std::endl;
+ const BlastModel& model = assetModel->getModel();
+
+ BPPGraphicsMesh& graphicsMesh = chunk.graphicsMesh;
+
+ const BlastModel::Chunk& chunk = model.chunks[0];//unfracture model only has one chunk
+
+ const std::vector<BlastModel::Chunk::Mesh>& meshes = chunk.meshes;
+ int meshSize = meshes.size();
+
+ if (meshSize == 0)
+ {
+ return;
+ }
+
+ std::vector<physx::PxVec3> positions;
+ for (int ms = 0; ms < meshSize; ms++)
+ {
+ const BlastModel::Chunk::Mesh& mesh = meshes[ms];
+ const SimpleMesh& simpleMesh = mesh.mesh;
+ const std::vector<SimpleMesh::Vertex>& vertices = simpleMesh.vertices;
+
+ int NumVertices = vertices.size();
+ for (uint32_t i = 0; i < NumVertices; ++i)
+ {
+ positions.push_back(physx::PxVec3(vertices[i].position.x, vertices[i].position.y, vertices[i].position.z));
+ }
+ }
+
+ for (size_t i = 0; i < positions.size(); ++i)
+ {
+ nvidia::NvVec3& item = graphicsMesh.positions.buf[i];
+ item.x = positions[i].x;
+ item.y = positions[i].y;
+ item.z = positions[i].z;
+ }
}
+}
- // order chunks, build map
- std::vector<uint32_t> chunkReorderInvMap;
+#if 0
+void SampleManager::applyFamilyToProjectParam(BlastFamily* pBlastFamily, bool addTo)
+{
+ const BlastAsset& blastAsset = pBlastFamily->getBlastAsset();
+ BlastAsset* pBlastAsset = (BlastAsset*)&blastAsset;
+
+ std::vector<BlastFamily*>& fs = m_AssetFamiliesMap[pBlastAsset];
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = getAssetDescMap();
+ AssetList::ModelAsset desc = AssetDescMap[pBlastAsset];
+
+ const BlastFamily::Settings& familySetting = pBlastFamily->getSettings();
+ physx::PxTransform transform = familySetting.transform;
+
+ char str[MAX_PATH];
+
+ BPPBlast& blast = BlastProject::ins().getParams().blast;
+ int assetID = BlastProject::ins().getAssetIDByName(desc.name.c_str());
+
+ // instance array
+ BPPAssetInstanceArray instanceArray;
+ instanceArray.arraySizes[0] = 1;
+ instanceArray.buf = new BPPAssetInstance[1];
+ BPPAssetInstance& instance = instanceArray.buf[0];
+ if (addTo)
+ {
+ ::init(instance);
+ int instanceIndex = fs.size() - 1;
+ sprintf(str, "%s_%d", desc.name.c_str(), instanceIndex);
+ copy(instance.name, str);
+ instance.asset = assetID;
+ PxVec3 p = transform.p;
+ PxQuat q = transform.q;
+ instance.transform.position = nvidia::NvVec3(p.x, p.y, p.z);
+ instance.transform.rotation = nvidia::NvVec4(q.x, q.y, q.z, q.w);
+ }
+ else
{
- std::vector<uint32_t> chunkReorderMap(chunkCount);
- std::vector<char> scratch(chunkCount * sizeof(NvBlastChunkDesc));
- NvBlastEnsureAssetExactSupportCoverage(chunkDesc.data(), chunkCount, scratch.data(), loggingCallback);
- NvBlastBuildAssetDescChunkReorderMap(chunkReorderMap.data(), chunkDesc.data(), chunkCount, scratch.data(), loggingCallback);
- NvBlastApplyAssetDescChunkReorderMapInplace(chunkDesc.data(), chunkCount, bondDescs.data(), bondCount, chunkReorderMap.data(), scratch.data(), loggingCallback);
- chunkReorderInvMap.resize(chunkReorderMap.size());
- Nv::Blast::invertMap(chunkReorderInvMap.data(), chunkReorderMap.data(), static_cast<unsigned int>(chunkReorderMap.size()));
+ BPPAssetInstance* pInstance = getInstanceByFamily(pBlastFamily);
+ copy(instance, *pInstance);
}
- // get result geometry
- std::vector<std::vector<Triangle>> resultGeometry(chunkMeshes.size());
- for (uint32_t i = 0; i < chunkMeshes.size(); ++i)
+ std::vector<BPPAssetInstance*> instances;
+ BlastProject::ins().getAssetInstances(assetID, instances);
+ int instanceSize = instances.size();
+ std::vector<std::string> instanceNames(instanceSize);
+ std::vector<BlastFamily*> instanceFamilys(instanceSize);
+ for (int is = 0; is < instanceSize; is++)
{
- uint32_t chunkIndex = chunkReorderInvMap[i];
- resultGeometry[chunkIndex] = chunkMeshes[i];
+ instanceNames[is] = instances[is]->name;
+ instanceFamilys[is] = m_instanceFamilyMap[instances[is]];
+ m_instanceFamilyMap.erase(m_instanceFamilyMap.find(instances[is]));
}
- // prepare physics data (convexes)
- std::vector<ExtPxAssetDesc::ChunkDesc> pxChunks(chunkCount);
- std::vector<ExtPxAssetDesc::SubchunkDesc> pxSubchunks;
- buildPxChunks(resultGeometry, pxChunks, pxSubchunks);
+ if (addTo)
+ {
+ merge(blast.blastAssetInstances, instanceArray);
+ instanceNames.push_back(str);
+ instanceFamilys.push_back(pBlastFamily);
- // build and serialize ExtPhysicsAsset
- ExtPxAssetDesc descriptor;
- descriptor.bondCount = bondCount;
- descriptor.bondDescs = bondDescs.data();
- descriptor.chunkCount = chunkCount;
- descriptor.chunkDescs = chunkDesc.data();
- descriptor.bondFlags = nullptr;
- descriptor.pxChunks = pxChunks.data();
- ExtPxAsset* asset = ExtPxAsset::create(descriptor, tk);
- if (asset == nullptr)
+ std::vector<BPPChunk*> chunks = BlastProject::ins().getChildrenChunks(assetID);
+ for (size_t i = 0; i < chunks.size(); ++i)
+ {
+ chunks[i]->visible = isChunkVisible(fs, i);
+ }
+ }
+ else
{
- return false;
+ apart(blast.blastAssetInstances, instanceArray);
}
- physx::PsFileBuffer fileBuf(outBlastFilePath.c_str(), physx::PxFileBuf::OPEN_WRITE_ONLY);
- if (!asset->serialize(fileBuf, *cooking))
+ instanceSize = instanceNames.size();
+ for (int is = 0; is < instanceSize; is++)
{
- return false;
+ BPPAssetInstance* curInstance = BlastProject::ins().getAssetInstance(assetID, instanceNames[is].c_str());
+ if (curInstance != nullptr)
+ {
+ m_instanceFamilyMap[curInstance] = instanceFamilys[is];
+ }
}
- fileBuf.close();
- asset->release();
- saveFractureToObj(resultGeometry, assetName, outDir);
+ freeBlast(instanceArray);
- m_bNeedConfig = true;
+ m_bNeedRefreshTree = true;
+}
+#endif
- return true;
+BlastAsset* SampleManager::loadBlastFile(std::string dir, std::string file, AssetList::ModelAsset modelAsset)
+{
+ GlobalSettings::Inst().m_projectFileDir = dir;
+ GlobalSettings::Inst().m_projectFileName = file;
+
+ TkFramework& framework = getBlastController().getTkFramework();
+ PxPhysics& physics = getPhysXController().getPhysics();
+ PxCooking& cooking = getPhysXController().getCooking();
+ Renderer& renderer = getRenderer();
+ ExtSerialization& serialization = *getBlastController().getExtSerialization();
+
+ BlastAssetModelSimple* pBlastAssetModelSimple = new BlastAssetModelSimple(
+ framework, physics, cooking, serialization, renderer, file.c_str());
+
+ addBlastAsset(pBlastAssetModelSimple, modelAsset);
+
+ return pBlastAssetModelSimple;
}
-void SampleManager::_setSourceAsset()
+void SampleManager::addBlastAsset(BlastAssetModelSimple* pBlastAssetModelSimple, AssetList::ModelAsset modelAsset, bool inProject)
{
- std::vector<BlastFamilyPtr>& families = m_blastController->getFamilies();
- if (families.size() > 0)
+ // 1
+ m_AssetDescMap[pBlastAssetModelSimple] = modelAsset;
+ m_AssetFamiliesMap[pBlastAssetModelSimple].clear();
+ pBlastAssetModelSimple->initialize();
+
+ // 2
+ m_sceneController->addBlastAsset(pBlastAssetModelSimple, modelAsset);
+
+ if (!inProject)
{
- BlastFamilyPtr spLastFamily = families.back();
+ // 3
+ _addAssetToProjectParam(pBlastAssetModelSimple);
+ }
- m_fTool->setSourceAsset(&(spLastFamily->getBlastAsset()));
+ //4
+ const BlastModel& model = pBlastAssetModelSimple->getModel();
+ const physx::PxVec3 extent = (model.bbMax - model.bbMin) * 0.5f;
+ atcore_float3 max = gfsdk_max(*(atcore_float3*)&m_assetExtents, *(atcore_float3*)&(extent));
+ m_assetExtents = *(physx::PxVec3*)&max;
+
+ getGizmoToolController().setAxisLength(m_assetExtents.magnitude());
+
+ m_bNeedRefreshTree = true;
+ /*
+ BPPAsset* pBPPAsset = BlastProject::ins().getAsset(modelAsset.name.c_str());
+ BlastSceneTree::ins()->addBlastAsset(*pBPPAsset);
+ */
+}
+
+void SampleManager::removeBlastAsset(BlastAssetModelSimple* pBlastAssetModelSimple)
+{
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = m_AssetDescMap.find(pBlastAssetModelSimple);
+ /*
+ AssetList::ModelAsset modelAsset = itADM->second;
+ BPPAsset* pBPPAsset = BlastProject::ins().getAsset(modelAsset.name.c_str());
+ BlastSceneTree::ins()->removeBlastInstances(*pBPPAsset);
+ BlastSceneTree::ins()->removeBlastAsset(*pBPPAsset);
+ */
+ // 3
+ _removeInstancesFromProjectParam(pBlastAssetModelSimple);
+ _removeAssetFromProjectParam(pBlastAssetModelSimple);
+
+ // 2
+ m_sceneController->removeBlastAsset(pBlastAssetModelSimple);
+
+ _refreshInstanceFamilyMap();
+
+ // 1
+ m_AssetDescMap.erase(itADM);
+
+ m_bNeedRefreshTree = true;
+}
+
+BlastFamily* SampleManager::addBlastFamily(BlastAsset* pBlastAsset, physx::PxTransform transform, bool inProject)
+{
+ if (pBlastAsset == nullptr)
+ {
+ return nullptr;
+ }
+
+ BlastFamily* pBlastFamily = m_sceneController->addBlastFamily(pBlastAsset, transform);
+
+ if (!inProject)
+ {
+ _addInstanceToProjectParam(pBlastFamily);
}
+
+ _refreshInstanceFamilyMap();
+ /*
+ BPPAssetInstance* pBPPAssetInstance = getInstanceByFamily(pBlastFamily);
+ BlastSceneTree::ins()->addBlastInstance(*pBPPAssetInstance);
+ */
+ /*
+ AssetList::ModelAsset modelAsset = m_AssetDescMap[pBlastAsset];
+ int assetID = BlastProject::ins().getAssetIDByName(modelAsset.name.c_str());
+ std::vector<BPPAssetInstance*> instances;
+ BlastProject::ins().getAssetInstances(assetID, instances);
+ std::vector<BlastFamily*> families = m_AssetFamiliesMap[pBlastAsset];
+ int familiesSize = families.size();
+ for (int fs = 0; fs < familiesSize; fs++)
+ {
+ m_instanceFamilyMap.insert(std::make_pair(instances[fs], families[fs]));
+ }
+ */
+ // should not quit here. we still need set up right bounding extent
+ m_bNeedRefreshTree = true;
+ return pBlastFamily;
}
-void SampleManager::addRenderMaterial(RenderMaterial* pRenderMaterial)
+bool SampleManager::removeBlastFamily(BlastAsset* pBlastAsset, int nFamilyIndex)
{
- if (pRenderMaterial == nullptr)
+ if (pBlastAsset == nullptr)
{
- return;
+ return false;
}
- std::string materialName = pRenderMaterial->getMaterialName();
- if (materialName.empty())
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAFM = m_AssetFamiliesMap.find(pBlastAsset);
+ if (itAFM == m_AssetFamiliesMap.end())
{
- return;
+ return false;
}
- m_RenderMaterialMap[materialName] = pRenderMaterial;
+ std::vector<BlastFamily*> families = itAFM->second;
+ int familySize = families.size();
+ if (familySize == 0 || familySize <= nFamilyIndex)
+ {
+ return false;
+ }
- std::string textureFileName = pRenderMaterial->getTextureFileName();
- MaterialLibraryPanel::ins()->addMaterial(materialName, textureFileName);
+ _removeInstanceFromProjectParam(families[nFamilyIndex]);
+ /*
+ BPPAssetInstance* pBPPAssetInstance = getInstanceByFamily(families[nFamilyIndex]);
+ BlastSceneTree::ins()->addBlastInstance(*pBPPAssetInstance);
+ */
+ m_sceneController->removeBlastFamily(pBlastAsset, nFamilyIndex);
+
+ _refreshInstanceFamilyMap();
+ m_bNeedRefreshTree = true;
+ return true;
}
-void SampleManager::removeRenderMaterial(std::string name)
+void SampleManager::refreshAsset(BlastAsset* pBlastAsset)
{
- if (name.empty())
+ m_fTool->setSourceAsset(pBlastAsset);
+ m_fTool->finalizeFracturing();
+
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator it = m_AssetDescMap.find(pBlastAsset);
+ AssetList::ModelAsset desc = it->second;
+
+ int nChunkCount = pBlastAsset->getPxAsset()->getChunkCount();
+ int nBondCount = pBlastAsset->getPxAsset()->getTkAsset().getBondCount();
+
+ std::vector<bool> supports(nChunkCount);
+ std::vector<bool> statics(nChunkCount);
+
+ int nCur = 0;
+
+ BPPBlast& blast = BlastProject::ins().getParams().blast;
+ int assetID = BlastProject::ins().getAssetIDByName(desc.name.c_str());
+ int chunkSize = blast.chunks.arraySizes[0];
+ for (int cs = 0; cs < chunkSize; cs++)
{
- return;
+ BPPChunk& chunk = blast.chunks.buf[cs];
+ if (chunk.asset == assetID)
+ {
+ supports[nCur] = chunk.support;
+ statics[nCur] = chunk.staticFlag;
+ nCur++;
+ }
}
- std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(name);
- if (it != m_RenderMaterialMap.end())
+ if (nCur != nChunkCount)
{
- m_RenderMaterialMap.erase(it);
- MaterialLibraryPanel::ins()->removeMaterial(name);
+ assert("chunk size not right");
}
+
+ nCur = 0;
+
+ std::vector<uint8_t> joints(nBondCount);
+ std::vector<uint32_t> worlds(nBondCount);
+ int bondSize = blast.bonds.arraySizes[0];
+ for (int bs = 0; bs < bondSize; bs++)
+ {
+ BPPBond& bond = blast.bonds.buf[bs];
+ if (bond.asset == assetID)
+ {
+ joints[nCur] = bond.support.enableJoint;
+ worlds[nCur] = bond.toChunk;
+ nCur++;
+ }
+ }
+
+ if (nCur != nBondCount)
+ {
+ assert("bond size not right");
+ }
+
+ _replaceAsset(pBlastAsset, supports, statics, joints, worlds);
}
-void SampleManager::deleteRenderMaterial(std::string name)
+void SampleManager::UpdateCamera()
{
- if (name.empty())
+ m_renderer->UpdateCamera();
+}
+
+void SampleManager::_addAssetToProjectParam(BlastAsset* pBlastAsset)
+{
+ BlastAssetModel* assetModel = dynamic_cast<BlastAssetModel*>(pBlastAsset);
+
+ BPPBlast& blast = BlastProject::ins().getParams().blast;
+
+ std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = getAssetFamiliesMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = getAssetDescMap();
+
+ AssetList::ModelAsset desc = AssetDescMap[pBlastAsset];
+ std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset];
+
+ BlastController& blastController = getBlastController();
+ SceneController& sceneController = getSceneController();
+
+ char str[MAX_PATH];
+
+ // asset array
+ BPPAssetArray assetArray;
+ assetArray.arraySizes[0] = 1;
+ assetArray.buf = new BPPAsset[1];
+ BPPAsset& asset = assetArray.buf[0];
+ ::init(asset);
+ copy(asset.name, desc.name.c_str());
+ asset.ID = BlastProject::ins().generateNewAssetID();
+ merge(blast.blastAssets, assetArray);
+
+ 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;
+
+ std::vector<bool> isSupports(chunkCount);
+ isSupports.assign(chunkCount, false);
+ std::vector<uint32_t> fromIDs(bondCount);
+ std::vector<uint32_t> toIDs(bondCount);
+ fromIDs.assign(bondCount, -1);
+ toIDs.assign(bondCount, -1);
+
+ for (uint32_t node0 = 0; node0 < supportGraph.nodeCount; ++node0)
{
- return;
+ const uint32_t chunkIndex0 = supportGraph.chunkIndices[node0];
+ if (chunkIndex0 >= chunkCount)
+ {
+ continue;
+ }
+
+ isSupports[chunkIndex0] = 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];
+
+ if (chunkIndex0 < chunkIndex1)
+ {
+ fromIDs[bondIndex] = chunkIndex0;
+ toIDs[bondIndex] = chunkIndex1;
+ }
+ else
+ {
+ fromIDs[bondIndex] = chunkIndex1;
+ toIDs[bondIndex] = chunkIndex0;
+ }
+ }
}
- m_NeedDeleteRenderMaterials.push_back(name);
+ // chunks
+ BPPChunkArray chunkArray;
+ {
+ chunkArray.buf = new BPPChunk[chunkCount];
+ chunkArray.arraySizes[0] = chunkCount;
+ char chunkname[10];
+ for (int cc = 0; cc < chunkCount; ++cc)
+ {
+ BPPChunk& chunk = chunkArray.buf[cc];
+ ::init(chunk);
+
+ 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());
+
+ chunk.asset = asset.ID;
+ chunk.ID = cc;
+ chunk.parentID = pNvBlastChunk[cc].parentChunkIndex;
+ chunk.staticFlag = pExtPxChunk[cc].isStatic;
+ chunk.visible = isChunkVisible(fs, cc);
+ chunk.support = isSupports[cc];
+
+ if (assetModel != nullptr)
+ {
+ const BlastModel& model = assetModel->getModel();
+
+ BPPGraphicsMesh& graphicsMesh = chunk.graphicsMesh;
+ ::init(graphicsMesh);
+
+ const BlastModel::Chunk& chunk = model.chunks[cc];
+
+ const std::vector<BlastModel::Chunk::Mesh>& meshes = chunk.meshes;
+ int meshSize = meshes.size();
+
+ if (meshSize == 0)
+ {
+ continue;
+ }
+
+ std::vector<physx::PxVec3> positions;
+ std::vector<physx::PxVec3> normals;
+ std::vector<physx::PxVec3> tangents;
+ std::vector<physx::PxVec2> uv;
+ std::vector<uint32_t> ind;
+ std::vector<int> faceBreakPoint;
+ std::vector<uint32_t> materialIndexes;
+ uint16_t curIndex = 0;
+ for (int ms = 0; ms < meshSize; ms++)
+ {
+ const BlastModel::Chunk::Mesh& mesh = meshes[ms];
+ materialIndexes.push_back(mesh.materialIndex);
+ const SimpleMesh& simpleMesh = mesh.mesh;
+ const std::vector<SimpleMesh::Vertex>& vertices = simpleMesh.vertices;
+ const std::vector<uint16_t>& indices = simpleMesh.indices;
+
+ int NumVertices = vertices.size();
+ for (uint32_t i = 0; i < NumVertices; ++i)
+ {
+ positions.push_back(physx::PxVec3(vertices[i].position.x, vertices[i].position.y, vertices[i].position.z));
+ normals.push_back(physx::PxVec3(vertices[i].normal.x, vertices[i].normal.y, vertices[i].normal.z));
+ tangents.push_back(physx::PxVec3(vertices[i].tangent.x, vertices[i].tangent.y, vertices[i].tangent.z));
+ uv.push_back(physx::PxVec2(vertices[i].uv.x, vertices[i].uv.y));
+ }
+ int NumIndices = indices.size();
+ for (uint32_t i = 0; i < NumIndices; ++i)
+ {
+ ind.push_back(indices[i] + curIndex);
+ }
+ curIndex += NumVertices;
+ faceBreakPoint.push_back(NumIndices / 3);
+ }
+
+ graphicsMesh.materialAssignments.buf = new BPPMaterialAssignments[materialIndexes.size()];
+ graphicsMesh.materialAssignments.arraySizes[0] = materialIndexes.size();
+ for (size_t i = 0; i < materialIndexes.size(); ++i)
+ {
+ BPPMaterialAssignments& assignment = graphicsMesh.materialAssignments.buf[i];
+ assignment.libraryMaterialID = materialIndexes[i];
+ assignment.faceMaterialID = materialIndexes[i];
+ }
+
+ graphicsMesh.positions.buf = new nvidia::NvVec3[positions.size()];
+ graphicsMesh.positions.arraySizes[0] = positions.size();
+ for (size_t i = 0; i < positions.size(); ++i)
+ {
+ nvidia::NvVec3& item = graphicsMesh.positions.buf[i];
+ item.x = positions[i].x;
+ item.y = positions[i].y;
+ item.z = positions[i].z;
+ }
+
+ graphicsMesh.normals.buf = new nvidia::NvVec3[normals.size()];
+ graphicsMesh.normals.arraySizes[0] = normals.size();
+ for (size_t i = 0; i < normals.size(); ++i)
+ {
+ nvidia::NvVec3& item = graphicsMesh.normals.buf[i];
+ item.x = normals[i].x;
+ item.y = normals[i].y;
+ item.z = normals[i].z;
+ }
+
+ graphicsMesh.tangents.buf = new nvidia::NvVec3[tangents.size()];
+ graphicsMesh.tangents.arraySizes[0] = tangents.size();
+ for (size_t i = 0; i < tangents.size(); ++i)
+ {
+ nvidia::NvVec3& item = graphicsMesh.tangents.buf[i];
+ item.x = tangents[i].x;
+ item.y = tangents[i].y;
+ item.z = tangents[i].z;
+ }
+
+ graphicsMesh.texcoords.buf = new nvidia::NvVec2[uv.size()];
+ graphicsMesh.texcoords.arraySizes[0] = uv.size();
+ for (size_t i = 0; i < uv.size(); ++i)
+ {
+ nvidia::NvVec2& item = graphicsMesh.texcoords.buf[i];
+ item.x = uv[i].x;
+ item.y = uv[i].y;
+ }
+
+ size_t indexCount = ind.size();
+ size_t faceCount = ind.size() / 3;
+
+ graphicsMesh.vertextCountInFace = 3;
+
+ graphicsMesh.positionIndexes.buf = new int32_t[indexCount];
+ graphicsMesh.positionIndexes.arraySizes[0] = indexCount;
+
+ graphicsMesh.normalIndexes.buf = new int32_t[indexCount];
+ graphicsMesh.normalIndexes.arraySizes[0] = indexCount;
+
+ graphicsMesh.texcoordIndexes.buf = new int32_t[indexCount];
+ graphicsMesh.texcoordIndexes.arraySizes[0] = indexCount;
+
+ graphicsMesh.materialIDs.buf = new int32_t[faceCount];
+ graphicsMesh.materialIDs.arraySizes[0] = faceCount;
+
+ for (size_t i = 0; i < indexCount; ++i)
+ {
+ graphicsMesh.positionIndexes.buf[i] = ind[i];
+ graphicsMesh.normalIndexes.buf[i] = ind[i];
+ graphicsMesh.texcoordIndexes.buf[i] = ind[i];
+ }
+
+ for (size_t f = 0; f < faceCount; f++)
+ {
+ int32_t ex = f < faceBreakPoint[0] ? 0 : 1;
+ graphicsMesh.materialIDs.buf[f] = ex;
+ }
+ }
+ }
+
+ merge(blast.chunks, chunkArray);
+ }
+
+ // bonds
+ BPPBondArray bondArray;
+ {
+ bondArray.buf = new BPPBond[bondCount];
+ bondArray.arraySizes[0] = bondCount;
+ char bondname[20];
+ bool visible;
+ for (int bc = 0; bc < bondCount; ++bc)
+ {
+ BPPBond& bond = bondArray.buf[bc];
+ bond.name.buf = nullptr;
+ ::init(bond);
+
+ visible = isChunkVisible(fs, fromIDs[bc]) || isChunkVisible(fs, toIDs[bc]);
+ bond.visible = visible;
+ bond.fromChunk = fromIDs[bc];
+ bond.toChunk = toIDs[bc];
+
+ if (bond.toChunk == 0xFFFFFFFF)
+ {
+ sprintf(bondname, "Bond_%d_world", bond.fromChunk);
+ }
+ else
+ {
+ sprintf(bondname, "Bond_%d_%d", bond.fromChunk, bond.toChunk);
+ }
+ copy(bond.name, bondname);
+ bond.asset = asset.ID;
+
+ bond.support.healthMask.buf = nullptr;
+ bond.support.bondStrength = 1.0;
+ bond.support.enableJoint = false;
+ }
+
+ merge(blast.bonds, bondArray);
+ }
+
+ freeBlast(bondArray);
+ freeBlast(chunkArray);
+ freeBlast(assetArray);
+
+ m_bNeedRefreshTree = true;
}
-void SampleManager::renameRenderMaterial(std::string oldName, std::string newName)
+void SampleManager::_removeAssetFromProjectParam(BlastAsset* pBlastAsset)
{
- if (oldName.empty() || newName.empty())
+ if (pBlastAsset == nullptr)
{
return;
}
- std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(oldName);
- if (it != m_RenderMaterialMap.end())
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = m_AssetDescMap.find(pBlastAsset);
+ if (itADM == m_AssetDescMap.end())
{
- RenderMaterial* pRenderMaterial = it->second;
- m_RenderMaterialMap.erase(it);
- pRenderMaterial->setMaterialName(newName);
- m_RenderMaterialMap[newName] = pRenderMaterial;
+ return;
}
+
+ AssetList::ModelAsset desc = m_AssetDescMap[pBlastAsset];
+
+ BPPBlast& blast = BlastProject::ins().getParams().blast;
+
+ int32_t assetId = BlastProject::ins().getAssetIDByName(desc.name.c_str());
+
+ apart(blast.blastAssets, assetId);
+ apart(blast.chunks, assetId);
+ apart(blast.bonds, assetId);
}
-void SampleManager::getCurrentSelectedInstance(BlastAsset** ppBlastAsset, int& index)
+void SampleManager::_addInstanceToProjectParam(BlastFamily* pBlastFamily)
{
- *ppBlastAsset = m_pCurBlastAsset;
- index = m_nCurFamilyIndex;
+ const BlastAsset& blastAsset = pBlastFamily->getBlastAsset();
+ BlastAsset* pBlastAsset = (BlastAsset*)&blastAsset;
+
+ std::vector<BlastFamily*>& fs = m_AssetFamiliesMap[pBlastAsset];
+ AssetList::ModelAsset desc = m_AssetDescMap[pBlastAsset];
+
+ const BlastFamily::Settings& familySetting = pBlastFamily->getSettings();
+ physx::PxTransform transform = familySetting.transform;
+
+ char str[MAX_PATH];
+
+ BPPBlast& blast = BlastProject::ins().getParams().blast;
+ int assetID = BlastProject::ins().getAssetIDByName(desc.name.c_str());
+
+ // instance array
+ BPPAssetInstanceArray instanceArray;
+ instanceArray.arraySizes[0] = 1;
+ instanceArray.buf = new BPPAssetInstance[1];
+ BPPAssetInstance& instance = instanceArray.buf[0];
+ ::init(instance);
+ int instanceIndex = fs.size() - 1;
+ sprintf(str, "%s_%d", desc.name.c_str(), instanceIndex);
+ copy(instance.name, str);
+ instance.asset = assetID;
+ PxVec3 p = transform.p;
+ PxQuat q = transform.q;
+ instance.transform.position = nvidia::NvVec3(p.x, p.y, p.z);
+ instance.transform.rotation = nvidia::NvVec4(q.x, q.y, q.z, q.w);
+
+ merge(blast.blastAssetInstances, instanceArray);
+
+ std::vector<BPPChunk*> chunks = BlastProject::ins().getChildrenChunks(assetID);
+ for (size_t i = 0; i < chunks.size(); ++i)
+ {
+ chunks[i]->visible = isChunkVisible(fs, i);
+ }
+
+ freeBlast(instanceArray);
+
+ m_bNeedRefreshTree = true;
}
-void SampleManager::setCurrentSelectedInstance(BlastAsset* pBlastAsset, int index)
+void SampleManager::_removeInstanceFromProjectParam(BlastFamily* pBlastFamily)
{
- m_pCurBlastAsset = pBlastAsset;
- m_nCurFamilyIndex = index;
+ BPPAssetInstance* pInstance = getInstanceByFamily(pBlastFamily);
+ if (pInstance == nullptr)
+ {
+ return;
+ }
- MaterialAssignmentsPanel::ins()->updateValues();
+ BPPBlast& blast = BlastProject::ins().getParams().blast;
+ apart(blast.blastAssetInstances, pInstance->asset, pInstance->name.buf);
}
-void SampleManager::getMaterialForCurrentFamily(RenderMaterial** ppRenderMaterial, bool externalSurface)
+void SampleManager::_removeInstancesFromProjectParam(BlastAsset* pBlastAsset)
{
- if (m_pCurBlastAsset == nullptr || m_nCurFamilyIndex < 0)
+ if (pBlastAsset == nullptr)
{
return;
}
- std::vector<BlastFamily*>& fs = m_AssetFamiliesMap[m_pCurBlastAsset];
- int fsSize = fs.size();
- if (fsSize == 0 || fsSize < m_nCurFamilyIndex)
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = m_AssetDescMap.find(pBlastAsset);
+ if (itADM == m_AssetDescMap.end())
{
return;
}
- BlastFamily* pBlastFamily = fs[m_nCurFamilyIndex];
- pBlastFamily->getMaterial(ppRenderMaterial, externalSurface);
+ AssetList::ModelAsset desc = m_AssetDescMap[pBlastAsset];
+
+ BPPBlast& blast = BlastProject::ins().getParams().blast;
+
+ int32_t assetId = BlastProject::ins().getAssetIDByName(desc.name.c_str());
+
+ apart(blast.blastAssetInstances, assetId);
}
-void SampleManager::setMaterialForCurrentFamily(RenderMaterial* pRenderMaterial, bool externalSurface)
+void SampleManager::_refreshInstanceFamilyMap()
{
- if (m_pCurBlastAsset == nullptr || m_nCurFamilyIndex < 0)
+ m_instanceFamilyMap.clear();
+
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM;
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAFM;
+ for (itADM = m_AssetDescMap.begin(); itADM != m_AssetDescMap.end(); itADM++)
{
- return;
+ BlastAsset* pBlastAsset = itADM->first;
+ itAFM = m_AssetFamiliesMap.find(pBlastAsset);
+ if (itAFM == m_AssetFamiliesMap.end())
+ {
+ continue;
+ }
+
+ AssetList::ModelAsset modelAsset = itADM->second;
+ int assetID = BlastProject::ins().getAssetIDByName(modelAsset.name.c_str());
+ std::vector<BPPAssetInstance*> instances;
+ BlastProject::ins().getAssetInstances(assetID, instances);
+ int instancesSize = instances.size();
+ std::vector<BlastFamily*> families = itAFM->second;
+ int familiesSize = families.size();
+ if (instancesSize != familiesSize)
+ {
+ assert("size of instance in scene and project not equal");
+ }
+ for (int fs = 0; fs < familiesSize; fs++)
+ {
+ m_instanceFamilyMap.insert(std::make_pair(instances[fs], families[fs]));
+ }
}
+}
- std::vector<BlastFamily*>& fs = m_AssetFamiliesMap[m_pCurBlastAsset];
- int fsSize = fs.size();
- if (fsSize == 0 || fsSize < m_nCurFamilyIndex)
+bool SampleManager::eventAlreadyHandled()
+{
+ bool isAlt = (GetAsyncKeyState(VK_MENU) && 0x8000);
+ bool isLight = (GetAsyncKeyState('L') && 0x8000);
+ return m_selectionToolController->IsEnabled() && !(isAlt || isLight);
+}
+
+void SampleManager::ApplyAutoSelectNewChunks(BlastAsset* pNewBlastAsset, std::vector<uint32_t>& NewChunkIndexes)
+{
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAFM = m_AssetFamiliesMap.find(pNewBlastAsset);
+ if (itAFM == m_AssetFamiliesMap.end())
{
return;
}
- BlastFamily* pBlastFamily = fs[m_nCurFamilyIndex];
- pBlastFamily->setMaterial(pRenderMaterial, externalSurface);
+ bool autoSelectNewChunks = BlastProject::ins().getParams().fracture.general.autoSelectNewChunks;
+
+ std::vector<BlastFamily*> families = itAFM->second;
+ for (BlastFamily* pBlastFamily : families)
+ {
+ pBlastFamily->clearChunksSelected();
+
+ if (!autoSelectNewChunks)
+ {
+ continue;
+ }
+
+ for (uint32_t chunkInd : NewChunkIndexes)
+ {
+ pBlastFamily->setChunkSelected(chunkInd, true);
+ pBlastFamily->setChunkVisible(chunkInd, true);
+ }
+ }
+
+ BlastSceneTree::ins()->ApplyAutoSelectNewChunks(pNewBlastAsset, NewChunkIndexes);
+}
+
+void SampleManager::ApplySelectionDepthTest()
+{
+ bool selectionDepthTest = BlastProject::ins().getParams().fracture.general.selectionDepthTest;
+
+ std::vector<BlastFamily*>& families = m_blastController->getFamilies();
+
+ for (BlastFamily* pBlastFamily : families)
+ {
+ std::vector<uint32_t> selectedChunks = pBlastFamily->getSelectedChunks();
+
+ for (uint32_t chunkInd : selectedChunks)
+ {
+ pBlastFamily->setChunkSelected(chunkInd, true);
+ pBlastFamily->setChunkVisible(chunkInd, true);
+ }
+ }
} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.h
index 0c5c8b6..c16fa25 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef SAMPLE_MANAGER_H
#define SAMPLE_MANAGER_H
@@ -14,21 +32,23 @@
#include "Application.h"
#include "Sample.h"
#include <map>
-
+#include <functional>
+#include "ProjectParams.h"
+#include "RenderMaterial.h"
class SampleManager;
class BlastFractureTool;
class BlastAsset;
class BlastFamily;
-class RenderMaterial;
+
namespace Nv
{
-namespace Blast
-{
- class Mesh;
- class RandomGeneratorBase;
- class VoronoiSitesGenerator;
- struct SlicingConfiguration;
-}
+ namespace Blast
+ {
+ class Mesh;
+ class RandomGeneratorBase;
+ class VoronoiSitesGenerator;
+ struct SlicingConfiguration;
+ }
}
class ISampleController : public IApplicationController
@@ -56,59 +76,59 @@ class FractureExecutor
public:
FractureExecutor()
: m_fractureTool(0)
- , m_chunkId(-1)
, m_randomGenerator(nullptr)
- , m_sourMesh(nullptr)
+ , m_pCurBlastAsset(nullptr)
{
+ m_chunkIds.clear();
}
virtual bool execute() = 0;
- void setSourceMesh(Nv::Blast::Mesh* mesh);
- void setSourceAsset(const BlastAsset* blastAsset);
- void setTargetChunk(uint32_t chunkId) { m_chunkId = chunkId; }
+ void setSourceAsset(BlastAsset* blastAsset);
+ void setTargetChunk(uint32_t chunkId)
+ {
+ m_chunkIds.clear();
+ m_chunkIds.push_back(chunkId);
+ }
+ void setTargetChunks(std::vector<uint32_t>& chunkIds)
+ {
+ m_chunkIds.clear();
+ std::vector<uint32_t>::iterator it;
+ for (it = chunkIds.begin(); it != chunkIds.end(); it++)
+ {
+ m_chunkIds.push_back(*it);
+ }
+ std::sort(m_chunkIds.begin(), m_chunkIds.end(), std::greater<uint32_t>());
+ }
void setRandomGenerator(Nv::Blast::RandomGeneratorBase* randomGenerator) { m_randomGenerator = randomGenerator; }
protected:
BlastFractureTool* m_fractureTool;
- uint32_t m_chunkId;
+ std::vector<uint32_t> m_chunkIds;
Nv::Blast::RandomGeneratorBase* m_randomGenerator;
- Nv::Blast::Mesh* m_sourMesh;
+ BlastAsset* m_pCurBlastAsset;
};
class VoronoiFractureExecutor : public FractureExecutor
{
public:
VoronoiFractureExecutor();
- void setCellsCount(uint32_t cellsCount);
+ void setBPPVoronoi(BPPVoronoi* voronoi) { m_voronoi = voronoi; }
virtual bool execute();
private:
- uint32_t m_cellsCount;
+ BPPVoronoi* m_voronoi;
};
class SliceFractureExecutor : public FractureExecutor
{
public:
SliceFractureExecutor();
- void applyNoise(float amplitude, float frequency, int32_t octaves, float falloff, int32_t relaxIterations, float relaxFactor, int32_t seed = 0);
- void applyConfig(int32_t xSlices, int32_t ySlices, int32_t zSlices, float offsetVariations, float angleVariations);
+ void setBPPSlice(BPPSlice* slice) { m_slice = slice; }
virtual bool execute();
private:
- Nv::Blast::SlicingConfiguration* m_config;
-};
-
-enum BlastToolType
-{
- BTT_Damage = 0,
- BTT_Drag,
- BTT_Select,
- BTT_Translate,
- BTT_Scale,
- BTT_Rotation,
- BTT_Edit,
- BTT_Num
+ BPPSlice* m_slice;
};
enum SelectMode
@@ -125,12 +145,13 @@ class BlastController;
class SceneController;
class DamageToolController;
class SelectionToolController;
+class ExplodeToolController;
class GizmoToolController;
class EditionToolController;
class SampleController;
class CommonUIController;
class SimpleRandomGenerator;
-
+class BlastAssetModelSimple;
/**
*/
class SampleManager
@@ -146,27 +167,18 @@ class SampleManager
int run();
int free();
- void addModelAsset(std::string path, std::string file, bool isSkinned, physx::PxTransform transform, bool clear = true);
-
bool createAsset(
- std::string path,
- std::string assetName,
- std::vector<physx::PxVec3>& positions,
- std::vector<physx::PxVec3>& normals,
- std::vector<physx::PxVec2>& uv,
- std::vector<unsigned int>& indices,
- bool fracture = false);
+ BlastAssetModelSimple** ppBlastAsset,
+ std::vector<Nv::Blast::Mesh*>& meshes,
+ std::vector<int32_t>& parentIds,
+ std::vector<bool>& supports,
+ std::vector<bool>& statics,
+ std::vector<uint8_t>& joints,
+ std::vector<uint32_t>& worlds);
- bool createAsset(
- const std::string& path,
- const std::string& assetName,
- const std::vector<Nv::Blast::Mesh* >& meshes,
- bool fracture = false);
-
- bool saveAsset();
- bool fractureAsset(std::string& path, std::string& assetName, const BlastAsset* blastAsset, int32_t chunkId);
+ bool saveAsset(BlastAsset* pBlastAsset);
- bool postProcessCurrentAsset();
+ bool exportAsset();
Renderer& getRenderer()
{
@@ -198,6 +210,10 @@ class SampleManager
return *m_selectionToolController;
}
+ ExplodeToolController& getExplodeToolController() const
+ {
+ return *m_explodeToolController;
+ }
GizmoToolController& getGizmoToolController() const
{
return *m_gizmoToolController;
@@ -218,11 +234,6 @@ class SampleManager
return *m_commonUIController;
}
- const SampleConfig& getConfig() const
- {
- return m_config;
- }
-
std::vector<uint32_t> getCurrentSelectedChunks();
std::map<BlastAsset*, std::vector<uint32_t>> getSelectedChunks();
void clearChunksSelected();
@@ -231,8 +242,6 @@ class SampleManager
void setFractureExecutor(FractureExecutor* executor);
- void setBlastToolType(BlastToolType type);
-
void output(const char* str);
void output(float value);
void output(physx::PxVec3& vec);
@@ -249,27 +258,75 @@ class SampleManager
return m_AssetDescMap;
}
+ BlastFamily* getFamilyByInstance(BPPAssetInstance* instance);
+ BPPAssetInstance* getInstanceByFamily(BlastFamily* family);
+ void updateFamily(BlastFamily* oldFamily, BlastFamily* newFamily);
+
std::map<std::string, RenderMaterial*>& getRenderMaterials(){ return m_RenderMaterialMap; }
- void addRenderMaterial(RenderMaterial* pRenderMaterial);
void removeRenderMaterial(std::string name);
- void deleteRenderMaterial(std::string name);
void renameRenderMaterial(std::string oldName, std::string newName);
+ void reloadRenderMaterial(std::string name, float r, float g, float b, bool diffuse = true);
+ void reloadRenderMaterial(std::string name, std::string texture, RenderMaterial::TextureType tt = RenderMaterial::TT_Diffuse);
+ void reloadRenderMaterial(std::string name, float specularShininess);
+ RenderMaterial* getRenderMaterial(std::string name, bool create = true);
bool m_bNeedRefreshTree;
void getCurrentSelectedInstance(BlastAsset** ppBlastAsset, int& index);
void setCurrentSelectedInstance(BlastAsset* pBlastAsset, int index);
- void getMaterialForCurrentFamily(RenderMaterial** ppRenderMaterial, bool externalSurface);
- void setMaterialForCurrentFamily(RenderMaterial* pRenderMaterial, bool externalSurface);
+ void getMaterialForCurrentFamily(std::string& name, bool externalSurface);
+ void setMaterialForCurrentFamily(std::string name, bool externalSurface);
+
+ void updateAssetFamilyStressSolver(BPPAsset* bppAsset, BPPStressSolver& stressSolver);
+ // only update unfractured mode mesh
+ void updateModelMeshToProjectParam(BlastAsset* pBlastAsset);
+
+ BlastAsset* loadBlastFile(std::string dir, std::string file, AssetList::ModelAsset modelAsset);
+ void addBlastAsset(BlastAssetModelSimple* pBlastAsset, AssetList::ModelAsset modelAsset, bool inProject = false);
+ void removeBlastAsset(BlastAssetModelSimple* pBlastAsset);
+ BlastFamily* addBlastFamily(BlastAsset* pBlastAsset, physx::PxTransform transform, bool inProject = false);
+ bool removeBlastFamily(BlastAsset* pBlastAsset, int nFamilyIndex);
+
+ BlastAsset* getCurBlastAsset() { return m_pCurBlastAsset; }
+
+ void refreshAsset(BlastAsset* pBlastAsset);
+
+ void UpdateCamera();
+
+ bool IsSimulating() { return m_simulating; }
+ void EnableSimulating(bool bSimulating);
+ bool IsStepforward() { return m_stepforward; }
+ void EnableStepforward(bool bStepforward);
+
+ physx::PxVec3 getAssetExtent() { return m_assetExtents; }
+
+ bool eventAlreadyHandled();
+
+ void ApplyAutoSelectNewChunks(BlastAsset* pNewBlastAsset, std::vector<uint32_t>& NewChunkIndexes);
+ void ApplySelectionDepthTest();
private:
- bool _createAsset(
- const std::string& assetName,
- const std::string& outDir,
- const std::vector<Nv::Blast::Mesh* >& meshes);
+ void _createAsset(BlastAssetModelSimple** ppBlastAsset,
+ std::vector<bool>& supports,
+ std::vector<bool>& statics,
+ std::vector<uint8_t>& joints,
+ std::vector<uint32_t>& worlds);
+
+ BlastAsset* _replaceAsset(BlastAsset* pBlastAsset,
+ std::vector<bool>& supports,
+ std::vector<bool>& statics,
+ std::vector<uint8_t>& joints,
+ std::vector<uint32_t>& worlds);
void _setSourceAsset();
+ void _addAssetToProjectParam(BlastAsset* pBlastAsset);
+ void _removeAssetFromProjectParam(BlastAsset* pBlastAsset);
+ void _addInstanceToProjectParam(BlastFamily* pBlastFamily);
+ void _removeInstanceFromProjectParam(BlastFamily* pBlastFamily);
+ void _removeInstancesFromProjectParam(BlastAsset* pBlastAsset);
+ void _refreshInstanceFamilyMap();
+
private:
Renderer* m_renderer;
PhysXController* m_physXController;
@@ -277,15 +334,13 @@ private:
SceneController* m_sceneController;
DamageToolController* m_damageToolController;
SelectionToolController* m_selectionToolController;
+ ExplodeToolController* m_explodeToolController;
GizmoToolController* m_gizmoToolController;
EditionToolController* m_editionToolController;
SampleController* m_sampleController;
CommonUIController* m_commonUIController;
-
- SampleConfig m_config;
-
+
Application* m_pApplication;
- BlastToolType m_ToolType;
BlastFractureTool* m_fTool;
FractureExecutor* m_fractureExecutor;
@@ -294,11 +349,13 @@ private:
std::map<BlastAsset*, AssetList::ModelAsset> m_AssetDescMap;
std::map<std::string, RenderMaterial*> m_RenderMaterialMap;
std::vector<std::string> m_NeedDeleteRenderMaterials;
+ std::map<BPPAssetInstance*, BlastFamily*> m_instanceFamilyMap;
BlastAsset* m_pCurBlastAsset;
int m_nCurFamilyIndex;
-
- bool m_bNeedConfig;
+ physx::PxVec3 m_assetExtents;
+ bool m_simulating;
+ bool m_stepforward;
};
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.cpp
index 5146914..1cf9e26 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.cpp
@@ -1,12 +1,30 @@
-/*
- * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
- *
- * NVIDIA CORPORATION and its licensors retain all intellectual property
- * and proprietary rights in and to this software, related documentation
- * and any modifications thereto. Any use, reproduction, disclosure or
- * distribution of this software and related documentation without an express
- * license agreement from NVIDIA CORPORATION is strictly prohibited.
- */
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "PhysXController.h"
#include "RenderMaterial.h"
@@ -19,7 +37,11 @@
#include "ConvexRenderMesh.h"
#include "RenderUtils.h"
#include "SampleProfiler.h"
-#include "NvBlastProfiler.h"
+#include "NvBlastExtCustomProfiler.h"
+#include "NvBlastPxCallbacks.h"
+// Add By Lixu Begin
+#include "Mesh.h"
+// Add By Lixu End
#include "PxPhysicsVersion.h"
#include "PxPvdTransport.h"
@@ -35,6 +57,10 @@
#include "PxMaterial.h"
#include "PxFoundationVersion.h"
#include "PxMath.h"
+// Add By Lixu Begin
+#include "PxRigidActorExt.h"
+#include "SimpleScene.h"
+// Add By Lixu End
#include <imgui.h>
#include <chrono>
@@ -47,14 +73,17 @@ const DirectX::XMFLOAT4 PLANE_COLOR(1.0f, 1.0f, 1.0f, 1.0f);
const DirectX::XMFLOAT4 HOOK_LINE_COLOR(1.0f, 1.0f, 1.0f, 1.0f);
const float DEFAULT_FIXED_TIMESTEP = 1.0f / 60.0f;
+static Nv::Blast::ExtCustomProfiler gBlastProfiler;
+
PhysXController::PhysXController(PxSimulationFilterShader filterShader)
: m_filterShader(filterShader)
, m_gpuPhysicsAvailable(true)
+, m_isSimulating(false)
, m_useGPUPhysics(true)
, m_lastSimulationTime(0)
, m_paused(false)
, m_draggingActor(nullptr)
-, m_draggingEnabled(true)
+, m_draggingEnabled(false)
, m_draggingTryReconnect(false)
, m_perfWriter(NULL)
, m_fixedTimeStep(DEFAULT_FIXED_TIMESTEP)
@@ -65,7 +94,7 @@ PhysXController::PhysXController(PxSimulationFilterShader filterShader)
QueryPerformanceFrequency(&m_performanceFreq);
// Add By Lixu Begin
- m_bForce = true;
+ m_bFirstTime = true;
// Add By Lixu End
}
@@ -81,6 +110,7 @@ void PhysXController::onInitialize()
void PhysXController::onTerminate()
{
+ simualtionSyncEnd();
releasePhysXPrimitives();
releasePhysX();
}
@@ -92,13 +122,13 @@ void PhysXController::onTerminate()
void PhysXController::initPhysX()
{
- m_foundation = PxCreateFoundation(PX_FOUNDATION_VERSION, m_allocator, m_errorCallback);
+ m_foundation = PxCreateFoundation(PX_FOUNDATION_VERSION, NvBlastGetPxAllocatorCallback(), NvBlastGetPxErrorCallback());
m_pvd = PxCreatePvd(*m_foundation);
- NvBlastProfilerSetCallback(m_pvd);
- NvBlastProfilerEnablePlatform(false);
- NvBlastProfilerSetDetail(NvBlastProfilerDetail::LOW);
+ NvBlastProfilerSetCallback(&gBlastProfiler);
+ NvBlastProfilerSetDetail(Nv::Blast::ProfilerDetail::LOW);
+ gBlastProfiler.setPlatformEnabled(false);
PxTolerancesScale scale;
@@ -144,6 +174,7 @@ void PhysXController::initPhysX()
}
m_physicsScene = m_physics->createScene(sceneDesc);
+ m_editPhysicsScene = m_physics->createScene(sceneDesc);
m_defaultMaterial = m_physics->createMaterial(0.8f, 0.7f, 0.1f);
@@ -176,6 +207,7 @@ void PhysXController::releasePhysX()
{
m_defaultMaterial->release();
m_physicsScene->release();
+ m_editPhysicsScene->release();
if (m_cudaContext)
m_cudaContext->release();
m_dispatcher->release();
@@ -241,61 +273,92 @@ void PhysXController::notifyRigidDynamicDestroyed(PxRigidDynamic* rigidDynamic)
}
-
-
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Controller events
+// Simulation control
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void PhysXController::Animate(double dt)
+void PhysXController::simulationBegin(float dt)
{
PROFILER_SCOPED_FUNCTION();
// Add By Lixu Begin
- if (m_paused && !m_bForce)
+ if (m_paused && !m_bFirstTime)
return;
- if (m_bForce)
+ if (m_bFirstTime)
{
m_paused = true;
- m_bForce = false;
+ m_bFirstTime = false;
}
// Add By Lixu End
- // slower physics if fps is too low
- dt = PxClamp(dt, 0.0, 0.033333);
-
updateDragging(dt);
+ processExplosionQueue();
+
+ // slower physics if fps is too low
+ dt = PxClamp(dt, 0.0f, 0.0333f);
{
- PROFILER_SCOPED("PhysX simulate");
- steady_clock::time_point start = steady_clock::now();
+ PROFILER_SCOPED("PhysX simulate call");
if (m_useFixedTimeStep)
{
m_timeAccumulator += dt;
m_substepCount = (uint32_t)std::floor(m_timeAccumulator / m_fixedTimeStep);
m_timeAccumulator -= m_fixedTimeStep * m_substepCount;
m_substepCount = m_maxSubstepCount > 0 ? physx::PxClamp<uint32_t>(m_substepCount, 0, m_maxSubstepCount) : m_substepCount;
- for (uint32_t i = 0; i < m_substepCount; ++i)
+ if (m_substepCount > 0)
{
- PROFILER_SCOPED("PhysX simulate (substep)");
m_physicsScene->simulate(m_fixedTimeStep);
- m_physicsScene->fetchResults(true);
+ m_isSimulating = true;
}
}
else
{
m_substepCount = 1;
+ PX_ASSERT(!m_isSimulating);
m_physicsScene->simulate(dt);
- m_physicsScene->fetchResults(true);
+ m_isSimulating = true;
+
}
- m_lastSimulationTime = duration_cast<microseconds>(steady_clock::now() - start).count() * 0.000001;
}
- PROFILER_BEGIN("Debug Render Buffer");
- getRenderer().queueRenderBuffer(&m_physicsScene->getRenderBuffer());
- PROFILER_END();
+// Add By Lixu Begin
+ if (getManager()->IsStepforward())
+ {
+ m_paused = true;
+ getManager()->EnableStepforward(false);
+ }
+// Add By Lixu End
+}
+
+void PhysXController::simualtionSyncEnd()
+{
+ PROFILER_SCOPED_FUNCTION();
+
+ if (m_isSimulating)
+ {
+ steady_clock::time_point start = steady_clock::now();
+ m_physicsScene->fetchResults(true);
+
+ // For fixed time step case it could be that we need more then one step (m_maxSubstepCount > 1). We will run leftover steps synchronously right there.
+ // Ideally is to make them overlap with other logic too, but it's much harder and requires more synchronization logic. Don't want to obfuscate sample code.
+ if (m_useFixedTimeStep && m_substepCount > 1)
+ {
+ for (uint32_t i = 0; i < m_substepCount - 1; i++)
+ {
+ m_physicsScene->simulate(m_fixedTimeStep);
+ m_physicsScene->fetchResults(true);
+ }
+ }
+ m_lastSimulationTime = duration_cast<microseconds>(steady_clock::now() - start).count() * 0.000001;
- updateActorTransforms();
+ m_isSimulating = false;
+
+ updateActorTransforms();
+
+ PROFILER_BEGIN("Debug Render Buffer");
+ getRenderer().queueRenderBuffer(&m_physicsScene->getRenderBuffer());
+ PROFILER_END();
+ }
}
@@ -363,8 +426,11 @@ void PhysXController::updateDragging(double dt)
PxVec3 hookPoint = m_draggingActor->getGlobalPose().transform(m_draggingActorHookLocalPoint);
m_draggingActorLastHookWorldPoint = hookPoint;
m_dragVector = (m_dragAttractionPoint - hookPoint);
- PxVec3 dragVeloctiy = (m_dragVector * DRAGGING_FORCE_FACTOR - DRAGGING_VELOCITY_FACTOR * m_draggingActor->getLinearVelocity()) * dt;
- PxRigidBodyExt::addForceAtLocalPos(*m_draggingActor, dragVeloctiy * m_draggingActor->getMass(), m_draggingActorHookLocalPoint, PxForceMode::eIMPULSE, true);
+ if (!m_draggingActor->getRigidBodyFlags().isSet(PxRigidBodyFlag::eKINEMATIC))
+ {
+ PxVec3 dragVeloctiy = (m_dragVector * DRAGGING_FORCE_FACTOR - DRAGGING_VELOCITY_FACTOR * m_draggingActor->getLinearVelocity()) * dt;
+ PxRigidBodyExt::addForceAtLocalPos(*m_draggingActor, dragVeloctiy * m_draggingActor->getMass(), m_draggingActorHookLocalPoint, PxForceMode::eIMPULSE, true);
+ }
// debug render line
m_dragDebugRenderBuffer.clear();
@@ -404,9 +470,12 @@ LRESULT PhysXController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa
m_dragDistance = (eyePos - hit.position).magnitude();
m_draggingActor = hit.actor->is<PxRigidDynamic>();
m_draggingActorHookLocalPoint = m_draggingActor->getGlobalPose().getInverse().transform(hit.position);
- m_draggingActor->setLinearVelocity(PxVec3(0, 0, 0));
- m_draggingActor->setAngularVelocity(PxVec3(0, 0, 0));
m_dragAttractionPoint = hit.position;
+ if (!m_draggingActor->getRigidBodyFlags().isSet(PxRigidBodyFlag::eKINEMATIC))
+ {
+ m_draggingActor->setLinearVelocity(PxVec3(0, 0, 0));
+ m_draggingActor->setAngularVelocity(PxVec3(0, 0, 0));
+ }
}
}
}
@@ -433,6 +502,71 @@ LRESULT PhysXController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Explosion
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ExplodeOverlapCallback : public PxOverlapCallback
+{
+public:
+ ExplodeOverlapCallback(PxVec3 worldPos, float radius, float explosiveImpulse)
+ : m_worldPos(worldPos)
+ , m_radius(radius)
+ , m_explosiveImpulse(explosiveImpulse)
+ , PxOverlapCallback(m_hitBuffer, sizeof(m_hitBuffer) / sizeof(m_hitBuffer[0])) {}
+
+ PxAgain processTouches(const PxOverlapHit* buffer, PxU32 nbHits)
+ {
+ for (PxU32 i = 0; i < nbHits; ++i)
+ {
+ PxRigidActor* actor = buffer[i].actor;
+ PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>();
+ if (rigidDynamic && !(rigidDynamic->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC))
+ {
+ if (m_actorBuffer.find(rigidDynamic) == m_actorBuffer.end())
+ {
+ m_actorBuffer.insert(rigidDynamic);
+ PxVec3 dr = rigidDynamic->getGlobalPose().transform(rigidDynamic->getCMassLocalPose()).p - m_worldPos;
+ float distance = dr.magnitude();
+ float factor = PxClamp(1.0f - (distance * distance) / (m_radius * m_radius), 0.0f, 1.0f);
+ float impulse = factor * m_explosiveImpulse * 1000.0f;
+ PxVec3 vel = dr.getNormalized() * impulse / rigidDynamic->getMass();
+ rigidDynamic->setLinearVelocity(rigidDynamic->getLinearVelocity() + vel);
+ }
+ }
+ }
+ return true;
+ }
+
+private:
+ PxOverlapHit m_hitBuffer[1000];
+ float m_explosiveImpulse;
+ std::set<PxRigidDynamic*> m_actorBuffer;
+ PxVec3 m_worldPos;
+ float m_radius;
+};
+
+void PhysXController::explode(PxVec3 worldPos, float damageRadius, float explosiveImpulse)
+{
+ ExplodeOverlapCallback overlapCallback(worldPos, damageRadius, explosiveImpulse);
+ m_physicsScene->overlap(PxSphereGeometry(damageRadius), PxTransform(worldPos), overlapCallback);
+}
+
+void PhysXController::explodeDelayed(PxVec3 worldPos, float damageRadius, float explosiveImpulse)
+{
+ m_explosionQueue.push_back({ worldPos, damageRadius, explosiveImpulse });
+}
+
+void PhysXController::processExplosionQueue()
+{
+ for (auto& e : m_explosionQueue)
+ {
+ explode(e.worldPos, e.damageRadius, e.explosiveImpulse);
+ }
+ m_explosionQueue.clear();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// UI
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -446,8 +580,7 @@ void PhysXController::drawUI()
}
ImGui::Text("Substep Count: %d", m_substepCount);
- ImGui::Text("Simulation Time (total): %4.2f ms", getLastSimulationTime() * 1000);
- ImGui::Text("Simulation Time (substep): %4.2f ms", m_substepCount > 0 ? (getLastSimulationTime() / m_substepCount) * 1000 : 0.0);
+ ImGui::Text("Sync Simulation Time (total): %4.2f ms", getLastSimulationTime() * 1000);
}
@@ -456,6 +589,10 @@ void PhysXController::drawUI()
// PhysX Primitive
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Add By Lixu Begin
+PhysXController::Actor* planeActor_Pri = nullptr;
+// Add By Lixu End
+
void PhysXController::initPhysXPrimitives()
{
// physx primitive render materials
@@ -470,6 +607,11 @@ void PhysXController::initPhysXPrimitives()
// create plane
Actor* plane = spawnPhysXPrimitivePlane(PxPlane(PxVec3(0, 1, 0).getNormalized(), 0));
plane->setColor(PLANE_COLOR);
+
+// Add By Lixu Begin
+ planeActor_Pri = plane;
+ planeActor_Pri->setHidden(true);
+// Add By Lixu End
}
void PhysXController::releasePhysXPrimitives()
@@ -557,7 +699,7 @@ void PhysXController::removeUnownedPhysXActors()
{
if (m_physXActorsToRemove.size())
{
- m_physicsScene->removeActors(&m_physXActorsToRemove[0], (PxU32)m_physXActorsToRemove.size());
+ m_physicsScene->removeActors(m_physXActorsToRemove.data(), (PxU32)m_physXActorsToRemove.size());
for (size_t i = 0; i < m_physXActorsToRemove.size(); ++i)
{
m_physXActorsToRemove[i]->release();
@@ -580,7 +722,7 @@ PhysXController::Actor::Actor(PhysXController* controller, PxRigidActor* actor,
uint32_t shapesCount = actor->getNbShapes();
m_shapes.resize(shapesCount);
- actor->getShapes(&m_shapes[0], shapesCount);
+ actor->getShapes(m_shapes.data(), shapesCount);
m_renderables.resize(m_shapes.size());
for (uint32_t i = 0; i < m_shapes.size(); i++)
@@ -724,8 +866,23 @@ PxVec3 unproject(PxMat44& proj, PxMat44& view, float x, float y)
void PhysXController::getEyePoseAndPickDir(float mouseX, float mouseY, PxVec3& eyePos, PxVec3& pickDir)
{
- PxMat44 view = XMMATRIXToPxMat44(getRenderer().getCamera().GetViewMatrix());
- PxMat44 proj = XMMATRIXToPxMat44(getRenderer().getCamera().GetProjMatrix());
+ // Add By Lixu Begin
+ PxMat44 view, proj;
+ SimpleScene* simpleScene = SimpleScene::Inst();
+ Camera* pSceneCamera = simpleScene->GetCamera();
+ if (pSceneCamera->UseLHS())
+ {
+ DirectX::XMMATRIX viewMatrix = SimpleScene::Inst()->GetViewMatrix();
+ DirectX::XMMATRIX projMatrix = SimpleScene::Inst()->GetProjMatrix();
+ view = XMMATRIXToPxMat44(viewMatrix);
+ proj = XMMATRIXToPxMat44(projMatrix);
+ }
+ else
+ {
+ view = XMMATRIXToPxMat44(getRenderer().getCamera().GetViewMatrix());
+ proj = XMMATRIXToPxMat44(getRenderer().getCamera().GetProjMatrix());
+ }
+ // Add By Lixu End
PxMat44 eyeTransform = view.inverseRT();
eyePos = eyeTransform.getPosition();
@@ -750,7 +907,6 @@ bool PhysXController::ExportCollisionRepX(const char* fname, physx::PxPhysics* p
return false;
int count = pSDK->getNbScenes();
- assert(count == 1);
physx::PxSerializationRegistry* psr = physx::PxSerialization::createSerializationRegistry(*pSDK);
@@ -822,4 +978,77 @@ void PhysXController::ClearOldCOllisions()
size = m_physics->getNbConvexMeshes();
}
}
-// Add By Lixu Begin
+
+bool PhysXController::isPlaneVisible()
+{
+ return !planeActor_Pri->isHidden();
+}
+
+void PhysXController::setPlaneVisible(bool bVisible)
+{
+ planeActor_Pri->setHidden(!bVisible);
+}
+
+PxRigidDynamic* PhysXController::createEditPhysXActor(const std::vector<BlastModel::Chunk::Mesh>& meshes, const PxTransform& pos)
+{
+ PxRigidDynamic *actor = m_physics->createRigidDynamic(PxTransform(pos));
+
+ for (size_t i = 0; i < meshes.size(); ++i)
+ {
+ const SimpleMesh& mesh = meshes[i].mesh;
+
+ size_t vertexCount = mesh.vertices.size();
+ if (vertexCount == 0)
+ {
+ continue;
+ }
+ PxVec3* verts = new PxVec3[vertexCount];
+ for (size_t i = 0; i < vertexCount; ++i)
+ {
+ verts[i] = mesh.vertices[i].position;
+ }
+
+ PxConvexMeshDesc convexDesc;
+ convexDesc.points.count = vertexCount;
+ convexDesc.points.stride = sizeof(PxVec3);
+ convexDesc.points.data = verts;
+ convexDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
+
+ {
+ PxCookingParams params = m_cooking->getParams();
+ params.convexMeshCookingType = PxConvexMeshCookingType::eQUICKHULL;
+ m_cooking->setParams(params);
+
+ PxDefaultMemoryOutputStream outStream;
+ bool bCooking = m_cooking->cookConvexMesh(convexDesc, outStream);
+ PxU8* outStreamData = outStream.getData();
+ PxU32 outStreamSize = outStream.getSize();
+ if (!bCooking || outStreamData == nullptr || outStreamSize == 0)
+ {
+ delete[] verts;
+ continue;
+ }
+
+ PxDefaultMemoryInputData input(outStreamData, outStreamSize);
+ PxConvexMesh* convexMesh = m_physics->createConvexMesh(input);
+ if (convexMesh == nullptr)
+ {
+ delete[] verts;
+ continue;
+ }
+ PxShape* shape = m_physics->createShape(PxConvexMeshGeometry(convexMesh), *m_defaultMaterial);
+ if (shape)
+ {
+ actor->attachShape(*shape);
+ }
+
+ }
+
+ delete[] verts;
+ }
+
+ actor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
+ m_editPhysicsScene->addActor(*actor);
+ return actor;
+}
+// Add By Lixu End
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.h
index 2473526..fc59203 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef PHYSX_CONTROLLER_H
#define PHYSX_CONTROLLER_H
@@ -15,10 +33,11 @@
#include <DirectXMath.h>
#include "DebugRenderBuffer.h"
#include "PxFiltering.h"
-#include "PxDefaultAllocator.h"
-#include "PxDefaultErrorCallback.h"
#include <set>
#include <map>
+// Add By Lixu Begin
+#include "BlastModel.h"
+// Add By Lixu End
using namespace physx;
@@ -27,13 +46,14 @@ class PerformanceDataWriter;
class RenderMaterial;
class Renderable;
class IRenderMesh;
+// Add By Lixu Begin
+class SimpleMesh;
+// Add By Lixu End
namespace physx
{
class PxCpuDispatcher;
class PxFoundation;
-class PxDefaultAllocator;
-class PxDefaultErrorCallback;
class PxPhysics;
class PxCooking;
class PxPvd;
@@ -95,16 +115,17 @@ class PhysXController : public ISampleController
//////// virtual callbacks ////////
- virtual void onInitialize();
- virtual void onTerminate();
-
- virtual void Animate(double dt);
+ virtual void onInitialize() override;
+ virtual void onTerminate() override;
virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//////// public API ////////
+ void simulationBegin(float dt);
+ void simualtionSyncEnd();
+
void getEyePoseAndPickDir(float mouseX, float mouseY, PxVec3& eyePos, PxVec3& pickDir);
// wrappers to physx calls
@@ -138,6 +159,9 @@ class PhysXController : public ISampleController
void notifyRigidDynamicDestroyed(PxRigidDynamic*);
+ void explode(PxVec3 worldPos, float damageRadius, float explosiveImpulse);
+ void explodeDelayed(PxVec3 worldPos, float damageRadius, float explosiveImpulse);
+
void drawUI();
//////// public getters ////////
@@ -159,7 +183,16 @@ class PhysXController : public ISampleController
{
return m_physXPlaneRenderMaterial;
}
- bool m_bForce;
+ bool m_bFirstTime;
+ bool isPlaneVisible();
+ void setPlaneVisible(bool bVisible);
+
+ PxScene& getEditPhysXScene() const
+ {
+ return *m_editPhysicsScene;
+ }
+
+ PxRigidDynamic* createEditPhysXActor(const std::vector<BlastModel::Chunk::Mesh>& meshes, const PxTransform& pos);
// Add By Lixu End
PxPhysics& getPhysics() const
@@ -229,6 +262,7 @@ class PhysXController : public ISampleController
void releasePhysXPrimitives();
void updateActorTransforms();
void updateDragging(double dt);
+ void processExplosionQueue();
//////// used controllers ////////
@@ -243,8 +277,6 @@ class PhysXController : public ISampleController
// PhysX
PxFoundation* m_foundation;
- PxDefaultAllocator m_allocator;
- PxDefaultErrorCallback m_errorCallback;
PxPhysics* m_physics;
PxCooking* m_cooking;
PxPvd* m_pvd;
@@ -253,6 +285,9 @@ class PhysXController : public ISampleController
PxMaterial* m_defaultMaterial;
PxSimulationFilterShader m_filterShader;
PxScene* m_physicsScene;
+ // Add By Lixu Begin
+ PxScene* m_editPhysicsScene;
+ // Add By Lixu End
// PhysX API related
std::vector<PxActor*> m_physXActorsToRemove;
@@ -265,9 +300,10 @@ class PhysXController : public ISampleController
RenderMaterial* m_physXPrimitiveTransparentRenderMaterial;
// simulation
+ bool m_isSimulating;
bool m_gpuPhysicsAvailable;
bool m_useGPUPhysics;
- double m_lastSimulationTime;
+ double m_lastSimulationTime;
LARGE_INTEGER m_performanceFreq;
bool m_paused;
bool m_useFixedTimeStep;
@@ -290,6 +326,15 @@ class PhysXController : public ISampleController
// Performance writer
PerformanceDataWriter* m_perfWriter;
+ // explosion
+ struct ExplosionData
+ {
+ PxVec3 worldPos;
+ float damageRadius;
+ float explosiveImpulse;
+ };
+
+ std::vector<ExplosionData> m_explosionQueue;
};
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.cpp
index 074cc2d..dc938b9 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "ConvexRenderMesh.h"
#include "Renderer.h"
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.h
index dfe8d8f..f7bc5c6 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef CONVEX_RENDER_MESH_H
#define CONVEX_RENDER_MESH_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.cpp
index 61ae9e0..0feae3f 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "CustomRenderMesh.h"
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.h
index b0ddea1..025d3bf 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef CUSTOM_RENDER_MESH_H
#define CUSTOM_RENDER_MESH_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/DebugRenderBuffer.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/DebugRenderBuffer.h
index 7810733..06cd509 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/DebugRenderBuffer.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/DebugRenderBuffer.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef DEBUGRENDERBUFFER_H
#define DEBUGRENDERBUFFER_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.cpp
index cdf63f2..c6c8398 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.cpp
@@ -1,12 +1,29 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
#include "Mesh.h"
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.h
index b10f0d6..fa214e0 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef MESH_H
#define MESH_H
@@ -38,6 +56,7 @@ public:
public:
physx::PxVec3 position;
physx::PxVec3 normal;
+ physx::PxVec3 tangent;
physx::PxVec2 uv;
};
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.cpp
index 06c7616..bcb1580 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.cpp
@@ -1,12 +1,29 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
#include "PrimitiveRenderMesh.h"
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.h
index 0f3f345..107af25 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef PRIMITIVE_RENDER_MESH_H
#define PRIMITIVE_RENDER_MESH_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.cpp
index 1b90f8f..a9fedf0 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.cpp
@@ -1,20 +1,38 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "RenderMaterial.h"
#include <DirectXMath.h>
#include "ShaderUtils.h"
#include "Renderer.h"
#include "SampleManager.h"
-
-
+#include "Light.h"
+#include "D3D11TextureResource.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// RenderMaterial
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -22,15 +40,20 @@
RenderMaterial::RenderMaterial(const char* materialName, ResourceManager& resourceCallback, const char* shaderFileName,
const char* textureFileName, BlendMode blendMode)
{
-// Add By Lixu Begin
mMaterialName = materialName;
- mTextureFileName = textureFileName;
- SampleManager::ins()->addRenderMaterial(this);
-// Add By Lixu End
+ setDiffuseColor(0.5, 0.5, 0.5, 1.0);
+ mTextureFileNames[TT_Diffuse] = textureFileName;
this->initialize(resourceCallback, shaderFileName, textureFileName, blendMode);
}
+RenderMaterial::RenderMaterial(const char* materialName, ResourceManager& resourceCallback, const char* shaderFileName, float r, float g, float b, float a, BlendMode blendMode)
+{
+ mMaterialName = materialName;
+ setDiffuseColor(r, g, b, a);
+ this->initialize(resourceCallback, shaderFileName, "", blendMode);
+}
+
void RenderMaterial::initialize(ResourceManager& resourceCallback, const char* shaderFileName, const char* textureFileName, BlendMode blendMode)
{
std::vector<std::string> v;
@@ -40,10 +63,16 @@ void RenderMaterial::initialize(ResourceManager& resourceCallback, const char* s
void RenderMaterial::initialize(ResourceManager& resourceCallback, std::vector<std::string> shaderFileNames, const char* textureFileName, BlendMode blendMode)
{
- mTextureSRV = nullptr;
- mTexture = nullptr;
+ for (int i = 0; i < TT_Num; i++)
+ {
+ m_TextureSRVs[i] = nullptr;
+ mTextureResources[i] = nullptr;
+ }
mBlendState = nullptr;
+ memset(mSpecularColor, 0, sizeof(float) * 4);
+ mSpecularShininess = 20;
+
for (uint32_t i = 0; i < shaderFileNames.size(); i++)
{
const ShaderFileResource* resource = resourceCallback.requestShaderFile(shaderFileNames[i].c_str());
@@ -55,9 +84,9 @@ void RenderMaterial::initialize(ResourceManager& resourceCallback, std::vector<s
}
mShaderGroups.reserve(mShaderFilePathes.size());
- if (!mTextureFileName.empty())
+ if (!mTextureFileNames[TT_Diffuse].empty())
{
- mTexture = resourceCallback.requestTexture(mTextureFileName.c_str());
+ mTextureResources[TT_Diffuse] = resourceCallback.requestTexture(mTextureFileNames[TT_Diffuse].c_str());
}
setBlending(blendMode);
@@ -82,15 +111,14 @@ void RenderMaterial::releaseReloadableResources()
mRenderMeshToInstanceMap.clear();
// Add By Lixu End
- SAFE_RELEASE(mTextureSRV);
+ for (int i = 0; i < TT_Num; i++)
+ {
+ SAFE_RELEASE(m_TextureSRVs[i]);
+ }
}
RenderMaterial::~RenderMaterial()
{
-// Add By Lixu Begin
- SampleManager::ins()->removeRenderMaterial(mMaterialName);
-// Add By Lixu End
-
releaseReloadableResources();
SAFE_RELEASE(mBlendState);
}
@@ -160,10 +188,15 @@ void RenderMaterial::reload()
}
// load texture
- if (mTexture)
+ for (int i = 0; i < TT_Num; i++)
{
- V(DirectX::CreateShaderResourceView(device, mTexture->image.GetImages(), mTexture->image.GetImageCount(),
- mTexture->metaData, &mTextureSRV));
+ if (mTextureResources[i])
+ {
+ V(DirectX::CreateShaderResourceView(device,
+ mTextureResources[i]->image.GetImages(),
+ mTextureResources[i]->image.GetImageCount(),
+ mTextureResources[i]->metaData, &m_TextureSRVs[i]));
+ }
}
}
@@ -219,8 +252,12 @@ void RenderMaterial::Instance::bind(ID3D11DeviceContext& context, uint32_t slot,
{
mMaterial.mShaderGroups[mShaderNum]->Set(&context, !depthStencilOnly);
+ GPUShaderResource* pResource = Light::GetEnvTextureSRV();
+ ID3D11ShaderResourceView* pEnvTextureSRV = D3D11TextureResource::GetResource(pResource);
+
context.OMSetBlendState(mMaterial.mBlendState, nullptr, 0xFFFFFFFF);
- context.PSSetShaderResources(slot, 1, &(mMaterial.mTextureSRV));
+ context.PSSetShaderResources(slot, TT_Num, mMaterial.m_TextureSRVs);
+ context.PSSetShaderResources(TT_Num, 1, &pEnvTextureSRV);
context.IASetInputLayout(mInputLayout);
}
@@ -230,38 +267,72 @@ bool RenderMaterial::Instance::isValid()
}
// Add By Lixu Begin
-void RenderMaterial::setTextureFileName(std::string textureFileName)
+void RenderMaterial::setTextureFileName(std::string textureFileName, TextureType tt)
{
- if (mTextureFileName == textureFileName)
+ if (mTextureFileNames[tt] == textureFileName)
{
return;
}
+ mTextureFileNames[tt] = textureFileName;
- mTextureFileName = textureFileName;
- mTexture = nullptr;
- SAFE_RELEASE(mTextureSRV);
+ mTextureResources[tt] = nullptr;
+ SAFE_RELEASE(m_TextureSRVs[tt]);
- if (mTextureFileName.empty())
+ if (mTextureFileNames[tt].empty())
{
return;
}
- std::string searchDir = mTextureFileName;
+ std::string searchDir = mTextureFileNames[tt];
size_t ind = searchDir.find_last_of('/');
if (ind > 0)
searchDir = searchDir.substr(0, ind);
ResourceManager* pResourceManager = ResourceManager::ins();
pResourceManager->addSearchDir(searchDir.c_str());
- mTexture = pResourceManager->requestTexture(mTextureFileName.c_str());
- if (mTexture == nullptr)
+ mTextureResources[tt] = pResourceManager->requestTexture(mTextureFileNames[tt].c_str());
+ if (mTextureResources[tt] == nullptr)
{
return;
}
ID3D11Device* device = GetDeviceManager()->GetDevice();
- DirectX::CreateShaderResourceView(device, mTexture->image.GetImages(), mTexture->image.GetImageCount(),
- mTexture->metaData, &mTextureSRV);
+ DirectX::CreateShaderResourceView(device,
+ mTextureResources[tt]->image.GetImages(),
+ mTextureResources[tt]->image.GetImageCount(),
+ mTextureResources[tt]->metaData, &m_TextureSRVs[tt]);
+}
+
+void RenderMaterial::setDiffuseColor(float r, float g, float b, float a)
+{
+ mDiffuseColor[0] = r;
+ mDiffuseColor[1] = g;
+ mDiffuseColor[2] = b;
+ mDiffuseColor[3] = a;
+}
+
+void RenderMaterial::getDiffuseColor(float& r, float& g, float& b, float& a)
+{
+ r = mDiffuseColor[0];
+ g = mDiffuseColor[1];
+ b = mDiffuseColor[2];
+ a = mDiffuseColor[3];
+}
+
+void RenderMaterial::setSpecularColor(float r, float g, float b, float a)
+{
+ mSpecularColor[0] = r;
+ mSpecularColor[1] = g;
+ mSpecularColor[2] = b;
+ mSpecularColor[3] = a;
+}
+
+void RenderMaterial::getSpecularColor(float& r, float& g, float& b, float& a)
+{
+ r = mSpecularColor[0];
+ g = mSpecularColor[1];
+ b = mSpecularColor[2];
+ a = mSpecularColor[3];
}
RenderMaterial* g_DefaultRenderMaterial = nullptr;
@@ -270,8 +341,13 @@ RenderMaterial* RenderMaterial::getDefaultRenderMaterial()
if (g_DefaultRenderMaterial == nullptr)
{
ResourceManager* pResourceManager = ResourceManager::ins();
- g_DefaultRenderMaterial = new RenderMaterial("", *pResourceManager, "model_simple_ex");
+ g_DefaultRenderMaterial = new RenderMaterial("", *pResourceManager, "model_simple_textured_ex", 0.5, 0.5, 0.5);
}
return g_DefaultRenderMaterial;
}
+
+bool RenderMaterial::isBadTexture(TextureType tt)
+{
+ return (nullptr == m_TextureSRVs[tt]);
+}
// Add By Lixu End \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.h
index e144a94..27f0672 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef RENDER_MATERIAL_H
#define RENDER_MATERIAL_H
@@ -38,7 +56,16 @@ class RenderMaterial
BLEND_ADDITIVE
};
+ enum TextureType
+ {
+ TT_Diffuse,
+ TT_Specular,
+ TT_Normal,
+ TT_Num
+ };
+
RenderMaterial(const char* materialName, ResourceManager& resourceProvider, const char* shaderFileName, const char* textureFileName = "", BlendMode blendMode = BLEND_NONE);
+ RenderMaterial(const char* materialName, ResourceManager& resourceProvider, const char* shaderFileName, float r, float g, float b, float a = 1.0, BlendMode blendMode = BLEND_NONE);
~RenderMaterial();
void setBlending(BlendMode blendMode);
@@ -65,11 +92,18 @@ class RenderMaterial
typedef Instance* InstancePtr;
std::string getMaterialName(){ return mMaterialName; }
void setMaterialName(std::string materialName){ mMaterialName = materialName; }
- std::string getTextureFileName(){ return mTextureFileName; }
- void setTextureFileName(std::string textureFileName);
+ std::string getTextureFileName(TextureType tt = TT_Diffuse){ return mTextureFileNames[tt]; }
+ void setTextureFileName(std::string textureFileName, TextureType tt = TT_Diffuse);
+ void getDiffuseColor(float& r, float& g, float& b, float& a);
+ void setDiffuseColor(float r, float g, float b, float a = 1.0);
+ void getSpecularColor(float& r, float& g, float& b, float& a);
+ void setSpecularColor(float r, float g, float b, float a = 1.0);
+ float getSpecularShininess() { return mSpecularShininess; }
+ void setSpecularShininess(float specularShininess) { mSpecularShininess = specularShininess; }
void addRelatedRenderable(Renderable* pRenderable){ mRelatedRenderables.push_back(pRenderable); }
std::vector<Renderable*>& getRelatedRenderables(){ return mRelatedRenderables; }
void clearRelatedRenderables(){ mRelatedRenderables.clear(); }
+ bool isBadTexture(TextureType tt = TT_Diffuse);
static RenderMaterial* getDefaultRenderMaterial();
// Add By Lixu End
@@ -84,7 +118,7 @@ class RenderMaterial
std::string mMaterialName;
std::string mShaderFileName;
- std::string mTextureFileName;
+// std::string mTextureFileName;
struct ShaderGroup
{
@@ -121,13 +155,24 @@ class RenderMaterial
// Add By Lixu Begin
std::map<const IRenderMesh*, Instance*> mRenderMeshToInstanceMap;
std::vector<Renderable*> mRelatedRenderables;
+// float mr;
+// float mg;
+// float mb;
+// float ma;
// Add By Lixu End
- const TextureResource* mTexture;
- ID3D11ShaderResourceView* mTextureSRV;
+// const TextureResource* mTexture;
+// ID3D11ShaderResourceView* mTextureSRV;
std::vector<std::string> mShaderFilePathes;
std::vector<ShaderGroup*> mShaderGroups;
ID3D11BlendState* mBlendState;
BlendMode mBlendMode;
+
+ std::string mTextureFileNames[TT_Num];
+ const TextureResource* mTextureResources[TT_Num];
+ ID3D11ShaderResourceView* m_TextureSRVs[TT_Num];
+ float mDiffuseColor[4];
+ float mSpecularColor[4];
+ float mSpecularShininess;
};
#endif \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderUtils.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderUtils.h
index 12df9f2..098f7a9 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderUtils.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderUtils.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef RENDER_UTILS_H
#define RENDER_UTILS_H
@@ -75,4 +93,27 @@ static DirectX::XMFLOAT4 XMFLOAT4Lerp(const DirectX::XMFLOAT4 v0, const DirectX:
return v;
}
+static const physx::PxVec3 forwardVector = physx::PxVec3(0, 0, 1);
+static const physx::PxVec3 upVector = physx::PxVec3(0, 1, 0);
+static const physx::PxVec3 rightVector = physx::PxVec3(1, 0, 0);
+
+PX_INLINE physx::PxQuat quatLookAt(const physx::PxVec3 direction)
+{
+ float d = direction.dot(forwardVector);
+ if (physx::PxAbs(d + 1.0f) < 1e-5f)
+ {
+ return physx::PxQuat(physx::PxPi, upVector);
+ }
+ else if (physx::PxAbs(d - 1.0f) < 1e-5f)
+ {
+ return physx::PxQuat(physx::PxIdentity);
+ }
+ else
+ {
+ float angle = physx::PxAcos(d);
+ physx::PxVec3 axis = forwardVector.cross(direction).getNormalized();
+ return physx::PxQuat(angle, axis);
+ }
+}
+
#endif //RENDER_UTILS_H \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.cpp
index 51569b7..5ce713d 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "Renderable.h"
#include "Renderer.h"
@@ -17,6 +35,8 @@ const DirectX::XMFLOAT4 DEFAULT_COLOR(0.5f, 0.5f, 0.5f, 1.0f);
Renderable::Renderable(IRenderMesh& mesh, RenderMaterial& material) : m_mesh(mesh), m_scale(1, 1, 1), m_color(DEFAULT_COLOR), m_hidden(false), m_transform(PxIdentity)
// Add By Lixu Begin
, m_selected(false)
+, m_depthTest(true)
+, m_highlight(false)
// Add By Lixu End
{
setMaterial(material);
@@ -37,17 +57,65 @@ void Renderable::render(Renderer& renderer, bool depthStencilOnly) const
}
m_materialInstance->bind(*renderer.m_context, 0, depthStencilOnly);
+
+ DirectX::XMFLOAT4 diffuseColor = getColor();
+ DirectX::XMFLOAT4 specularColor = diffuseColor;
+ float useDiffuseTexture = -1.0;
+ float useSpecularTexture = -1.0;
+ float useNormalTexture = -1.0;
+ float specularShininess = 1.0;
+ RenderMaterial& renderMaterial = m_materialInstance->getMaterial();
+ std::string mName = renderMaterial.getMaterialName();
+ if (mName != "")
+ {
+ float r, g, b, a;
+ std::string texName;
+
+ renderMaterial.getDiffuseColor(r, g, b, a);
+ diffuseColor = DirectX::XMFLOAT4(r, g, b, a);
+ renderMaterial.getSpecularColor(r, g, b, a);
+ specularColor = DirectX::XMFLOAT4(r, g, b, a);
+
+ texName = renderMaterial.getTextureFileName();
+ if (texName != "" && !renderMaterial.isBadTexture())
+ {
+ useDiffuseTexture = 1.0;
+ }
+
+ texName = renderMaterial.getTextureFileName(RenderMaterial::TT_Specular);
+ if (texName != "" && !renderMaterial.isBadTexture(RenderMaterial::TT_Specular))
+ {
+ useSpecularTexture = 1.0;
+ }
+
+ texName = renderMaterial.getTextureFileName(RenderMaterial::TT_Normal);
+ if (texName != "" && !renderMaterial.isBadTexture(RenderMaterial::TT_Normal))
+ {
+ useNormalTexture = 1.0;
+ }
+
+ specularShininess = renderMaterial.getSpecularShininess();
+ }
+
+ float selected = -1.0;
+ if (m_selected || m_highlight)
+ {
+ selected = 1.0;
+ }
// setup object CB
{
D3D11_MAPPED_SUBRESOURCE mappedResource;
renderer.m_context->Map(renderer.m_objectCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
Renderer::CBObject* objectBuffer = (Renderer::CBObject*)mappedResource.pData;
- objectBuffer->world = PxMat44ToXMMATRIX(getModelMatrix());
- objectBuffer->color = getColor();
-// Add By Lixu Begin
- objectBuffer->selected = m_selected ? 1.0 : -1.0;
-// Add By Lixu End
+ objectBuffer->worldMatrix = PxMat44ToXMMATRIX(getModelMatrix());
+ objectBuffer->diffuseColor = diffuseColor;
+ objectBuffer->specularColor = specularColor;
+ objectBuffer->useDiffuseTexture = useDiffuseTexture;
+ objectBuffer->useSpecularTexture = useSpecularTexture;
+ objectBuffer->useNormalTexture = useNormalTexture;
+ objectBuffer->specularShininess = specularShininess;
+ objectBuffer->selected = selected;
renderer.m_context->Unmap(renderer.m_objectCB, 0);
}
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.h
index 9e38e4f..2d2e37b 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef RENDERABLE_H
#define RENDERABLE_H
@@ -105,6 +123,26 @@ public:
{
m_mesh.setScale(scale, replace);
}
+
+ void setDepthTest(bool depthTest)
+ {
+ m_depthTest = depthTest;
+ }
+
+ bool isDepthTest() const
+ {
+ return m_depthTest;
+ }
+
+ void setHighlight(bool highlight)
+ {
+ m_highlight = highlight;
+ }
+
+ bool isHighlight() const
+ {
+ return m_highlight;
+ }
// Add By Lixu End
bool isTransparent() const
@@ -145,6 +183,8 @@ private:
bool m_hidden;
// Add By Lixu Begin
bool m_selected;
+ bool m_depthTest;
+ bool m_highlight;
// Add By Lixu End
};
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.cpp
index 49b1669..9fe5038 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "Renderer.h"
#include "RenderUtils.h"
@@ -16,6 +34,10 @@
#include "PxRenderBuffer.h"
#include <set>
+#include "SimpleScene.h"
+#include "GlobalSettings.h"
+#include "Light.h"
+#include "AppMainWindow.h"
const float CAMERA_CLIP_NEAR = 1.0f;
@@ -36,6 +58,7 @@ Renderer::Renderer()
, m_RSState(nullptr)
, m_opaqueRenderDSState(nullptr)
, m_transparencyRenderDSState(nullptr)
+, m_opaqueRenderNoDepthDSState(nullptr)
, m_DSTexture(nullptr)
, m_DSView(nullptr)
, m_DSTextureSRV(nullptr)
@@ -152,6 +175,18 @@ HRESULT Renderer::DeviceCreated(ID3D11Device* device)
V(device->CreateDepthStencilState(&desc, &m_transparencyRenderDSState));
}
+ // Opaque Render Depth-Stencil state Without Depth Test
+ {
+ D3D11_DEPTH_STENCIL_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.StencilEnable = FALSE;
+ desc.DepthEnable = FALSE;
+ desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
+
+ V(device->CreateDepthStencilState(&desc, &m_opaqueRenderNoDepthDSState));
+ }
+
// Linear sampler
{
D3D11_SAMPLER_DESC desc;
@@ -210,6 +245,7 @@ void Renderer::DeviceDestroyed()
SAFE_RELEASE(m_RSState);
SAFE_RELEASE(m_opaqueRenderDSState);
SAFE_RELEASE(m_transparencyRenderDSState);
+ SAFE_RELEASE(m_opaqueRenderNoDepthDSState);
SAFE_RELEASE(m_pointSampler);
SAFE_RELEASE(m_linearSampler);
SAFE_RELEASE(m_debugPrimitiveVB);
@@ -226,12 +262,10 @@ void Renderer::DeviceDestroyed()
void Renderer::onInitialize()
{
// search paths
- m_resourceManager.addSearchDir("..\\..\\samples\\resources");
- m_resourceManager.addSearchDir("..\\..\\..\\samples\\resources");
- for (const std::string& d : getManager()->getConfig().additionalResourcesDir)
- {
- m_resourceManager.addSearchDir(d.c_str());
- }
+ m_resourceManager.addSearchDir("..\\resources");
+ m_resourceManager.addSearchDir("..\\..\\..\\..\\bin\\resources");
+ //m_resourceManager.addSearchDir("..\\..\\samples\\resources");
+ //m_resourceManager.addSearchDir("..\\..\\..\\samples\\resources");
// debug primitive render material and input layout
{
@@ -257,7 +291,8 @@ void Renderer::BackBufferResized(ID3D11Device* /*device*/, const DXGI_SURFACE_DE
m_screenWidth = sd->Width;
m_screenHeight = sd->Height;
float fAspectRatio = m_screenWidth / m_screenHeight;
- m_camera.SetProjParams(DirectX::XM_PIDIV4, fAspectRatio, CAMERA_CLIP_NEAR, CAMERA_CLIP_FAR);
+ float fov = (GlobalSettings::Inst().m_fovAngle / 360.0f) * 3.141592653589793;
+ m_camera.SetProjParams(fov, fAspectRatio, CAMERA_CLIP_NEAR, CAMERA_CLIP_FAR);
SAFE_RELEASE(m_DSTexture);
SAFE_RELEASE(m_DSView);
@@ -329,13 +364,12 @@ void Renderer::Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11
m_context = ctx;
- ctx->ClearRenderTargetView(pRTV, CLEAR_SCENE_COLOR);
ctx->ClearDepthStencilView(m_DSView, D3D11_CLEAR_DEPTH, 1.0, 0);
ctx->RSSetViewports(1, &m_viewport);
// needed matrices
- DirectX::XMMATRIX viewMatrix = m_camera.GetViewMatrix();
- DirectX::XMMATRIX projMatrix = m_camera.GetProjMatrix();
+ DirectX::XMMATRIX viewMatrix = SimpleScene::Inst()->GetViewMatrix();
+ DirectX::XMMATRIX projMatrix = SimpleScene::Inst()->GetProjMatrix();
DirectX::XMMATRIX projMatrixInv = DirectX::XMMatrixInverse(NULL, projMatrix);
DirectX::XMMATRIX viewProjMatrix = viewMatrix * projMatrix;
@@ -346,7 +380,7 @@ void Renderer::Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11
CBCamera* cameraBuffer = (CBCamera*)mappedResource.pData;
cameraBuffer->viewProjection = viewProjMatrix;
cameraBuffer->projectionInv = projMatrixInv;
- DirectX::XMStoreFloat3(&(cameraBuffer->viewPos), m_camera.GetEyePt());
+ DirectX::XMStoreFloat3(&(cameraBuffer->viewPos), SimpleScene::Inst()->GetEyePt());
ctx->Unmap(m_cameraCB, 0);
}
@@ -355,6 +389,7 @@ void Renderer::Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11
D3D11_MAPPED_SUBRESOURCE mappedResource;
ctx->Map(m_worldCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
CBWorld* worldBuffer = (CBWorld*)mappedResource.pData;
+ Light::FillLightShaderParam(m_worldCBData.lightParam);
memcpy(worldBuffer, &m_worldCBData, sizeof(m_worldCBData));
//worldBuffer->ambientColor = m_CBWorldData.ambientColor;
//worldBuffer->pointLightPos = m_CBWorldData.pointLightPos;
@@ -388,12 +423,28 @@ void Renderer::Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11
}
}
- // render shadow map
- m_shadow.renderShadowMaps(this);
+ m_shadow.clearBuffer();
+
+ std::vector<Light>& lights = Light::GetDefaultLights();
+ for (int l = 0; l < 3; l++)
+ {
+ if (!lights[l].m_useShadows)
+ {
+ continue;
+ }
+
+ atcore_float3 eye = lights[l].m_lightCamera._eye;
+ eye.x = -eye.x;
+ atcore_float3 at = lights[l].m_lightCamera._at;
+ at.x = -at.x;
- // render shadow buffer
- ctx->OMSetRenderTargets(0, nullptr, nullptr);
- m_shadow.renderShadowBuffer(m_DSTextureSRV, nullptr);
+ ctx->OMSetRenderTargets(0, nullptr, m_DSView);
+ m_shadow.renderShadowMaps(this, eye, at);
+ ctx->OMSetRenderTargets(0, nullptr, nullptr);
+ m_shadow.renderShadowBuffer(m_DSTextureSRV, nullptr);
+ }
+
+ m_shadow.finalizeBuffer();
}
// Opaque render
@@ -413,20 +464,38 @@ void Renderer::Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11
CBCamera* cameraBuffer = (CBCamera*)mappedResource.pData;
cameraBuffer->viewProjection = viewProjMatrix;
cameraBuffer->projectionInv = projMatrixInv;
- DirectX::XMStoreFloat3(&(cameraBuffer->viewPos), m_camera.GetEyePt());
+ DirectX::XMStoreFloat3(&(cameraBuffer->viewPos), SimpleScene::Inst()->GetEyePt());
ctx->Unmap(m_cameraCB, 0);
}
+ std::vector<Renderable*> renderablesWithoutDepthTest;
+
// Render opaque renderables
m_visibleOpaqueRenderablesCount = 0;
for (auto it = m_renderables.begin(); it != m_renderables.end(); it++)
{
if (!(*it)->isTransparent() && !(*it)->isHidden())
{
+ if (!(*it)->isDepthTest())
+ {
+ renderablesWithoutDepthTest.push_back(*it);
+ continue;
+ }
(*it)->render(*this);
m_visibleOpaqueRenderablesCount++;
}
}
+
+ if (renderablesWithoutDepthTest.size() > 0)
+ {
+ ctx->OMSetDepthStencilState(m_opaqueRenderNoDepthDSState, 0xFF);
+ std::vector<Renderable*>::iterator itR;
+ for (itR = renderablesWithoutDepthTest.begin(); itR != renderablesWithoutDepthTest.end(); itR++)
+ {
+ (*itR)->render(*this);
+ }
+ ctx->OMSetDepthStencilState(m_opaqueRenderDSState, 0xFF);
+ }
}
// modulate shadows
@@ -444,6 +513,10 @@ void Renderer::Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11
ctx->RSSetViewports(1, &m_viewport);
// render debug render buffers
+ if (!AppMainWindow::Inst().m_bGizmoWithDepthTest)
+ {
+ ctx->OMSetDepthStencilState(m_opaqueRenderNoDepthDSState, 0xFF);
+ }
while (m_queuedRenderBuffers.size() > 0)
{
render(m_queuedRenderBuffers.back());
@@ -496,6 +569,10 @@ LRESULT Renderer::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
}
+ UpdateCamera();
+
+ return 0;
+
// Camera events
return m_camera.HandleMessages(hWnd, uMsg, wParam, lParam);
}
@@ -600,7 +677,7 @@ void Renderer::renderDebugPrimitive(const Renderer::RenderDebugVertex *vertices,
m_context->Map(m_objectCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
CBObject* objectBuffer = (CBObject*)mappedResource.pData;
- objectBuffer->world = PxMat44ToXMMATRIX(PxMat44(PxIdentity));
+ objectBuffer->worldMatrix = PxMat44ToXMMATRIX(PxMat44(PxIdentity));
m_context->Unmap(m_objectCB, 0);
@@ -733,4 +810,13 @@ void Renderer::drawUI()
ImGui::TreePop();
}
+}
+
+void Renderer::UpdateCamera()
+{
+ Camera* pCamera = SimpleScene::Inst()->m_pCamera;
+ DirectX::XMVECTORF32 eyePt = { pCamera->_eye.x, pCamera->_eye.y, pCamera->_eye.z, 0 };
+ DirectX::XMVECTORF32 lookAtPt = { pCamera->_at.x, pCamera->_at.y, pCamera->_at.z, 0 };
+ m_camera.SetViewParams(eyePt, lookAtPt);
+ m_camera.SetProjParams(pCamera->_fov, pCamera->_aspectRatio, pCamera->_znear, pCamera->_zfar);
} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.h
index 58662a6..6981e15 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef RENDERER_H
#define RENDERER_H
@@ -23,6 +41,7 @@
#include "RendererShadow.h"
#include "RendererHBAO.h"
#include <unordered_set>
+#include "LightShaderParam.h"
class CFirstPersonCamera;
class PhysXPrimitive;
@@ -95,7 +114,12 @@ class Renderer : public ISampleController
m_queuedRenderBuffers.push_back(buffer);
}
- ResourceManager& getResourceManager()
+ void clearQueue()
+ {
+ m_queuedRenderBuffers.clear();
+ }
+
+ ResourceManager& getResourceManager()
{
return m_resourceManager;
}
@@ -120,7 +144,7 @@ class Renderer : public ISampleController
// for internal usage (used by RenderShadows)
void renderDepthOnly(DirectX::XMMATRIX* viewProjectionSubstitute);
-
+ void UpdateCamera();
protected:
//////// controller callbacks ////////
@@ -174,14 +198,18 @@ class Renderer : public ISampleController
float specularPower;
DirectX::XMFLOAT3 dirLightColor;
float specularIntensity; // TODO: actually it's per object property
+ LightShaderParam lightParam;
};
struct CBObject
{
- DirectX::XMMATRIX world;
- DirectX::XMFLOAT4 color;
-// Add By Lixu Begin
+ DirectX::XMMATRIX worldMatrix;
+ DirectX::XMFLOAT4 diffuseColor;
+ DirectX::XMFLOAT4 specularColor;
+ float useDiffuseTexture;
+ float useSpecularTexture;
+ float useNormalTexture;
+ float specularShininess;
float selected;
-// Add By Lixu End
};
@@ -210,6 +238,7 @@ class Renderer : public ISampleController
ID3D11RasterizerState* m_RSState;
ID3D11DepthStencilState* m_opaqueRenderDSState;
ID3D11DepthStencilState* m_transparencyRenderDSState;
+ ID3D11DepthStencilState* m_opaqueRenderNoDepthDSState;
// DX11 samplers
ID3D11SamplerState* m_pointSampler;
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.cpp
index 5e20a49..c674b2b 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.cpp
@@ -1,12 +1,29 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
#include "RendererHBAO.h"
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.h
index 2478628..3237ddf 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef RENDERER_HBAO_H
#define RENDERER_HBAO_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.cpp
index 28a79e5..c26358b 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.cpp
@@ -1,12 +1,29 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
#include "RendererShadow.h"
@@ -16,7 +33,7 @@
#include "DXUTCamera.h"
#include "Renderer.h"
#include "UIHelpers.h"
-
+#include "SimpleScene.h"
#define CASCADES 1
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -168,7 +185,10 @@ void RendererShadow::changeShadowSettings(UINT Width, UINT Height, UINT uSampleC
void RendererShadow::reloadBuffers()
{
{
- m_shadowLibContext->RemoveMap(&m_shadowMapHandle);
+ if(m_shadowMapHandle != nullptr)
+ {
+ m_shadowLibContext->RemoveMap(&m_shadowMapHandle);
+ }
if (m_SMDesc.eMapType == GFSDK_ShadowLib_MapType_Texture &&
m_SMDesc.eViewType == GFSDK_ShadowLib_ViewType_Single &&
@@ -192,7 +212,10 @@ void RendererShadow::reloadBuffers()
m_shadowLibContext->DevModeCreateTexture2D(&m_downsampledShadowMap);
}
- m_shadowLibContext->RemoveBuffer(&m_shadowBufferHandle);
+ if (m_shadowBufferHandle != nullptr)
+ {
+ m_shadowLibContext->RemoveBuffer(&m_shadowBufferHandle);
+ }
m_shadowLibContext->AddBuffer(&m_SBDesc, &m_shadowBufferHandle);
}
@@ -220,7 +243,7 @@ static void ShadowMapRenderFunction(void* pParams, gfsdk_float4x4* pViewProj)
pRP->renderer->renderDepthOnly(&viewProjection);
}
-void RendererShadow::renderShadowMaps(Renderer* renderer)
+void RendererShadow::renderShadowMaps(Renderer* renderer, atcore_float3& lightPos, atcore_float3& lightLookAt)
{
// select technique
GFSDK_ShadowLib_TechniqueType technique = m_SBRenderParams.eTechniqueType;
@@ -240,8 +263,8 @@ void RendererShadow::renderShadowMaps(Renderer* renderer)
m_SMRenderParams.v3WorldSpaceBBox[1] = m_worldSpaceBBox1;
m_SMRenderParams.LightDesc.eLightType = GFSDK_ShadowLib_LightType_Directional;
- memcpy(&m_SMRenderParams.LightDesc.v3LightPos, &m_lightPos.x, sizeof(gfsdk_float3));
- memcpy(&m_SMRenderParams.LightDesc.v3LightLookAt, &m_lightLookAt.x, sizeof(gfsdk_float3));
+ memcpy(&m_SMRenderParams.LightDesc.v3LightPos, &lightPos, sizeof(gfsdk_float3));
+ memcpy(&m_SMRenderParams.LightDesc.v3LightLookAt, &lightLookAt, sizeof(gfsdk_float3));
m_SMRenderParams.LightDesc.fLightSize = m_lightSize;
m_SMRenderParams.LightDesc.bLightFalloff = false;
@@ -268,13 +291,9 @@ void RendererShadow::renderShadowBuffer(ID3D11ShaderResourceView* pDepthStencilS
m_SBRenderParams.PCSSPenumbraParams = m_PCSSParams;
m_SBRenderParams.fSoftShadowTestScale = m_softShadowTestScale;
- m_shadowLibContext->ClearBuffer(m_shadowBufferHandle);
-
m_SBRenderParams.DepthBufferDesc.DepthStencilSRV.pSRV = pDepthStencilSRV;
m_shadowLibContext->RenderBuffer(m_shadowMapHandle, m_shadowBufferHandle, &m_SBRenderParams);
-
- m_shadowLibContext->FinalizeBuffer(m_shadowBufferHandle, &m_shadowBufferSRV);
}
@@ -414,4 +433,14 @@ void RendererShadow::drawUI()
ImGui::DragFloat("PCSS: fBlockerSearchDitherPercent", &(m_PCSSParams.fBlockerSearchDitherPercent), 0.001f, 0.0f, 100.0f);
ImGui::DragFloat("PCSS: fFilterDitherPercent", &(m_PCSSParams.fFilterDitherPercent), 0.001f, 0.0f, 100.0f);
}
+}
+
+void RendererShadow::clearBuffer()
+{
+ m_shadowLibContext->ClearBuffer(m_shadowBufferHandle);
+}
+
+void RendererShadow::finalizeBuffer()
+{
+ m_shadowLibContext->FinalizeBuffer(m_shadowBufferHandle, &m_shadowBufferSRV);
} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.h
index cc81c67..e16af1f 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef RENDERER_SHADOW_H
#define RENDERER_SHADOW_H
@@ -31,7 +49,7 @@ public:
void setScreenResolution(float FovyRad, UINT Width, UINT Height, UINT uSampleCount, ID3D11DepthStencilView* pReadOnlyDSV);
void changeShadowSettings(UINT Width, UINT Height, UINT uSampleCount, ID3D11DepthStencilView* pReadOnlyDSV);
- void renderShadowMaps(Renderer* renderer);
+ void renderShadowMaps(Renderer* renderer, atcore_float3& lightPos, atcore_float3& lightLookAt);
void renderShadowBuffer(ID3D11ShaderResourceView* pDepthStencilSRV, ID3D11ShaderResourceView* pResolvedDepthStencilSRV);
void modulateShadowBuffer(ID3D11RenderTargetView* pOutputRTV);
void displayShadowMaps(ID3D11RenderTargetView* pOutputRTV, UINT Width, UINT Height);
@@ -42,6 +60,9 @@ public:
void drawUI();
+ void clearBuffer();
+ void finalizeBuffer();
+
private:
void reloadBuffers();
void ReleaseResources();
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.cpp
index a051f96..6e4cc50 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "ResourceManager.h"
#include "PxAssert.h"
@@ -50,6 +68,19 @@ const TextureResource* ResourceManager::requestTexture(const char* name)
return resource != nullptr ? static_cast<const TextureResource*>(resource) : nullptr;
}
+void ResourceManager::releaseTexture(const char* name)
+{
+ std::pair<ResourceType, std::string> key(eTEXTURE, name);
+ auto val = m_loadedResources.find(key);
+ if (val != m_loadedResources.end())
+ {
+ Resource* pResource = val->second;
+ delete pResource;
+ pResource = nullptr;
+ m_loadedResources.erase(key);
+ }
+}
+
const Resource* ResourceManager::requestResource(ResourceType type, const char* name)
{
// search in loaded
@@ -57,17 +88,17 @@ const Resource* ResourceManager::requestResource(ResourceType type, const char*
auto val = m_loadedResources.find(key);
if (val != m_loadedResources.end())
{
- return val->second.get();
+ return val->second;
}
- std::shared_ptr<Resource> resource;
+ Resource* resource = nullptr;
if (type == eSHADER_FILE)
{
char path[PATH_MAX_LEN];
const char* exts[] = { "hlsl" };
if (findFile(name, std::vector<const char*>(exts, exts + sizeof(exts) / sizeof(exts[0])), path))
{
- resource = std::shared_ptr<Resource>(new ShaderFileResource(path));
+ resource = new ShaderFileResource(path);
}
else
{
@@ -78,33 +109,38 @@ const Resource* ResourceManager::requestResource(ResourceType type, const char*
{
char path[PATH_MAX_LEN];
// Add By Lixu Begin
- const char* exts[] = { "dds", "tga", "jpg", "png" };
+ const char* exts[] = { "dds", "tga", "jpg", "png", "bmp" };
// Add By Lixu End
if (findFile(name, std::vector<const char*>(exts, exts + sizeof(exts) / sizeof(exts[0])), path))
{
- std::shared_ptr<TextureResource> textureResource(new TextureResource());
+ TextureResource* textureResource(new TextureResource());
WCHAR wPath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, path, -1, wPath, MAX_PATH);
wPath[MAX_PATH - 1] = 0;
const char* ext = strext(path);
- if (::strcmp(ext, "dds") == 0)
+ if (::stricmp(ext, "dds") == 0)
{
V(DirectX::LoadFromDDSFile(wPath, DirectX::DDS_FLAGS_NONE, &textureResource->metaData,
textureResource->image));
}
- else if (::strcmp(ext, "tga") == 0)
+ else if (::stricmp(ext, "tga") == 0)
{
V(DirectX::LoadFromTGAFile(wPath, &textureResource->metaData,
textureResource->image));
}
// Add By Lixu Begin
- else if (::strcmp(ext, "jpg") == 0)
+ else if (::stricmp(ext, "jpg") == 0)
{
V(DirectX::LoadFromWICFile(wPath, DirectX::TEX_FILTER_DEFAULT | DirectX::WIC_FLAGS_ALL_FRAMES, &textureResource->metaData,
textureResource->image));
}
- else if (::strcmp(ext, "png") == 0)
+ else if (::stricmp(ext, "png") == 0)
+ {
+ V(DirectX::LoadFromWICFile(wPath, DirectX::TEX_FILTER_DEFAULT | DirectX::WIC_FLAGS_ALL_FRAMES, &textureResource->metaData,
+ textureResource->image));
+ }
+ else if (::stricmp(ext, "bmp") == 0)
{
V(DirectX::LoadFromWICFile(wPath, DirectX::TEX_FILTER_DEFAULT | DirectX::WIC_FLAGS_ALL_FRAMES, &textureResource->metaData,
textureResource->image));
@@ -118,10 +154,10 @@ const Resource* ResourceManager::requestResource(ResourceType type, const char*
}
}
- if (resource.get())
+ if (resource)
{
m_loadedResources.emplace(key, resource);
- return resource.get();
+ return resource;
}
else
{
@@ -195,6 +231,15 @@ bool ResourceManager::findFileInDir(std::string fileNameFull, const char* path,
bool ResourceManager::findFile(std::string fileName, const std::vector<const char*>& exts, char* foundPath)
{
std::string fileNameOnly = fileName;
+
+ std::string::size_type pos = 0;
+ pos = fileNameOnly.find("\\", pos);
+ while ((pos != std::string::npos))
+ {
+ fileNameOnly.replace(pos, 1, "/");
+ pos = fileNameOnly.find("\\", (pos + 1));
+ }
+
size_t ind = fileNameOnly.find_last_of('/');
if (ind > 0)
fileNameOnly = fileNameOnly.substr(ind + 1);
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.h
index 0378438..697b16b 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef RESOURCE_MANAGER_H
#define RESOURCE_MANAGER_H
@@ -62,6 +80,8 @@ public:
const TextureResource* requestTexture(const char* name);
+ void releaseTexture(const char* name);
+
bool findFile(std::string fileName, std::string& foundPath);
bool findFile(std::string fileName, const std::vector<const char*>& exts, char* foundPath);
@@ -92,6 +112,6 @@ private:
//////// internal data ////////
std::vector<SearchDir> m_searchDirs;
- std::map<std::pair<ResourceType, std::string>, std::shared_ptr<Resource>> m_loadedResources;
+ std::map<std::pair<ResourceType, std::string>, Resource*> m_loadedResources;
};
#endif \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ShaderUtils.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ShaderUtils.h
index 778c811..da9caa0 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ShaderUtils.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ShaderUtils.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef SHADER_UTILS_H
#define SHADER_UTILS_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.cpp
index c575d6c..ff121d6 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.cpp
@@ -1,12 +1,29 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
#include "SkinnedRenderMesh.h"
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.h
index 2f690d8..f3643d8 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef SKINNED_RENDER_MESH_H
#define SKINNED_RENDER_MESH_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.cpp
index 00cf4df..b58f9f1 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.cpp
@@ -1,18 +1,37 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "SampleAssetListParser.h"
#include <PsFastXml.h>
#include "Sample.h"
#include "PxVec4.h"
#include "PxInputDataFromPxFileBuf.h"
+#include <bitset>
using namespace physx;
@@ -104,11 +123,6 @@ protected:
{
m_boxTemp.name = std::string(attr.getValue(i));
}
- else if (::strcmp(attr.getKey(i), "staticHeight") == 0)
- {
- std::string str = attr.getValue(i);
- sscanf(&str[0], "%f", &m_boxTemp.staticHeight);
- }
else if (::strcmp(attr.getKey(i), "jointAllBonds") == 0)
{
std::string str = attr.getValue(i);
@@ -122,6 +136,12 @@ protected:
std::string str = attr.getValue(i);
sscanf(&str[0], "%f %f %f", &m_boxTemp.extents.x, &m_boxTemp.extents.y, &m_boxTemp.extents.z);
}
+ else if (::strcmp(attr.getKey(i), "bondFlagsMask") == 0)
+ {
+ std::string str = attr.getValue(i);
+ std::bitset<8> bondFlags(str);
+ m_boxTemp.bondFlags = static_cast<uint32_t>(bondFlags.to_ulong());
+ }
}
if (m_boxTemp.id.empty())
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.h
index b6303ec..5d22833 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef SAMPLEASSETLISTPARSER_H
#define SAMPLEASSETLISTPARSER_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.cpp
index ec000b3..05681d0 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "SceneController.h"
#include "RenderUtils.h"
@@ -35,8 +53,14 @@
#include <imgui.h>
#include <sstream>
#include <tuple>
+#include <map>
-
+#include "BlastSceneTree.h"
+#include "SimpleScene.h"
+#include "SampleManager.h"
+// Add By Lixu Begin
+#include "ProjectParams.h"
+// Add By Lixu End
//////// Simple hash function ////////
static NvBlastID generateIDFromString(const char* str)
@@ -78,7 +102,7 @@ public:
virtual void load() = 0;
virtual void unload() = 0;
virtual bool isLoaded() const = 0;
- virtual void spawn(PxVec3 shift) = 0;
+ virtual void spawn(PxTransform transform) = 0;
virtual ImVec4 getUIColor() const
{
@@ -94,6 +118,8 @@ protected:
class SceneActor
{
public:
+ SceneActor() : removeOnReload(false) {}
+
virtual ~SceneActor() {}
virtual const char* getName() const = 0;
virtual const char* getSubname(int subindex) const { return nullptr; }
@@ -104,6 +130,8 @@ public:
virtual PxVec3 getSpawnShift() const { return PxVec3(PxZero); }
virtual void reload() {}
virtual void removeSubactor(int subindex) {}
+
+ bool removeOnReload;
};
@@ -116,7 +144,7 @@ public:
int subindex;
ActorIndex() { reset(); }
- ActorIndex(int i, int s) : index(i), subindex(s) {}
+ ActorIndex(int i, int s = -1) : index(i), subindex(s) {}
bool operator==(const ActorIndex& other) const
{
@@ -152,10 +180,27 @@ public:
{
m_assets.push_back(asset);
asset->initialize(this);
- m_assetsByID[asset->getID()] = asset;
+ std::string id = asset->getID();
+ m_assetsByID[id] = asset;
}
// Add By Lixu Begin
+ void removeAsset(SceneAsset* asset)
+ {
+ std::string id = asset->getID();
+ m_assetsByID.erase(m_assetsByID.find(id));
+
+ std::vector<SceneAsset*>::iterator it;
+ for (it = m_assets.begin(); it != m_assets.end(); it++)
+ {
+ if (*it == asset)
+ {
+ m_assets.erase(it);
+ break;
+ }
+ }
+ }
+
std::vector<SceneAsset*>& getAssets()
{
return m_assets;
@@ -316,7 +361,7 @@ public:
return;
}
- PxVec3 shift(PxZero);
+ PxTransform transform(PxIdentity);
// Add By Lixu Begin
/*
for (SceneActor* a : m_sceneActors)
@@ -327,7 +372,7 @@ public:
// Add By Lixu End
SceneAsset* asset = m_assets[m_lastSpawnedAsset];
- asset->spawn(shift);
+ asset->spawn(transform);
}
void addSceneActor(SceneActor* actor)
@@ -339,6 +384,21 @@ public:
}
}
+// Add By Lixu Begin
+ void removeSceneActor(SceneActor* actor)
+ {
+ std::vector<SceneActor*>::iterator itActors;
+ for (itActors = m_sceneActors.begin(); itActors != m_sceneActors.end(); itActors++)
+ {
+ if (*itActors == actor)
+ {
+ m_sceneActors.erase(itActors);
+ break;
+ }
+ }
+ }
+// Add By Lixu End
+
void removeSceneActor(ActorIndex actorIndex)
{
SceneActor* actor = getActorByIndex(actorIndex.index);
@@ -411,6 +471,7 @@ public:
m_assets[i]->unload();
}
+ m_assets.clear();
const int currentAsset = m_lastSpawnedAsset;
m_lastSpawnedAsset = -1;
return currentAsset;
@@ -418,10 +479,28 @@ public:
void reloadAllActors()
{
- for (SceneActor* a : m_sceneActors)
+ SceneActor* selectedActor = getSelectedActor();
+ ActorIndex selectIndex(0);
+
+ for (uint32_t i = 0; i < m_sceneActors.size(); i++)
{
- a->reload();
+ if (m_sceneActors[i]->removeOnReload)
+ {
+ removeSceneActor(ActorIndex(i));
+ i--;
+ }
}
+
+ for (uint32_t i = 0; i < m_sceneActors.size(); i++)
+ {
+ if (m_sceneActors[i] == selectedActor)
+ {
+ selectIndex.index = i;
+ }
+ m_sceneActors[i]->reload();
+ }
+
+ setSelectedActor(selectIndex.index, selectIndex.subindex);
}
void registerTkAsset(const TkAsset& tkAsset, SingleSceneAsset* asset)
@@ -496,18 +575,19 @@ class SingleSceneActor;
class SingleSceneAsset : public SceneAsset
{
public:
- SingleSceneAsset() : m_asset(nullptr) {}
+ SingleSceneAsset(BlastAsset* pBlastAsset) : m_asset(pBlastAsset) {}
virtual ~SingleSceneAsset() { unload(); }
- virtual void spawn(PxVec3 shift) override;
+ virtual void spawn(PxTransform transform) override;
virtual void load() override
{
if (!m_asset)
{
m_asset = createAsset();
- m_scene->registerTkAsset(m_asset->getPxAsset()->getTkAsset(), this);
}
+
+ m_scene->registerTkAsset(m_asset->getPxAsset()->getTkAsset(), this);
}
virtual void unload() override
@@ -543,7 +623,7 @@ private:
class ModelSceneAsset : public SingleSceneAsset
{
public:
- ModelSceneAsset() {}
+ ModelSceneAsset(BlastAsset* pBlastAsset) : SingleSceneAsset(pBlastAsset) {}
virtual const char* getID() const override{ return desc.id.c_str(); }
virtual const char* getName() const override { return desc.name.c_str(); }
@@ -557,10 +637,12 @@ public:
class SimpleModelSceneAsset : public ModelSceneAsset
{
public:
+ SimpleModelSceneAsset(BlastAsset* pBlastAsset) : ModelSceneAsset(pBlastAsset) {}
+
virtual BlastAsset* createAsset()
{
return new BlastAssetModelSimple(m_scene->getBlastController().getTkFramework(), m_scene->getPhysXController().getPhysics(),
- m_scene->getPhysXController().getCooking(), m_scene->getRenderer(), desc.file.c_str());
+ m_scene->getPhysXController().getCooking(), *m_scene->getBlastController().getExtSerialization(), m_scene->getRenderer(), desc.file.c_str());
}
virtual ImVec4 getUIColor() const override
@@ -573,10 +655,12 @@ public:
class SkinnedModelSceneAsset : public ModelSceneAsset
{
public:
+ SkinnedModelSceneAsset(BlastAsset* pBlastAsset) : ModelSceneAsset(pBlastAsset) {}
+
virtual BlastAsset* createAsset()
{
return new BlastAssetModelSkinned(m_scene->getBlastController().getTkFramework(), m_scene->getPhysXController().getPhysics(),
- m_scene->getPhysXController().getCooking(), m_scene->getRenderer(), desc.file.c_str());
+ m_scene->getPhysXController().getCooking(), *m_scene->getBlastController().getExtSerialization(), m_scene->getRenderer(), desc.file.c_str());
}
virtual ImVec4 getUIColor() const override
@@ -589,8 +673,10 @@ public:
class BoxesSceneAsset : public SingleSceneAsset
{
public:
- BoxesSceneAsset(const AssetList::BoxAsset& d) : desc(d)
+ BoxesSceneAsset(const AssetList::BoxAsset& d) : SingleSceneAsset(nullptr)
{
+ desc = d;
+
for (uint32_t lv = 0; lv < desc.levels.size(); ++lv)
{
const AssetList::BoxAsset::Level& level = desc.levels[lv];
@@ -600,6 +686,7 @@ public:
assetDesc.generatorSettings.extents = GeneratorAsset::Vec3(desc.extents.x, desc.extents.y, desc.extents.z);
assetDesc.staticHeight = desc.staticHeight;
assetDesc.jointAllBonds = desc.jointAllBonds;
+ assetDesc.generatorSettings.bondFlags = (CubeAssetGenerator::BondFlags)desc.bondFlags;
}
virtual ImVec4 getUIColor() const override
@@ -642,7 +729,7 @@ public:
virtual const char* getID() const override { return m_desc.id.c_str(); }
virtual const char* getName() const override { return m_desc.name.c_str(); }
- virtual void spawn(PxVec3 shift) override;
+ virtual void spawn(PxTransform transform) override;
virtual void load() override
{
@@ -726,10 +813,10 @@ private:
class SingleSceneActor : public SceneActor
{
public:
- SingleSceneActor(Scene& scene, SingleSceneAsset* asset, PxVec3 shift)
+ SingleSceneActor(Scene& scene, SingleSceneAsset* asset, PxTransform transform)
: m_scene(scene)
, m_asset(asset)
- , m_shift(shift)
+ , m_transform(transform)
{
m_index = m_asset->spawnCount++;
spawn();
@@ -740,6 +827,13 @@ public:
remove();
}
+// Add By Lixu Begin
+ SingleSceneAsset* getSceneAsset()
+ {
+ return m_asset;
+ }
+// Add By Lixu End
+
virtual const char* getName() const override
{
return m_name.c_str();
@@ -772,12 +866,26 @@ public:
virtual void reload() override
{
+ BlastFamilyPtr oldFamily = m_actor;
auto settings = m_actor->getSettings();
+
+ RenderMaterial* pRenderMaterial[2];
+ m_actor->getMaterial(&pRenderMaterial[0], true);
+ m_actor->getMaterial(&pRenderMaterial[1], false);
+
+ m_transform = settings.transform;
remove();
spawn();
+
+ m_actor->setMaterial(pRenderMaterial[0], true);
+ m_actor->setMaterial(pRenderMaterial[1], false);
+
m_actor->setSettings(settings);
+ SampleManager::ins()->updateFamily(oldFamily, m_actor);
}
+ BlastFamily* getFamily() { return m_actor; }
+
private:
void remove()
{
@@ -793,8 +901,7 @@ private:
str << " (" << m_index << ")";
m_name = str.str();
- PxTransform pose = m_asset->getInitialTransform();
- pose.p += m_shift;
+ PxTransform pose = m_transform;
BlastAsset::ActorDesc actorDesc = {
actorDesc.id = generateIDFromString(m_name.c_str()),
@@ -803,12 +910,29 @@ private:
};
m_actor = m_scene.getBlastController().spawnFamily(m_asset->getAsset(), actorDesc);
+ // Add By Lixu Begin
+ BlastFamily::Settings settings = m_actor->getSettings();
+ std::map<BlastAsset*, AssetList::ModelAsset>& assetDescMap = SampleManager::ins()->getAssetDescMap();
+ AssetList::ModelAsset& assetDesc = assetDescMap[m_asset->getAsset()];
+ BPPAsset* bppAsset = BlastProject::ins().getAsset(assetDesc.name.c_str());
+ if (nullptr != bppAsset)
+ {
+ BPPStressSolver& stressSolver = bppAsset->stressSolver;
+ ExtStressSolverSettings & stressSolverSettings = settings.stressSolverSettings;
+ stressSolverSettings.hardness = stressSolver.hardness;
+ stressSolverSettings.stressLinearFactor = stressSolver.linearFactor;
+ stressSolverSettings.stressAngularFactor = stressSolver.angularFactor;
+ stressSolverSettings.bondIterationsPerFrame = stressSolver.bondIterationsPerFrame;
+ stressSolverSettings.graphReductionLevel = stressSolver.graphReductionLevel;
+ m_actor->setSettings(settings);
+ }
+ // Add By Lixu End
}
Scene& m_scene;
BlastFamilyPtr m_actor;
SingleSceneAsset* m_asset;
- PxVec3 m_shift;
+ PxTransform m_transform;
uint32_t m_index;
std::string m_name;
};
@@ -816,10 +940,10 @@ private:
class CompositeSceneActor : public SceneActor
{
public:
- CompositeSceneActor(Scene& scene, CompositeSceneAsset* asset, PxVec3 shift)
+ CompositeSceneActor(Scene& scene, CompositeSceneAsset* asset, PxTransform transform)
: m_scene(scene)
, m_asset(asset)
- , m_shift(shift)
+ , m_transform(transform)
{
m_index = m_asset->spawnCount++;
spawn();
@@ -937,8 +1061,7 @@ private:
ExtPxManager& pxManager = m_scene.getBlastController().getExtPxManager();
for (uint32_t i = 0; i < actorCount; ++i)
{
- PxTransform pose = m_asset->getInitialTransform();
- pose.p += m_shift;
+ PxTransform pose = m_transform;
pose = assetDesc.assetRefs[i].transform.transform(pose);
BlastAsset::ActorDesc actorDesc = {
@@ -981,7 +1104,7 @@ private:
Scene& m_scene;
std::vector<Subactor> m_actors;
CompositeSceneAsset* m_asset;
- PxVec3 m_shift;
+ PxTransform m_transform;
uint32_t m_index;
std::string m_name;
};
@@ -1003,7 +1126,9 @@ public:
virtual const char* getName() const override
{
- return m_name;
+ // Add By Lixu Begin
+ return m_name.c_str();
+ // Add By Lixu End
}
virtual ImVec4 getUIColor() const override
@@ -1011,11 +1136,16 @@ public:
return ImColor(255, 100, 100, 255);
}
+ // Add By Lixu Begin
+ PhysXController::Actor* getActor() { return m_actor; }
+ // Add By Lixu End
private:
PhysXController& m_physXController;
PhysXController::Actor* m_actor;
- const char* m_name;
+ // Add By Lixu Begin
+ std::string m_name;
+ // Add By Lixu End
};
@@ -1024,19 +1154,19 @@ private:
// Assets Implementation
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void SingleSceneAsset::spawn(PxVec3 shift)
+void SingleSceneAsset::spawn(PxTransform transform)
{
load();
- SingleSceneActor* actor = new SingleSceneActor(*m_scene, this, shift);
+ SingleSceneActor* actor = new SingleSceneActor(*m_scene, this, transform);
m_scene->addSceneActor(actor);
}
-void CompositeSceneAsset::spawn(PxVec3 shift)
+void CompositeSceneAsset::spawn(PxTransform transform)
{
load();
if (isLoaded())
{
- CompositeSceneActor* actor = new CompositeSceneActor(*m_scene, this, shift);
+ CompositeSceneActor* actor = new CompositeSceneActor(*m_scene, this, transform);
m_scene->addSceneActor(actor);
}
}
@@ -1094,9 +1224,10 @@ protected:
// Controller
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-SceneController::SceneController() : m_cubeScale(1.0f)
+SceneController::SceneController() : m_cubeScale(1.0f), m_cubeThrowDownTime(-1.f)
{
m_scene = NULL;
+ BlastToSceneMap.clear();
}
SceneController::~SceneController()
@@ -1107,73 +1238,50 @@ void SceneController::onSampleStart()
{
// setup camera
CFirstPersonCamera* camera = &getRenderer().getCamera();
- DirectX::XMVECTORF32 lookAtPt = { 0, 10, 0, 0 };
- DirectX::XMVECTORF32 eyePt = { 0, 20, 60, 0 };
+ Camera* pCamera = SimpleScene::Inst()->m_pCamera;
+ DirectX::XMVECTORF32 eyePt = { pCamera->_eye.x, pCamera->_eye.y, pCamera->_eye.z, 0 };
+ DirectX::XMVECTORF32 lookAtPt = { pCamera->_at.x, pCamera->_at.y, pCamera->_at.z, 0 };
camera->SetViewParams(eyePt, lookAtPt);
- camera->SetRotateButtons(false, false, true, false);
+ camera->SetRotateButtons(false, false, false, false);
camera->SetEnablePositionMovement(true);
// setup scene
m_scene = new Scene(getRenderer(), getPhysXController(), getBlastController(), getCommonUIController());
- const SampleConfig& config = getManager()->getConfig();
-
- // add packman repo to search dirs
- bool packmanResourcesAdded = false;
- if (const char* packmanPath = std::getenv("PM_PACKAGES_ROOT"))
- {
- const char* RESOURCES_CONFIG_FILE = "resources.xml";
-
- std::string path;
- if (getRenderer().getResourceManager().findFile(RESOURCES_CONFIG_FILE, path))
- {
- physx::PsFileBuffer fileBuffer(path.c_str(), physx::general_PxIOStream2::PxFileBuf::OPEN_READ_ONLY);
- if (fileBuffer.isOpen())
- {
- PxInputDataFromPxFileBuf inputData(fileBuffer);
- PackmanConfigParser parser;
- physx::shdfnd::FastXml* xml = physx::shdfnd::createFastXml(&parser);
- xml->processXml(inputData, false);
- xml->release();
- for (auto& dep : parser.dependencies)
- {
- std::stringstream ss;
- ss << packmanPath << "\\" << dep.first << "\\" << dep.second;
- if (getRenderer().getResourceManager().addSearchDir(ss.str().c_str()))
- {
- packmanResourcesAdded = true;
- }
- }
- }
- }
- }
- if (!packmanResourcesAdded)
- {
- getManager()->getCommonUIController().addPopupMessage("Error", "BlastSampleResources package wasn't found. Consider running download_sample_resources.bat in root folder.", 5.0f);
- }
-
- // parse asset file
- AssetList assetList;
- if (!config.assetsFile.empty())
- {
- std::string path;
- if (getRenderer().getResourceManager().findFile(config.assetsFile, path))
- {
- parseAssetList(assetList, path);
- }
- }
-
- // add both asset file and asset list from config
- addAssets(config.additionalAssetList, packmanResourcesAdded);
- addAssets(assetList, packmanResourcesAdded);
-
-// Add By Lixu Begin
- int size = m_scene->getAssets().size();
- for (int i = 0; i < size; i++)
- {
- spawnAsset(i);
- }
-// Add By Lixu End
+ // commented by Jun Ma to prevent a crash. We do not need those demo resources. We only need shaders.
+ //// add packman repo to search dirs
+ //bool packmanResourcesAdded = false;
+ //if (const char* packmanPath = std::getenv("PM_PACKAGES_ROOT"))
+ //{
+ // const char* RESOURCES_CONFIG_FILE = "resources.xml";
+
+ // std::string path;
+ // if (getRenderer().getResourceManager().findFile(RESOURCES_CONFIG_FILE, path))
+ // {
+ // physx::PsFileBuffer fileBuffer(path.c_str(), physx::general_PxIOStream2::PxFileBuf::OPEN_READ_ONLY);
+ // if (fileBuffer.isOpen())
+ // {
+ // PxInputDataFromPxFileBuf inputData(fileBuffer);
+ // PackmanConfigParser parser;
+ // physx::shdfnd::FastXml* xml = physx::shdfnd::createFastXml(&parser);
+ // xml->processXml(inputData, false);
+ // xml->release();
+ // for (auto& dep : parser.dependencies)
+ // {
+ // std::stringstream ss;
+ // ss << packmanPath << "\\" << dep.first << "\\" << dep.second;
+ // if (getRenderer().getResourceManager().addSearchDir(ss.str().c_str()))
+ // {
+ // packmanResourcesAdded = true;
+ // }
+ // }
+ // }
+ // }
+ //}
+ //if (!packmanResourcesAdded)
+ //{
+ // getManager()->getCommonUIController().addPopupMessage("Error", "BlastSampleResources package wasn't found. Consider running download_sample_resources.bat in root folder.", 5.0f);
+ //}
}
void SceneController::addAssets(const AssetList& assetList, bool loadModels)
@@ -1185,11 +1293,11 @@ void SceneController::addAssets(const AssetList& assetList, bool loadModels)
ModelSceneAsset* asset;
if (!model.isSkinned)
{
- asset = new SimpleModelSceneAsset();
+ asset = new SimpleModelSceneAsset(nullptr);
}
else
{
- asset = new SkinnedModelSceneAsset();
+ asset = new SkinnedModelSceneAsset(nullptr);
}
asset->desc = model;
m_scene->addAsset(asset);
@@ -1208,6 +1316,141 @@ void SceneController::addAssets(const AssetList& assetList, bool loadModels)
}
}
+void SceneController::addBlastAsset(BlastAssetModelSimple* pBlastAsset, AssetList::ModelAsset modelAsset)
+{
+ // 1
+ ModelSceneAsset* asset = new SimpleModelSceneAsset(pBlastAsset);
+ asset->desc = modelAsset;
+ BlastToSceneMap[pBlastAsset] = asset;
+
+ // 2
+ m_scene->addAsset(asset);
+
+ // 3
+ asset->load();
+}
+
+void deleteSceneActors(Scene* scene, SceneAsset* asset)
+{
+ std::vector<SceneActor*> deleteActors;
+
+ std::vector<SceneActor*>& Actors = scene->getActors();
+ std::vector<SceneActor*>::iterator itActors;
+ for (itActors = Actors.begin(); itActors != Actors.end(); )
+ {
+ SingleSceneActor* pSceneActor = (SingleSceneActor*)*itActors;
+ SingleSceneAsset* pSingleSceneAsset = pSceneActor->getSceneAsset();
+ if (pSingleSceneAsset == asset)
+ {
+ deleteActors.push_back(pSceneActor);
+ itActors = Actors.erase(itActors);
+ }
+ else
+ {
+ itActors++;
+ }
+ }
+
+ for (itActors = deleteActors.begin(); itActors != deleteActors.end(); itActors++)
+ {
+ delete *itActors;
+ *itActors = nullptr;
+ }
+ deleteActors.clear();
+}
+
+void SceneController::removeBlastAsset(BlastAssetModelSimple* pBlastAsset)
+{
+ std::vector<SceneAsset*>& Assets = m_scene->getAssets();
+ std::vector<SceneAsset*>::iterator itAssets;
+ for (itAssets = Assets.begin(); itAssets != Assets.end(); itAssets++)
+ {
+ ModelSceneAsset* pSceneAsset = (ModelSceneAsset*)*itAssets;
+ BlastAsset* pAsset = pSceneAsset->getAsset();
+ if (pAsset == pBlastAsset)
+ {
+ deleteSceneActors(m_scene, pSceneAsset);
+
+ // 3
+ pSceneAsset->unload();
+
+ // 2
+ m_scene->removeAsset(pSceneAsset);
+
+ // 1
+ delete pSceneAsset;
+ std::map<BlastAsset*, ModelSceneAsset*>::iterator itBSM;
+ itBSM = BlastToSceneMap.find(pBlastAsset);
+ BlastToSceneMap.erase(itBSM);
+ break;
+ }
+ }
+}
+
+BlastFamily* SceneController::addBlastFamily(BlastAsset* pBlastAsset, physx::PxTransform transform)
+{
+ if (pBlastAsset == nullptr)
+ {
+ return nullptr;
+ }
+
+ std::map<BlastAsset*, ModelSceneAsset*>::iterator itBSM;
+ itBSM = BlastToSceneMap.find(pBlastAsset);
+ if (itBSM == BlastToSceneMap.end())
+ {
+ return nullptr;
+ }
+
+ ModelSceneAsset* asset = itBSM->second;
+ if (asset == nullptr)
+ {
+ return nullptr;
+ }
+
+ SingleSceneActor* actor = new SingleSceneActor(*m_scene, asset, transform);
+ m_scene->addSceneActor(actor);
+
+ BlastFamily* pBlastFamily = actor->getFamily();
+ if (pBlastFamily != nullptr)
+ {
+ pBlastFamily->updatePreSplit(0);
+ pBlastFamily->clearVisibleChangedChunks();
+ }
+ return pBlastFamily;
+}
+
+void SceneController::removeBlastFamily(BlastAsset* pBlastAsset, int nFamilyIndex)
+{
+ if (pBlastAsset == nullptr)
+ {
+ return;
+ }
+
+ std::map<BlastAsset*, ModelSceneAsset*>::iterator itBSM;
+ itBSM = BlastToSceneMap.find(pBlastAsset);
+ if (itBSM == BlastToSceneMap.end())
+ {
+ return;
+ }
+
+ ModelSceneAsset* asset = itBSM->second;
+ if (asset == nullptr)
+ {
+ return;
+ }
+
+ SceneActor* pSceneActor = m_scene->getActorByIndex(nFamilyIndex);
+ if (pSceneActor == nullptr)
+ {
+ return;
+ }
+
+ m_scene->removeSceneActor(pSceneActor);
+
+ delete pSceneActor;
+ pSceneActor = nullptr;
+}
+
void SceneController::onInitialize()
{
@@ -1241,12 +1484,28 @@ LRESULT SceneController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa
m_scene->reloadAllActors();
return 0;
case 'F':
- throwCube();
+ if (m_cubeThrowDownTime == -1.f)
+ {
+ m_cubeThrowDownTime = ImGui::GetTime();
+ }
return 0;
default:
break;
}
}
+ else if (uMsg == WM_KEYUP)
+ {
+ int iKeyPressed = static_cast<int>(wParam);
+ switch (iKeyPressed)
+ {
+ case 'F':
+ throwCube();
+ m_cubeThrowDownTime = -1.f;
+ return 0;
+ default:
+ break;
+ }
+ }
return 1;
}
@@ -1346,6 +1605,7 @@ void SceneController::drawUI()
{
ImGui::Text("Thrown Cube Params (F)");
ImGui::DragFloat("Cube Size", &m_cubeScale, 1.0f, 0.0f, 100.0f);
+ ImGui::Text("Cube Speed (hold F): %1.f", getCubeSpeed());
}
}
@@ -1355,14 +1615,21 @@ void SceneController::drawStatsUI()
m_scene->drawStatsUI();
}
+float SceneController::getCubeSpeed()
+{
+ const float CUBE_VELOCITY_SPEED_MIN = 70;
+ const float CUBE_VELOCITY_CHARGE_PER_SECOND = 300;
+ return m_cubeThrowDownTime > 0 ? CUBE_VELOCITY_SPEED_MIN + (ImGui::GetTime() - m_cubeThrowDownTime) * CUBE_VELOCITY_CHARGE_PER_SECOND : 0.f;
+}
+
void SceneController::throwCube()
{
- const float CUBE_VELOCITY = 100;
+ const float CUBE_VELOCITY = 400;
const float CUBE_DENSITY = 20000.0f;
CFirstPersonCamera* camera = &getRenderer().getCamera();
- PxVec3 eyePos = XMVECTORToPxVec4(camera->GetEyePt()).getXYZ();
- PxVec3 lookAtPos = XMVECTORToPxVec4(camera->GetLookAtPt()).getXYZ();
+ PxVec3 eyePos = XMVECTORToPxVec4(SimpleScene::Inst()->GetEyePt()).getXYZ();
+ PxVec3 lookAtPos = XMVECTORToPxVec4(SimpleScene::Inst()->GetLookAtPt()).getXYZ();
PhysXController::Actor* cube = getPhysXController().spawnPhysXPrimitiveBox(PxTransform(eyePos), PxVec3(m_cubeScale, m_cubeScale, m_cubeScale), CUBE_DENSITY);
PxRigidDynamic* rigidDynamic = cube->getActor()->is<PxRigidDynamic>();
cube->setColor(DirectX::XMFLOAT4(1, 0, 0, 1));
@@ -1390,7 +1657,8 @@ void SceneController::throwCube()
m_Projectiles.push_back(p);
m_scene->addSceneActor(p);
- getManager()->m_bNeedRefreshTree = true;
+// BlastSceneTree::ins()->addProjectile(p);
+ SampleManager::ins()->m_bNeedRefreshTree = true;
// Add By Lixu End
}
@@ -1428,82 +1696,41 @@ void SceneController::clearProjectile()
m_Projectiles.clear();
m_UsedNames.clear();
m_ReusedNames.clear();
+
+// BlastSceneTree::ins()->clearProjectile();
+ SampleManager::ins()->m_bNeedRefreshTree = true;
+}
+
+std::string SceneController::getProjectileName(PhysXSceneActor* projectile)
+{
+ return projectile->getName();
+}
+
+bool SceneController::getProjectileVisible(PhysXSceneActor* projectile)
+{
+ return !(projectile->getActor()->isHidden());
+}
+
+void SceneController::setProjectileVisible(PhysXSceneActor* projectile, bool val)
+{
+ projectile->getActor()->setHidden(!val);
}
void SceneController::ResetScene()
{
clearProjectile();
+// BlastSceneTree::ins()->clearProjectile();
m_scene->reloadAllActors();
+ SampleManager::ins()->m_bNeedRefreshTree = true;
}
void SceneController::ClearScene()
{
clearProjectile();
+// BlastSceneTree::ins()->clearProjectile();
m_scene->releaseAll();
-// Add By Lixu Begin
PhysXController& pc = getPhysXController();
pc.ClearOldCOllisions();
-// Add By Lixu End
-}
-
-bool SceneController::GetAssetDesc(const BlastAsset* asset, AssetList::ModelAsset& desc)
-{
- SampleManager* pSampleManager = getManager();
- SampleConfig* config = (SampleConfig*)&(pSampleManager->getConfig());
- std::vector<AssetList::ModelAsset>& modelAssets = config->additionalAssetList.models;
- std::vector<AssetList::ModelAsset>::iterator itModelAssets;
- std::vector<SceneAsset*>& sceneAssets = m_scene->getAssets();
- std::vector<SceneAsset*>::iterator itSceneAssets;
-
- bool find = false;
- for (itSceneAssets = sceneAssets.begin(); itSceneAssets != sceneAssets.end(); itSceneAssets++)
- {
- SceneAsset* sceneAsset = *itSceneAssets;
- std::string id = sceneAsset->getID();
- for (itModelAssets = modelAssets.begin(); itModelAssets != modelAssets.end(); itModelAssets++)
- {
- AssetList::ModelAsset& modelAsset = *itModelAssets;
- if (modelAsset.id == id)
- {
- if (!modelAsset.isSkinned)
- {
- SimpleModelSceneAsset* pSimpleModelSceneAsset = (SimpleModelSceneAsset*)sceneAsset;
- if (pSimpleModelSceneAsset->getAsset() == asset)
- {
- desc = modelAsset;
- find = true;
- break;
- }
- }
- else
- {
- SkinnedModelSceneAsset* pSkinnedModelSceneAsset = (SkinnedModelSceneAsset*)sceneAsset;
- if (pSkinnedModelSceneAsset->getAsset() == asset)
- {
- desc = modelAsset;
- find = true;
- break;
- }
- }
- }
- }
-
- if (find)
- {
- break;
- }
- }
-
- return find;
-}
-
-void SceneController::GetProjectilesNames(std::vector<std::string>& projectilesNames)
-{
- projectilesNames.clear();
- std::vector<std::string>::iterator it = m_UsedNames.begin();
- for (; it != m_UsedNames.end(); it++)
- {
- projectilesNames.push_back(*it);
- }
+ SampleManager::ins()->m_bNeedRefreshTree = true;
}
// Add By Lixu End \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.h
index 82f08d8..669ca40 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef SCENE_CONTROLLER_H
#define SCENE_CONTROLLER_H
@@ -23,6 +41,8 @@ class SingleSceneAsset;
class Scene;
// Add By Lixu Begin
class PhysXSceneActor;
+class BlastAssetModelSimple;
+class ModelSceneAsset;
// Add By Lixu End
class SceneController : public ISampleController
{
@@ -48,15 +68,22 @@ public:
// Add By Lixu Begin
void addProjectile();
void clearProjectile();
+ std::vector<PhysXSceneActor*> getPrejectiles() { return m_Projectiles; }
+ std::string getProjectileName(PhysXSceneActor* projectile);
+ bool getProjectileVisible(PhysXSceneActor* projectile);
+ void setProjectileVisible(PhysXSceneActor* projectile, bool val);
void ResetScene();
void ClearScene();
- bool GetAssetDesc(const BlastAsset* asset, AssetList::ModelAsset& desc);
- void GetProjectilesNames(std::vector<std::string>& projectilesNames);
+ void addBlastAsset(BlastAssetModelSimple* pBlastAsset, AssetList::ModelAsset modelAsset);
+ void removeBlastAsset(BlastAssetModelSimple* pBlastAsset);
+ BlastFamily* addBlastFamily(BlastAsset* pBlastAsset, physx::PxTransform transform);
+ void removeBlastFamily(BlastAsset* pBlastAsset, int nFamilyIndex);
// Add By Lixu End
private:
void addAssets(const AssetList& assetList, bool loadModels = true);
void throwCube();
+ float getCubeSpeed();
SceneController& operator= (SceneController&);
@@ -88,11 +115,14 @@ private:
Scene* m_scene;
float m_cubeScale;
+ float m_cubeThrowDownTime;
// Add By Lixu Begin
std::vector<std::string> m_UsedNames;
std::vector<std::string> m_ReusedNames;
std::vector<PhysXSceneActor*> m_Projectiles;
+
+ std::map<BlastAsset*, ModelSceneAsset*> BlastToSceneMap;
// Add By Lixu End
};
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp
index e56a124..f9e218b 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "CommonUIController.h"
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h
index da62674..4656203 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef COMMON_UI_CONTROLLER_H
#define COMMON_UI_CONTROLLER_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp
index fba1227..7f426bd 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "DamageToolController.h"
#include "RenderUtils.h"
@@ -18,11 +36,16 @@
#include <imgui.h>
#include "NvBlastTkActor.h"
+#include "NvBlastTkFamily.h"
#include "NvBlastExtDamageShaders.h"
#include "NvBlastExtPxActor.h"
#include "PxRigidDynamic.h"
#include "PxScene.h"
+#include "SimpleScene.h"
+#include "BlastSceneTree.h"
+#include "DefaultDamagePanel.h"
+#include "ViewerOutput.h"
using namespace Nv::Blast;
@@ -32,44 +55,113 @@ using namespace physx;
// Setup
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
const DirectX::XMFLOAT4 PICK_POINTER_ACTIVE_COLOR(1.0f, 0.f, 0.f, 0.6f);
+static const PxVec3 WEAPON_POSITION_IN_VIEW(0, -7, 23);
+static const float SEGMENT_DAMAGE_MAX_DISTANCE = 100.0f;
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+DamageToolController* gDamageToolController = nullptr;
+DamageToolController* DamageToolController::ins()
+{
+ return gDamageToolController;
+}
+void DamageToolController::setDamageAmount(float value)
+{
+ m_damage = value;
+}
+void DamageToolController::setExplosiveImpulse(float value)
+{
+ m_explosiveImpulse = value;
+}
+void DamageToolController::setStressForceFactor(float value)
+{
+ m_stressForceFactor = value;
+}
+void DamageToolController::setDamagerIndex(int index)
+{
+ m_damagerIndex = index;
+}
+void DamageToolController::setRadius(float value)
+{
+ m_damagers[m_damagerIndex].radius = value;
+}
+void DamageToolController::setDamageWhilePressed(bool value)
+{
+ m_damagers[m_damagerIndex].damageWhilePressed = value;
+}
DamageToolController::DamageToolController()
- : m_damageRadius(5.0f), m_compressiveDamage(1.0f), m_pickPointerColor(1.0f, 1.0f, 1.0f, 0.4f),
- m_pickPointerRenderMaterial(nullptr), m_pickPointerRenderable(nullptr), m_explosiveImpulse(100), m_damageProfile(0), m_stressForceFactor(1.0f)
+ : m_damage(100.0f), m_toolColor(1.0f, 1.0f, 1.0f, 0.4f),
+ m_toolRenderMaterial(nullptr), m_sphereToolRenderable(nullptr), m_lineToolRenderable(nullptr),
+ m_explosiveImpulse(100), m_damagerIndex(0), m_stressForceFactor(1.0f), m_isMousePressed(false), m_damageCountWhilePressed(0)
{
+ // damage amount calc using NvBlastExtMaterial
+ auto getDamageAmountFn = [](const float damage, ExtPxActor* actor)
+ {
+ const void* material = actor->getTkActor().getFamily().getMaterial();
+ return material ? reinterpret_cast<const NvBlastExtMaterial*>(material)->getNormalizedDamage(damage) : 0.f;
+ };
+
// Damage functions
- auto radialDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 position, PxVec3 normal)
+ auto radialDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal)
{
- NvBlastExtRadialDamageDesc desc =
+ const float damage = getDamageAmountFn(m_damage, actor);
+ if (damage > 0.f)
{
- m_compressiveDamage,
- { position.x, position.y, position.z },
- m_damageRadius,
- m_damageRadius + 2.0f
- };
+ NvBlastExtRadialDamageDesc desc =
+ {
+ damage,
+ { position.x, position.y, position.z },
+ damager->radius,
+ damager->radius * 1.6f
+ };
- actor->getTkActor().damage(damager->program, &desc, sizeof(desc));
+ actor->getTkActor().damage(damager->program, &desc, sizeof(desc));
+ }
};
- auto shearDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 position, PxVec3 normal)
+ auto lineSegmentDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal)
{
- PxVec3 force = -2 * normal;
+ const float damage = getDamageAmountFn(m_damage, actor);
+ if (damage > 0.f)
+ {
+ PxVec3 dir = (position - origin).getNormalized();
+ PxVec3 farEnd = origin + dir * 10000.0f;
- NvBlastExtShearDamageDesc desc =
+ NvBlastExtSegmentRadialDamageDesc desc =
+ {
+ damage,
+ { origin.x, origin.y, origin.z },
+ { farEnd.x, farEnd.y, farEnd.z },
+ damager->radius,
+ damager->radius * 1.6f
+ };
+
+ actor->getTkActor().damage(damager->program, &desc, sizeof(desc));
+ }
+ };
+ auto shearDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal)
+ {
+ const float damage = getDamageAmountFn(m_damage, actor);
+ if (damage > 0.f)
{
- { force.x, force.y, force.z },
- { position.x, position.y, position.z }
- };
+ PxVec3 impactNormal = -normal;
- actor->getTkActor().damage(damager->program, &desc, sizeof(desc));
+ NvBlastExtShearDamageDesc desc =
+ {
+ damage,
+ { impactNormal.x, impactNormal.y, impactNormal.z },
+ { position.x, position.y, position.z },
+ damager->radius,
+ damager->radius * 1.6f
+ };
+
+ actor->getTkActor().damage(damager->program, &desc, sizeof(desc));
+ }
};
- auto stressDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 position, PxVec3 normal)
+ auto stressDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal)
{
PxVec3 force = -m_stressForceFactor * normal * actor->getPhysXActor().getMass();
@@ -81,41 +173,96 @@ DamageToolController::DamageToolController()
Damager dam;
dam.uiName = "Radial Damage (Falloff)";
dam.program = NvBlastDamageProgram { NvBlastExtFalloffGraphShader, NvBlastExtFalloffSubgraphShader };
+ dam.pointerType = Damager::PointerType::Sphere;
dam.pointerColor = DirectX::XMFLOAT4(1.0f, 1.0f, 1.0f, 0.4f);
dam.executeFunction = radialDamageExecute;
- m_armory.push_back(dam);
+ m_damagers.push_back(dam);
}
{
Damager dam;
dam.uiName = "Radial Damage (Cutter)";
dam.program = NvBlastDamageProgram { NvBlastExtCutterGraphShader, NvBlastExtCutterSubgraphShader };
+ dam.pointerType = Damager::PointerType::Sphere;
dam.pointerColor = DirectX::XMFLOAT4(0.5f, 0.5f, 1.0f, 0.4f);
dam.executeFunction = radialDamageExecute;
- m_armory.push_back(dam);
+ m_damagers.push_back(dam);
+ }
+
+ {
+ Damager dam;
+ dam.uiName = "Segment Damage (Falloff)";
+ dam.program = NvBlastDamageProgram{ NvBlastExtSegmentFalloffGraphShader, NvBlastExtSegmentFalloffSubgraphShader };
+ dam.pointerType = Damager::PointerType::Line;
+ dam.pointerColor = DirectX::XMFLOAT4(0.1f, 1.0f, 0.1f, 0.4f);
+ dam.executeFunction = lineSegmentDamageExecute;
+ dam.damageWhilePressed = true;
+ dam.radius = .2f;
+ dam.radiusLimit = 20.0f;
+ m_damagers.push_back(dam);
}
{
Damager dam;
dam.uiName = "Shear Damage";
dam.program = NvBlastDamageProgram { NvBlastExtShearGraphShader, NvBlastExtShearSubgraphShader };
+ dam.pointerType = Damager::PointerType::Sphere;
dam.pointerColor = DirectX::XMFLOAT4(0.5f, 1.0f, 0.5f, 0.4f);
dam.executeFunction = shearDamageExecute;
- m_armory.push_back(dam);
+ m_damagers.push_back(dam);
}
{
Damager dam;
dam.uiName = "Stress Damage";
dam.program = { nullptr, nullptr };
+ dam.pointerType = Damager::PointerType::Sphere;
dam.pointerColor = DirectX::XMFLOAT4(0.5f, 0.5f, 1.0f, 0.4f);
dam.executeFunction = stressDamageExecute;
- m_armory.push_back(dam);
+ m_damagers.push_back(dam);
}
- for (const Damager& d : m_armory)
+ // UI
+ DefaultDamagePanel* pDefaultDamagePanel = DefaultDamagePanel::ins();
+ pDefaultDamagePanel->setUpdateData(false);
+ QComboBox* comboBoxDamageProfile = pDefaultDamagePanel->getDamageProfile();
+ comboBoxDamageProfile->clear();
+
+ // project
+ BPPDefaultDamage& damage = BlastProject::ins().getParams().defaultDamage;
+ damage.damageAmount = m_damage;
+ damage.explosiveImpulse = m_explosiveImpulse;
+ damage.stressDamageForce = m_stressForceFactor;
+ int count = m_damagers.size();
+ if (damage.damageStructs.buf != nullptr && damage.damageStructs.arraySizes[0] != count)
+ {
+ delete[] damage.damageStructs.buf;
+ damage.damageStructs.buf = nullptr;
+ damage.damageStructs.arraySizes[0] = 0;
+ }
+ if (damage.damageStructs.buf == nullptr)
{
- m_armoryNames.push_back(d.uiName);
+ damage.damageStructs.buf = new BPPDamageStruct[count];
+ damage.damageStructs.arraySizes[0] = count;
}
+ damage.damageProfile = 0;
+ int damageIndex = 0;
+
+ for (const Damager& d : m_damagers)
+ {
+ m_damagerNames.push_back(d.uiName);
+
+ // UI
+ comboBoxDamageProfile->addItem(d.uiName);
+
+ // project
+ BPPDamageStruct& damageStruct = damage.damageStructs.buf[damageIndex++];
+ damageStruct.damageRadius = d.radius;
+ damageStruct.continuously = d.damageWhilePressed;
+ }
+
+ pDefaultDamagePanel->updateValues();
+
+ gDamageToolController = this;
}
DamageToolController::~DamageToolController()
@@ -124,19 +271,22 @@ DamageToolController::~DamageToolController()
void DamageToolController::onSampleStart()
{
- // pick pointer
-// Add By Lixu Begin
- m_pickPointerRenderMaterial = new RenderMaterial("", getRenderer().getResourceManager(), "physx_primitive_transparent", "", RenderMaterial::BLEND_ALPHA_BLENDING);
-// Add By Lixu End
- IRenderMesh* mesh = getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Sphere);
- m_pickPointerRenderable = getRenderer().createRenderable(*mesh, *m_pickPointerRenderMaterial);
- m_pickPointerRenderable->setScale(PxVec3(m_damageRadius));
+ // damage tool pointer
+ m_toolRenderMaterial = new RenderMaterial("", getRenderer().getResourceManager(), "physx_primitive_transparent", "", RenderMaterial::BLEND_ALPHA_BLENDING);
+ {
+ IRenderMesh* mesh = getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Sphere);
+ m_sphereToolRenderable = getRenderer().createRenderable(*mesh, *m_toolRenderMaterial);
+ }
+ {
+ IRenderMesh* mesh = getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Box);
+ m_lineToolRenderable = getRenderer().createRenderable(*mesh, *m_toolRenderMaterial);
+ }
// default tool
- setDamageProfile(0);
+ m_damagerIndex = 0;
// start with damage mode by default
- setDamageMode(true);
+ setDamageMode(false);
}
void DamageToolController::onInitialize()
@@ -146,64 +296,139 @@ void DamageToolController::onInitialize()
void DamageToolController::onSampleStop()
{
- getRenderer().removeRenderable(m_pickPointerRenderable);
- SAFE_DELETE(m_pickPointerRenderMaterial);
+ getRenderer().removeRenderable(m_sphereToolRenderable);
+ getRenderer().removeRenderable(m_lineToolRenderable);
+ SAFE_DELETE(m_toolRenderMaterial);
}
+
void DamageToolController::Animate(double dt)
{
PROFILER_SCOPED_FUNCTION();
- m_pickPointerColor = XMFLOAT4Lerp(m_pickPointerColor, m_armory[m_damageProfile].pointerColor, dt * 5.0f);
- m_pickPointerRenderable->setColor(m_pickPointerColor);
-}
+ m_toolColor = XMFLOAT4Lerp(m_toolColor, m_damagers[m_damagerIndex].pointerColor, dt * 5.0f);
+ m_sphereToolRenderable->setHidden(true);
+ m_lineToolRenderable->setHidden(true);
-LRESULT DamageToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- PROFILER_SCOPED_FUNCTION();
-
- if (uMsg == WM_LBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP)
+ // damage mode
+ if (m_damageMode)
{
- float mouseX = (short)LOWORD(lParam) / getRenderer().getScreenWidth();
- float mouseY = (short)HIWORD(lParam) / getRenderer().getScreenHeight();
- bool press = uMsg == WM_LBUTTONDOWN;
+ // ray cast according to camera + mouse ray
+ PxVec3 eyePos, pickDir;
+ getPhysXController().getEyePoseAndPickDir(m_lastMousePos.x, m_lastMousePos.y, eyePos, pickDir);
+ pickDir = pickDir.getNormalized();
+
+ PxRaycastHit hit; hit.shape = NULL;
+ PxRaycastBuffer hit1;
+ getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL);
+ hit = hit1.block;
- // damage mode
- if (m_damageMode && m_pickPointerRenderable)
+ if (hit.shape)
{
- PxVec3 eyePos, pickDir;
- getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
- pickDir = pickDir.getNormalized();
+ PxMat44 cameraViewInv = XMMATRIXToPxMat44(getRenderer().getCamera().GetViewMatrix()).inverseRT();
+ PxVec3 weaponOrigin = eyePos + cameraViewInv.rotate(WEAPON_POSITION_IN_VIEW);
- PxRaycastHit hit; hit.shape = NULL;
- PxRaycastBuffer hit1;
- getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL);
- hit = hit1.block;
+ // damage function
+ const Damager& damager = m_damagers[m_damagerIndex];
+ auto damageFunction = [&](ExtPxActor* actor)
+ {
+ auto t0 = actor->getPhysXActor().getGlobalPose();
+ PxTransform t(t0.getInverse());
+ PxVec3 localNormal = t.rotate(hit.normal);
+ PxVec3 localPosition = t.transform(hit.position);
+ PxVec3 localOrigin = t.transform(weaponOrigin);
+ damager.executeFunction(&damager, actor, localOrigin, localPosition, localNormal);
+ };
+
+ // should damage?
+ bool shouldDamage = false;
+ if (m_isMousePressed)
+ {
+ shouldDamage = damager.damageWhilePressed || m_damageCountWhilePressed == 0;
+ m_damageCountWhilePressed++;
+ }
+ else
+ {
+ m_damageCountWhilePressed = 0;
+ }
- if (hit.shape)
+ // Update tool pointer and do damage with specific overlap
+ if (damager.pointerType == Damager::Sphere)
{
- PxRigidActor* actor = hit.actor;
- m_pickPointerRenderable->setHidden(false);
- m_pickPointerRenderable->setTransform(PxTransform(hit.position));
+ m_sphereToolRenderable->setHidden(false);
+ m_sphereToolRenderable->setColor(m_toolColor);
+ m_sphereToolRenderable->setScale(PxVec3(damager.radius));
+ m_sphereToolRenderable->setTransform(PxTransform(hit.position));
- if (press)
+ if (shouldDamage)
{
- damage(hit.position, hit.normal);
- m_pickPointerColor = PICK_POINTER_ACTIVE_COLOR;
+ if (getBlastController().overlap(PxSphereGeometry(damager.radius), PxTransform(hit.position), damageFunction))
+ {
+ m_toolColor = PICK_POINTER_ACTIVE_COLOR;
+ }
+ getPhysXController().explodeDelayed(hit.position, damager.radius, m_explosiveImpulse);
+ }
+ }
+ else if (damager.pointerType == Damager::Line)
+ {
+ m_lineToolRenderable->setHidden(false);
+ m_lineToolRenderable->setColor(m_toolColor);
+
+ PxVec3 scale(damager.radius, damager.radius, SEGMENT_DAMAGE_MAX_DISTANCE);
+ PxVec3 direction = (hit.position - weaponOrigin).getNormalized();
+ PxVec3 position = weaponOrigin + direction * SEGMENT_DAMAGE_MAX_DISTANCE;
+
+ m_lineToolRenderable->setScale(scale);
+ PxTransform t(position, quatLookAt(direction));
+ m_lineToolRenderable->setTransform(t);
+
+ if (shouldDamage)
+ {
+ if (this->getBlastController().overlap(PxBoxGeometry(scale), t, damageFunction))
+ {
+ m_toolColor = PICK_POINTER_ACTIVE_COLOR;
+ }
}
}
else
{
- m_pickPointerRenderable->setHidden(true);
+ PX_ASSERT(false);
}
}
}
+}
+
+
+LRESULT DamageToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ PROFILER_SCOPED_FUNCTION();
+
+ if (uMsg == WM_LBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP)
+ {
+ m_lastMousePos.x = (short)LOWORD(lParam) / getRenderer().getScreenWidth();
+ if (!SimpleScene::Inst()->m_pCamera->_lhs)
+ {
+ m_lastMousePos.x = 1 - m_lastMousePos.x;
+ }
+ m_lastMousePos.y = (short)HIWORD(lParam) / getRenderer().getScreenHeight();
+ }
+
+ if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
+ {
+ m_isMousePressed = (uMsg == WM_LBUTTONDOWN);
+ if (m_isMousePressed && !m_damageMode)
+ {
+ viewer_warn("damage mode is disable, please enable it first !");
+ }
+ }
if (uMsg == WM_MOUSEWHEEL)
{
+ /*
int delta = int((short)HIWORD(wParam)) / WHEEL_DELTA;
changeDamageRadius(delta * 0.3f);
+ */
}
if (uMsg == WM_KEYDOWN)
@@ -219,14 +444,12 @@ LRESULT DamageToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
else if (iKeyPressed >= '1' && iKeyPressed <= '9')
{
- uint32_t num = PxClamp<uint32_t>(iKeyPressed - '1', 0, (uint32_t)m_armory.size() - 1);
- setDamageProfile(num);
+ m_damagerIndex = PxClamp<uint32_t>(iKeyPressed - '1', 0, (uint32_t)m_damagers.size() - 1);
}
else if (iKeyPressed == VK_SPACE)
{
- setDamageMode(!isDamageMode());
+ //setDamageMode(!isDamageMode());
}
-
}
return 1;
@@ -234,61 +457,36 @@ LRESULT DamageToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
void DamageToolController::drawUI()
{
- ImGui::DragFloat("Compressive Damage", &m_compressiveDamage, 0.05f);
+ ImGui::DragFloat("Damage Amount", &m_damage, 1.0f);
ImGui::DragFloat("Explosive Impulse", &m_explosiveImpulse);
- ImGui::DragFloat("Damage Radius (Mouse WH)", &m_damageRadius);
ImGui::DragFloat("Stress Damage Force", &m_stressForceFactor);
// - - - - - - - -
ImGui::Spacing();
// Armory
- if (ImGui::Combo("Damage Profile", (int*)&m_damageProfile, m_armoryNames.data(), (int)m_armoryNames.size(), -1))
- {
- setDamageProfile(m_damageProfile);
- }
+ ImGui::Combo("Damage Profile", (int*)&m_damagerIndex, m_damagerNames.data(), (int)m_damagerNames.size(), -1);
+ Damager& damager = m_damagers[m_damagerIndex];
+ ImGui::DragFloat("Damage Radius (Mouse WH)", &damager.radius);
+ ImGui::Checkbox("Damage Continuously", &damager.damageWhilePressed);
}
-
void DamageToolController::setDamageMode(bool enabled)
{
m_damageMode = enabled;
- getPhysXController().setDraggingEnabled(!m_damageMode);
+ //getPhysXController().setDraggingEnabled(!m_damageMode);
if (!m_damageMode)
{
- m_pickPointerRenderable->setHidden(true);
+ m_sphereToolRenderable->setHidden(true);
+ m_lineToolRenderable->setHidden(true);
}
}
-
-void DamageToolController::setDamageProfile(uint32_t profile)
-{
- m_damageProfile = profile;
-}
-
-
void DamageToolController::changeDamageRadius(float dr)
{
- m_damageRadius += dr;
- m_damageRadius = PxMax(1.0f, m_damageRadius);
- m_pickPointerRenderable->setScale(PxVec3(m_damageRadius));
-}
-
-
-void DamageToolController::damage(physx::PxVec3 position, physx::PxVec3 normal)
-{
- auto damageFunction = [&](ExtPxActor* actor)
- {
- auto t0 = actor->getPhysXActor().getGlobalPose();
- PxTransform t(t0.getInverse());
- PxVec3 localNormal = t.rotate(normal);
- PxVec3 localPosition = t.transform(position);
- Damager& damager = m_armory[m_damageProfile];
- damager.execute(actor, localPosition, localNormal);
- };
-
- this->getBlastController().blast(position, m_damageRadius, m_explosiveImpulse, damageFunction);
-
+ Damager& damager = m_damagers[m_damagerIndex];
+ damager.radius += dr;
+ damager.radius = PxClamp<float>(damager.radius, 0.05f, damager.radiusLimit);
}
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h
index b6712f2..0aeb0d7 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef DAMAGE_TOOL_CONTROLLER_H
#define DAMAGE_TOOL_CONTROLLER_H
@@ -15,6 +33,7 @@
#include "NvBlastTypes.h"
#include <DirectXMath.h>
#include <functional>
+#include "PxVec2.h"
#include "PxVec3.h"
@@ -37,6 +56,14 @@ public:
DamageToolController();
virtual ~DamageToolController();
+ static DamageToolController* ins();
+ void setDamageAmount(float value);
+ void setExplosiveImpulse(float value);
+ void setStressForceFactor(float value);
+ void setDamagerIndex(int index);
+ void setRadius(float value);
+ void setDamageWhilePressed(bool value);
+
virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
virtual void Animate(double dt);
void drawUI();
@@ -54,8 +81,10 @@ public:
// Add By Lixu Begin
Renderable* getPickPointer()
{
- return m_pickPointerRenderable;
+ return m_sphereToolRenderable;
}
+
+ void setDamageMode(bool enabled);
// Add By Lixu End
private:
@@ -64,17 +93,9 @@ private:
//////// private methods ////////
- void damage(physx::PxVec3 position, physx::PxVec3 normal);
-
- void setDamageProfile(uint32_t profile);
- uint32_t getDamageProfile() const
- {
- return m_damageProfile;
- }
-
void changeDamageRadius(float dr);
- void setDamageMode(bool enabled);
+
//////// used controllers ////////
@@ -97,33 +118,48 @@ private:
//////// internal data ////////
- Renderable* m_pickPointerRenderable;
- RenderMaterial* m_pickPointerRenderMaterial;
- DirectX::XMFLOAT4 m_pickPointerColor;
+ RenderMaterial* m_toolRenderMaterial;
+ Renderable* m_sphereToolRenderable;
+ DirectX::XMFLOAT4 m_toolColor;
+ Renderable* m_lineToolRenderable;
- float m_damageRadius;
- float m_compressiveDamage;
- float m_explosiveImpulse;
- float m_stressForceFactor;
- uint32_t m_damageProfile;
+ float m_damage;
+ float m_explosiveImpulse;
+ float m_stressForceFactor;
struct Damager
{
- const char* uiName;
- NvBlastDamageProgram program;
- DirectX::XMFLOAT4 pointerColor;
- std::function<void(const Damager* damager, Nv::Blast::ExtPxActor* actor, physx::PxVec3 position, physx::PxVec3 normal)> executeFunction;
-
- void execute(Nv::Blast::ExtPxActor* actor, physx::PxVec3 position, physx::PxVec3 normal)
+ Damager() : damageWhilePressed(false), radius(5.0f), radiusLimit(1000.0f)
{
- executeFunction(this, actor, position, normal);
}
+
+ enum PointerType
+ {
+ Sphere,
+ Line
+ };
+
+ typedef std::function<void(const Damager* damager, Nv::Blast::ExtPxActor* actor, physx::PxVec3 origin, physx::PxVec3 position, physx::PxVec3 normal)> ExecuteFn;
+
+ const char* uiName;
+ NvBlastDamageProgram program;
+ PointerType pointerType;
+ DirectX::XMFLOAT4 pointerColor;
+ float radius;
+ float radiusLimit;
+ bool damageWhilePressed;
+ ExecuteFn executeFunction;
};
- std::vector<Damager> m_armory;
- std::vector<const char*> m_armoryNames;
+ std::vector<Damager> m_damagers;
+ std::vector<const char*> m_damagerNames;
+ uint32_t m_damagerIndex;
+
+ bool m_damageMode;
- bool m_damageMode;
+ physx::PxVec2 m_lastMousePos;
+ bool m_isMousePressed;
+ uint32_t m_damageCountWhilePressed;
};
#endif \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp
index 244f121..b2533a6 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "EditionToolController.h"
#include "BlastController.h"
@@ -76,7 +94,7 @@ LRESULT EditionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
PxRaycastHit hit; hit.shape = NULL;
PxRaycastBuffer hit1;
- getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL);
+ getPhysXController().getEditPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL);
hit = hit1.block;
PxRigidActor* actor = NULL;
@@ -109,19 +127,8 @@ void EditionToolController::fracture(PxActor* actor)
return;
}
- ExtPxActor* extActor = NULL;
PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>();
- if (NULL != rigidDynamic)
- {
- extActor = blastController.getExtPxManager().getActorFromPhysXActor(*rigidDynamic);
- }
- if (NULL == extActor)
- {
- return;
- }
-
- uint32_t chunkCount = extActor->getChunkCount();
- if (chunkCount <= 0)
+ if (NULL == rigidDynamic)
{
return;
}
@@ -131,7 +138,7 @@ void EditionToolController::fracture(PxActor* actor)
for (; it != families.end(); it++)
{
BlastFamilyPtr f = *it;
- if (f->find(extActor))
+ if (f->find(*actor))
{
pBlastFamily = f;
break;
@@ -142,17 +149,13 @@ void EditionToolController::fracture(PxActor* actor)
return;
}
- const uint32_t* chunkIndices = extActor->getChunkIndices();
+ const uint32_t chunkIndex = pBlastFamily->getChunkIndexByPxActor(*actor);
const BlastAsset& blastAsset = pBlastFamily->getBlastAsset();
- const BlastAsset* pBlastAsset = &blastAsset;
-
- SceneController& sceneController = getManager()->getSceneController();
- AssetList::ModelAsset desc;
- sceneController.GetAssetDesc(pBlastAsset, desc);
+ BlastAsset* pBlastAsset = (BlastAsset*)&blastAsset;
- std::string assetname = desc.id;
- GlobalSettings& globalSettings = GlobalSettings::Inst();
- getManager()->fractureAsset(globalSettings.m_projectFileDir, assetname, pBlastAsset, chunkIndices[0]);
- getManager()->addModelAsset(globalSettings.m_projectFileDir, assetname, desc.isSkinned, desc.transform, false);
+ VoronoiFractureExecutor executor;
+ executor.setSourceAsset(pBlastAsset);
+ executor.setTargetChunk(chunkIndex);
+ executor.execute();
} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h
index b1e88d1..5f71b58 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef EDITION_TOOL_CONTROLLER_H
#define EDITION_TOOL_CONTROLLER_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.cpp
new file mode 100644
index 0000000..28ac182
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.cpp
@@ -0,0 +1,256 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
+
+#include "ExplodeToolController.h"
+#include "RenderUtils.h"
+#include "BlastController.h"
+#include "Renderer.h"
+#include "PhysXController.h"
+#include "SampleProfiler.h"
+#include "GizmoToolController.h"
+
+#include <imgui.h>
+
+#include "NvBlastTkActor.h"
+#include "NvBlastExtDamageShaders.h"
+
+#include "PxRigidDynamic.h"
+#include "PxScene.h"
+#include "BlastSceneTree.h"
+#include "SimpleScene.h"
+#include "ViewerOutput.h"
+
+using namespace Nv::Blast;
+using namespace physx;
+
+const float EXPLODE_MIN = 0.0f;
+const float EXPLODE_MAX = 2.0f;
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Setup
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+ExplodeToolController::ExplodeToolController()
+ : m_previousExplodeValue(0.0f)
+ , m_starDrag(false)
+{
+}
+
+ExplodeToolController::~ExplodeToolController()
+{
+}
+
+void ExplodeToolController::onSampleStart()
+{
+}
+
+void ExplodeToolController::onInitialize()
+{
+ m_previousExplodeValue = 0.0f;
+}
+
+
+void ExplodeToolController::onSampleStop()
+{
+}
+
+void ExplodeToolController::Animate(double dt)
+{
+ PROFILER_SCOPED_FUNCTION();
+}
+
+
+LRESULT ExplodeToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ PROFILER_SCOPED_FUNCTION();
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager->IsSimulating())
+ {
+ return 1;
+ }
+
+ if (uMsg == WM_LBUTTONDOWN)
+ {
+ m_mouseStartPoint.x = (short)LOWORD(lParam);
+ m_mouseStartPoint.y = (short)HIWORD(lParam);
+ m_starDrag = true;
+ }
+ else if (uMsg == WM_MOUSEMOVE)
+ {
+ if (!m_starDrag)
+ return 1;
+
+ float theDragDistance = (short)LOWORD(lParam) - m_mouseStartPoint.x;
+ // ignore shorter mouse move
+ if (fabs(theDragDistance) <= 3.0)
+ return 1;
+
+ theDragDistance /= getRenderer().getScreenWidth();
+ theDragDistance *= EXPLODE_MAX;
+ float theNewExplodeValue = m_previousExplodeValue + (float)theDragDistance;
+
+ if (theNewExplodeValue < 0)
+ theNewExplodeValue = 0;
+ else if (theNewExplodeValue > EXPLODE_MAX)
+ theNewExplodeValue = EXPLODE_MAX;
+
+ _explode(theNewExplodeValue);
+ }
+ else if (uMsg == WM_LBUTTONUP)
+ {
+ m_previousExplodeValue = 0.0f;
+ m_starDrag = false;
+ }
+ return 1;
+}
+
+void ExplodeToolController::drawUI()
+{
+}
+
+void ExplodeToolController::_explode(float value)
+{
+ SampleManager* pSampleManager = SampleManager::ins();
+
+ BlastAsset* pBlastAsset = nullptr;
+ int nFamilyIndex = -1;
+ pSampleManager->getCurrentSelectedInstance(&pBlastAsset, nFamilyIndex);
+ if (pBlastAsset == nullptr)
+ {
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ if (AssetDescMap.size() == 1)
+ {
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itAssetDescMap = AssetDescMap.begin();
+ pSampleManager->setCurrentSelectedInstance(itAssetDescMap->first, -1);
+ pBlastAsset = pSampleManager->getCurBlastAsset();
+ viewer_msg("no asset selected, use the only one in current scene.");
+ }
+ }
+ if (pBlastAsset == nullptr)
+ {
+ viewer_msg("please select one asset before explode.");
+ return;
+ }
+
+ std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = pSampleManager->getAssetFamiliesMap();
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAFM = AssetFamiliesMap.find(pBlastAsset);
+ if (itAFM == AssetFamiliesMap.end())
+ {
+ return;
+ }
+
+ std::vector<BlastFamily*> families = itAFM->second;
+ int familySize = families.size();
+ if (familySize == 0)
+ {
+ viewer_msg("no instance for current asset.");
+ return;
+ }
+
+ if (nFamilyIndex == -1 || nFamilyIndex >= familySize)
+ {
+ nFamilyIndex = 0;
+ viewer_msg("no instance selected, use the first one of current asset.");
+ }
+
+ BlastFamily* pFamily = families[nFamilyIndex];
+
+ PxScene& scene = pSampleManager->getPhysXController().getEditPhysXScene();
+ const PxU32 actorsCountTotal = scene.getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC);
+ if (actorsCountTotal == 0)
+ {
+ return;
+ }
+
+ std::vector<PxActor*> actorsTotal(actorsCountTotal);
+ PxU32 nbActors = scene.getActors(PxActorTypeFlag::eRIGID_DYNAMIC, &actorsTotal[0], actorsCountTotal, 0);
+ PX_ASSERT(actorsCountTotal == nbActors);
+
+ std::vector<PxActor*> actors;
+ PxActor* pRootActor = nullptr;
+ for (int act = 0; act < actorsCountTotal; act++)
+ {
+ if (pFamily->find(*actorsTotal[act]))
+ {
+ if (pRootActor == nullptr)
+ {
+ uint32_t chunkIndex = pFamily->getChunkIndexByPxActor(*actorsTotal[act]);
+ std::vector<uint32_t> chunkIndexes;
+ chunkIndexes.push_back(chunkIndex);
+ std::vector<BlastChunkNode*> chunkNodes = BlastTreeData::ins().getChunkNodeByBlastChunk(pBlastAsset, chunkIndexes);
+ if (chunkNodes.size() > 0 && BlastTreeData::isRoot(chunkNodes[0]))
+ {
+ pRootActor = actorsTotal[act];
+ }
+ else
+ {
+ actors.push_back(actorsTotal[act]);
+ }
+ }
+ else
+ {
+ actors.push_back(actorsTotal[act]);
+ }
+ }
+ }
+
+ if (pRootActor == nullptr)
+ {
+ return;
+ }
+
+ BlastController& blastController = pSampleManager->getBlastController();
+
+ PxVec3 origin = pRootActor->getWorldBounds().getCenter();
+
+ int actorsCount = actors.size();
+ for (int ac = 0; ac < actorsCount; ac++)
+ {
+ PxActor* actor = actors[ac];
+ PxRigidDynamic* dynamic = actor->is<PxRigidDynamic>();
+ PX_ASSERT(dynamic != nullptr);
+ PxTransform transformOld = dynamic->getGlobalPose();
+ PxTransform transformNew = transformOld;
+
+ PxBounds3 bound = actor->getWorldBounds();
+ PxVec3 target = bound.getCenter();
+
+ //PxVec3 tChange = (target - origin) * value;
+ //PxVec3 newTarget = target + tChange;
+ //transformNew.p = transformOld.p + tChange;
+ transformNew.p = (target - origin) * value;
+
+ dynamic->setGlobalPose(transformNew);
+ blastController.updateActorRenderableTransform(*actor, transformNew, false);
+ }
+}
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.h
new file mode 100644
index 0000000..9a417ca
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.h
@@ -0,0 +1,100 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef EXPLODE_TOOL_CONTROLLER_H
+#define EXPLODE_TOOL_CONTROLLER_H
+
+#include "SampleManager.h"
+#include "PxVec2.h"
+#include "PxVec3.h"
+#include "DebugRenderBuffer.h"
+#include "BlastFamily.h"
+#include "NvBlastExtPxManager.h"
+#include "BlastSceneTree.h"
+
+class Renderable;
+class RenderMaterial;
+
+namespace Nv
+{
+namespace Blast
+{
+class ExtPxActor;
+}
+}
+
+namespace physx
+{
+ class PxScene;
+}
+
+class ExplodeToolController : public ISampleController
+{
+public:
+ ExplodeToolController();
+ virtual ~ExplodeToolController();
+
+ virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual void Animate(double dt);
+ void drawUI();
+
+ virtual void onInitialize();
+ virtual void onSampleStart();
+ virtual void onSampleStop();
+
+private:
+ ExplodeToolController& operator= (ExplodeToolController&);
+
+ //////// private methods ////////
+
+ //////// used controllers ////////
+
+ Renderer& getRenderer() const
+ {
+ return getManager()->getRenderer();
+ }
+
+ PhysXController& getPhysXController() const
+ {
+ return getManager()->getPhysXController();
+ }
+
+ BlastController& getBlastController() const
+ {
+ return getManager()->getBlastController();
+ }
+
+ void _explode(float value);
+ //////// internal data ////////
+
+ float m_previousExplodeValue;
+ PxVec2 m_mouseStartPoint;
+ bool m_starDrag;
+};
+
+#endif // EXPLODE_TOOL_CONTROLLER_H \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp
index ff0ffa9..ea91766 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "GizmoToolController.h"
#include "RenderUtils.h"
@@ -15,6 +33,7 @@
#include "Renderer.h"
#include "PhysXController.h"
#include "SampleProfiler.h"
+#include "ViewerOutput.h"
#include <imgui.h>
@@ -23,9 +42,12 @@
#include "PxRigidDynamic.h"
#include "PxScene.h"
+#include "PxPhysics.h"
+#include "cooking/PxCooking.h"
+#include "NvBlastExtPxActor.h"
#include <AppMainWindow.h>
-
-
+#include "BlastSceneTree.h"
+#include "SimpleScene.h"
using namespace Nv::Blast;
using namespace physx;
@@ -43,65 +65,123 @@ const physx::PxU32 Y_DIRECTION_COLOR_U = XMFLOAT4ToU32Color(Y_DIRECTION_COLOR_F)
const physx::PxU32 Z_DIRECTION_COLOR_U = XMFLOAT4ToU32Color(Z_DIRECTION_COLOR_F);
const physx::PxU32 HIGHLIGHT_COLOR_U = XMFLOAT4ToU32Color(HIGHLIGHT_COLOR_F);
-const float defaultAxisLength = 10.0;
+float defaultAxisLength = 10.0;
const float defaultAxisModifier = -1.0;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-GizmoToolController::GizmoToolController()
+void modifyPxActorByLocalWay(PxScene& pxScene, PxRigidDynamic& actor, PxTransform& gp_old, PxTransform& gp_new)
{
- m_bGizmoFollowed = false;
+ uint32_t shapesCount = actor.getNbShapes();
+ if (shapesCount > 0)
+ {
+ PxTransform gp_newInv = gp_new.getInverse();
- int segment = 36;
- double span = PxTwoPi / segment;
- PxVec3* vertex = new PxVec3[segment];
+ PxTransform lp_old;
+ PxTransform lp_new;
- for (int i = 0; i < segment; i++)
- {
- vertex[i].x = 0;
- vertex[i].y = 10 * PxSin(i * span);
- vertex[i].z = 10 * PxCos(i * span);
- }
- // x
- for (int i = 0; i < segment - 1; i++)
- {
- m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], X_DIRECTION_COLOR_U));
- }
- m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], X_DIRECTION_COLOR_U));
+ std::vector<PxShape*> shapes(shapesCount);
+ actor.getShapes(&shapes[0], shapesCount);
- for (int i = 0; i < segment; i++)
- {
- vertex[i].x = 10 * PxCos(i * span);
- vertex[i].y = 0;
- vertex[i].z = 10 * PxSin(i * span);
- }
- // y
- for (int i = 0; i < segment - 1; i++)
- {
- m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], Y_DIRECTION_COLOR_U));
+ pxScene.removeActor(actor);
+ for (uint32_t i = 0; i < shapesCount; i++)
+ {
+ PxShape* shape = shapes[i];
+
+ actor.detachShape(*shape);
+
+ lp_old = shape->getLocalPose();
+ lp_new = gp_newInv * gp_old * lp_old;
+ shape->setLocalPose(lp_new);
+
+ actor.attachShape(*shape);
+ }
+ pxScene.addActor(actor);
}
- m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], Y_DIRECTION_COLOR_U));
+}
- for (int i = 0; i < segment; i++)
+void scalePxActor(PxScene& pxScene, PxRigidDynamic& actor, PxMat44& scale)
+{
+ uint32_t shapesCount = actor.getNbShapes();
+ if (shapesCount == 0)
{
- vertex[i].x = 10 * PxCos(i * span);
- vertex[i].y = 10 * PxSin(i * span);
- vertex[i].z = 0;
+ return;
}
- // z
- for (int i = 0; i < segment - 1; i++)
+
+ std::vector<PxShape*> shapes(shapesCount);
+ actor.getShapes(&shapes[0], shapesCount);
+
+ pxScene.removeActor(actor);
+
+ for (uint32_t i = 0; i < shapesCount; i++)
{
- m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], Z_DIRECTION_COLOR_U));
+ PxShape* shape = shapes[i];
+
+ PxConvexMeshGeometry mesh;
+ bool valid = shape->getConvexMeshGeometry(mesh);
+ if (!valid)
+ {
+ continue;
+ }
+
+ PxConvexMesh* pMesh = mesh.convexMesh;
+ if (NULL == pMesh)
+ {
+ continue;
+ }
+
+ PxU32 numVertex = pMesh->getNbVertices();
+ if (numVertex == 0)
+ {
+ continue;
+ }
+
+ const PxVec3* pVertex = pMesh->getVertices();
+ PxVec3* pVertexNew = new PxVec3[numVertex];
+ for (PxU32 v = 0; v < numVertex; v++)
+ {
+ pVertexNew[v] = scale.transform(pVertex[v]);
+ }
+
+ PxConvexMeshDesc convexMeshDesc;
+ convexMeshDesc.points.count = numVertex;
+ convexMeshDesc.points.data = pVertexNew;
+ convexMeshDesc.points.stride = sizeof(PxVec3);
+ convexMeshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
+ SampleManager* manager = SampleManager::ins();
+ PxPhysics& physics = manager->getPhysXController().getPhysics();
+ PxCooking& cooking = manager->getPhysXController().getCooking();
+ PxConvexMesh* convexMesh = cooking.createConvexMesh(convexMeshDesc, physics.getPhysicsInsertionCallback());
+ if (NULL == convexMesh)
+ {
+ delete[] pVertexNew;
+ continue;
+ }
+
+ mesh.convexMesh = convexMesh;
+
+ actor.detachShape(*shape);
+ shape->setGeometry(mesh);
+ actor.attachShape(*shape);
+
+ pMesh->release();
+ delete[] pVertexNew;
}
- m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], Z_DIRECTION_COLOR_U));
- delete[] vertex;
- vertex = NULL;
+ pxScene.addActor(actor);
+}
+
+GizmoToolController::GizmoToolController()
+{
+ m_bGizmoFollowed = false;
+
+ UpdateCircleRenderData(defaultAxisLength);
resetPos();
+
+ BlastSceneTree::ins()->addObserver(this);
}
GizmoToolController::~GizmoToolController()
@@ -154,6 +234,37 @@ void GizmoToolController::onSampleStop()
{
}
+void GizmoToolController::dataSelected(std::vector<BlastNode*> selections)
+{
+ if (!IsEnabled())
+ return;
+
+ BlastController& blastController = getBlastController();
+ std::vector<BlastFamilyPtr>& families = blastController.getFamilies();
+
+ std::set<PxActor*> selectedActors;
+ PxActor* targetActor = nullptr;
+ for (BlastFamily* family : families)
+ {
+ std::vector<uint32_t> selectedChunks = family->getSelectedChunks();
+ for (uint32_t chunkIndex : selectedChunks)
+ {
+ PxActor* actor = nullptr;
+ family->getPxActorByChunkIndex(chunkIndex, &actor);
+
+ if (actor)
+ {
+ selectedActors.insert(actor);
+ targetActor = actor;
+ }
+ }
+ }
+
+ if (targetActor)
+ setTargetActor(targetActor);
+ getSelectionToolController().setTargetActors(selectedActors);
+}
+
void GizmoToolController::Animate(double dt)
{
PROFILER_SCOPED_FUNCTION();
@@ -170,6 +281,9 @@ void GizmoToolController::Animate(double dt)
return;
}
+ m_TargetPos = m_CurrentActor->getGlobalPose().p;
+ m_bNeedResetPos = true;
+
bool isTranslation = m_GizmoToolMode == GTM_Translate;
bool isScale = m_GizmoToolMode == GTM_Scale;
bool isRotation = m_GizmoToolMode == GTM_Rotation;
@@ -187,6 +301,8 @@ void GizmoToolController::Animate(double dt)
m_AxisBoxRenderable[AT_Y]->setHidden(!isScale);
m_AxisBoxRenderable[AT_Z]->setHidden(!isScale);
+ syncRenderableState();
+
if (showLine)
{
if (m_bNeedResetPos)
@@ -430,8 +546,6 @@ void GizmoToolController::Animate(double dt)
m_bNeedResetColor = false;
}
-#include "PxPhysics.h"
-#include "cooking/PxCooking.h"
LRESULT GizmoToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PROFILER_SCOPED_FUNCTION();
@@ -439,297 +553,338 @@ LRESULT GizmoToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
if (uMsg == WM_LBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP)
{
float mouseX = (short)LOWORD(lParam) / getRenderer().getScreenWidth();
+ if (!SimpleScene::Inst()->m_pCamera->_lhs)
+ {
+ mouseX = 1 - mouseX;
+ }
float mouseY = (short)HIWORD(lParam) / getRenderer().getScreenHeight();
- bool press = uMsg == WM_LBUTTONDOWN;
- if (m_GizmoToolMode == GTM_Translate)
+ PxVec3 eyePos, pickDir;
+ getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
+ pickDir = pickDir.getNormalized();
+
+ if (uMsg == WM_LBUTTONDOWN)
{
- if (uMsg == WM_LBUTTONDOWN)
+ if (m_AxisSelected == AT_Num)
{
- if (m_AxisSelected == AT_Num)
- {
- PxVec3 eyePos, pickDir;
- getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
- pickDir = pickDir.getNormalized();
+ PxRaycastBufferN<32> hits;
+ GetPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hits, PxHitFlag::ePOSITION | PxHitFlag::eMESH_MULTIPLE);
- PxRaycastHit hit; hit.shape = NULL;
- PxRaycastBuffer hit1;
- getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL);
- hit = hit1.block;
+ PxU32 nbThouches = hits.getNbTouches();
+ const PxRaycastHit* touches = hits.getTouches();
- if (hit.shape)
+ PxRigidActor* actor = NULL;
+ for (PxU32 u = 0; u < nbThouches; ++u)
+ {
+ const PxRaycastHit& t = touches[u];
+ if (t.shape && getBlastController().isActorVisible(*(t.actor)))
{
- PxRigidActor* actor = hit.actor;
- PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>();
- if (NULL != rigidDynamic)
- {
- m_CurrentActor = actor;
- getSelectionToolController().pointSelect(m_CurrentActor);
+ actor = t.actor;
+ }
+ }
- PxTransform gp = m_CurrentActor->getGlobalPose();
+ if (actor)
+ {
+ PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>();
+ if (NULL != rigidDynamic)
+ {
+ m_CurrentActor = rigidDynamic;
+ getSelectionToolController().pointSelect(m_CurrentActor);
- m_TargetPos = gp.p;
- m_Axis[AT_X] = gp.q.rotate(PxVec3(defaultAxisLength, 0, 0));
- m_Axis[AT_Y] = gp.q.rotate(PxVec3(0, defaultAxisLength, 0));
- m_Axis[AT_Z] = gp.q.rotate(PxVec3(0, 0, defaultAxisLength));
+ PxTransform gp = m_CurrentActor->getGlobalPose();
- m_bNeedResetPos = true;
- }
- else
- {
- m_CurrentActor = NULL;
- getSelectionToolController().clearSelect();
- }
+ m_TargetPos = gp.p;
+ m_Axis[AT_X] = gp.q.rotate(PxVec3(defaultAxisLength, 0, 0));
+ m_Axis[AT_Y] = gp.q.rotate(PxVec3(0, defaultAxisLength, 0));
+ m_Axis[AT_Z] = gp.q.rotate(PxVec3(0, 0, defaultAxisLength));
+
+ m_bNeedResetPos = true;
+ }
+ else
+ {
+ m_CurrentActor = NULL;
+ getSelectionToolController().clearSelect();
}
}
- else
+ }
+ else
+ {
+ m_bGizmoFollowed = (m_CurrentActor != NULL);
+
+ if (m_GizmoToolMode == GTM_Scale)
{
- m_bGizmoFollowed = (m_CurrentActor != NULL);
+ m_LastAxis[AT_X] = m_Axis[AT_X].getNormalized();
+ m_LastAxis[AT_Y] = m_Axis[AT_Y].getNormalized();
+ m_LastAxis[AT_Z] = m_Axis[AT_Z].getNormalized();
}
}
- else if (uMsg == WM_MOUSEMOVE)
+ }
+ else if (uMsg == WM_MOUSEMOVE)
+ {
+ if (m_bGizmoFollowed)
{
- if (m_bGizmoFollowed)
+ switch (m_GizmoToolMode)
{
- PxVec3 eyePos, pickDir;
- getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
- pickDir = pickDir.getNormalized();
-
- PxVec3 axis = m_Axis[m_AxisSelected];
- axis = axis.getNormalized();
- PxVec3 samplepoint = eyePos + pickDir;
- PxVec3 normal = m_LastEyeRay.cross(axis);
- normal = normal.getNormalized();
- PxVec3 foot;
- GetFootFromPointToPlane(samplepoint, eyePos, normal, foot);
- PxVec3 direction = foot - eyePos;
- direction = direction.getNormalized();
- PxVec3 target;
- GetIntersectBetweenLines(m_LastFoot, axis, eyePos, direction, target);
- PxVec3 delta = target - m_LastFoot;
-
- m_LastEyeRay = direction;
- m_LastFoot = target;
-
- PxTransform gp_old = m_CurrentActor->getGlobalPose();
- PxTransform gp_new(gp_old.p + delta, gp_old.q);;
- m_CurrentActor->setGlobalPose(gp_new);
-
- m_TargetPos = gp_new.p;
-
- bool local = AppMainWindow::Inst().m_bGizmoWithLocal;
- if (local)
+ case GTM_Translate:
{
- uint32_t shapesCount = m_CurrentActor->getNbShapes();
- if (shapesCount > 0)
+ if (AppMainWindow::Inst().m_bGizmoWithLocal && !CanModifyLocal(m_CurrentActor))
{
- PxTransform gp_newInv = gp_new.getInverse();
+ char message[1024];
+ sprintf(message, "Only unfractured model can be modify in local way in edit mode!");
+ viewer_warn(message);
+ return 1;
+ }
- PxTransform lp_old;
- PxTransform lp_new;
+ PxVec3 axis = m_Axis[m_AxisSelected];
+ axis = axis.getNormalized();
+ PxVec3 samplepoint = eyePos + pickDir;
+ PxVec3 normal = m_LastEyeRay.cross(axis);
+ normal = normal.getNormalized();
+ PxVec3 foot;
+ GetFootFromPointToPlane(samplepoint, eyePos, normal, foot);
+ PxVec3 direction = foot - eyePos;
+ direction = direction.getNormalized();
+ PxVec3 target;
+ GetIntersectBetweenLines(m_LastFoot, axis, eyePos, direction, target);
+ PxVec3 delta = target - m_LastFoot;
- std::vector<PxShape*> shapes(shapesCount);
- m_CurrentActor->getShapes(&shapes[0], shapesCount);
- getPhysXController().getPhysXScene().removeActor(*m_CurrentActor);
- for (uint32_t i = 0; i < shapesCount; i++)
- {
- PxShape* shape = shapes[i];
+ m_LastEyeRay = direction;
+ m_LastFoot = target;
- m_CurrentActor->detachShape(*shape);
+ PxTransform gp_old = m_CurrentActor->getGlobalPose();
+ PxTransform gp_new(gp_old.p + delta, gp_old.q);
+ m_CurrentActor->setGlobalPose(gp_new);
- lp_old = shape->getLocalPose();
- lp_new = gp_newInv * gp_old * lp_old;
- shape->setLocalPose(lp_new);
+ bool modifyLocal = AppMainWindow::Inst().m_bGizmoWithLocal && CanModifyLocal(m_CurrentActor);
- m_CurrentActor->attachShape(*shape);
- }
- getPhysXController().getPhysXScene().addActor(*m_CurrentActor);
+ if (!SampleManager::ins()->IsSimulating())
+ {
+ getBlastController().updateActorRenderableTransform(*m_CurrentActor, gp_new, modifyLocal);
+ if (CanMapToRootChunk(m_CurrentActor) && !modifyLocal)
+ UpdateAssetInstanceTransform(gp_new);
}
- }
- m_bNeedResetPos = true;
- m_bNeedResetColor = true;
- }
- else if(m_CurrentActor != NULL)
- {
- PxVec3 eyePos, pickDir;
- getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
- pickDir = pickDir.getNormalized();
+ m_TargetPos = gp_new.p;
- m_LastEyeRay = pickDir;
+ if (modifyLocal)
+ {
+ modifyPxActorByLocalWay(GetPhysXScene(), *m_CurrentActor, gp_old, gp_new);
+ }
- // get axis which intersect with this eye ray
- AxisType as = AT_Num;
+ m_bNeedResetPos = true;
+ m_bNeedResetColor = true;
+ }
+ break;
+ case GTM_Scale:
{
- double distanceMin = PX_MAX_F32;
- double tolerance = 1;
- int line_index = -1;
- PxVec3 foot;
- std::vector<PxDebugLine>& lines = m_AxisRenderBuffer.m_lines;
- int linesize = lines.size();
- for (int l = 0; l < linesize; l++)
+ if (AppMainWindow::Inst().m_bGizmoWithLocal && !CanModifyLocal(m_CurrentActor))
{
- PxVec3 start = lines[l].pos0;
- PxVec3 end = lines[l].pos1;
- PxVec3 dir = end - start;
- double length = dir.magnitude();
- // separate the line to 10 segment
- double delta = length * 0.1;
- for (int segment = 0; segment <= 10; segment++)
- {
- PxVec3 vertex = start + 0.1 * segment * dir;
- double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot);
+ char message[1024];
+ sprintf(message, "Only unfractured model can be modify in local way in edit mode!");
+ viewer_warn(message);
+ return 1;
+ }
- if (distance < distanceMin)
- {
- distanceMin = distance;
- line_index = l;
- m_LastFoot = foot;
- }
- }
+ PxVec3 axis = m_LastAxis[m_AxisSelected];
+ PxVec3 samplepoint = eyePos + pickDir;
+ PxVec3 normal = m_LastEyeRay.cross(axis);
+ normal = normal.getNormalized();
+ PxVec3 foot;
+ GetFootFromPointToPlane(samplepoint, eyePos, normal, foot);
+ PxVec3 direction = foot - eyePos;
+ direction = direction.getNormalized();
+ PxVec3 target;
+ GetIntersectBetweenLines(m_LastFoot, axis, eyePos, direction, target);
+ PxVec3 delta = target - m_LastFoot;
+
+ if (m_AxisSelected == AT_X)
+ {
+ delta *= defaultAxisModifier;
}
- if (distanceMin < tolerance)
+ m_Axis[m_AxisSelected] = m_LastAxis[m_AxisSelected] * defaultAxisLength + delta;
+
+ bool isShift = (GetAsyncKeyState(VK_SHIFT) && 0x8000);
+ if (isShift)
{
- int axis_index = line_index * 3 / linesize;
- as = (AxisType)axis_index;
+ float length = m_Axis[m_AxisSelected].magnitude();
+ m_Axis[AT_X] = m_LastAxis[AT_X] * length;
+ m_Axis[AT_Y] = m_LastAxis[AT_Y] * length;
+ m_Axis[AT_Z] = m_LastAxis[AT_Z] * length;
}
- }
- setAxisSelected(as);
- }
- }
- else if (uMsg == WM_LBUTTONUP)
- {
- m_bNeedResetPos = true;
- m_bNeedResetColor = true;
- m_bGizmoFollowed = false;
- }
- }
- else if (m_GizmoToolMode == GTM_Scale)
- {
- if (uMsg == WM_LBUTTONDOWN)
- {
- if (m_AxisSelected == AT_Num)
- {
- PxVec3 eyePos, pickDir;
- getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
- pickDir = pickDir.getNormalized();
- PxRaycastHit hit; hit.shape = NULL;
- PxRaycastBuffer hit1;
- getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL);
- hit = hit1.block;
+ ScaleActor(false);
+
+ m_bNeedResetPos = true;
+ m_bNeedResetColor = true;
+ }
+ break;
- if (hit.shape)
+ case GTM_Rotation:
{
- PxRigidActor* actor = hit.actor;
- PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>();
- if (NULL != rigidDynamic)
+ if (AppMainWindow::Inst().m_bGizmoWithLocal && !CanModifyLocal(m_CurrentActor))
+ {
+ char message[1024];
+ sprintf(message, "Only unfractured model can be modify in local way in edit mode!");
+ viewer_warn(message);
+ return 1;
+ }
+
+ PxVec3 planenormal = m_Axis[m_AxisSelected];
+ planenormal = planenormal.getNormalized();
+
+ PxVec3 from, to;
+ CalPlaneLineIntersectPoint(from, planenormal, m_TargetPos, m_LastEyeRay, eyePos);
+ CalPlaneLineIntersectPoint(to, planenormal, m_TargetPos, pickDir, eyePos);
+ from = from - m_TargetPos;
+ to = to - m_TargetPos;
+ from = from.getNormalized();
+ to = to.getNormalized();
+ float cosangle = from.dot(to);
+ float angle = PxAcos(cosangle);
+ PxVec3 cross = from.cross(to);
+ cross = cross.getNormalized();
+
+ PxQuat q(angle, cross);
+ if (m_AxisSelected == AT_X)
+ {
+ m_Axis[AT_Y] = q.rotate(m_Axis[AT_Y]);
+ m_Axis[AT_Z] = q.rotate(m_Axis[AT_Z]);
+ }
+ else if (m_AxisSelected == AT_Y)
+ {
+ m_Axis[AT_X] = q.rotate(m_Axis[AT_X]);
+ m_Axis[AT_Z] = q.rotate(m_Axis[AT_Z]);
+ }
+ else if (m_AxisSelected == AT_Z)
{
- m_CurrentActor = actor;
- getSelectionToolController().pointSelect(m_CurrentActor);
+ m_Axis[AT_X] = q.rotate(m_Axis[AT_X]);
+ m_Axis[AT_Y] = q.rotate(m_Axis[AT_Y]);
+ }
- PxTransform gp = m_CurrentActor->getGlobalPose();
+ m_LastEyeRay = pickDir;
- m_TargetPos = gp.p;
- m_Axis[AT_X] = gp.q.rotate(PxVec3(defaultAxisLength, 0, 0));
- m_Axis[AT_Y] = gp.q.rotate(PxVec3(0, defaultAxisLength, 0));
- m_Axis[AT_Z] = gp.q.rotate(PxVec3(0, 0, defaultAxisLength));
+ PxTransform gp_old = m_CurrentActor->getGlobalPose();
+ PxTransform gp_new = PxTransform(gp_old.p, CalConvertQuat());
+ m_CurrentActor->setGlobalPose(gp_new);
+ bool modifyLocal = AppMainWindow::Inst().m_bGizmoWithLocal && CanModifyLocal(m_CurrentActor);
- m_bNeedResetPos = true;
+ if (!SampleManager::ins()->IsSimulating())
+ {
+ getBlastController().updateActorRenderableTransform(*m_CurrentActor, gp_new, modifyLocal);
+ if (CanMapToRootChunk(m_CurrentActor))
+ UpdateAssetInstanceTransform(gp_new);
}
- else
+
+ if (modifyLocal)
{
- m_CurrentActor = NULL;
- getSelectionToolController().clearSelect();
+ modifyPxActorByLocalWay(GetPhysXScene(), *m_CurrentActor, gp_old, gp_new);
}
+
+ m_bNeedResetPos = true;
+ m_bNeedResetColor = true;
}
- }
- else
- {
- m_bGizmoFollowed = (m_CurrentActor != NULL);
- m_LastAxis[AT_X] = m_Axis[AT_X].getNormalized();
- m_LastAxis[AT_Y] = m_Axis[AT_Y].getNormalized();
- m_LastAxis[AT_Z] = m_Axis[AT_Z].getNormalized();
+ break;
}
}
- else if (uMsg == WM_MOUSEMOVE)
+ else if(m_CurrentActor != NULL)
{
- if (m_bGizmoFollowed)
+ m_LastEyeRay = pickDir;
+
+ // get axis which intersect with this eye ray
+ AxisType as = AT_Num;
{
- PxVec3 eyePos, pickDir;
- getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
- pickDir = pickDir.getNormalized();
-
- PxVec3 axis = m_LastAxis[m_AxisSelected];
- PxVec3 samplepoint = eyePos + pickDir;
- PxVec3 normal = m_LastEyeRay.cross(axis);
- normal = normal.getNormalized();
+ double distanceMin = PX_MAX_F32;
+ double tolerance = defaultAxisLength / 20.0f;
+ int line_index = -1;
PxVec3 foot;
- GetFootFromPointToPlane(samplepoint, eyePos, normal, foot);
- PxVec3 direction = foot - eyePos;
- direction = direction.getNormalized();
- PxVec3 target;
- GetIntersectBetweenLines(m_LastFoot, axis, eyePos, direction, target);
- PxVec3 delta = target - m_LastFoot;
-
- if (m_AxisSelected == AT_X)
- {
- delta *= defaultAxisModifier;
- }
- m_Axis[m_AxisSelected] = m_LastAxis[m_AxisSelected] * defaultAxisLength + delta;
-
- bool isShift = (GetAsyncKeyState(VK_SHIFT) && 0x8000);
- if (isShift)
+ switch (m_GizmoToolMode)
{
- float length = m_Axis[m_AxisSelected].magnitude();
- m_Axis[AT_X] = m_LastAxis[AT_X] * length;
- m_Axis[AT_Y] = m_LastAxis[AT_Y] * length;
- m_Axis[AT_Z] = m_LastAxis[AT_Z] * length;
- }
-
- ScaleActor(false);
-
- m_bNeedResetPos = true;
- m_bNeedResetColor = true;
- }
- else if (m_CurrentActor != NULL)
- {
- PxVec3 eyePos, pickDir;
- getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
- pickDir = pickDir.getNormalized();
-
- m_LastEyeRay = pickDir;
+ case GTM_Translate:
+ {
+ std::vector<PxDebugLine>& lines = m_AxisRenderBuffer.m_lines;
+ int linesize = lines.size();
+ for (int l = 0; l < linesize; l++)
+ {
+ PxVec3 start = lines[l].pos0;
+ PxVec3 end = lines[l].pos1;
+ PxVec3 dir = end - start;
- // get axis which intersect with this eye ray
- AxisType as = AT_Num;
- {
- double distanceMin = PX_MAX_F32;
- double tolerance = 1;
- int line_index = -1;
- std::vector<PxDebugLine>& lines = m_AxisRenderBuffer.m_lines;
- int linesize = lines.size();
- PxVec3 foot;
- for (int l = 0; l < linesize; l++)
+ // separate the line to 10 segment
+ for (int segment = 0; segment <= 10; segment++)
+ {
+ PxVec3 vertex = start + 0.1 * segment * dir;
+ double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot);
+
+ if (distance < distanceMin)
+ {
+ distanceMin = distance;
+ line_index = l;
+ m_LastFoot = foot;
+ }
+ }
+ }
+ if (distanceMin < tolerance)
+ {
+ int axis_index = line_index * 3 / linesize;
+ as = (AxisType)axis_index;
+ }
+ }
+ break;
+ case GTM_Scale:
{
- PxVec3 vertex = lines[l].pos1;
- double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot);
+ std::vector<PxDebugLine>& lines = m_AxisRenderBuffer.m_lines;
+ int linesize = lines.size();
+ for (int l = 0; l < linesize; l++)
+ {
+ PxVec3 vertex = lines[l].pos1;
+ double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot);
- if (distance < distanceMin)
+ if (distance < distanceMin)
+ {
+ distanceMin = distance;
+ line_index = l;
+ m_LastFoot = foot;
+ }
+ }
+ if (distanceMin < tolerance)
{
- distanceMin = distance;
- line_index = l;
- m_LastFoot = foot;
+ as = (AxisType)line_index;
}
}
- if (distanceMin < tolerance)
+ break;
+ case GTM_Rotation:
{
- as = (AxisType)line_index;
+ std::vector<PxDebugLine>& lines = m_CircleRenderBuffer.m_lines;
+ int linesize = lines.size();
+ for (int l = 0; l < linesize; l++)
+ {
+ PxVec3 vertex = lines[l].pos0;
+ double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot);
+
+ if (distance < distanceMin)
+ {
+ distanceMin = distance;
+ line_index = l;
+ m_LastFoot = foot;
+ }
+ }
+ if (distanceMin < tolerance)
+ {
+ int axis_index = line_index * 3 / linesize;
+ as = (AxisType)axis_index;
+ }
}
+ break;
+ default:
+ break;
}
- setAxisSelected(as);
}
+ setAxisSelected(as);
}
- else if (uMsg == WM_LBUTTONUP)
+ }
+ else if (uMsg == WM_LBUTTONUP)
+ {
+ if (m_GizmoToolMode == GTM_Scale)
{
if (m_AxisSelected != AT_Num)
{
@@ -742,180 +897,16 @@ LRESULT GizmoToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
m_Axis[AT_Y] = m_LastAxis[AT_Y] * defaultAxisLength;
m_Axis[AT_Z] = m_LastAxis[AT_Z] * defaultAxisLength;
}
-
- m_bNeedResetPos = true;
- m_bNeedResetColor = true;
- m_bGizmoFollowed = false;
}
- }
- else if (m_GizmoToolMode == GTM_Rotation)
- {
- if (uMsg == WM_LBUTTONDOWN)
- {
- if (m_AxisSelected == AT_Num)
- {
- PxVec3 eyePos, pickDir;
- getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
- pickDir = pickDir.getNormalized();
-
- PxRaycastHit hit; hit.shape = NULL;
- PxRaycastBuffer hit1;
- getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL);
- hit = hit1.block;
-
- if (hit.shape)
- {
- PxRigidActor* actor = hit.actor;
- PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>();
- if (NULL != rigidDynamic)
- {
- m_CurrentActor = actor;
- getSelectionToolController().pointSelect(m_CurrentActor);
- PxTransform gp = m_CurrentActor->getGlobalPose();
-
- m_TargetPos = gp.p;
- m_Axis[AT_X] = gp.q.rotate(PxVec3(defaultAxisLength, 0, 0));
- m_Axis[AT_Y] = gp.q.rotate(PxVec3(0, defaultAxisLength, 0));
- m_Axis[AT_Z] = gp.q.rotate(PxVec3(0, 0, defaultAxisLength));
-
- m_bNeedResetPos = true;
- }
- else
- {
- m_CurrentActor = NULL;
- getSelectionToolController().clearSelect();
- }
- }
- }
- else
- {
- m_bGizmoFollowed = (m_CurrentActor != NULL);
- }
- }
- else if (uMsg == WM_MOUSEMOVE)
+ if (m_AxisSelected != AT_Num && AppMainWindow::Inst().m_bGizmoWithLocal)
{
- if (m_bGizmoFollowed)
- {
- PxVec3 eyePos, pickDir;
- getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
- pickDir = pickDir.getNormalized();
-
- PxVec3 planenormal = m_Axis[m_AxisSelected];
- planenormal = planenormal.getNormalized();
-
- PxVec3 from, to;
- CalPlaneLineIntersectPoint(from, planenormal, m_TargetPos, m_LastEyeRay, eyePos);
- CalPlaneLineIntersectPoint(to, planenormal, m_TargetPos, pickDir, eyePos);
- from = from - m_TargetPos;
- to = to - m_TargetPos;
- from = from.getNormalized();
- to = to.getNormalized();
- float cosangle = from.dot(to);
- float angle = PxAcos(cosangle);
- PxVec3 cross = from.cross(to);
- cross = cross.getNormalized();
-
- PxQuat q(angle, cross);
- if (m_AxisSelected == AT_X)
- {
- m_Axis[AT_Y] = q.rotate(m_Axis[AT_Y]);
- m_Axis[AT_Z] = q.rotate(m_Axis[AT_Z]);
- }
- else if (m_AxisSelected == AT_Y)
- {
- m_Axis[AT_X] = q.rotate(m_Axis[AT_X]);
- m_Axis[AT_Z] = q.rotate(m_Axis[AT_Z]);
- }
- else if (m_AxisSelected == AT_Z)
- {
- m_Axis[AT_X] = q.rotate(m_Axis[AT_X]);
- m_Axis[AT_Y] = q.rotate(m_Axis[AT_Y]);
- }
-
- m_LastEyeRay = pickDir;
-
- PxTransform gp_old = m_CurrentActor->getGlobalPose();
- PxTransform gp_new = PxTransform(gp_old.p, CalConvertQuat());
- m_CurrentActor->setGlobalPose(gp_new);
-
- bool local = AppMainWindow::Inst().m_bGizmoWithLocal;
- if (local)
- {
- uint32_t shapesCount = m_CurrentActor->getNbShapes();
- if (shapesCount > 0)
- {
- PxTransform gp_newInv = gp_new.getInverse();
-
- PxTransform lp_old;
- PxTransform lp_new;
-
- std::vector<PxShape*> shapes(shapesCount);
- m_CurrentActor->getShapes(&shapes[0], shapesCount);
- getPhysXController().getPhysXScene().removeActor(*m_CurrentActor);
- for (uint32_t i = 0; i < shapesCount; i++)
- {
- PxShape* shape = shapes[i];
-
- m_CurrentActor->detachShape(*shape);
-
- lp_old = shape->getLocalPose();
- lp_new = gp_newInv * gp_old * lp_old;
- shape->setLocalPose(lp_new);
-
- m_CurrentActor->attachShape(*shape);
- }
- getPhysXController().getPhysXScene().addActor(*m_CurrentActor);
- }
- }
-
- m_bNeedResetPos = true;
- m_bNeedResetColor = true;
- }
- else if (m_CurrentActor != NULL)
- {
- PxVec3 eyePos, pickDir;
- getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
- pickDir = pickDir.getNormalized();
-
- m_LastEyeRay = pickDir;
-
- // get axis which intersect with this eye ray
- AxisType as = AT_Num;
- {
- double distanceMin = PX_MAX_F32;
- double tolerance = 1;
- int line_index = -1;
- std::vector<PxDebugLine>& lines = m_CircleRenderBuffer.m_lines;
- int linesize = lines.size();
- PxVec3 foot;
- for (int l = 0; l < linesize; l++)
- {
- PxVec3 vertex = lines[l].pos0;
- double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot);
-
- if (distance < distanceMin)
- {
- distanceMin = distance;
- line_index = l;
- m_LastFoot = foot;
- }
- }
- if (distanceMin < tolerance)
- {
- int axis_index = line_index * 3 / linesize;
- as = (AxisType)axis_index;
- }
- }
- setAxisSelected(as);
- }
- }
- else if (uMsg == WM_LBUTTONUP)
- {
- m_bNeedResetPos = true;
- m_bNeedResetColor = true;
- m_bGizmoFollowed = false;
+ getBlastController().updateModelMeshToProjectParam(*m_CurrentActor);
}
+
+ m_bNeedResetPos = true;
+ m_bNeedResetColor = true;
+ m_bGizmoFollowed = false;
}
}
@@ -937,6 +928,8 @@ void GizmoToolController::setGizmoToolMode(GizmoToolMode mode)
m_bNeedResetPos = true;
m_bNeedResetColor = true;
+
+ showAxisRenderables(true);
}
void GizmoToolController::setAxisSelected(AxisType type)
@@ -950,6 +943,23 @@ void GizmoToolController::setAxisSelected(AxisType type)
m_bNeedResetColor = true;
}
+void GizmoToolController::setAxisLength(float axisLength)
+{
+ defaultAxisLength = axisLength;
+ UpdateCircleRenderData(axisLength);
+
+ float scale = axisLength / 10.f * 0.2f;
+ m_AxisConeRenderable[AT_X]->setScale(PxVec3(scale, 2 * scale, scale));
+ m_AxisConeRenderable[AT_Y]->setScale(PxVec3(scale, 2 * scale, scale));
+ m_AxisConeRenderable[AT_Z]->setScale(PxVec3(scale, 2 * scale, scale));
+
+ m_AxisBoxRenderable[AT_X]->setScale(PxVec3(scale, scale, scale));
+ m_AxisBoxRenderable[AT_Y]->setScale(PxVec3(scale, scale, scale));
+ m_AxisBoxRenderable[AT_Z]->setScale(PxVec3(scale, scale, scale));
+
+ m_bNeedResetPos = true;
+}
+
void GizmoToolController::showAxisRenderables(bool show)
{
bool isTranslate = m_GizmoToolMode == GTM_Translate;
@@ -974,6 +984,98 @@ void GizmoToolController::resetPos()
m_CurrentActor = NULL;
}
+void GizmoToolController::setTargetActor(PxActor* actor)
+{
+ m_bNeedResetPos = true;
+ m_CurrentActor = nullptr;
+ if (actor == nullptr)
+ {
+ return;
+ }
+ PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>();
+ if (rigidDynamic == nullptr)
+ {
+ return;
+ }
+
+ m_CurrentActor = rigidDynamic;
+ getSelectionToolController().pointSelect(m_CurrentActor);
+
+ PxTransform gp = m_CurrentActor->getGlobalPose();
+
+ m_TargetPos = gp.p;
+ m_Axis[AT_X] = gp.q.rotate(PxVec3(defaultAxisLength, 0, 0));
+ m_Axis[AT_Y] = gp.q.rotate(PxVec3(0, defaultAxisLength, 0));
+ m_Axis[AT_Z] = gp.q.rotate(PxVec3(0, 0, defaultAxisLength));
+}
+
+PxActor* GizmoToolController::getTargetActor()
+{
+ return m_CurrentActor;
+}
+
+physx::PxScene& GizmoToolController::GetPhysXScene()
+{
+ if (getManager()->IsSimulating())
+ {
+ return getPhysXController().getPhysXScene();
+ }
+ else
+ {
+ return getPhysXController().getEditPhysXScene();
+ }
+}
+
+void GizmoToolController::UpdateCircleRenderData(float axisLength)
+{
+ int segment = 36;
+ double span = PxTwoPi / segment;
+ PxVec3* vertex = new PxVec3[segment];
+ m_CircleRenderData.clear();
+
+ for (int i = 0; i < segment; i++)
+ {
+ vertex[i].x = 0;
+ vertex[i].y = axisLength * PxSin(i * span);
+ vertex[i].z = axisLength * PxCos(i * span);
+ }
+ // x
+ for (int i = 0; i < segment - 1; i++)
+ {
+ m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], X_DIRECTION_COLOR_U));
+ }
+ m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], X_DIRECTION_COLOR_U));
+
+ for (int i = 0; i < segment; i++)
+ {
+ vertex[i].x = axisLength * PxCos(i * span);
+ vertex[i].y = 0;
+ vertex[i].z = axisLength * PxSin(i * span);
+ }
+ // y
+ for (int i = 0; i < segment - 1; i++)
+ {
+ m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], Y_DIRECTION_COLOR_U));
+ }
+ m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], Y_DIRECTION_COLOR_U));
+
+ for (int i = 0; i < segment; i++)
+ {
+ vertex[i].x = axisLength * PxCos(i * span);
+ vertex[i].y = axisLength * PxSin(i * span);
+ vertex[i].z = 0;
+ }
+ // z
+ for (int i = 0; i < segment - 1; i++)
+ {
+ m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], Z_DIRECTION_COLOR_U));
+ }
+ m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], Z_DIRECTION_COLOR_U));
+
+ delete[] vertex;
+ vertex = NULL;
+}
+
bool GizmoToolController::CalPlaneLineIntersectPoint(PxVec3& result, PxVec3 planeNormal, PxVec3 planePoint, PxVec3 linedirection, PxVec3 linePoint)
{
float dot = planeNormal.dot(linedirection);
@@ -1008,6 +1110,16 @@ bool GizmoToolController::GetFootFromPointToPlane(PxVec3& point, PxVec3& origin,
bool GizmoToolController::GetIntersectBetweenLines(PxVec3& origin1, PxVec3& direction1, PxVec3& origin2, PxVec3& direction2, PxVec3& intersect)
{
+ float test = ((origin2 - origin1).getNormalized()).dot(direction1.cross(direction2));
+ if (direction1.cross(direction2).isZero())
+ {// if two lines are parallel
+ return false;
+ }
+ else if (abs(test) >= 0.001)
+ {// if two lines aren't in the same plane
+ return false;
+ }
+
PxVec3 normal1 = direction1.cross(direction2);
PxVec3 normal2 = normal1.cross(direction1);
normal2 = normal2.getNormalized();
@@ -1062,38 +1174,22 @@ PxQuat GizmoToolController::CalConvertQuat()
void GizmoToolController::ScaleActor(bool replace)
{
- if (NULL == m_CurrentActor)
- {
- return;
- }
- ExtPxActor* extActor = NULL;
- PxRigidDynamic* rigidDynamic = m_CurrentActor->is<PxRigidDynamic>();
- if (NULL != rigidDynamic)
- {
- extActor = getBlastController().getExtPxManager().getActorFromPhysXActor(*rigidDynamic);
- }
- if (NULL == extActor)
+ if (nullptr == m_CurrentActor)
{
return;
}
- std::vector<BlastFamilyPtr>& families = getBlastController().getFamilies();
- if (families.size() == 0)
+ bool isLocal = AppMainWindow::Inst().m_bGizmoWithLocal;
+
+ if (isLocal && !CanModifyLocal(m_CurrentActor))
{
+ char message[1024];
+ sprintf(message, "Only unfractured model can be modify in local way in edit mode!");
+ viewer_warn(message);
return;
}
- BlastFamilyPtr pBlastFamily = NULL;
- std::vector<BlastFamilyPtr>::iterator it = families.begin();
- for (; it != families.end(); it++)
- {
- BlastFamilyPtr f = *it;
- if (f->find(extActor))
- {
- pBlastFamily = f;
- break;
- }
- }
+ BlastFamilyPtr pBlastFamily = getBlastController().getFamilyByPxActor(*m_CurrentActor);
if (NULL == pBlastFamily)
{
return;
@@ -1116,7 +1212,6 @@ void GizmoToolController::ScaleActor(bool replace)
}
PxMat44 scale = PxMat44(PxVec4(delta, 1));
- bool isLocal = AppMainWindow::Inst().m_bGizmoWithLocal;
if (!isLocal)
{
PxTransform gp = m_CurrentActor->getGlobalPose();
@@ -1134,77 +1229,87 @@ void GizmoToolController::ScaleActor(bool replace)
scale = world * scale * worldInv;
}
- pBlastFamily->setActorScale(*extActor, scale, replace);
+ pBlastFamily->setActorScale(*m_CurrentActor, scale, replace);
if (!replace)
{
return;
}
- uint32_t shapesCount = m_CurrentActor->getNbShapes();
- if (shapesCount == 0)
+ scalePxActor(GetPhysXScene(), *m_CurrentActor, scale);
+}
+
+bool GizmoToolController::CanMapToRootChunk(PxActor* actor)
+{
+ if (actor)
{
- return;
+ BlastFamily* family = getBlastController().getFamilyByPxActor(*actor);
+ if (family == nullptr)
+ return false;
+
+ const BlastAsset& asset = family->getBlastAsset();
+ uint32_t chunkIndex = family->getChunkIndexByPxActor(*actor);
+
+ std::vector<uint32_t> chunkIndexes;
+ chunkIndexes.push_back(chunkIndex);
+ std::vector<BlastChunkNode*> chunkNodes = BlastTreeData::ins().getChunkNodeByBlastChunk(&asset, chunkIndexes);
+ if (chunkNodes.size() > 0)
+ return BlastTreeData::isRoot(chunkNodes[0]);
}
+ return false;
+}
- std::vector<PxShape*> shapes(shapesCount);
- m_CurrentActor->getShapes(&shapes[0], shapesCount);
-
- getPhysXController().getPhysXScene().removeActor(*m_CurrentActor);
-
- for (uint32_t i = 0; i < shapesCount; i++)
+bool GizmoToolController::CanModifyLocal(PxActor* actor)
+{
+ if (nullptr != actor
+ && !SampleManager::ins()->IsSimulating()
+ && !getBlastController().isAssetFractrued(*actor))
{
- PxShape* shape = shapes[i];
-
- PxConvexMeshGeometry mesh;
- bool valid = shape->getConvexMeshGeometry(mesh);
- if (!valid)
- {
- continue;
- }
+ return true;
+ }
- PxConvexMesh* pMesh = mesh.convexMesh;
- if (NULL == pMesh)
- {
- continue;
- }
+ return false;
+}
- PxU32 numVertex = pMesh->getNbVertices();
- if (numVertex == 0)
- {
- continue;
- }
+void GizmoToolController::UpdateAssetInstanceTransform(const PxTransform& position)
+{
+ if (!m_CurrentActor)
+ return;
- const PxVec3* pVertex = pMesh->getVertices();
- PxVec3* pVertexNew = new PxVec3[numVertex];
- for (PxU32 v = 0; v < numVertex; v++)
- {
- pVertexNew[v] = scale.transform(pVertex[v]);
- }
+ BlastFamily* family = getBlastController().getFamilyByPxActor(*m_CurrentActor);
+ if (family)
+ {
+ BPPAssetInstance* bppInstance = SampleManager::ins()->getInstanceByFamily(family);
- PxConvexMeshDesc convexMeshDesc;
- convexMeshDesc.points.count = numVertex;
- convexMeshDesc.points.data = pVertexNew;
- convexMeshDesc.points.stride = sizeof(PxVec3);
- convexMeshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
- PxPhysics& physics = getManager()->getPhysXController().getPhysics();
- PxCooking& cooking = getManager()->getPhysXController().getCooking();
- PxConvexMesh* convexMesh = cooking.createConvexMesh(convexMeshDesc, physics.getPhysicsInsertionCallback());
- if (NULL == convexMesh)
+ if (bppInstance)
{
- delete[] pVertexNew;
- continue;
- }
+ bppInstance->transform.position = *((nvidia::NvVec3*)(&position.p));
+ bppInstance->transform.rotation = *((nvidia::NvVec4*)(&position.q));
- mesh.convexMesh = convexMesh;
+ family->initTransform(position);
+ // modify corresponding asset's transform, it's need to modify in future
+ {
+ const BlastAsset& asset = family->getBlastAsset();
+ SampleManager* sampleManager = SampleManager::ins();
+ std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager->getAssetFamiliesMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = sampleManager->getAssetDescMap();
- m_CurrentActor->detachShape(*shape);
- shape->setGeometry(mesh);
- m_CurrentActor->attachShape(*shape);
+ BlastAsset* pBlastAsset = (BlastAsset*)&asset;
- pMesh->release();
- delete[] pVertexNew;
+ AssetList::ModelAsset& m = AssetDescMap[pBlastAsset];
+ m.transform = position;
+ }
+ }
}
+}
- getPhysXController().getPhysXScene().addActor(*m_CurrentActor);
+void GizmoToolController::syncRenderableState()
+{
+ bool depthTest = AppMainWindow::Inst().m_bGizmoWithDepthTest;
+ m_AxisConeRenderable[AT_X]->setDepthTest(depthTest);
+ m_AxisConeRenderable[AT_Y]->setDepthTest(depthTest);
+ m_AxisConeRenderable[AT_Z]->setDepthTest(depthTest);
+ m_AxisBoxRenderable[AT_X]->setDepthTest(depthTest);
+ m_AxisBoxRenderable[AT_Y]->setDepthTest(depthTest);
+ m_AxisBoxRenderable[AT_Z]->setDepthTest(depthTest);
} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h
index 215cde5..8586ad3 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef GIZMO_TOOL_CONTROLLER_H
#define GIZMO_TOOL_CONTROLLER_H
@@ -14,6 +32,7 @@
#include "SampleManager.h"
#include "DebugRenderBuffer.h"
#include "NvBlastExtPxManager.h"
+#include "BlastSceneTree.h"
class Renderable;
class RenderMaterial;
@@ -26,6 +45,11 @@ class ExtPhysicsActor;
}
}
+namespace physx
+{
+ class PxScene;
+}
+
enum AxisType
{
AT_X = 0,
@@ -41,7 +65,10 @@ enum GizmoToolMode
GTM_Rotation
};
-class GizmoToolController : public ISampleController
+void modifyPxActorByLocalWay(PxScene& pxScene, PxRigidDynamic& actor, PxTransform& gp_old, PxTransform& gp_new);
+void scalePxActor(PxScene& pxScene, PxRigidDynamic& actor, PxMat44& scale);
+
+class GizmoToolController : public ISampleController, public ISceneObserver
{
public:
GizmoToolController();
@@ -55,16 +82,26 @@ public:
virtual void onSampleStart();
virtual void onSampleStop();
+ virtual void dataSelected(std::vector<BlastNode*> selections);
+
void setGizmoToolMode(GizmoToolMode mode);
+ GizmoToolMode getGizmoToolMode() { return m_GizmoToolMode; }
void setAxisSelected(AxisType type);
+ void setAxisLength(float axisLength);
void showAxisRenderables(bool show);
void resetPos();
+ void setTargetActor(PxActor* actor);
+ PxActor* getTargetActor();
+ void syncRenderableState();
+ bool CanMapToRootChunk(PxActor* actor);
private:
GizmoToolController& operator= (GizmoToolController&);
//////// private methods ////////
+ physx::PxScene& GetPhysXScene();
+ void UpdateCircleRenderData(float axisLength);
bool CalPlaneLineIntersectPoint(PxVec3& result, PxVec3 planeNormal, PxVec3 planePoint, PxVec3 linedirection, PxVec3 linePoint);
float DistanceFromPointToLine(PxVec3& point, PxVec3& origin, PxVec3& direction, PxVec3& foot);
bool GetFootFromPointToPlane(PxVec3& point, PxVec3& origin, PxVec3& normal, PxVec3& foot);
@@ -72,6 +109,10 @@ private:
PxQuat CalDirectionQuat(AxisType type);
PxQuat CalConvertQuat();
void ScaleActor(bool replace);
+
+ bool CanModifyLocal(PxActor* actor);
+ void UpdateAssetInstanceTransform(const PxTransform& position);
+
//////// used controllers ////////
Renderer& getRenderer() const
@@ -103,7 +144,7 @@ private:
PxVec3 m_LastFoot;
PxVec3 m_LastAxis[AT_Num];
- PxRigidActor* m_CurrentActor;
+ PxRigidDynamic* m_CurrentActor;
bool m_bNeedResetPos;
bool m_bNeedResetColor;
@@ -119,6 +160,8 @@ private:
std::vector<PxDebugLine> m_CircleRenderData;
DebugRenderBuffer m_CircleRenderBuffer;
+
+ std::vector<BlastAssetInstanceNode*> m_assetInstances;
};
#endif // GIZMO_TOOL_CONTROLLER_H \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp
index 02a511f..458aec3 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#include "SelectionToolController.h"
#include "RenderUtils.h"
@@ -14,6 +32,7 @@
#include "Renderer.h"
#include "PhysXController.h"
#include "SampleProfiler.h"
+#include "GizmoToolController.h"
#include <imgui.h>
@@ -23,7 +42,7 @@
#include "PxRigidDynamic.h"
#include "PxScene.h"
#include "BlastSceneTree.h"
-
+#include "SimpleScene.h"
using namespace Nv::Blast;
using namespace physx;
@@ -39,6 +58,9 @@ using namespace physx;
SelectionToolController::SelectionToolController()
{
m_bRectSelecting = false;
+ m_bSelecting = false;
+
+ BlastSceneTree::ins()->addObserver(this);
}
SelectionToolController::~SelectionToolController()
@@ -58,6 +80,29 @@ void SelectionToolController::onSampleStop()
{
}
+void SelectionToolController::dataSelected(std::vector<BlastNode*> selections)
+{
+ m_actorsSelected.clear();
+
+ BlastController& blastController = getBlastController();
+ std::vector<BlastFamilyPtr>& families = blastController.getFamilies();
+
+ for (BlastFamily* family : families)
+ {
+ std::vector<uint32_t> selectedChunks = family->getSelectedChunks();
+ for (uint32_t chunkIndex : selectedChunks)
+ {
+ PxActor* actor = nullptr;
+ family->getPxActorByChunkIndex(chunkIndex, &actor);
+
+ if (actor)
+ {
+ m_actorsSelected.emplace(actor);
+ }
+ }
+ }
+}
+
void SelectionToolController::Animate(double dt)
{
PROFILER_SCOPED_FUNCTION();
@@ -76,6 +121,10 @@ LRESULT SelectionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP
if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP)
{
float mouseX = (short)LOWORD(lParam) / getRenderer().getScreenWidth();
+ if (!SimpleScene::Inst()->m_pCamera->_lhs)
+ {
+ mouseX = 1 - mouseX;
+ }
float mouseY = (short)HIWORD(lParam) / getRenderer().getScreenHeight();
bool press = uMsg == WM_LBUTTONDOWN;
@@ -89,7 +138,18 @@ LRESULT SelectionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP
m_RectSelectSpaceDir = pickDir.getNormalized();
m_RectRenderBuffer.clear();
- m_bRectSelecting = true;
+ bool isCtrl = (GetAsyncKeyState(VK_CONTROL) && 0x8000);
+ bool isAlt = (GetAsyncKeyState(VK_MENU) && 0x8000);
+ bool isLight = (GetAsyncKeyState('L') && 0x8000);
+ // ctrl+leftbutton is used for light changing
+ // alt+leftbutton is used for camera rotate movement in AppMainWindow.cpp
+ // so, we use rect select when ctrl and alt off
+ m_bRectSelecting = !(isAlt || isLight);// !(isCtrl || isAlt);
+ if (isAlt || isLight)
+ {
+ m_RectRenderBuffer.clear();
+ }
+ m_bSelecting = true;
}
else if (uMsg == WM_MOUSEMOVE)
{
@@ -161,8 +221,9 @@ LRESULT SelectionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP
{
return 1;
}
-
- if (m_bRectSelecting)
+ bool isAlt = (GetAsyncKeyState(VK_MENU) && 0x8000);
+ bool isLight = (GetAsyncKeyState('L') && 0x8000);
+ if (m_bSelecting && !(isAlt || isLight))
{
bool isShift = (GetAsyncKeyState(VK_SHIFT) && 0x8000);
bool isCtrl = (GetAsyncKeyState(VK_CONTROL) && 0x8000);
@@ -180,15 +241,18 @@ LRESULT SelectionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP
{
selectMode = SM_SUB;
}
-
int width = getRenderer().getScreenWidth();
int height = getRenderer().getScreenHeight();
int deltaX = (mouseX - m_RectSelectScreenPos.x) * width;
int deltaY = (mouseY - m_RectSelectScreenPos.y) * height;
float distance = deltaX * deltaX + deltaY * deltaY;
- // rect select mode
- if (distance > 1)
+ if (distance < 1)
+ {
+ m_bRectSelecting = false;
+ }
+ if (m_bRectSelecting)
{
+ // rect select mode
PxVec3 eyePos, pickDir[3];
getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir[0]);
getPhysXController().getEyePoseAndPickDir(m_RectSelectScreenPos.x, mouseY, eyePos, pickDir[1]);
@@ -243,23 +307,35 @@ LRESULT SelectionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP
getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir);
pickDir = pickDir.getNormalized();
- PxRaycastHit hit; hit.shape = NULL;
- PxRaycastBuffer hit1;
- getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL);
- hit = hit1.block;
+ PxRaycastBufferN<32> hits;
+
+ GetPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hits, PxHitFlag::eDEFAULT | PxHitFlag::eMESH_MULTIPLE);
+
+ PxU32 nbThouches = hits.getNbTouches();
+ const PxRaycastHit* touches = hits.getTouches();
PxRigidActor* actor = NULL;
- if (hit.shape)
+ float fDistance = PX_MAX_F32;
+ for (PxU32 u = 0; u < nbThouches; ++u)
{
- actor = hit.actor;
+ const PxRaycastHit& t = touches[u];
+ if (t.shape && getBlastController().isActorVisible(*(t.actor)))
+ {
+ if (fDistance > t.distance)
+ {
+ fDistance = t.distance;
+ actor = t.actor;
+ }
+ }
}
+
pointSelect(actor, selectMode);
}
}
- BlastSceneTree::ins()->updateChunkItemSelection();
m_RectRenderBuffer.clear();
m_bRectSelecting = false;
+ m_bSelecting = false;
}
}
@@ -272,42 +348,35 @@ void SelectionToolController::drawUI()
void SelectionToolController::pointSelect(PxActor* actor, SelectMode selectMode)
{
- ExtPxActor* extActor = NULL;
- if (NULL != actor)
- {
- PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>();
- if (NULL != rigidDynamic)
- {
- extActor = getBlastController().getExtPxManager().getActorFromPhysXActor(*rigidDynamic);
- }
- }
-
if (selectMode == SM_RESET)
{
clearSelect();
- if (NULL != extActor)
+ if (NULL != actor)
{
- setActorSelected(*extActor, true);
- m_actorsSelected.emplace(extActor);
+ setActorSelected(*actor, true);
+ m_actorsSelected.emplace(actor);
}
}
else if (selectMode == SM_ADD)
{
- if (NULL != extActor)
+ if (NULL != actor)
{
- setActorSelected(*extActor, true);
- m_actorsSelected.emplace(extActor);
+ setActorSelected(*actor, true);
+ m_actorsSelected.emplace(actor);
}
}
else if (selectMode == SM_SUB)
{
- if (NULL != extActor)
+ if (NULL != actor)
{
- setActorSelected(*extActor, false);
- m_actorsSelected.erase(extActor);
+ setActorSelected(*actor, false);
+ m_actorsSelected.erase(actor);
}
}
+
+ BlastSceneTree::ins()->updateChunkItemSelection();
+ trySelectAssetInstanceNode(m_actorsSelected);
}
#include "PxPhysics.h"
@@ -316,8 +385,8 @@ void SelectionToolController::pointSelect(PxActor* actor, SelectMode selectMode)
class RectSelectionCallback : public PxOverlapCallback
{
public:
- RectSelectionCallback(ExtPxManager& physicsManager, std::set<ExtPxActor*>& actorBuffer)
- : m_physicsManager(physicsManager), m_actorBuffer(actorBuffer), PxOverlapCallback(m_hitBuffer, sizeof(m_hitBuffer) / sizeof(m_hitBuffer[0])) {}
+ RectSelectionCallback(std::set<PxActor*>& actorBuffer)
+ :m_actorBuffer(actorBuffer), PxOverlapCallback(m_hitBuffer, sizeof(m_hitBuffer) / sizeof(m_hitBuffer[0])) {}
PxAgain processTouches(const PxOverlapHit* buffer, PxU32 nbHits)
{
@@ -326,25 +395,20 @@ public:
PxRigidDynamic* rigidDynamic = buffer[i].actor->is<PxRigidDynamic>();
if (rigidDynamic)
{
- ExtPxActor* actor = m_physicsManager.getActorFromPhysXActor(*rigidDynamic);
- if (actor != nullptr)
- {
- m_actorBuffer.insert(actor);
- }
+ m_actorBuffer.insert(rigidDynamic);
}
}
return true;
}
private:
- ExtPxManager& m_physicsManager;
- std::set<ExtPxActor*>& m_actorBuffer;
- PxOverlapHit m_hitBuffer[1000];
+ std::set<PxActor*>& m_actorBuffer;
+ PxOverlapHit m_hitBuffer[1000];
};
void SelectionToolController::rectSelect(PxVec3 eyePos, PxVec3 lefttop, PxVec3 leftbottom, PxVec3 righttop, PxVec3 rightbottom, SelectMode selectMode)
{
- std::set<ExtPxActor*> actorsToSelect;
+ std::set<PxActor*> actorsToSelect;
float nearClip = 1;
PxVec3 nearlefttop = lefttop * nearClip;
@@ -373,8 +437,8 @@ void SelectionToolController::rectSelect(PxVec3 eyePos, PxVec3 lefttop, PxVec3 l
PxConvexMesh* convexMesh = cooking.createConvexMesh(convexMeshDesc, physics.getPhysicsInsertionCallback());
if (NULL != convexMesh)
{
- RectSelectionCallback overlapCallback(getBlastController().getExtPxManager(), actorsToSelect);
- getManager()->getPhysXController().getPhysXScene().overlap(PxConvexMeshGeometry(convexMesh), PxTransform(eyePos), overlapCallback);
+ RectSelectionCallback overlapCallback(actorsToSelect);
+ GetPhysXScene().overlap(PxConvexMeshGeometry(convexMesh), PxTransform(eyePos), overlapCallback);
convexMesh->release();
}
@@ -382,33 +446,42 @@ void SelectionToolController::rectSelect(PxVec3 eyePos, PxVec3 lefttop, PxVec3 l
{
clearSelect();
- for (ExtPxActor* actor : actorsToSelect)
+ for (PxActor* actor : actorsToSelect)
{
- setActorSelected(*actor, true);
- m_actorsSelected.emplace(actor);
+ if (getBlastController().isActorVisible(*actor))
+ {
+ setActorSelected(*actor, true);
+ m_actorsSelected.emplace(actor);
+ }
}
}
else if (selectMode == SM_ADD)
{
- for (ExtPxActor* actor : actorsToSelect)
+ for (PxActor* actor : actorsToSelect)
{
- setActorSelected(*actor, true);
- m_actorsSelected.emplace(actor);
+ if (getBlastController().isActorVisible(*actor))
+ {
+ setActorSelected(*actor, true);
+ m_actorsSelected.emplace(actor);
+ }
}
}
else if (selectMode == SM_SUB)
{
- for (ExtPxActor* actor : actorsToSelect)
+ for (PxActor* actor : actorsToSelect)
{
setActorSelected(*actor, false);
m_actorsSelected.erase(actor);
}
}
+
+ BlastSceneTree::ins()->updateChunkItemSelection();
+ trySelectAssetInstanceNode(m_actorsSelected);
}
void SelectionToolController::clearSelect()
{
- for (ExtPxActor* actor : m_actorsSelected)
+ for (PxActor* actor : m_actorsSelected)
{
setActorSelected(*actor, false);
}
@@ -417,7 +490,75 @@ void SelectionToolController::clearSelect()
SampleManager::ins()->clearChunksSelected();
}
-void SelectionToolController::setActorSelected(const ExtPxActor& actor, bool selected)
+void SelectionToolController::setTargetActor(PxActor* actor)
+{
+ if (actor == nullptr)
+ {
+ return;
+ }
+
+ setActorSelected(*actor, true);
+ m_actorsSelected.emplace(actor);
+
+ BlastSceneTree::ins()->updateChunkItemSelection();
+ trySelectAssetInstanceNode(m_actorsSelected);
+}
+
+PxActor* SelectionToolController::getTargetActor()
+{
+ PxActor* targetActor = nullptr;
+ if (m_actorsSelected.size() > 0)
+ {
+ targetActor = *m_actorsSelected.begin();
+ }
+ return targetActor;
+}
+
+void SelectionToolController::setTargetActors(std::set<PxActor*>& actors)
+{
+ for (PxActor* actor : actors)
+ {
+ setActorSelected(*actor, true);
+ m_actorsSelected.emplace(actor);
+ }
+
+ BlastSceneTree::ins()->updateChunkItemSelection();
+ trySelectAssetInstanceNode(m_actorsSelected);
+}
+
+std::set<PxActor*> SelectionToolController::getTargetActors()
+{
+ return m_actorsSelected;
+}
+
+void SelectionToolController::trySelectAssetInstanceNode(std::set<PxActor*>& selectedActors)
+{
+ BlastController& blastController = getBlastController();
+ GizmoToolController& gizmoToolController = getManager()->getGizmoToolController();
+
+ for (PxActor* actor : selectedActors)
+ {
+ if (gizmoToolController.CanMapToRootChunk(actor))
+ {
+ BlastFamily* family = getBlastController().getFamilyByPxActor(*actor);
+ BlastSceneTree::ins()->selectTreeItem(family);
+ }
+ }
+}
+
+physx::PxScene& SelectionToolController::GetPhysXScene()
+{
+ if (getManager()->IsSimulating())
+ {
+ return getPhysXController().getPhysXScene();
+ }
+ else
+ {
+ return getPhysXController().getEditPhysXScene();
+ }
+}
+
+void SelectionToolController::setActorSelected(const PxActor& actor, bool selected)
{
std::vector<BlastFamilyPtr>& families = getBlastController().getFamilies();
if (families.size() == 0)
@@ -430,7 +571,7 @@ void SelectionToolController::setActorSelected(const ExtPxActor& actor, bool sel
for (; it != families.end(); it++)
{
BlastFamilyPtr f = *it;
- if (f->find((ExtPxActor*)&actor))
+ if (f->find(actor))
{
pBlastFamily = f;
break;
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h
index 5261b90..74220e7 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef SELECTION_TOOL_CONTROLLER_H
#define SELECTION_TOOL_CONTROLLER_H
@@ -17,6 +35,8 @@
#include "DebugRenderBuffer.h"
#include "BlastFamily.h"
#include "NvBlastExtPxManager.h"
+#include "BlastSceneTree.h"
+
class Renderable;
class RenderMaterial;
@@ -28,7 +48,12 @@ class ExtPxActor;
}
}
-class SelectionToolController : public ISampleController
+namespace physx
+{
+ class PxScene;
+}
+
+class SelectionToolController : public ISampleController, public ISceneObserver
{
public:
SelectionToolController();
@@ -42,15 +67,27 @@ public:
virtual void onSampleStart();
virtual void onSampleStop();
+ virtual void dataSelected(std::vector<BlastNode*> selections);
+
void pointSelect(PxActor* actor, SelectMode selectMode = SM_RESET);
void rectSelect(PxVec3 eyePos, PxVec3 lefttop, PxVec3 leftbottom, PxVec3 righttop, PxVec3 rightbottom, SelectMode selectMode = SM_RESET);
void clearSelect();
+ void setTargetActor(PxActor* actor);
+ PxActor* getTargetActor();
+
+ void setTargetActors(std::set<PxActor*>& actors);
+ std::set<PxActor*> getTargetActors();
+
+ void trySelectAssetInstanceNode(std::set<PxActor*>& selectedActors);
+
private:
SelectionToolController& operator= (SelectionToolController&);
//////// private methods ////////
+ physx::PxScene& GetPhysXScene();
+
//////// used controllers ////////
Renderer& getRenderer() const
@@ -73,10 +110,11 @@ private:
PxVec2 m_RectSelectScreenPos;
PxVec3 m_RectSelectSpaceDir;
bool m_bRectSelecting;
+ bool m_bSelecting;
DebugRenderBuffer m_RectRenderBuffer;
- void setActorSelected(const ExtPxActor& actor, bool selected);
- std::set<ExtPxActor*> m_actorsSelected;
+ void setActorSelected(const PxActor& actor, bool selected);
+ std::set<PxActor*> m_actorsSelected;
};
#endif // SELECTION_TOOL_CONTROLLER_H \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/PxInputDataFromPxFileBuf.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/PxInputDataFromPxFileBuf.h
index dfa8260..e309abd 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/PxInputDataFromPxFileBuf.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/PxInputDataFromPxFileBuf.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef PXINPUTDATAFROMPXFILEBUF_H
#define PXINPUTDATAFROMPXFILEBUF_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.cpp
index 4df23fd..cb63eeb 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.cpp
@@ -1,12 +1,29 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
#include "SampleProfiler.h"
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.h
index 1ea3663..5f8a326 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef SAMPLEPROFILER_H
#define SAMPLEPROFILER_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleTime.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleTime.h
index c62ced2..8226cd4 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleTime.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleTime.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef SAMPLE_TIME_H
#define SAMPLE_TIME_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/UIHelpers.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/UIHelpers.h
index b23eb84..cdd50ff 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/UIHelpers.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/UIHelpers.h
@@ -1,12 +1,30 @@
-/*
-* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* NVIDIA CORPORATION and its licensors retain all intellectual property
-* and proprietary rights in and to this software, related documentation
-* and any modifications thereto. Any use, reproduction, disclosure or
-* distribution of this software and related documentation without an express
-* license agreement from NVIDIA CORPORATION is strictly prohibited.
-*/
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
#ifndef UI_HELPERS_H
#define UI_HELPERS_H
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.cpp
index a271137..9eafabc 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.cpp
@@ -1,3 +1,31 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
+
#include "Utils.h"
#include <string>
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.h
index 5d4addc..42bf713 100644
--- a/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.h
+++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.h
@@ -1,3 +1,31 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+
+
#ifndef UTILS_H
#define UTILS_H
diff --git a/tools/ArtistTools/source/BlastPlugin/Shaders/common_buffers_ex.hlsl b/tools/ArtistTools/source/BlastPlugin/Shaders/common_buffers_ex.hlsl
new file mode 100644
index 0000000..0076599
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/Shaders/common_buffers_ex.hlsl
@@ -0,0 +1,60 @@
+#ifndef COMMON_BUFFERS_HLSL
+#define COMMON_BUFFERS_HLSL
+
+cbuffer Camera : register(b0)
+{
+ row_major matrix viewProjection;
+ row_major matrix projectionInv;
+ float3 viewPos;
+};
+
+struct Light
+{
+ int m_enable;
+ float3 m_dir;
+
+ int m_useShadows;
+ float3 m_color;
+
+ float3 m_ambientColor;
+ int m_isEnvLight;
+
+ int m_lhs;
+ int _reserved1;
+ int _reserved2;
+ int _reserved3;
+
+ float m_depthBias;
+ float m_depthGain;
+ int m_useEnvMap;
+ float m_intensity;
+
+ row_major float4x4 m_viewMatrix;
+ row_major float4x4 m_lightMatrix;
+};
+
+cbuffer World : register(b1)
+{
+ float3 ambientColor;
+ float3 pointLightPos;
+ float3 pointLightColor;
+ float3 dirLightDir;
+ float specularPower;
+ float3 dirLightColor;
+ float specularIntensity;
+ Light g_Light[4];
+};
+
+cbuffer Object : register(b2)
+{
+ row_major matrix worldMatrix;
+ float4 m_diffuseColor;
+ float4 m_specularColor;
+ float m_useDiffuseTexture;
+ float m_useSpecularTexture;
+ float m_useNormalTexture;
+ float m_specularShininess;
+ float selected;
+};
+
+#endif \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/Shaders/lighting_ex.hlsl b/tools/ArtistTools/source/BlastPlugin/Shaders/lighting_ex.hlsl
new file mode 100644
index 0000000..6878e23
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/Shaders/lighting_ex.hlsl
@@ -0,0 +1,51 @@
+#include "common_buffers_ex.hlsl"
+
+static const float att_c = 1.0f;
+static const float att_l = 0.014f;
+static const float att_q = 0.0007f;
+
+
+float CalcAttenuation(float distance)
+{
+ return 1 / (att_c + att_l * distance + att_q * distance * distance);
+};
+
+
+float3 CalcLight(float3 textureColor, float3 lightDir, float3 viewDir, float3 normal, float3 lightColor, float specPower, float specIntensity, float attenuation)
+{
+ normal = normalize(normal);
+
+ // diffuse
+ float3 dirToLight = normalize(-lightDir);
+ float diffuseFactor = max(dot(normal, dirToLight), 0.0);
+ float3 diffuse = lightColor * textureColor * diffuseFactor * attenuation;
+
+ // specular (Blinn-Phong)
+ float3 halfwayDir = normalize(dirToLight + viewDir);
+ float specFactor = pow(max(dot(viewDir, halfwayDir), 0.0), specPower);
+ float3 spec = lightColor * specFactor * attenuation * specIntensity;
+
+ return diffuse + spec;
+};
+
+float3 CalcPixelLight(float3 diffuseColor, float3 worldPos, float3 normal)
+{
+ float3 viewDir = normalize(viewPos - worldPos);
+
+ // ambient
+ float3 ambient = ambientColor * diffuseColor;
+
+ // dir light
+ float3 dirLight = CalcLight(diffuseColor, dirLightDir, viewDir, normal, dirLightColor, specularPower, specularIntensity, 1);
+
+ // point light
+ float3 pointLightDir = worldPos - pointLightPos;
+ float distance = length(pointLightDir);
+ float attenuation = CalcAttenuation(distance);
+ float3 pointLight = CalcLight(diffuseColor, pointLightDir, viewDir, normal, pointLightColor, specularPower, specularIntensity, attenuation);
+
+ // hacky hack: ambient attenuates within point light distance
+ ambient *= attenuation;
+
+ return ambient + dirLight + pointLight;
+}; \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/Shaders/model_simple_ex.hlsl b/tools/ArtistTools/source/BlastPlugin/Shaders/model_simple_ex.hlsl
new file mode 100644
index 0000000..409054c
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/Shaders/model_simple_ex.hlsl
@@ -0,0 +1,56 @@
+#include "common_buffers_ex.hlsl"
+#include "lighting.hlsl"
+
+struct VS_INPUT
+{
+ float3 position : POSITION0;
+ float3 normal : NORMAL0;
+ float health : TEXCOORD1;
+};
+
+struct VS_OUTPUT
+{
+ float4 position : SV_POSITION;
+ float4 worldPos : POSITION0;
+ float3 normal : NORMAL0;
+ float health : TEXCOORD1;
+};
+
+VS_OUTPUT VS(VS_INPUT iV)
+{
+ VS_OUTPUT oV;
+
+ float4 worldSpacePos = mul(float4(iV.position, 1.0f), model);
+ oV.position = mul(worldSpacePos, viewProjection);
+
+ oV.worldPos = worldSpacePos;
+
+ // normals
+ float3 worldNormal = mul(iV.normal, (float3x3)model);
+ oV.normal = worldNormal;
+
+ oV.health = iV.health;
+
+ return oV;
+}
+
+float4 PS(VS_OUTPUT iV) : SV_Target0
+{
+ float3 lightColor = CalcPixelLight(defaultColor.xyz, iV.worldPos.xyz, iV.normal);
+ lightColor.r = 1.0f - iV.health; // hack for health
+ float4 color = float4(lightColor, 1);
+
+ if(selected > 0)
+ {
+ if(color.r > 0.5)
+ {
+ color.r = 0.5;
+ }
+ else
+ {
+ color.r += 0.5;
+ }
+ }
+
+ return color;
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/Shaders/model_simple_textured_ex.hlsl b/tools/ArtistTools/source/BlastPlugin/Shaders/model_simple_textured_ex.hlsl
new file mode 100644
index 0000000..152174c
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/Shaders/model_simple_textured_ex.hlsl
@@ -0,0 +1,160 @@
+#include "common_buffers_ex.hlsl"
+#include "lighting_ex.hlsl"
+
+SamplerState defaultSampler : register(s0);
+Texture2D diffuseTexture : register(t0);
+Texture2D specularTexture : register(t1);
+Texture2D normalTexture : register(t2);
+Texture2D envTexture : register(t3);
+
+struct VS_INPUT
+{
+ float3 position : POSITION0;
+ float3 normal : NORMAL0;
+ float3 tangent : TANGENT0;
+ float2 uv : TEXCOORD0;
+ float health : TEXCOORD1;
+};
+
+struct VS_OUTPUT
+{
+ float4 position : SV_POSITION;
+ float4 worldPos : POSITION0;
+ float3 normal : NORMAL0;
+ float3 tangent : TANGENT0;
+ float2 uv : TEXCOORD0;
+ float health : TEXCOORD1;
+};
+
+VS_OUTPUT VS(VS_INPUT iV)
+{
+ VS_OUTPUT oV;
+
+ float4 worldSpacePos = mul(float4(iV.position, 1.0f), worldMatrix);
+ oV.position = mul(worldSpacePos, viewProjection);
+
+ oV.worldPos = worldSpacePos;
+
+ // normals
+ float3 worldNormal = mul(float4(iV.normal, 0.0f), worldMatrix);
+ oV.normal = worldNormal;
+
+ oV.tangent = normalize(iV.tangent);
+
+ oV.uv = iV.uv;
+ oV.health = iV.health;
+
+ return oV;
+}
+
+inline float2 GetLightTexCoord(float3 lightdirection)
+{
+ const float M_PI = 3.1415923;
+ float u = 0.5f + 0.5f * atan2(lightdirection.y, lightdirection.x) / M_PI;
+ float v = 0.5f - 0.5f * lightdirection.z;
+ return float2(u,v);
+}
+
+inline float3 computeDiffuseLighting(
+ float3 diffuse, float3 lightdirection, float3 surfacenormal )
+{
+ float ratio = max(0, dot(surfacenormal, lightdirection));
+ return diffuse * ratio;
+}
+
+inline float3 computeSpecularLighting(
+ float3 lightcolor, float3 lightdirection, float3 surfacenormal,
+ float3 viewvector, float3 specularity, float shininess)
+{
+ float3 H = normalize(viewvector + surfacenormal);
+ float NdotH = max(0, dot(H, surfacenormal));
+ float specular = pow(NdotH, shininess);
+ float3 output = specular * lightcolor * specularity;
+ return output;
+}
+
+float4 PS(VS_OUTPUT iV) : SV_Target0
+{
+ float3 diffuseColor = m_diffuseColor.xyz;
+ if(m_useDiffuseTexture > 0)
+ {
+ diffuseColor = diffuseTexture.Sample(defaultSampler, iV.uv).xyz;
+ }
+ float3 specularColor = m_specularColor.xyz;
+ if(m_useSpecularTexture > 0)
+ {
+ specularColor = specularTexture.Sample(defaultSampler, iV.uv).xyz;
+ }
+ float3 N = normalize(iV.normal.xyz);
+ if (m_useNormalTexture > 0)
+ {
+ float3 normalColor = normalTexture.Sample(defaultSampler, iV.uv).xyz;
+ normalColor = (normalColor - 0.5) * 2.0f;
+ float3 T = normalize(iV.tangent.xyz);
+ float3 B = normalize(cross(T, N));
+ float3 PN = N;
+ PN += normalColor.x * T;
+ PN += normalColor.y * B;
+ PN += normalColor.z * N;
+ N = normalize(PN);
+ }
+
+ float4 color = float4(0,0,0,1);
+
+ float3 P = iV.worldPos.xyz;
+ float3 E = normalize(viewPos.xyz - P);
+ float shininess = m_specularShininess;
+
+ float3 albedo = diffuseColor.rgb;
+ float3 specularity = specularColor.rgb;
+
+ float3 diffuse = 0;
+ float3 specular = 0;
+ float3 ambient = 0;
+
+ [unroll]
+ for (int i = 0; i < 4; i++)
+ {
+ Light L = g_Light[i];
+
+ if (L.m_enable)
+ {
+ float3 Ldiffuse = 0;
+ float3 Lspecular = 0;
+ float3 Ldir = 0;
+
+ if (L.m_isEnvLight)
+ {
+ Ldir = N;
+ float2 texcoords = GetLightTexCoord(Ldir);
+ float3 Lcolor = (L.m_useEnvMap) ? envTexture.Sample(defaultSampler,texcoords.xy).rgb : L.m_color;
+ Lcolor *= L.m_intensity;
+ Ldiffuse = Lspecular = Lcolor;
+ }
+ else
+ {
+ Ldir = L.m_dir;
+ Ldiffuse = Lspecular = L.m_intensity * L.m_color;
+ }
+
+ diffuse += computeDiffuseLighting( Ldiffuse, Ldir, N);
+ specular += computeSpecularLighting( Lspecular, Ldir, N, E, specularity, shininess);
+ ambient += L.m_ambientColor;
+ }
+ }
+
+ color.rgb = (ambient + diffuse) * albedo + specular;
+
+ if(selected > 0)
+ {
+ if(color.r > 0.5)
+ {
+ color.r = 0.5;
+ }
+ else
+ {
+ color.r += 0.5;
+ }
+ }
+ return color;
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/BlastSceneTree.ui b/tools/ArtistTools/source/BlastPlugin/UI/BlastSceneTree.ui
new file mode 100644
index 0000000..52e80f7
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/BlastSceneTree.ui
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BlastSceneTree</class>
+ <widget class="QDockWidget" name="BlastSceneTree">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>300</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="features">
+ <set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
+ </property>
+ <property name="windowTitle">
+ <string>BlastSceneTree</string>
+ </property>
+ <widget class="QWidget" name="widget">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnAsset">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Asset.png</normaloff>:/AppMainWindow/images/Asset.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="assetComposite">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/AssetComposite.png</normaloff>:/AppMainWindow/images/AssetComposite.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnChunk">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Chunk_Support_Unstatic.png</normaloff>:/AppMainWindow/images/Chunk_Support_Unstatic.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnBond">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Bond.png</normaloff>:/AppMainWindow/images/Bond.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnProjectile">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Projectile.png</normaloff>:/AppMainWindow/images/Projectile.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnExpandCollapse">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/ExpanCollapse.png</normaloff>:/AppMainWindow/images/ExpanCollapse.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTreeView" name="blastSceneTree">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources>
+ <include location="BlastToolBar.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/BlastToolBar.qrc b/tools/ArtistTools/source/BlastPlugin/UI/BlastToolBar.qrc
new file mode 100644
index 0000000..ae61540
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/BlastToolBar.qrc
@@ -0,0 +1,66 @@
+<RCC>
+ <qresource prefix="AppMainWindow">
+ <file>images/TextureBox.bmp</file>
+ <file>images/CheckBox.png</file>
+ <file>images/ArrowUp.png</file>
+ <file>images/ArrowDown.png</file>
+ <file>images/transportLoop.png</file>
+ <file>images/transportPlay.png</file>
+ <file>images/transportRewind.png</file>
+ <file>images/transportStepForward.png</file>
+ <file>images/transportStop.png</file>
+ <file>images/simulationPlay.png</file>
+ <file>images/simulationStop.png</file>
+ <file>images/simulationStep.png</file>
+ <file>images/DarkBorder.png</file>
+ <file>images/openFile.png</file>
+ <file>images/importFile.png</file>
+ <file>images/saveDisc.png</file>
+ <file>images/refreshReload.png</file>
+ <file>images/TextureEnabled_icon.png</file>
+ <file>images/TextureDisabled_icon.png</file>
+ <file>images/TextureIsUsed_icon.png</file>
+ <file>images/Remove_icon.png</file>
+ <file>images/Refresh_icon.png</file>
+ <file>images/CurveEditor.png</file>
+ <file>images/Add.png</file>
+ <file>images/Up.png</file>
+ <file>images/Down.png</file>
+ <file>images/EditWrench.png</file>
+ <file>images/playlist.png</file>
+ <file>images/visibilityToggle_notVisible.png</file>
+ <file>images/visibilityToggle_visible.png</file>
+ <file>ThemeDark.qss</file>
+ <file>images/Blast_ToolBar_btnExportFilepath.png</file>
+ <file>images/Blast_ToolBar_btnSelectTool.png</file>
+ <file>images/Blast_ToolBar_btnTranslate.png</file>
+ <file>images/Blast_ToolBar_btnRotate.png</file>
+ <file>images/Blast_ToolBar_btnScale.png</file>
+ <file>images/Blast_ToolBar_btnGizmoWithGlobal.png</file>
+ <file>images/Blast_ToolBar_btnGizmoWithLocal.png</file>
+ <file>images/Blast_ToolBar_btnPaintbrush.png</file>
+ <file>images/Blast_ToolBar_btnExplodedViewTool.png</file>
+ <file>images/Blast_ToolBar_btnJointsTool.png</file>
+ <file>images/Blast_ToolBar_btnFuseSelectedChunks.png</file>
+ <file>images/Blast_ToolBar_btnReset.png</file>
+ <file>images/Blast_ToolBar_btnSimulatePlay.png</file>
+ <file>images/Blast_ToolBar_btnFrameStepForward.png</file>
+ <file>images/Blast_ToolBar_btnBomb.png</file>
+ <file>images/Blast_ToolBar_btnDamage.png</file>
+ <file>images/Blast_ToolBar_btnProjectile.png</file>
+ <file>images/Blast_ToolBar_btnDropObject.png</file>
+ <file>images/Blast_ToolBar_btnPreferences.png</file>
+ <file>images/Asset.png</file>
+ <file>images/AssetComposite.png</file>
+ <file>images/Chunk_Unsupport_Unstatic.png</file>
+ <file>images/Chunk_Support_Unstatic.png</file>
+ <file>images/Chunk_Support_Static.png</file>
+ <file>images/Bond.png</file>
+ <file>images/Projectile.png</file>
+ <file>images/Pen.png</file>
+ <file>images/Select.png</file>
+ <file>images/ExpanCollapse.png</file>
+ <file>ThemeDark.qss</file>
+ </qresource>
+</RCC>
+ \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/CollisionToolsDlg.ui b/tools/ArtistTools/source/BlastPlugin/UI/CollisionToolsDlg.ui
new file mode 100644
index 0000000..012c082
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/CollisionToolsDlg.ui
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CollisionToolsDlg</class>
+ <widget class="QDialog" name="CollisionToolsDlg">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>368</width>
+ <height>220</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="1">
+ <widget class="QComboBox" name="comboBoxCollisionShape">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelCollisionShape">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Collision Shape</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="spinBoxQuality">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelQuality">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Quality</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelApplyFilter">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Apply Filter</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="comboBoxApplyFilter">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QComboBox" name="comboBoxTargetPlatform">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="labelTargetPlatform">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Target Platform</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QSpinBox" name="spinBoxMaxHulls">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="labelMaxHulls">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Max Hulls</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="labelTrimHulls">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Trim Hulls %</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QSpinBox" name="spinBoxTrimHulls">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="btnReset">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Reset</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnApply">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Apply</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>comboBoxApplyFilter</tabstop>
+ <tabstop>comboBoxCollisionShape</tabstop>
+ <tabstop>spinBoxQuality</tabstop>
+ <tabstop>spinBoxMaxHulls</tabstop>
+ <tabstop>spinBoxTrimHulls</tabstop>
+ <tabstop>comboBoxTargetPlatform</tabstop>
+ <tabstop>btnReset</tabstop>
+ <tabstop>btnApply</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/DefaultDamagePanel.ui b/tools/ArtistTools/source/BlastPlugin/UI/DefaultDamagePanel.ui
new file mode 100644
index 0000000..651cd83
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/DefaultDamagePanel.ui
@@ -0,0 +1,332 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DefaultDamagePanel</class>
+ <widget class="QWidget" name="DefaultDamagePanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>176</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>340</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>340</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="leftMargin">
+ <number>4</number>
+ </property>
+ <property name="topMargin">
+ <number>9</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="horizontalSpacing">
+ <number>2</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxDamageAmount">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelDamageAmount">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>155</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>155</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Damage Amount</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxStressDamageForce">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxDamageRadius">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="labelDamageRadius">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>155</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>155</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Damage Radius (Mouse WH)</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelStressDamageForce">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>155</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>155</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Stress Damage Force</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="labelDamageProfile">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>155</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>155</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Damage Profile</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelExplosiveImpulse">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>155</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>155</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Explosive Impulse</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="comboBoxDamageProfile">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxExplosiveImpulse">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="decimals">
+ <number>3</number>
+ </property>
+ <property name="maximum">
+ <double>999.990000000000009</double>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="labelDamageContinuously">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>155</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>155</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Damage Continuously</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QCheckBox" name="checkBoxDamageContinuously">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>spinBoxDamageAmount</tabstop>
+ <tabstop>spinBoxExplosiveImpulse</tabstop>
+ <tabstop>spinBoxStressDamageForce</tabstop>
+ <tabstop>comboBoxDamageProfile</tabstop>
+ <tabstop>spinBoxDamageRadius</tabstop>
+ <tabstop>checkBoxDamageContinuously</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/FileReferencesPanel.ui b/tools/ArtistTools/source/BlastPlugin/UI/FileReferencesPanel.ui
new file mode 100644
index 0000000..15d727b
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/FileReferencesPanel.ui
@@ -0,0 +1,427 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FileReferencesPanel</class>
+ <widget class="QWidget" name="FileReferencesPanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>311</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>340</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>340</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelFBXSourceAsset">
+ <property name="text">
+ <string>FBX Source Asset</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLineEdit" name="lineEditFBXSourceAsset"/>
+ </item>
+ <item row="1" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnOpenFile">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/openFile.png</normaloff>:/AppMainWindow/images/openFile.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnReload">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/refreshReload.png</normaloff>:/AppMainWindow/images/refreshReload.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnRemove">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Remove_icon.png</normaloff>:/AppMainWindow/images/Remove_icon.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Export Assets</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelFBX">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>FBX</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="lineEditCollision"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelCollision">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Collision</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="lineEditObj"/>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="lineEditFBX"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelObj">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Obj</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QCheckBox" name="checkBoxFBX">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QCheckBox" name="checkBoxObj">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QCheckBox" name="checkBoxCollision">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="labelLLAsset">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>LLAsset</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="lineEditLLAsset"/>
+ </item>
+ <item row="3" column="2">
+ <widget class="QCheckBox" name="checkBoxLLAsset">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="labelTKAsset">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>TKAsset</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLineEdit" name="lineEditTKAsset"/>
+ </item>
+ <item row="4" column="2">
+ <widget class="QCheckBox" name="checkBoxTKAsset">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="labelBPXA">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>BPXA</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLineEdit" name="lineEditBPXA"/>
+ </item>
+ <item row="5" column="2">
+ <widget class="QCheckBox" name="checkBoxBPXA">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QPushButton" name="btnSave">
+ <property name="minimumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/saveDisc.png</normaloff>:/AppMainWindow/images/saveDisc.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>lineEditFBXSourceAsset</tabstop>
+ <tabstop>btnOpenFile</tabstop>
+ <tabstop>btnReload</tabstop>
+ <tabstop>btnRemove</tabstop>
+ <tabstop>lineEditFBX</tabstop>
+ <tabstop>checkBoxFBX</tabstop>
+ <tabstop>lineEditObj</tabstop>
+ <tabstop>checkBoxObj</tabstop>
+ <tabstop>lineEditCollision</tabstop>
+ <tabstop>checkBoxCollision</tabstop>
+ <tabstop>lineEditLLAsset</tabstop>
+ <tabstop>checkBoxLLAsset</tabstop>
+ <tabstop>lineEditTKAsset</tabstop>
+ <tabstop>checkBoxTKAsset</tabstop>
+ <tabstop>lineEditBPXA</tabstop>
+ <tabstop>checkBoxBPXA</tabstop>
+ <tabstop>btnSave</tabstop>
+ </tabstops>
+ <resources>
+ <include location="BlastToolBar.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/FiltersDockWidget.ui b/tools/ArtistTools/source/BlastPlugin/UI/FiltersDockWidget.ui
new file mode 100644
index 0000000..e8b8522
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/FiltersDockWidget.ui
@@ -0,0 +1,565 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FiltersDockWidget</class>
+ <widget class="QDockWidget" name="FiltersDockWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>375</width>
+ <height>233</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>375</width>
+ <height>233</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>524287</width>
+ <height>524287</height>
+ </size>
+ </property>
+ <property name="features">
+ <set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
+ </property>
+ <property name="allowedAreas">
+ <set>Qt::LeftDockWidgetArea</set>
+ </property>
+ <property name="windowTitle">
+ <string>Filters</string>
+ </property>
+ <widget class="QWidget" name="widget">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="1" column="3">
+ <widget class="QPushButton" name="btnModifyFilterPreset">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/EditWrench.png</normaloff>:/AppMainWindow/images/EditWrench.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelFilterPreset">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>60</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Filter Preset</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="btnAddFilterPrest">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Add.png</normaloff>:/AppMainWindow/images/Add.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QPushButton" name="btnRemoveFilterPreset">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Remove_icon.png</normaloff>:/AppMainWindow/images/Remove_icon.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="5">
+ <widget class="QPushButton" name="btnSaveFilterPreset">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/saveDisc.png</normaloff>:/AppMainWindow/images/saveDisc.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="comboBoxFilterPreset">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="6">
+ <widget class="QMenuBar" name="menuBar">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>20</height>
+ </size>
+ </property>
+ <widget class="QMenu" name="menuRule">
+ <property name="title">
+ <string>Rule</string>
+ </property>
+ <addaction name="actionAllDescendants"/>
+ <addaction name="actionAllParents"/>
+ </widget>
+ <widget class="QMenu" name="menuDepth">
+ <property name="title">
+ <string>Depth</string>
+ </property>
+ <addaction name="actionDepthAll"/>
+ <addaction name="actionDepth0"/>
+ <addaction name="actionDepth1"/>
+ <addaction name="actionDepth2"/>
+ <addaction name="actionDepth3"/>
+ <addaction name="actionDepth4"/>
+ <addaction name="actionDepth5"/>
+ </widget>
+ <widget class="QMenu" name="menuItem_Type">
+ <property name="title">
+ <string>Item Type</string>
+ </property>
+ <addaction name="actionItemTypeAll"/>
+ <addaction name="actionChunk"/>
+ <addaction name="actionSupportChunk"/>
+ <addaction name="actionStaticSupportChunk"/>
+ <addaction name="actionBond"/>
+ <addaction name="actionWorldBond"/>
+ </widget>
+ <widget class="QMenu" name="menuOperator">
+ <property name="title">
+ <string>Operator</string>
+ </property>
+ <addaction name="actionEqualTo"/>
+ <addaction name="actionNotEquaTo"/>
+ </widget>
+ <addaction name="menuRule"/>
+ <addaction name="menuDepth"/>
+ <addaction name="menuItem_Type"/>
+ <addaction name="menuOperator"/>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <item row="2" column="0" colspan="3">
+ <widget class="QListWidget" name="listWidget">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="3">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSelect">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Select.png</normaloff>:/AppMainWindow/images/Select.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnVisible">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/visibilityToggle_visible.png</normaloff>:/AppMainWindow/images/visibilityToggle_visible.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnInVisible">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/visibilityToggle_notVisible.png</normaloff>:/AppMainWindow/images/visibilityToggle_notVisible.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <action name="actionAllDescendants">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>All Descendants</string>
+ </property>
+ </action>
+ <action name="actionAllParents">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>All Parents</string>
+ </property>
+ </action>
+ <action name="actionDepthAll">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>All</string>
+ </property>
+ </action>
+ <action name="actionDepth0">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Depth 0</string>
+ </property>
+ </action>
+ <action name="actionDepth1">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Depth 1</string>
+ </property>
+ </action>
+ <action name="actionDepth2">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Depth 2</string>
+ </property>
+ </action>
+ <action name="actionDepth3">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Depth 3</string>
+ </property>
+ </action>
+ <action name="actionDepth4">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Depth 4</string>
+ </property>
+ </action>
+ <action name="actionDepth5">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Depth 5</string>
+ </property>
+ </action>
+ <action name="actionItemTypeAll">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>All</string>
+ </property>
+ </action>
+ <action name="actionChunk">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Chunk</string>
+ </property>
+ </action>
+ <action name="actionSupportChunk">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Support Chunk</string>
+ </property>
+ </action>
+ <action name="actionStaticSupportChunk">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Static Support Chunk</string>
+ </property>
+ </action>
+ <action name="actionBond">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Bond</string>
+ </property>
+ </action>
+ <action name="actionWorldBond">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>World Bond</string>
+ </property>
+ </action>
+ <action name="actionEqualTo">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Equal To</string>
+ </property>
+ </action>
+ <action name="actionNotEquaTo">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Not Equal To</string>
+ </property>
+ </action>
+ </widget>
+ <tabstops>
+ <tabstop>comboBoxFilterPreset</tabstop>
+ <tabstop>btnAddFilterPrest</tabstop>
+ <tabstop>btnModifyFilterPreset</tabstop>
+ <tabstop>btnRemoveFilterPreset</tabstop>
+ <tabstop>btnSaveFilterPreset</tabstop>
+ <tabstop>listWidget</tabstop>
+ <tabstop>btnSelect</tabstop>
+ <tabstop>btnVisible</tabstop>
+ <tabstop>btnInVisible</tabstop>
+ </tabstops>
+ <resources>
+ <include location="BlastToolBar.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/FractureGeneralPanel.ui b/tools/ArtistTools/source/BlastPlugin/UI/FractureGeneralPanel.ui
new file mode 100644
index 0000000..627ad58
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/FractureGeneralPanel.ui
@@ -0,0 +1,359 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FractureGeneralPanel</class>
+ <widget class="QWidget" name="FractureGeneralPanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>157</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>340</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>340</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>6</number>
+ </property>
+ <property name="horizontalSpacing">
+ <number>2</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelFracturePreset">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Fracture Preset</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnAddPreset">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Add.png</normaloff>:/AppMainWindow/images/Add.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnModifyPreset">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/EditWrench.png</normaloff>:/AppMainWindow/images/EditWrench.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSavePreset">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/saveDisc.png</normaloff>:/AppMainWindow/images/saveDisc.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelFractureType">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Fracture Type</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="comboBoxFractureType">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="comboBoxFracturePreset">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="3">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Internal Material</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelApplyMaterial">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Apply Material</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="comboBoxApplyMaterial">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QLabel" name="labelAutoSelectNewChunks">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>240</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>240</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Auto-Select New Chunks</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QCheckBox" name="checkBoxAutoSelectNewChunks"/>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>comboBoxFracturePreset</tabstop>
+ <tabstop>btnAddPreset</tabstop>
+ <tabstop>btnModifyPreset</tabstop>
+ <tabstop>btnSavePreset</tabstop>
+ <tabstop>comboBoxFractureType</tabstop>
+ <tabstop>comboBoxApplyMaterial</tabstop>
+ <tabstop>checkBoxAutoSelectNewChunks</tabstop>
+ </tabstops>
+ <resources>
+ <include location="BlastToolBar.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/FractureSliceSettingsPanel.ui b/tools/ArtistTools/source/BlastPlugin/UI/FractureSliceSettingsPanel.ui
new file mode 100644
index 0000000..aa95fee
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/FractureSliceSettingsPanel.ui
@@ -0,0 +1,486 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FractureSliceSettingsPanel</class>
+ <widget class="QWidget" name="FractureSliceSettingsPanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>276</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>340</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>340</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelRotationVariation">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Rotation Variation</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelNumSlices">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Num Slices (x/y/z)</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelOffsetVariation">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Offset Variation</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxOffsetVariation">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="decimals">
+ <number>2</number>
+ </property>
+ <property name="maximum">
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxRotationVariation">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="decimals">
+ <number>2</number>
+ </property>
+ <property name="maximum">
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="labelNoiseAmplitude">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Noise Amplitude</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxNoiseAmplitude">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="decimals">
+ <number>2</number>
+ </property>
+ <property name="maximum">
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="labelNoiseFrequency">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Noise Frequency</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxNoiseFrequency">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="decimals">
+ <number>2</number>
+ </property>
+ <property name="maximum">
+ <double>10.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.100000000000000</double>
+ </property>
+ <property name="value">
+ <double>1.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="labelNoiseSeed">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Noise Seed</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QSpinBox" name="spinBoxNoiseSeed">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>2147483647</number>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="QPushButton" name="btnApplyFracture">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Apply Fracture</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="labelSurfaceResolution">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Surface Resolution</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QSpinBox" name="spinBoxSurfaceResolution">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>2147483647</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QSpinBox" name="spinBoxNumSlicesX">
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxNumSlicesY">
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxNumSlicesZ">
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="labelNoiseOctaveNumber">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Noise Octave Number</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QSpinBox" name="spinBoxNoiseOctaveNumber">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>spinBoxNumSlicesX</tabstop>
+ <tabstop>spinBoxNumSlicesY</tabstop>
+ <tabstop>spinBoxNumSlicesZ</tabstop>
+ <tabstop>spinBoxOffsetVariation</tabstop>
+ <tabstop>spinBoxRotationVariation</tabstop>
+ <tabstop>spinBoxNoiseAmplitude</tabstop>
+ <tabstop>spinBoxNoiseFrequency</tabstop>
+ <tabstop>spinBoxNoiseOctaveNumber</tabstop>
+ <tabstop>spinBoxNoiseSeed</tabstop>
+ <tabstop>spinBoxSurfaceResolution</tabstop>
+ <tabstop>btnApplyFracture</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/FractureVisualizersPanel.ui b/tools/ArtistTools/source/BlastPlugin/UI/FractureVisualizersPanel.ui
new file mode 100644
index 0000000..a2c0ff6
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/FractureVisualizersPanel.ui
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FractureVisualizersPanel</class>
+ <widget class="QWidget" name="FractureVisualizersPanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>50</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>340</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>340</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelSelectionDepthTest">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>170</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>170</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Selection Depth Test</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QCheckBox" name="checkBoxSelectionDepthTest"/>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/FractureVoronoiSettingsPanel.ui b/tools/ArtistTools/source/BlastPlugin/UI/FractureVoronoiSettingsPanel.ui
new file mode 100644
index 0000000..d69ebf1
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/FractureVoronoiSettingsPanel.ui
@@ -0,0 +1,500 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FractureVoronoiSettingsPanel</class>
+ <widget class="QWidget" name="FractureVoronoiSettingsPanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>358</width>
+ <height>319</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>358</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>358</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="4" column="0">
+ <widget class="QLabel" name="labelSiteGeneration">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Site Generation</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="1">
+ <widget class="QPushButton" name="btnApplyFracture">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Apply Fracture</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="comboBoxSiteGeneration">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <item>
+ <property name="text">
+ <string>UniformlyGenerateSitesInMesh </string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ClusteredSitesGeneration</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <widget class="QGroupBox" name="groupBoxVisualizers">
+ <property name="title">
+ <string>Visualizers</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>9</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>9</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelGridPreview">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Grid Preview</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QCheckBox" name="checkBoxGridPreview"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelFracturePreview">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Fracture Preview</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="checkBoxFracturePreview"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelCutterMesh">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Cutter Mesh</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QCheckBox" name="checkBoxCutterMesh"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="5" column="0" rowspan="2" colspan="3">
+ <widget class="QWidget" name="widgetUniform" native="true">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_6">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labeNumberOfSites">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Number of Sites</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="spinBoxNumberOfSites">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="8" column="0" colspan="3">
+ <widget class="QWidget" name="widgetClusters" native="true">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>80</height>
+ </size>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="spinBoxNumberOfClusters">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxClusterRadius">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelNumberOfClusters">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Number Of Clusters</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelSitesPerCluster">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Sites Per Cluster</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelClusterRadius">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>ClusterRadius</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="spinBoxSitesPerCluster">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ <zorder>labelNumberOfClusters</zorder>
+ <zorder>spinBoxNumberOfClusters</zorder>
+ <zorder>labelSitesPerCluster</zorder>
+ <zorder>spinBoxSitesPerCluster</zorder>
+ <zorder>labelClusterRadius</zorder>
+ <zorder>spinBoxClusterRadius</zorder>
+ <zorder>horizontalSpacer_2</zorder>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>checkBoxGridPreview</tabstop>
+ <tabstop>checkBoxFracturePreview</tabstop>
+ <tabstop>checkBoxCutterMesh</tabstop>
+ <tabstop>comboBoxSiteGeneration</tabstop>
+ <tabstop>spinBoxNumberOfSites</tabstop>
+ <tabstop>spinBoxNumberOfClusters</tabstop>
+ <tabstop>spinBoxSitesPerCluster</tabstop>
+ <tabstop>spinBoxClusterRadius</tabstop>
+ <tabstop>btnApplyFracture</tabstop>
+ </tabstops>
+ <resources>
+ <include location="BlastToolBar.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/GeneralPanel.ui b/tools/ArtistTools/source/BlastPlugin/UI/GeneralPanel.ui
new file mode 100644
index 0000000..481bc01
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/GeneralPanel.ui
@@ -0,0 +1,492 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>GeneralPanel</class>
+ <widget class="QWidget" name="GeneralPanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>223</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>340</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>340</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="1">
+ <widget class="QComboBox" name="comboBoxUserPreset">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelUserPreset">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>User Preset</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnAddUserPreset">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Add.png</normaloff>:/AppMainWindow/images/Add.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnModifyUserPreset">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/EditWrench.png</normaloff>:/AppMainWindow/images/EditWrench.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSaveUserPreset">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/saveDisc.png</normaloff>:/AppMainWindow/images/saveDisc.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" colspan="3">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Stress Solver</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <item row="6" column="0">
+ <widget class="QLabel" name="labelGraphReductionLevel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>170</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>170</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Graph Reduction Level</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelAngularFactor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>160</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>170</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Angular Factor</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelLinearFactor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>160</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>170</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Linear Factor</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QSpinBox" name="spinBoxBondIterations">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>500000</number>
+ </property>
+ <property name="singleStep">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>18000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxLinearFactor">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <double>100.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.010000000000000</double>
+ </property>
+ <property name="value">
+ <double>0.250000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxAngularFactor">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <double>100.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.010000000000000</double>
+ </property>
+ <property name="value">
+ <double>0.750000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QSpinBox" name="spinBoxGraphReductionLevel">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>32</number>
+ </property>
+ <property name="value">
+ <number>3</number>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="labelBondIterations">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>160</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>170</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Bond Iterations Per Frame</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelMaterialHardness">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>160</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>170</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Material Hardness</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxMaterialHardness">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="minimum">
+ <double>0.010000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>100000.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>10.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>1000.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>comboBoxUserPreset</tabstop>
+ <tabstop>btnAddUserPreset</tabstop>
+ <tabstop>btnModifyUserPreset</tabstop>
+ <tabstop>btnSaveUserPreset</tabstop>
+ <tabstop>spinBoxMaterialHardness</tabstop>
+ <tabstop>spinBoxLinearFactor</tabstop>
+ <tabstop>spinBoxAngularFactor</tabstop>
+ <tabstop>spinBoxBondIterations</tabstop>
+ <tabstop>spinBoxGraphReductionLevel</tabstop>
+ </tabstops>
+ <resources>
+ <include location="BlastToolBar.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/MaterialAssignmentsPanel.ui b/tools/ArtistTools/source/BlastPlugin/UI/MaterialAssignmentsPanel.ui
new file mode 100644
index 0000000..7e87913
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/MaterialAssignmentsPanel.ui
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MaterialAssignmentsPanel</class>
+ <widget class="QWidget" name="MaterialAssignmentsPanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>135</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>340</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>340</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelMaterialID1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Material ID 1</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="comboBoxMaterialID1">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelMaterialID2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Material ID 2</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="comboBoxMaterialID2">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="labelMaterialID3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Material ID 3</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="comboBoxMaterialID3">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="labelMaterialID4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Material ID 4</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="comboBoxMaterialID4">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Apply materials to ID's of selected objects</string>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/MaterialLibraryPanel.ui b/tools/ArtistTools/source/BlastPlugin/UI/MaterialLibraryPanel.ui
new file mode 100644
index 0000000..751a5c8
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/MaterialLibraryPanel.ui
@@ -0,0 +1,753 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MaterialLibraryPanel</class>
+ <widget class="QWidget" name="MaterialLibraryPanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>396</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>340</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>340</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Materials</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnAddMat">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Add.png</normaloff>:/AppMainWindow/images/Add.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnModifyMat">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/EditWrench.png</normaloff>:/AppMainWindow/images/EditWrench.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnRemoveMat">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Remove_icon.png</normaloff>:/AppMainWindow/images/Remove_icon.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QListWidget" name="listWidget"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Render Attributes</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Diffuse Color</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnSpecularColor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSpecularColorTex">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/TextureEnabled_icon.png</normaloff>:/AppMainWindow/images/TextureEnabled_icon.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSpecularColorTexReload">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/refreshReload.png</normaloff>:/AppMainWindow/images/refreshReload.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSpecularColorTexClear">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Remove_icon.png</normaloff>:/AppMainWindow/images/Remove_icon.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnDiffuseColor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnDiffuseColorTex">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/TextureEnabled_icon.png</normaloff>:/AppMainWindow/images/TextureEnabled_icon.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnDiffuseColorTexReload">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/refreshReload.png</normaloff>:/AppMainWindow/images/refreshReload.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnDiffuseColorTexClear">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Remove_icon.png</normaloff>:/AppMainWindow/images/Remove_icon.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Specular Shininess</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="spinSpecularShin">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Specular Color</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Normal Texture</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnNormalColorTex">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/TextureEnabled_icon.png</normaloff>:/AppMainWindow/images/TextureEnabled_icon.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnNormalColorTexReload">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/refreshReload.png</normaloff>:/AppMainWindow/images/refreshReload.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnNormalColorTexClear">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="BlastToolBar.qrc">
+ <normaloff>:/AppMainWindow/images/Remove_icon.png</normaloff>:/AppMainWindow/images/Remove_icon.png</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>btnNormalColorTexClear</tabstop>
+ <tabstop>btnModifyMat</tabstop>
+ <tabstop>btnRemoveMat</tabstop>
+ <tabstop>listWidget</tabstop>
+ <tabstop>btnDiffuseColor</tabstop>
+ <tabstop>btnDiffuseColorTex</tabstop>
+ <tabstop>btnDiffuseColorTexReload</tabstop>
+ <tabstop>btnDiffuseColorTexClear</tabstop>
+ <tabstop>btnSpecularColor</tabstop>
+ <tabstop>btnAddMat</tabstop>
+ <tabstop>btnSpecularColorTex</tabstop>
+ <tabstop>btnSpecularColorTexReload</tabstop>
+ <tabstop>btnSpecularColorTexClear</tabstop>
+ <tabstop>spinSpecularShin</tabstop>
+ <tabstop>btnNormalColorTex</tabstop>
+ <tabstop>btnNormalColorTexReload</tabstop>
+ </tabstops>
+ <resources>
+ <include location="BlastToolBar.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/NoiseToolsDlg.ui b/tools/ArtistTools/source/BlastPlugin/UI/NoiseToolsDlg.ui
new file mode 100644
index 0000000..d843793
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/NoiseToolsDlg.ui
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>NoiseToolsDlg</class>
+ <widget class="QDialog" name="NoiseToolsDlg">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>333</width>
+ <height>201</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="1">
+ <widget class="QPushButton" name="btnApply">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Apply</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="2">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Interior Faces</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelApplyByMateria">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Apply by Material</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelAmplitude">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Amplitude</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxAmplitude">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelFrequency">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Frequency</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxFrequency">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="labelGridScale">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Grid Scale</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxAmplitude_3">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="comboBoxApplyByMaterial">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>comboBoxApplyByMaterial</tabstop>
+ <tabstop>spinBoxAmplitude</tabstop>
+ <tabstop>spinBoxFrequency</tabstop>
+ <tabstop>spinBoxAmplitude_3</tabstop>
+ <tabstop>btnApply</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/SourceAssetOpenDlg.ui b/tools/ArtistTools/source/BlastPlugin/UI/SourceAssetOpenDlg.ui
new file mode 100644
index 0000000..78ae7e7
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/SourceAssetOpenDlg.ui
@@ -0,0 +1,496 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SourceAssetOpenDlg</class>
+ <widget class="QDialog" name="SourceAssetOpenDlg">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>458</width>
+ <height>238</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="3" column="2">
+ <widget class="QDoubleSpinBox" name="spinBoxYAxis">
+ <property name="minimumSize">
+ <size>
+ <width>89</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>89</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3">
+ <widget class="QDoubleSpinBox" name="spinBoxZAxis">
+ <property name="minimumSize">
+ <size>
+ <width>89</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>89</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="fileLabel">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>90</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text">
+ <string>File</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="skinnedLabel">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>90</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text">
+ <string>Skinned</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="positionLabel">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>90</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text">
+ <string>Position</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxXAxis">
+ <property name="minimumSize">
+ <size>
+ <width>89</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>89</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxXPosition">
+ <property name="minimumSize">
+ <size>
+ <width>89</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>89</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>89</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Scene Unit</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QComboBox" name="cbSceneUnit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>89</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="currentText">
+ <string>Unknown</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>Unknown</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Centimeter</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Meter</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Inch</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="appendLabel">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>90</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text">
+ <string>Append</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QCheckBox" name="checkBoxAppend"/>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="preFracturedLabel">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>90</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text">
+ <string>PreFractured</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QCheckBox" name="checkBoxPreFractured"/>
+ </item>
+ <item row="7" column="2">
+ <widget class="QLabel" name="autoComputeLabel">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>90</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text">
+ <string>AutoCompute</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="3">
+ <widget class="QCheckBox" name="checkBoxAutoCompute"/>
+ </item>
+ <item row="8" column="1" colspan="4">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="checkBoxSkinned"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="rotationLabel">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>90</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text">
+ <string>Rotation Axis</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QPushButton" name="btnOpenFile">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Open File</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxDegree">
+ <property name="minimumSize">
+ <size>
+ <width>89</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>89</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="rotationDegree">
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>90</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text">
+ <string>Rotation Degree</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QDoubleSpinBox" name="spinBoxYPosition">
+ <property name="minimumSize">
+ <size>
+ <width>89</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>89</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QDoubleSpinBox" name="spinBoxZPosition">
+ <property name="minimumSize">
+ <size>
+ <width>89</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>89</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="3">
+ <widget class="QLineEdit" name="lineEditFile">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>lineEditFile</tabstop>
+ <tabstop>btnOpenFile</tabstop>
+ <tabstop>checkBoxSkinned</tabstop>
+ <tabstop>spinBoxXPosition</tabstop>
+ <tabstop>spinBoxYPosition</tabstop>
+ <tabstop>spinBoxZPosition</tabstop>
+ <tabstop>spinBoxXAxis</tabstop>
+ <tabstop>spinBoxYAxis</tabstop>
+ <tabstop>spinBoxZAxis</tabstop>
+ <tabstop>spinBoxDegree</tabstop>
+ <tabstop>checkBoxAppend</tabstop>
+ <tabstop>checkBoxPreFractured</tabstop>
+ <tabstop>checkBoxAutoCompute</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>SourceAssetOpenDlg</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>SourceAssetOpenDlg</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/SupportPanel.ui b/tools/ArtistTools/source/BlastPlugin/UI/SupportPanel.ui
new file mode 100644
index 0000000..0ea87ce
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/SupportPanel.ui
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SupportPanel</class>
+ <widget class="QWidget" name="SupportPanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>66</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>340</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>340</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelEnableJoint">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>170</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>170</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Enable Joint</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="checkBoxEnableJoint"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelBondStrength">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>170</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>170</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Bond Strength</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QDoubleSpinBox" name="spinBoxBondStrength">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>spinBoxBondStrength</tabstop>
+ <tabstop>checkBoxEnableJoint</tabstop>
+ </tabstops>
+ <resources>
+ <include location="BlastToolBar.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/ThemeDark.qss b/tools/ArtistTools/source/BlastPlugin/UI/ThemeDark.qss
new file mode 100644
index 0000000..97e00c0
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/ThemeDark.qss
@@ -0,0 +1,457 @@
+AppMainWindow *
+{
+ background-color:rgb(68,68,68); color:rgb(200,200,200);
+}
+
+AppMainWindow::separator
+{
+ background-color: rgb(68, 68, 68);
+
+ /*trick: qdockwidget stylesheet seems to have bugs, use the separator border*/
+
+ border-right-width: 2px;
+ border-image: url(:/AppMainWindow/images/DarkBorder.png) 2;
+}
+
+AppMainWindow::separator:hover
+{
+ background-color: #666666;
+}
+
+AppMainWindow QDockWidget::title
+{
+ text-align: center;
+ /*
+ border-top-color: rgb(45,45,45);
+ border-top-width: 2px;
+ border-top-style: groove;
+ */
+
+ background-color: rgb(68,68,68);
+ border-width: 2px;
+ border-image: url(:/AppMainWindow/images/DarkBorder.png) 2;
+
+}
+
+AppMainWindow QTextBrowser
+{
+ /*
+ border-width: 1px;
+ border-image: url(:/AppMainWindow/images/DarkBorder.png) 2;
+ */
+ border: 1px solid gray;
+ background-color:rgb(40,40,40);
+}
+
+AppMainWindow QCheckBox::indicator::unchecked
+{
+ background-color:rgb(40,40,40);
+}
+
+AppMainWindow QCheckBox::indicator::checked
+{
+ image:url(:/AppMainWindow/images/CheckBox.png);
+}
+
+AppMainWindow QPushButton
+{
+ border: 1px solid gray;
+}
+
+AppMainWindow QPushButton:pressed
+{
+ border: 2px solid rgb(118,185,0);
+ /*background-color: rgb(118,185,0);*/
+}
+
+AppMainWindow QPushButton:checked
+{
+ border: 2px solid rgb(118,185,0);
+ /*background-color: rgb(118,185,0);*/
+}
+
+/****** QScrollbar Styles ******/
+AppMainWindow QScrollBar:vertical
+{
+ width: 22px;
+ /*
+ border-width: 2px;
+ border-image: url(:/AppMainWindow/images/DarkBorder.png) 2;
+ */
+ border: 1px solid rgb(40,40,40);
+ margin: 20px 1px 20px 0px;
+}
+
+AppMainWindow QScrollBar::handle:vertical
+{
+ border-top: 1px solid rgb(40,40,40);
+ border-bottom: 1px solid rgb(40,40,40);
+ background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
+ stop:0 rgb(116,116,116), stop: 1 rgb(95,95,95));
+ min-height: 20px;
+}
+
+AppMainWindow QScrollBar::add-line:vertical
+{
+ border: 1px solid rgb(40,40,40);
+ background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
+ stop:0 rgb(116,116,116), stop: 1 rgb(95,95,95));
+
+ margin-right: 1px;
+ margin-bottom: 1px;
+ height: 18px;
+ subcontrol-position: bottom;
+ subcontrol-origin: margin;
+}
+
+AppMainWindow QScrollBar::sub-line:vertical
+{
+ margin-top: 1px;
+ margin-right: 1px;
+ border: 1px solid rgb(40,40,40);
+ background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
+ stop:0 rgb(116,116,116), stop: 1 rgb(95,95,95));
+ height: 18px;
+ subcontrol-position: top;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::up-arrow:vertical
+{
+ image: url(:/AppMainWindow/images/ArrowUp.png);
+}
+
+QScrollBar::up-arrow:vertical:pressed
+{
+ top: 1px;
+}
+
+QScrollBar::down-arrow:vertical
+{
+ image: url(:/AppMainWindow/images/ArrowDown.png);
+}
+
+QScrollBar::down-arrow:vertical:pressed
+{
+ top: 1px;
+}
+
+AppMainWindow QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical
+{
+ background: none;
+}
+
+/****** ListWidget Styles ******/
+AppMainWindow QListWidget {
+ alternate-background-color: yellow;
+ border: 1px solid gray;
+ border-radius: 0px;
+ }
+
+AppMainWindow QListWidget {
+ show-decoration-selected: 1; /* make the selection span the entire width of the view */
+ }
+
+ AppMainWindow QListWidget::item:alternate {
+ background: #EEEEEE;
+ }
+
+ AppMainWindow QListWidget::item:selected {
+ border: 1px solid #6a6ea9;
+ }
+
+ AppMainWindow QListWidget::item:selected:!active {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #00aa00, stop: 1 #00dd00);
+ }
+
+ AppMainWindow QListWidget::item:selected:active {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #00aa00, stop: 1 #00dd00);
+ }
+
+ AppMainWindow QListWidget::item:hover {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #DDFFDD, stop: 1 #CCFFCC);
+ }
+
+ /****** TreeView Styles ******/
+AppMainWindow QTreeView {
+ alternate-background-color: yellow;
+ border: 1px solid gray;
+ border-radius: 0px;
+ }
+
+AppMainWindow QTreeView {
+ show-decoration-selected: 1; /* make the selection span the entire width of the view */
+ }
+
+ AppMainWindow QTreeView::item:alternate {
+ background: #EEEEEE;
+ }
+
+ AppMainWindow QTreeView::item:selected {
+ border: 1px solid #6a6ea9;
+ }
+
+ AppMainWindow QTreeView::item:selected:!active {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #00aa00, stop: 1 #00dd00);
+ }
+
+ AppMainWindow QTreeView::item:selected:active {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #00aa00, stop: 1 #00dd00);
+ }
+
+ AppMainWindow QTreeView::item:hover {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #DDFFDD, stop: 1 #CCFFCC);
+ }
+
+/****** ComboBox Styles ******/
+AppMainWindow QComboBox {
+ border: 1px solid gray;
+ border-radius: 0px;
+ }
+
+AppMainWindow QComboBox QAbstractItemView
+{
+ background-color: rgb(68,68,68);
+ selection-background-color: rgb(118,185,0);
+}
+
+ AppMainWindow QComboBox::drop-down {
+ subcontrol-origin: padding;
+ subcontrol-position: top right;
+ /*width: 15px;*/
+
+ border-left-width: 1px;
+ border-left-color: gray;
+ border-left-style: solid;
+
+ }
+
+AppMainWindow QComboBox::down-arrow {
+ image: url(:/AppMainWindow/images/ArrowDown.png);
+ }
+
+AppMainWindow QComboBox::down-arrow:on {
+ top: 1px;
+
+ }
+
+/****** QTabWidget Styles ******/
+AppMainWindow QTabWidget::pane
+{
+ /* The tab widget frame */
+ border-top: 0px solid transparent;
+
+}
+
+AppMainWindow QTabWidget::tab-bar
+{
+ left: 5px;
+}
+
+AppMainWindow QTabBar::tab {
+ margin-top: 1px;
+ background-color: rgb(68,68,68);
+ border: 1px solid gray;
+ border-bottom-color: rgb(68,68,68); /* same as the pane color */
+ min-width: 10ex;
+ padding: 2px 8px;
+}
+
+AppMainWindow QTabBar::tab:selected
+{
+ background-color: #666666;
+ border-color: gray;
+ border-bottom-color: transparent;
+}
+
+AppMainWindow QTabBar::tab:!selected {
+ margin-top: 3px; /* make non-selected tabs look smaller */
+}
+
+/****** Spin And DoubleSpin Styles ******/
+
+AppMainWindow QDoubleSpinBox
+ {
+ border: 1px solid gray;
+ background-color: rgb(40,40,40);
+ }
+
+AppMainWindow QSpinBox
+ {
+ border: 1px solid gray;
+ background-color: rgb(40,40,40);
+ }
+
+AppMainWindow QSpinBox::up-button
+{
+ background-color:rgb(68,68,68);
+ border: 1px solid gray;
+ margin-top: 1px;
+ margin-right: 1px;
+}
+
+AppMainWindow QSpinBox::up-button:pressed {
+ border: 1px solid rgb(118,185,0);
+}
+
+AppMainWindow QSpinBox::down-button
+{
+ background-color:rgb(68,68,68);
+ border: 1px solid gray;
+ margin-bottom: 1px;
+ margin-right: 1px;
+}
+
+AppMainWindow QSpinBox::down-button:pressed {
+ border: 1px solid rgb(118,185,0);
+}
+
+AppMainWindow QSpinBox::up-arrow
+{
+ image: url(:/AppMainWindow/images/ArrowUp.png);
+ width: 4px;
+}
+AppMainWindow QSpinBox::down-arrow
+{
+ image: url(:/AppMainWindow/images/ArrowDown.png);
+ width: 4px;
+}
+
+AppMainWindow QDoubleSpinBox::up-button
+{
+ background-color:rgb(68,68,68);
+ border: 1px solid gray;
+ margin-top: 1px;
+ margin-right: 1px;
+}
+
+AppMainWindow QDoubleSpinBox::up-button:pressed {
+ border: 1px solid rgb(118,185,0);
+}
+
+AppMainWindow QDoubleSpinBox::down-button
+{
+ background-color:rgb(68,68,68);
+ border: 1px solid gray;
+ margin-bottom: 1px;
+ margin-right: 1px;
+}
+
+AppMainWindow QDoubleSpinBox::down-button:pressed {
+ border: 1px solid rgb(118,185,0);
+}
+
+AppMainWindow QDoubleSpinBox::up-arrow
+{
+ image: url(:/AppMainWindow/images/ArrowUp.png);
+ width: 4px;
+}
+
+AppMainWindow QDoubleSpinBox::down-arrow
+{
+ image: url(:/AppMainWindow/images/ArrowDown.png);
+ width: 4px;
+}
+
+AppMainWindow QDoubleSpinBox::disabled
+{
+ background-color:rgb(32,32,32);
+ color:rgb(68,68,68);
+ border: 1px solid rgb(68,68,68);
+}
+
+AppMainWindow QDoubleSpinBox::up-button:disabled {
+ border: 1px solid rgb(68,68,68);
+}
+
+AppMainWindow QDoubleSpinBox::down-button:disabled {
+ border: 1px solid rgb(68,68,68);
+}
+
+/****** Menu Styles ******/
+QMenuBar
+{
+ border-image: url(:/AppMainWindow/images/DarkBorder.png) 2;
+ border-bottom-width: 2px;
+}
+
+AppMainWindow QMenuBar::item
+{
+ spacing: 3px; /* spacing between menu bar items */
+ padding: 1px 4px;
+ margin-bottom: 2px;
+ background: transparent;
+ border-radius: 0px;
+}
+
+AppMainWindow QMenuBar::item:selected:enabled { /* when selected using mouse or keyboard */
+ background: #666666;
+}
+
+AppMainWindow QMenuBar::item:pressed:enabled {
+ background: rgb(118,185,0);
+}
+
+AppMainWindow QMenu {
+ border: 1px solid rgb(50,50,50);
+
+}
+
+AppMainWindow QMenuBar:disabled
+{
+ color:rgb(0,0,0);
+}
+
+AppMainWindow QMenu:disabled
+{
+ color:rgb(0,0,0);
+}
+
+AppMainWindow QMenu::item {
+ padding: 2px 25px 2px 20px;
+ border: 1px solid transparent; /* reserve space for selection border */
+}
+
+AppMainWindow QMenu::item:selected:enabled {
+ border-color: rgb(70,70,70);
+ background: rgba(118,185,0, 250);
+}
+/****** ExpandablePanel Styles ******/
+
+AppMainWindow QGroupBox
+{
+ margin-top: 1.5ex;
+ border: 1px solid gray;
+ border-radius: 0px;
+}
+
+AppMainWindow QGroupBox::title
+{
+ subcontrol-origin: margin;
+ left: 10px;
+ padding: 0px 3px;
+}
+
+/*
+ExpandablePanel QPushButton[flat="true"]
+{
+ border-color: rgb(40,40,40);
+ image:url(:/AppMainWindow/images/TextureBox.bmp)
+}
+
+ExpandablePanel QPushButton[flat="true"]:pressed
+{
+ margin: 2px;
+}
+*/
+
+ExpandablePanel TitleLabel
+{
+ background:rgb(78, 78, 78);
+}
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/ThemeDefault.qss b/tools/ArtistTools/source/BlastPlugin/UI/ThemeDefault.qss
new file mode 100644
index 0000000..f59dd25
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/ThemeDefault.qss
@@ -0,0 +1,76 @@
+/****** General Styles ******/
+
+AppMainWindow QPushButton
+{
+ /*border: 1px solid gray;*/
+ background-color: rgb(230,230,230);
+ border-left: 1px solid rgb(200,200,200);
+ border-top: 1px solid rgb(200,200,200);
+ border-right: 1px solid rgb(60,60,60);
+ border-bottom: 1px solid rgb(60,60,60);
+}
+
+
+AppMainWindow QPushButton:pressed
+{
+ /*border: 2px solid gray;*/
+ border-left: 1px solid rgb(60,60,60);
+ border-top: 1px solid rgb(60,60,60);
+ border-right: 1px solid rgb(200,200,200);
+ border-bottom: 1px solid rgb(200,200,200);
+}
+
+AppMainWindow QPushButton:checked
+{
+ border: 1px solid gray;
+ border-left: 1px solid rgb(60,60,60);
+ border-top: 1px solid rgb(60,60,60);
+ border-right: 1px solid rgb(200,200,200);
+ border-bottom: 1px solid rgb(200,200,200);
+}
+/****** MainToolbar Styles ******/
+
+MainToolbar QPushButton[flat="true"]
+{
+ border:0px;
+}
+
+
+/****** ExpandablePanel Styles ******/
+
+ExpandablePanel
+{
+ background:rgb(240,240,240);
+}
+
+ExpandablePanel QGroupBox
+{
+ margin-top: 1.5ex;
+ border: 1px solid gray;
+ border-radius: 0px;
+}
+
+ExpandablePanel QGroupBox::title
+{
+ subcontrol-origin: margin;
+ left: 10px;
+ padding: 0px 3px;
+}
+
+ExpandablePanel QPushButton[flat="true"]
+{
+ border: 1px solid rgb(60,60,60);
+ image:url(:/AppMainWindow/images/TextureBox.bmp)
+}
+
+ExpandablePanel QPushButton[flat="true"]:pressed
+{
+ border: 2px solid rgb(60,60,60);
+ image:url(:/AppMainWindow/images/TextureBox.bmp)
+}
+
+ExpandablePanel TitleLabel
+{
+ background:rgb(219, 219, 219);
+ border-bottom:1px solid rgb(185,185,185);
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Add.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Add.png
new file mode 100644
index 0000000..35fd8ed
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Add.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/ArrowDown.png b/tools/ArtistTools/source/BlastPlugin/UI/images/ArrowDown.png
new file mode 100644
index 0000000..9b55420
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/ArrowDown.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/ArrowUp.png b/tools/ArtistTools/source/BlastPlugin/UI/images/ArrowUp.png
new file mode 100644
index 0000000..fea1fbe
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/ArrowUp.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Asset.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Asset.png
new file mode 100644
index 0000000..d44806f
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Asset.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/AssetComposite.png b/tools/ArtistTools/source/BlastPlugin/UI/images/AssetComposite.png
new file mode 100644
index 0000000..86dd5d2
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/AssetComposite.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnBomb.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnBomb.png
new file mode 100644
index 0000000..354ba1f
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnBomb.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnDamage.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnDamage.png
new file mode 100644
index 0000000..1fa8e7e
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnDamage.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnDropObject.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnDropObject.png
new file mode 100644
index 0000000..82e3945
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnDropObject.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnExplodedViewTool.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnExplodedViewTool.png
new file mode 100644
index 0000000..31a1520
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnExplodedViewTool.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnExportFilepath.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnExportFilepath.png
new file mode 100644
index 0000000..6f10fc6
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnExportFilepath.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnFrameStepForward.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnFrameStepForward.png
new file mode 100644
index 0000000..e20352e
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnFrameStepForward.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnFuseSelectedChunks.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnFuseSelectedChunks.png
new file mode 100644
index 0000000..c7f35ef
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnFuseSelectedChunks.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnGizmoWithGlobal.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnGizmoWithGlobal.png
new file mode 100644
index 0000000..ba8ccdb
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnGizmoWithGlobal.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnGizmoWithLocal.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnGizmoWithLocal.png
new file mode 100644
index 0000000..329f02f
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnGizmoWithLocal.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnJointsTool.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnJointsTool.png
new file mode 100644
index 0000000..63a9bfd
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnJointsTool.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnPaintbrush.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnPaintbrush.png
new file mode 100644
index 0000000..797dd2c
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnPaintbrush.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnPreferences.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnPreferences.png
new file mode 100644
index 0000000..6b9bb07
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnPreferences.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnProjectile.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnProjectile.png
new file mode 100644
index 0000000..bd17d36
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnProjectile.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnReset.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnReset.png
new file mode 100644
index 0000000..52522df
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnReset.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnRotate.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnRotate.png
new file mode 100644
index 0000000..acf2348
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnRotate.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnScale.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnScale.png
new file mode 100644
index 0000000..773de30
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnScale.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnSelectTool.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnSelectTool.png
new file mode 100644
index 0000000..07a8489
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnSelectTool.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnSimulatePlay.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnSimulatePlay.png
new file mode 100644
index 0000000..92269bb
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnSimulatePlay.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnTranslate.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnTranslate.png
new file mode 100644
index 0000000..3090384
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Blast_ToolBar_btnTranslate.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Bond.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Bond.png
new file mode 100644
index 0000000..6f632c2
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Bond.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/CheckBox.png b/tools/ArtistTools/source/BlastPlugin/UI/images/CheckBox.png
new file mode 100644
index 0000000..ac53487
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/CheckBox.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_Support_Static.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_Support_Static.png
new file mode 100644
index 0000000..6fa5c90
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_Support_Static.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_Support_Unstatic.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_Support_Unstatic.png
new file mode 100644
index 0000000..819b2f5
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_Support_Unstatic.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_UnSupport_UnStatic.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_UnSupport_UnStatic.png
new file mode 100644
index 0000000..8530dc1
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Chunk_UnSupport_UnStatic.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/CurveEditor.png b/tools/ArtistTools/source/BlastPlugin/UI/images/CurveEditor.png
new file mode 100644
index 0000000..f92c6e4
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/CurveEditor.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/DarkBorder.png b/tools/ArtistTools/source/BlastPlugin/UI/images/DarkBorder.png
new file mode 100644
index 0000000..9771804
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/DarkBorder.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Down.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Down.png
new file mode 100644
index 0000000..376a821
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Down.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/EditWrench.png b/tools/ArtistTools/source/BlastPlugin/UI/images/EditWrench.png
new file mode 100644
index 0000000..563a602
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/EditWrench.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/ExpanCollapse.png b/tools/ArtistTools/source/BlastPlugin/UI/images/ExpanCollapse.png
new file mode 100644
index 0000000..9edf959
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/ExpanCollapse.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Pen.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Pen.png
new file mode 100644
index 0000000..aaee27d
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Pen.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Projectile.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Projectile.png
new file mode 100644
index 0000000..859c9f2
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Projectile.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Refresh_icon.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Refresh_icon.png
new file mode 100644
index 0000000..c189dd5
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Refresh_icon.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Remove_icon.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Remove_icon.png
new file mode 100644
index 0000000..ebb63d9
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Remove_icon.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Select.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Select.png
new file mode 100644
index 0000000..8f89717
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Select.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/TextureBox.bmp b/tools/ArtistTools/source/BlastPlugin/UI/images/TextureBox.bmp
new file mode 100644
index 0000000..43f95b2
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/TextureBox.bmp
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/TextureDisabled_icon.png b/tools/ArtistTools/source/BlastPlugin/UI/images/TextureDisabled_icon.png
new file mode 100644
index 0000000..3a727f4
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/TextureDisabled_icon.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/TextureEnabled_icon.png b/tools/ArtistTools/source/BlastPlugin/UI/images/TextureEnabled_icon.png
new file mode 100644
index 0000000..a8f11d5
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/TextureEnabled_icon.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/TextureIsUsed_icon.png b/tools/ArtistTools/source/BlastPlugin/UI/images/TextureIsUsed_icon.png
new file mode 100644
index 0000000..75d52dc
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/TextureIsUsed_icon.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/Up.png b/tools/ArtistTools/source/BlastPlugin/UI/images/Up.png
new file mode 100644
index 0000000..6f8903c
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/Up.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/importFile.png b/tools/ArtistTools/source/BlastPlugin/UI/images/importFile.png
new file mode 100644
index 0000000..e4ffc91
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/importFile.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/openFile.png b/tools/ArtistTools/source/BlastPlugin/UI/images/openFile.png
new file mode 100644
index 0000000..b91e69c
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/openFile.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/playlist.png b/tools/ArtistTools/source/BlastPlugin/UI/images/playlist.png
new file mode 100644
index 0000000..3c6db13
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/playlist.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/refreshReload.png b/tools/ArtistTools/source/BlastPlugin/UI/images/refreshReload.png
new file mode 100644
index 0000000..745c9cb
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/refreshReload.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/saveDisc.png b/tools/ArtistTools/source/BlastPlugin/UI/images/saveDisc.png
new file mode 100644
index 0000000..c0dc719
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/saveDisc.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/simulationPlay.png b/tools/ArtistTools/source/BlastPlugin/UI/images/simulationPlay.png
new file mode 100644
index 0000000..e5bc551
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/simulationPlay.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/simulationStep.png b/tools/ArtistTools/source/BlastPlugin/UI/images/simulationStep.png
new file mode 100644
index 0000000..8ab9e49
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/simulationStep.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/simulationStop.png b/tools/ArtistTools/source/BlastPlugin/UI/images/simulationStop.png
new file mode 100644
index 0000000..8576b5b
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/simulationStop.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/transportLoop.png b/tools/ArtistTools/source/BlastPlugin/UI/images/transportLoop.png
new file mode 100644
index 0000000..3e13e2f
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/transportLoop.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/transportPlay.png b/tools/ArtistTools/source/BlastPlugin/UI/images/transportPlay.png
new file mode 100644
index 0000000..e5e593e
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/transportPlay.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/transportRewind.png b/tools/ArtistTools/source/BlastPlugin/UI/images/transportRewind.png
new file mode 100644
index 0000000..95664d2
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/transportRewind.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/transportStepForward.png b/tools/ArtistTools/source/BlastPlugin/UI/images/transportStepForward.png
new file mode 100644
index 0000000..4d35753
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/transportStepForward.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/transportStop.png b/tools/ArtistTools/source/BlastPlugin/UI/images/transportStop.png
new file mode 100644
index 0000000..27f3cbd
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/transportStop.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/visibilityToggle_notVisible.png b/tools/ArtistTools/source/BlastPlugin/UI/images/visibilityToggle_notVisible.png
new file mode 100644
index 0000000..56b24fe
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/visibilityToggle_notVisible.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/UI/images/visibilityToggle_visible.png b/tools/ArtistTools/source/BlastPlugin/UI/images/visibilityToggle_visible.png
new file mode 100644
index 0000000..3e5a88e
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/UI/images/visibilityToggle_visible.png
Binary files differ
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.cpp
deleted file mode 100644
index b42a4f5..0000000
--- a/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.cpp
+++ /dev/null
@@ -1,306 +0,0 @@
-#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/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.h b/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.h
deleted file mode 100644
index b4e5bcf..0000000
--- a/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#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/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp b/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp
index a6cdf64..ab0ca85 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp
@@ -4,18 +4,50 @@
#include <QtWidgets/QPushButton>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QMenu>
+#include <QtWidgets/QShortcut>
#include <QtCore/QFileInfo>
+#include <QtGui/qevent.h>
+#include <QtGui/QPainter>
#include <assert.h>
#include "ProjectParams.h"
#include <SimpleScene.h>
#include <BlastController.h>
+#include "SelectionToolController.h"
+#include "GizmoToolController.h"
#include <SceneController.h>
#include <NvBlastExtPxAsset.h>
#include <NvBlastTkAsset.h>
#include <NvBlastAsset.h>
#include <BlastFamilyModelSimple.h>
#include "GlobalSettings.h"
+#include <deque>
+#include "ViewerOutput.h"
+static QIcon sCompositeIcon;
+static QIcon sAssetIcon;
+static QIcon sChunkUUIcon;
+static QIcon sChunkSUIcon;
+static QIcon sChunkSSIcon;
+static QIcon sBondIcon;
+static QIcon sProjectileIcon;
+
+static QPixmap sVisibleIcon = QPixmap(":/AppMainWindow/images/visibilityToggle_visible.png").scaled(QSize(24, 24), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+static QPixmap sInVisibleIcon = QPixmap(":/AppMainWindow/images/visibilityToggle_notVisible.png").scaled(QSize(24, 24), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+
+class BlastSceneTreeDataLock
+{
+public:
+ BlastSceneTreeDataLock()
+ {
+ BlastSceneTree::ins()->_updateData = false;
+ }
+ ~BlastSceneTreeDataLock()
+ {
+ BlastSceneTree::ins()->_updateData = true;
+ }
+};
+
+#if 0
bool isChunkVisible(std::vector<BlastFamily*>& fs, uint32_t chunkIndex)
{
int fsSize = fs.size();
@@ -35,6 +67,7 @@ bool isChunkVisible(std::vector<BlastFamily*>& fs, uint32_t chunkIndex)
}
return visible;
}
+#endif
void setChunkVisible(std::vector<BlastFamily*>& fs, uint32_t chunkIndex, bool visible)
{
@@ -60,13 +93,28 @@ void setChunkSelected(std::vector<BlastFamily*>& fs, uint32_t chunkIndex, bool s
for (int i = 0; i < fsSize; i++)
{
- fs[i]->setChunkSelected(chunkIndex, selected);
+ BlastFamily* bf = fs[i];
+ if(bf)
+ bf->setChunkSelected(chunkIndex, selected);
+ }
+}
+
+void BlastNode::traverse(BlastVisitorBase& visitor)
+{
+ visitor.visit(this);
+
+ for (BlastNode* node : children)
+ {
+ if (!visitor.continueTraversing())
+ break;
+
+ node->traverse(visitor);
}
}
void BlastChunkNode::setVisible(bool val)
{
- BPPChunk* pBPPChunk = (BPPChunk*)_data;
+ BPPChunk* pBPPChunk = (BPPChunk*)getData();
pBPPChunk->visible = val;
BlastAsset* pBlastAsset = (BlastAsset*)_assetPtr;
@@ -74,32 +122,88 @@ void BlastChunkNode::setVisible(bool val)
SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap();
- std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset];
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator it = AssetFamiliesMap.find(pBlastAsset);
+ if (it == AssetFamiliesMap.end())
+ {
+ return;
+ }
+ std::vector<BlastFamily*>& fs = it->second;
setChunkVisible(fs, pBPPChunk->ID, val);
}
void BlastChunkNode::setSelected(bool val)
{
- BPPChunk* pBPPChunk = (BPPChunk*)_data;
- pBPPChunk->visible = val;
+ BPPChunk* pBPPChunk = (BPPChunk*)getData();
BlastAsset* pBlastAsset = (BlastAsset*)_assetPtr;
SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap();
- std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset];
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator it = AssetFamiliesMap.find(pBlastAsset);
+ if (it == AssetFamiliesMap.end())
+ {
+ return;
+ }
+ std::vector<BlastFamily*>& fs = it->second;
setChunkSelected(fs, pBPPChunk->ID, val);
}
+void BlastAssetNode::setSelected(bool val)
+{
+ BPPAsset* pBPPAsset = (BPPAsset*)getData();
+ std::string strAsset = pBPPAsset->name.buf;
+
+ BlastAsset* pBlastAsset = nullptr;
+ SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = sampleManager.getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itAssetDescMap;
+ for (itAssetDescMap = AssetDescMap.begin();
+ itAssetDescMap != AssetDescMap.end(); itAssetDescMap++)
+ {
+ AssetList::ModelAsset& model = itAssetDescMap->second;
+ if (model.name == strAsset)
+ {
+ pBlastAsset = itAssetDescMap->first;
+ break;
+ }
+ }
+
+ sampleManager.setCurrentSelectedInstance(pBlastAsset, -1);
+
+ std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap();
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAFM = AssetFamiliesMap.find(pBlastAsset);
+ if (itAFM == AssetFamiliesMap.end())
+ {
+ return;
+ }
+ std::vector<BlastFamily*>& fs = itAFM->second;
+ for (BlastFamily* pBlastFamily : fs)
+ {
+ pBlastFamily->highlightChunks();
+ }
+}
+
+bool BlastProjectileNode::getVisible()
+{
+ return SampleManager::ins()->getSceneController().getProjectileVisible((PhysXSceneActor*)getData());
+}
+
+void BlastProjectileNode::setVisible(bool val)
+{
+ SampleManager::ins()->getSceneController().setProjectileVisible((PhysXSceneActor*)getData(), val);
+}
+
void BlastAssetInstanceNode::setSelected(bool val)
{
- BPPAssetInstance* pBPPAssetInstance = (BPPAssetInstance*)_data;
- std::string name = pBPPAssetInstance->name;
+ BPPAssetInstance* pBPPAssetInstance = (BPPAssetInstance*)getData();
+ if (pBPPAssetInstance == nullptr)
+ return;
+ std::string name = pBPPAssetInstance->name.buf;
- std::string strAsset = name.substr(0, name.find_first_of("_"));
+ std::string strAsset = name.substr(0, name.find_last_of("_"));
BlastAsset* pBlastAsset = nullptr;
SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = sampleManager.getAssetDescMap();
@@ -119,6 +223,9 @@ void BlastAssetInstanceNode::setSelected(bool val)
int nIndex = atoi(strIndex.c_str());
sampleManager.setCurrentSelectedInstance(pBlastAsset, nIndex);
+
+ std::vector<BlastFamily*> fs = { SampleManager::ins()->getFamilyByInstance(pBPPAssetInstance) };
+ setChunkSelected(fs, 0, val);
}
BlastTreeData& BlastTreeData::ins()
@@ -152,7 +259,7 @@ std::vector<BlastChunkNode*> BlastTreeData::getTopChunkNodes(std::vector<BlastCh
bool isCurNodeTop = true;
for (size_t j = 0; j < nodes.size(); ++j)
{
- if (i != j && isChild(nodes[i], nodes[j]))
+ if (i != j && isChild(nodes[j], nodes[i]))
{
isCurNodeTop = false;
break;
@@ -168,6 +275,18 @@ std::vector<BlastChunkNode*> BlastTreeData::getTopChunkNodes(std::vector<BlastCh
return result;
}
+int BlastTreeData::getDepth(BlastNode* node)
+{
+ int depth = -1; // here it's from -1 because it traverse from Blast asset node
+ while (nullptr != node && (eBond == node->getType() || eChunk == node->getType()))
+ {
+ ++depth;
+ node = node->getParent();
+ }
+
+ return depth;
+}
+
bool BlastTreeData::isRoot(BlastChunkNode* node)
{
if (node == nullptr || node->getParent() == nullptr)
@@ -197,6 +316,7 @@ void removeChunkNodeSupport(BlastChunkNode* node)
BPPChunk* chunk = static_cast<BPPChunk*>(node->getData());
chunk->support = false;
+ chunk->staticFlag = false;
for (BlastNode* curNode : node->children)
{
@@ -207,14 +327,72 @@ void removeChunkNodeSupport(BlastChunkNode* node)
}
}
+void setAncestorSupportFlag(BlastChunkNode* ancestor, BlastChunkNode* startChild)
+{
+ if (nullptr == ancestor || nullptr == startChild)
+ return;
+
+ {
+ BPPChunk* bppChunk = (BPPChunk*)(ancestor->getData());
+ bppChunk->support = false;
+ bppChunk->staticFlag = false;
+ }
+
+ std::deque<BlastChunkNode*> ancestors;
+ for (BlastNode* node : ancestor->children)
+ {
+ if (eChunk == node->getType())
+ {
+ ancestors.push_back(static_cast<BlastChunkNode*>(node));
+ }
+ }
+
+ while (ancestors.size() > 0)
+ {
+ BlastChunkNode* curAncestor = ancestors.front();
+ ancestors.pop_front();
+
+ bool isChild = BlastTreeData::isChild(curAncestor, startChild);
+ if (isChild)
+ {
+ if (curAncestor != startChild)
+ {
+ for (BlastNode* node : curAncestor->children)
+ {
+ if (eChunk == node->getType())
+ {
+ ancestors.push_back(static_cast<BlastChunkNode*>(node));
+ }
+ }
+ }
+ }
+ else
+ {
+ BPPChunk* bppChunk = (BPPChunk*)(curAncestor->getData());
+ bppChunk->support = true;
+ bppChunk->staticFlag = false;
+ }
+ }
+}
+
void BlastTreeData::makeSupport(BlastChunkNode* node)
{
if (node == nullptr)
return;
+
+ // 1 set flag for current node
BPPChunk* chunk = static_cast<BPPChunk*>(node->getData());
chunk->staticFlag = false;
chunk->support = true;
+ // 2 set flag for ancestors
+ BlastChunkNode* supportAncestor = ins().getSupportAncestor(node);
+ if (supportAncestor)
+ {
+ setAncestorSupportFlag(supportAncestor, node);
+ }
+
+ // 3 set flag for children
for (BlastNode* curNode : node->children)
{
if (eChunk == curNode->getType())
@@ -228,10 +406,20 @@ void BlastTreeData::makeStaticSupport(BlastChunkNode* node)
{
if (node == nullptr)
return;
+
+ // 1 set flag for current node
BPPChunk* chunk = static_cast<BPPChunk*>(node->getData());
chunk->staticFlag = true;
chunk->support = true;
+ // 2 set flag for ancestors
+ BlastChunkNode* supportAncestor = ins().getSupportAncestor(node);
+ if (supportAncestor)
+ {
+ setAncestorSupportFlag(supportAncestor, node);
+ }
+
+ // 3 set flag for children
for (BlastNode* curNode : node->children)
{
if (eChunk == curNode->getType())
@@ -259,8 +447,37 @@ void BlastTreeData::removeSupport(BlastChunkNode* node)
{
BPPChunk* curChunk = static_cast<BPPChunk*>(curNode->getData());
curChunk->support = true;
+ curChunk->staticFlag = false;
+ }
+ }
+}
+
+std::string BlastTreeData::getAssetName(BlastAsset* asset)
+{
+ std::map<BlastAsset*, AssetList::ModelAsset>& assetDescMap = SampleManager::ins()->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itrAssetDesc = assetDescMap.find(asset);
+
+ if (itrAssetDesc != assetDescMap.end())
+ {
+ return itrAssetDesc->second.name;
+ }
+
+ return "";
+}
+
+BlastAsset* BlastTreeData::getAsset(std::string assetName)
+{
+ std::map<BlastAsset*, AssetList::ModelAsset>& assetDescMap = SampleManager::ins()->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itrAssetDesc = assetDescMap.begin();
+ for (; itrAssetDesc != assetDescMap.end(); ++itrAssetDesc)
+ {
+ if (itrAssetDesc->second.name == assetName)
+ {
+ return itrAssetDesc->first;
}
}
+
+ return nullptr;
}
BlastNode* BlastTreeData::getBlastNodeByProjectData(void* data)
@@ -328,6 +545,53 @@ void BlastTreeData::remove(const BlastAssetInstanceNode* node)
//to do
}
+BlastAssetInstanceNode* BlastTreeData::getAssetInstanceNode(BlastFamily* family)
+{
+ BPPAssetInstance* instance = SampleManager::ins()->getInstanceByFamily(family);
+ return getAssetInstanceNode(instance);
+}
+
+BlastAssetInstanceNode* BlastTreeData::getAssetInstanceNode(BPPAssetInstance* instance)
+{
+ if (nullptr == instance)
+ return nullptr;
+
+ for (BlastNode* node : _assetInstancesNode->children)
+ {
+ if ((BPPAssetInstance*)(node->getData()) == instance)
+ {
+ return (BlastAssetInstanceNode*)node;
+ }
+ }
+
+ return nullptr;
+}
+
+std::vector<BlastAssetInstanceNode*> BlastTreeData::getAssetInstanceNodes(BlastChunkNode* chunkNode)
+{
+ std::vector<BlastAssetInstanceNode*> instanceNodes;
+
+ if (nullptr == chunkNode)
+ return instanceNodes;
+
+ BlastAsset* asset = getAsset(chunkNode);
+
+ if (isRoot(chunkNode))
+ {
+ BPPAssetInstance* instance = (BPPAssetInstance*)(chunkNode->getData());
+
+ for (BlastNode* instanceNode : _assetInstancesNode->children)
+ {
+ BPPAssetInstance* instance = (BPPAssetInstance*)(instanceNode->getData());
+ BlastFamily* family = SampleManager::ins()->getFamilyByInstance(instance);
+ if (&(family->getBlastAsset()) == asset)
+ instanceNodes.push_back((BlastAssetInstanceNode*)instanceNode);
+ }
+ }
+
+ return instanceNodes;
+}
+
void BlastTreeData::update()
{
_freeBlastNode();
@@ -352,269 +616,20 @@ void BlastTreeData::update()
BlastAssetVec.push_back(it->first);
}
int modelAssetsSize = AssetDescMap.size();
-
- std::vector<std::string> projectilesNames;
- sceneController.GetProjectilesNames(projectilesNames);
-
- // compoistie
- {
- BPPComposite& composite = blast.composite;
- composite.composite.buf = nullptr;
- composite.visible = true;
- copy(composite.composite, "BlastComposite");
-
- // asset instance array
- {
- BPPAssetInstanceArray& instanceArray = composite.blastAssetInstances;
- instanceArray.arraySizes[0] = familiesSize;
- if (familiesSize > 0)
- {
- instanceArray.buf = new BPPAssetInstance[familiesSize];
- int curInstanceIndex = 0;
- char instancename[MAX_PATH];
- std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAssetFamiliesMap;
- for (itAssetFamiliesMap = AssetFamiliesMap.begin();
- itAssetFamiliesMap != AssetFamiliesMap.end(); itAssetFamiliesMap++)
- {
- BlastAsset* pBlastAsset = itAssetFamiliesMap->first;
- std::vector<BlastFamily*>& fs = itAssetFamiliesMap->second;
- int fsSize = fs.size();
- for (int i = 0; i < fsSize; i++)
- {
- BPPAssetInstance& instance = instanceArray.buf[curInstanceIndex];
- instance.name.buf = nullptr;
- instance.source.buf = nullptr;
- instance.visible = true;
-
- AssetList::ModelAsset desc = AssetDescMap[pBlastAsset];
- sprintf(instancename, "%s_Instance_%d", desc.name.c_str(), i);
- copy(instance.name, instancename);
-
- std::string assetFilePath = GlobalSettings::MakeFileName(GlobalSettings::Inst().m_projectFileDir.c_str(), std::string(desc.file + ".bpxa").c_str());
- sprintf(instancename, "%s", assetFilePath.c_str());
- copy(instance.source, instancename);
-
- PxVec3 p = desc.transform.p;
- PxQuat q = desc.transform.q;
- instanceArray.buf[curInstanceIndex].transform.position = nvidia::NvVec3(p.x, p.y, p.z);
- instanceArray.buf[curInstanceIndex].transform.rotation = nvidia::NvVec4(q.x, q.y, q.z, q.w);
-
- curInstanceIndex++;
- }
- }
- }
- }
-
- // landmark array
- if (0)
- {
- BPPLandmarkArray& landmarkArray = composite.landmarks;
- landmarkArray.buf = new BPPLandmark[2];
- landmarkArray.arraySizes[0] = 2;
- landmarkArray.buf[0].name.buf = nullptr;
- landmarkArray.buf[1].name.buf = nullptr;
-
- copy(landmarkArray.buf[0].name, "Landmark_1");
- copy(landmarkArray.buf[1].name, "Landmark_2");
- }
- }
-
- // asset array
- {
- BPPAssetArray& assetArray = blast.blastAssets;
- assetArray.arraySizes[0] = modelAssetsSize;
- if (modelAssetsSize > 0)
- {
- assetArray.buf = new BPPAsset[modelAssetsSize];
- int curAssetIndex = 0;
-
- blast.chunks.buf = nullptr;
- blast.chunks.arraySizes[0] = 0;
- blast.bonds.buf = nullptr;
- blast.bonds.arraySizes[0] = 0;
-
- std::map<BlastAsset*, AssetList::ModelAsset>::iterator itAssetDescMap;
- for (itAssetDescMap = AssetDescMap.begin();
- itAssetDescMap != AssetDescMap.end(); itAssetDescMap++)
- {
- BlastAsset* pBlastAsset = itAssetDescMap->first;
- AssetList::ModelAsset& desc = itAssetDescMap->second;
- std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset];
-
- BPPAsset& asset = assetArray.buf[curAssetIndex];
- asset.path.buf = nullptr;
- asset.activePreset.buf = nullptr;
- std::string assetFilePath = GlobalSettings::MakeFileName(GlobalSettings::Inst().m_projectFileDir.c_str(), std::string(desc.file + ".bpxa").c_str());
- copy(asset.path, assetFilePath.c_str());
-
- const ExtPxAsset* pExtPxAsset = pBlastAsset->getPxAsset();
- const ExtPxChunk* pExtPxChunk = pExtPxAsset->getChunks();
-
- const TkAsset& tkAsset = pExtPxAsset->getTkAsset();
- uint32_t chunkCount = tkAsset.getChunkCount();
- const NvBlastChunk* pNvBlastChunk = tkAsset.getChunks();
- uint32_t bondCount = tkAsset.getBondCount();
- const NvBlastBond* pNvBlastBond = tkAsset.getBonds();
-
- const NvBlastSupportGraph supportGraph = tkAsset.getGraph();
- uint32_t* chunkIndices = supportGraph.chunkIndices;
- uint32_t* adjacencyPartition = supportGraph.adjacencyPartition;
- uint32_t* adjacentNodeIndices = supportGraph.adjacentNodeIndices;
- uint32_t* adjacentBondIndices = supportGraph.adjacentBondIndices;
-
- ChunkSupport* pSupport = new ChunkSupport[chunkCount];
- BondChunkIndices* pBCIndices = new BondChunkIndices[bondCount];
-
- for (uint32_t node0 = 0; node0 < supportGraph.nodeCount; ++node0)
- {
- const uint32_t chunkIndex0 = supportGraph.chunkIndices[node0];
-
- pSupport[chunkIndex0].m_bSupport = true;
-
- for (uint32_t adjacencyIndex = adjacencyPartition[node0]; adjacencyIndex < adjacencyPartition[node0 + 1]; adjacencyIndex++)
- {
- uint32_t node1 = supportGraph.adjacentNodeIndices[adjacencyIndex];
-
- // add this condition if you don't want to iterate all bonds twice
- if (node0 > node1)
- continue;
-
- const uint32_t chunkIndex1 = supportGraph.chunkIndices[node1];
-
- uint32_t bondIndex = supportGraph.adjacentBondIndices[adjacencyIndex];
-
- pBCIndices[bondIndex].SetIndices(chunkIndex0, chunkIndex1);
- }
- }
-
- // chunks
- {
- BPPChunkArray curArray;
- curArray.buf = new BPPChunk[chunkCount];
- curArray.arraySizes[0] = chunkCount;
- char chunkname[10];
- for (int cc = 0; cc < chunkCount; ++cc)
- {
- BPPChunk& chunk = curArray.buf[cc];
- chunk.name.buf = nullptr;
- chunk.asset.buf = nullptr;
-
- std::vector<uint32_t> parentChunkIndexes;
- parentChunkIndexes.push_back(cc);
- uint32_t parentChunkIndex = cc;
- while ((parentChunkIndex = pNvBlastChunk[parentChunkIndex].parentChunkIndex) != -1)
- {
- parentChunkIndexes.push_back(parentChunkIndex);
- }
-
- std::string strChunkName = "Chunk";
- for (int pcIndex = parentChunkIndexes.size() - 1; pcIndex >= 0; pcIndex--)
- {
- sprintf(chunkname, "_%d", parentChunkIndexes[pcIndex]);
- strChunkName += chunkname;
- }
- copy(chunk.name, strChunkName.c_str());
-
- copy(chunk.asset, asset.path);
- chunk.ID = cc;
- chunk.parentID = pNvBlastChunk[cc].parentChunkIndex;
- chunk.staticFlag = pExtPxChunk[cc].isStatic;
- chunk.visible = isChunkVisible(fs, cc);
- chunk.support = pSupport[cc].m_bSupport;
- }
-
- merge(blast.chunks, curArray);
- freeBlast(curArray);
- }
-
- // bonds
- {
- BPPBondArray curArray;
- curArray.buf = new BPPBond[bondCount];
- curArray.arraySizes[0] = bondCount;
- char bondname[10];
- bool visible;
- for (int bc = 0; bc < bondCount; ++bc)
- {
- BPPBond& bond = curArray.buf[bc];
- bond.name.buf = nullptr;
- bond.asset.buf = nullptr;
-
- visible = isChunkVisible(fs, pBCIndices[bc].chunkIndices[0])
- || isChunkVisible(fs, pBCIndices[bc].chunkIndices[1]);
- bond.visible = visible;
- bond.fromChunk = pBCIndices[bc].chunkIndices[0];
- bond.toChunk = pBCIndices[bc].chunkIndices[1];
-
- sprintf(bondname, "Bond_%d_%d", bond.fromChunk, bond.toChunk);
- copy(bond.name, bondname);
- copy(bond.asset, asset.path);
-
- bond.support.healthMask.buf = nullptr;
- bond.support.bondStrength = 1.0;
- bond.support.enableJoint = false;
- }
-
- merge(blast.bonds, curArray);
- freeBlast(curArray);
- }
-
- delete[] pSupport;
- pSupport = nullptr;
- delete[] pBCIndices;
- pBCIndices = nullptr;
-
- curAssetIndex++;
- }
- }
- }
-
- // projectile
- {
- BPPProjectileArray& projectileArray = blast.projectiles;
- int BPPProjectileSize = projectilesNames.size();
- projectileArray.arraySizes[0] = BPPProjectileSize;
- if (BPPProjectileSize > 0)
- {
- projectileArray.buf = new BPPProjectile[BPPProjectileSize];
- for (int i = 0; i < BPPProjectileSize; i++)
- {
- projectileArray.buf[i].name.buf = nullptr;
- copy(projectileArray.buf[i].name, projectilesNames[i].c_str());
- projectileArray.buf[i].visible = true;
- }
- }
- }
-
- // graphics meshes
- if (0)
- {
- BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes;
- graphicsMeshArray.buf = new BPPGraphicsMesh[3];
- graphicsMeshArray.arraySizes[0] = 3;
- graphicsMeshArray.buf[0].name.buf = nullptr;
- copy(graphicsMeshArray.buf[0].name, "SurfaceMesh1");
- graphicsMeshArray.buf[0].visible = true;
-
- graphicsMeshArray.buf[1].name.buf = nullptr;
- copy(graphicsMeshArray.buf[1].name, "SurfaceMesh2");
- graphicsMeshArray.buf[1].visible = true;
-
- graphicsMeshArray.buf[2].name.buf = nullptr;
- copy(graphicsMeshArray.buf[2].name, "DisplayMesh1");
- graphicsMeshArray.buf[2].visible = true;
- }
}
BPPAssetArray& assetArray = blast.blastAssets;
int count = assetArray.arraySizes[0];
+ if (BlastAssetVec.size() != count)
+ {
+ return;
+ }
for (int c = 0; c < count; ++c)
{
BPPAsset& asset = assetArray.buf[c];
- QFileInfo fileInfo(asset.path.buf);
- BlastAssetNode* assetNode = new BlastAssetNode(fileInfo.baseName().toUtf8().data(), asset);
+ BlastAssetNode* assetNode = new BlastAssetNode(asset.name.buf, asset);
_assets.push_back(assetNode);
_blastProjectDataToNodeMap.insert(std::make_pair((void*)&asset, assetNode));
@@ -632,53 +647,41 @@ void BlastTreeData::update()
}
}
- BPPComposite& composite = blast.composite;
- _composite = new BlastCompositeNode(composite.composite.buf, composite);
- _blastProjectDataToNodeMap.insert(std::make_pair((void*)&composite, _composite));
- BPPAssetInstanceArray& assetInstanceArray = composite.blastAssetInstances;
+ _assetInstancesNode = new BlastAssetInstancesNode("BlastAssetInstances");
+ _blastProjectDataToNodeMap.insert(std::make_pair(nullptr, _assetInstancesNode));
+ BPPAssetInstanceArray& assetInstanceArray = blast.blastAssetInstances;
count = assetInstanceArray.arraySizes[0];
for (int i = 0; i < count; ++i)
{
- BPPAssetInstance& blastAssetInstance = composite.blastAssetInstances.buf[i];
+ BPPAssetInstance& blastAssetInstance = assetInstanceArray.buf[i];
BlastAssetInstanceNode* blastAssetInstanceNode = new BlastAssetInstanceNode(blastAssetInstance.name.buf, blastAssetInstance);
- _composite->children.push_back(blastAssetInstanceNode);
- blastAssetInstanceNode->setParent(_composite);
+ _assetInstancesNode->children.push_back(blastAssetInstanceNode);
+ blastAssetInstanceNode->setParent(_assetInstancesNode);
_blastProjectDataToNodeMap.insert(std::make_pair((void*)&blastAssetInstance, blastAssetInstanceNode));
}
- BPPLandmarkArray& landmarkArray = composite.landmarks;
- count = landmarkArray.arraySizes[0];
- for (int i = 0; i < count; ++i)
- {
- BPPLandmark& landmark = composite.landmarks.buf[i];
- BlastLandmarkNode* landmarkNode = new BlastLandmarkNode(landmark.name.buf, landmark);
- _composite->children.push_back(landmarkNode);
- landmarkNode->setParent(_composite);
- _blastProjectDataToNodeMap.insert(std::make_pair((void*)&landmark, landmarkNode));
- }
-
- BPPProjectileArray& projectileArray = blast.projectiles;
- count = projectileArray.arraySizes[0];
- for (int i = 0; i < count; ++i)
+ SceneController& sceneController = SampleManager::ins()->getSceneController();
+ std::vector<PhysXSceneActor*> projectiles = sceneController.getPrejectiles();
+ for (PhysXSceneActor* projectile : projectiles)
{
- BPPProjectile& projectile = projectileArray.buf[i];
- BlastProjectileNode* projectileNode = new BlastProjectileNode(projectile.name.buf, projectile);
+ BlastProjectileNode* projectileNode = new BlastProjectileNode(sceneController.getProjectileName(projectile), projectile);
_projectiles.push_back(projectileNode);
_blastProjectDataToNodeMap.insert(std::make_pair((void*)&projectile, projectileNode));
}
- BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes;
- count = graphicsMeshArray.arraySizes[0];
- for (int i = 0; i < count; ++i)
- {
- BPPGraphicsMesh& graphicsMesh = graphicsMeshArray.buf[i];
- BlastGraphicsMeshNode* projectileNode = new BlastGraphicsMeshNode(graphicsMesh.name.buf, graphicsMesh);
- _graphicsMeshes.push_back(projectileNode);
- }
+ //BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes;
+ //count = graphicsMeshArray.arraySizes[0];
+ //for (int i = 0; i < count; ++i)
+ //{
+ // BPPGraphicsMesh& graphicsMesh = graphicsMeshArray.buf[i];
+ // BlastGraphicsMeshNode* graphicsNode = new BlastGraphicsMeshNode(graphicsMesh.name.buf, graphicsMesh);
+ // _graphicsMeshes.push_back(graphicsNode);
+ //}
}
-void BlastTreeData::updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible)
+BlastNode* BlastTreeData::getNodeByIndex(uint32_t assetIndex, uint32_t chunkIndex)
{
+ BlastNode* pNode = nullptr;
BPPBlast& blast = BlastProject::ins().getParams().blast;
BPPAssetArray& assetArray = blast.blastAssets;
if (assetIndex < assetArray.arraySizes[0])
@@ -688,13 +691,13 @@ void BlastTreeData::updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool
std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset);
if (chunkIndex < childChunks.size())
{
- BPPChunk& chunk = *(childChunks[chunkIndex]);
- chunk.visible = visible;
+ BPPChunk& chunk = *(childChunks[chunkIndex]);
+ pNode = getBlastNodeByProjectData(&chunk);
}
}
+ return pNode;
}
-
void BlastTreeData::update(const BlastAsset* asset)
{
//to do
@@ -744,15 +747,21 @@ BlastAsset* BlastTreeData::getAsset(BlastNode* node)
if (eAsset == node->getType())
{
- std::map<BlastAsset*, AssetList::ModelAsset>& assetDescMap = SampleManager::ins()->getAssetDescMap();
- std::map<BlastAsset*, AssetList::ModelAsset>::iterator itrAssetDesc = assetDescMap.begin();
- for (; itrAssetDesc != assetDescMap.end(); ++itrAssetDesc)
- {
- if (itrAssetDesc->second.name == node->name)
- {
- return itrAssetDesc->first;
- }
- }
+ return getAsset(node->name);
+ }
+
+ return nullptr;
+}
+
+BlastAssetNode* BlastTreeData::getAssetNode(BlastAsset* asset)
+{
+ if (nullptr == asset)
+ return nullptr;
+
+ for (BlastAssetNode* node : _assets)
+ {
+ if (node->name == getAssetName(asset))
+ return node;
}
return nullptr;
@@ -789,6 +798,250 @@ std::vector<BlastChunkNode*> BlastTreeData::getChunkNodeByBlastChunk(const Blast
return chunkNodes;
}
+std::vector<BlastNode*> _getNodesByDepth(BlastNode* curNode, uint32_t depth, int32_t curDepth)
+{
+ std::vector<BlastNode*> res;
+ if (depth == curDepth && curNode != nullptr)
+ {
+ res.push_back(curNode);
+ }
+ else if (curNode != nullptr)
+ {
+ for (BlastNode* node : curNode->children)
+ {
+ std::vector<BlastNode*> nodes = _getNodesByDepth(node, depth, curDepth + 1);
+ res.insert(res.begin(), nodes.begin(), nodes.end());
+ }
+ }
+
+ return res;
+}
+
+std::vector<BlastChunkNode*> BlastTreeData::getRootChunkNodeByInstance(const BlastAssetInstanceNode* node)
+{
+ std::vector<BlastChunkNode*> chunks;
+ if (nullptr != node)
+ {
+ const BPPAssetInstance* pBPPAssetInstance = (BPPAssetInstance*)(const_cast<BlastAssetInstanceNode*>(node)->getData());
+ BlastFamily* family = SampleManager::ins()->getFamilyByInstance(const_cast<BPPAssetInstance*>(pBPPAssetInstance));
+ if (family)
+ {
+ const BlastAsset& asset = family->getBlastAsset();
+ BlastAssetNode* assetNode = getAssetNode(const_cast<BlastAsset*>(&asset));
+ if (assetNode)
+ {
+ for (BlastNode* curNode : assetNode->children)
+ {
+ if (eChunk == curNode->getType())
+ {
+ chunks.push_back((BlastChunkNode*)curNode);
+ }
+ }
+ }
+ }
+ }
+ return chunks;
+}
+
+std::vector<BlastNode*> BlastTreeData::getNodesByDepth(BlastAssetNode* node, uint32_t depth)
+{
+ return _getNodesByDepth(node, depth, -1); // here it's from -1 because it traverse from Blast asset node
+}
+
+std::vector<BlastNode*> BlastTreeData::getNodesByDepth(uint32_t depth)
+{
+ std::vector<BlastNode*> res;
+ for (BlastAssetNode* node : _assets)
+ {
+ std::vector<BlastNode*> nodes = getNodesByDepth(node, depth);
+ res.insert(res.begin(), nodes.begin(), nodes.end());
+ }
+ return res;
+}
+
+std::vector<BlastNode*> BlastTreeData::getNodesByDepth(std::vector<uint32_t> depths)
+{
+ std::vector<BlastNode*> res;
+ for (uint32_t depth : depths)
+ {
+ std::vector<BlastNode*> nodes = getNodesByDepth(depth);
+ res.insert(res.begin(), nodes.begin(), nodes.end());
+ }
+ return res;
+}
+
+std::vector<BlastChunkNode*> _getSupportChunkNodes(BlastNode* curNode)
+{
+ std::vector<BlastChunkNode*> res;
+ if (nullptr != curNode && eChunk == curNode->getType() && static_cast<BlastChunkNode*>(curNode)->isSupport())
+ {
+ res.push_back(static_cast<BlastChunkNode*>(curNode));
+ }
+ else if (curNode != nullptr)
+ {
+ for (BlastNode* node : curNode->children)
+ {
+ std::vector<BlastChunkNode*> nodes = _getSupportChunkNodes(node);
+ res.insert(res.begin(), nodes.begin(), nodes.end());
+ }
+ }
+
+ return res;
+}
+
+std::vector<BlastChunkNode*> BlastTreeData::getSupportChunkNodes(BlastAssetNode* node)
+{
+ return _getSupportChunkNodes(node);
+}
+
+std::vector<BlastChunkNode*> BlastTreeData::getSupportChunkNodes()
+{
+ std::vector<BlastChunkNode*> res;
+ for (BlastAssetNode* node : _assets)
+ {
+ std::vector<BlastChunkNode*> nodes = getSupportChunkNodes(node);
+ res.insert(res.begin(), nodes.begin(), nodes.end());
+ }
+ return res;
+}
+
+const std::vector<BlastNode*>& _getAllChunkNodes(std::vector<BlastNode*>& res, BlastNode* curNode)
+{
+ if (nullptr == curNode)
+ return res;
+ if (eChunk == curNode->getType())
+ {
+ res.push_back(static_cast<BlastNode*>(curNode));
+ }
+ for (BlastNode* node : curNode->children)
+ {
+ _getAllChunkNodes(res, node);
+ }
+
+ return res;
+}
+
+std::vector<BlastChunkNode*> BlastTreeData::getSiblingChunkNodes(BlastChunkNode* node)
+{
+ std::vector<BlastChunkNode*> res;
+
+ if (nullptr == node)
+ return res;
+
+ BlastNode* parent = node->getParent();
+ if (nullptr == parent || eChunk != parent->getType())
+ {
+ return res;
+ }
+
+ BlastChunkNode* chunkNodeParent = static_cast<BlastChunkNode*>(parent);
+
+ for (BlastNode* child : chunkNodeParent->children)
+ {
+ if (eChunk == child->getType() && child != node)
+ res.push_back(static_cast<BlastChunkNode*>(child));
+ }
+ return res;
+}
+
+BlastChunkNode* BlastTreeData::getSupportAncestor(BlastChunkNode* node)
+{
+ if (nullptr == node)
+ return nullptr;
+
+ BlastNode* parent = node->getParent();
+ while (parent && eChunk == parent->getType())
+ {
+ BlastChunkNode* chunkNodeParent = static_cast<BlastChunkNode*>(parent);
+ BPPChunk* bppChunk = (BPPChunk*)(chunkNodeParent->getData());
+ if (bppChunk->support)
+ return chunkNodeParent;
+ parent = chunkNodeParent->getParent();
+ }
+
+ return nullptr;
+}
+
+const std::vector<BlastNode*>& BlastTreeData::getAllChunkNodes(std::vector<BlastNode*>& res, BlastAssetNode* node)
+{
+ return _getAllChunkNodes(res, node);
+}
+
+const std::vector<BlastNode*>& BlastTreeData::getAllChunkNodes(std::vector<BlastNode*>& res)
+{
+ for (BlastAssetNode* node : _assets)
+ {
+ getAllChunkNodes(res, node);
+ }
+ return res;
+}
+
+const std::vector<BlastNode*>& _getAllLeavesChunkNodes(std::vector<BlastNode*>& res, BlastNode* curNode)
+{
+ if (nullptr == curNode)
+ return res;
+ if (eChunk == curNode->getType())
+ {
+ if (BlastTreeData::isLeaf(dynamic_cast<BlastChunkNode*>(curNode)))
+ res.push_back(curNode);
+ }
+ for (BlastNode* node : curNode->children)
+ {
+ _getAllLeavesChunkNodes(res, node);
+ }
+
+ return res;
+}
+
+const std::vector<BlastNode*>& BlastTreeData::getAllLeavesChunkNodes(std::vector<BlastNode*>& res, BlastAssetNode* node)
+{
+ return _getAllLeavesChunkNodes(res, node);
+}
+
+const std::vector<BlastNode*>& BlastTreeData::getAllLeavesChunkNodes(std::vector<BlastNode*>& res)
+{
+ for (BlastAssetNode* node : _assets)
+ {
+ getAllLeavesChunkNodes(res, node);
+ }
+ return res;
+}
+
+// start from -1 because asset also takes one level.
+const std::vector<BlastNode*>& _getChunkNodesFullCoverage(std::vector<BlastNode*>& res, BlastNode* curNode, int depth, int currDepth = -1)
+{
+ if (nullptr == curNode)
+ return res;
+ if (eChunk == curNode->getType())
+ {
+ if((currDepth == depth) || ((currDepth < depth) && BlastTreeData::isLeaf(dynamic_cast<BlastChunkNode*>(curNode))))
+ res.push_back(curNode);
+ }
+ if (currDepth < depth)
+ {
+ for (BlastNode* node : curNode->children)
+ {
+ _getChunkNodesFullCoverage(res, node, depth, currDepth + 1);
+ }
+ }
+
+ return res;
+}
+
+const std::vector<BlastNode*>& BlastTreeData::getChunkNodesFullCoverage(std::vector<BlastNode*>& res, BlastAssetNode* node, int depth)
+{
+ return _getChunkNodesFullCoverage(res, node, depth);
+}
+
+const std::vector<BlastNode*>& BlastTreeData::getChunkNodesFullCoverage(std::vector<BlastNode*>& res, int depth)
+{
+ for (BlastAssetNode* node : _assets)
+ {
+ getChunkNodesFullCoverage(res, node, depth);
+ }
+ return res;
+}
+
bool isCompleteSupport(BlastChunkNode* node)
{
if (node == nullptr)
@@ -894,36 +1147,83 @@ bool BlastTreeData::isOverlapSupportAsset(const BlastAssetNode* node)
return false;
}
+void BlastTreeData::traverse(BlastVisitorBase& visitor)
+{
+ for (BlastAssetNode* assetNode : _assets)
+ {
+ if (!visitor.continueTraversing())
+ break;
+
+ assetNode->traverse(visitor);
+ }
+}
+
BlastTreeData::BlastTreeData()
{
+ _assetInstancesNode = new BlastAssetInstancesNode("BlastAssetInstances");
+ _blastProjectDataToNodeMap.clear();
}
-void BlastTreeData::_addChunkNode(const BPPChunk& parentData, BPPAsset& asset, BlastChunkNode* parentNode, void* assetPtr)
+void BlastTreeData::_addChunkNode(BPPChunk& parentData, BPPAsset& asset, BlastChunkNode* parentNode, void* assetPtr)
{
- if (parentNode != nullptr)
+ if (parentNode == nullptr)
{
- std::vector<BPPBond*> bonds = BlastProject::ins().getBondsByChunk(asset, parentData.ID);
- for (size_t i = 0; i < bonds.size(); ++i)
+ return;
+ }
+
+ std::vector<BPPBond*> bonds = BlastProject::ins().getBondsByChunk(asset, parentData.ID);
+ for (size_t i = 0; i < bonds.size(); ++i)
+ {
+ BPPBond* bond = bonds[i];
+ BlastBondNode* bondNode = new BlastBondNode(bond->name.buf, *bond);
+ parentNode->children.push_back(bondNode);
+ bondNode->setParent(parentNode);
+ _blastProjectDataToNodeMap.insert(std::make_pair((void*)bond, bondNode));
+ }
+
+ std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset, parentData.ID);
+ for (size_t i = 0; i < childChunks.size(); ++i)
+ {
+ BPPChunk& chunk = *(childChunks[i]);
+ BlastChunkNode* chunkNode = new BlastChunkNode(chunk.name.buf, chunk, assetPtr);
+ parentNode->children.push_back(chunkNode);
+ chunkNode->setParent(parentNode);
+ _blastProjectDataToNodeMap.insert(std::make_pair((void*)&chunk, chunkNode));
+ _addChunkNode(chunk, asset, chunkNode, assetPtr);
+ }
+}
+
+void BlastTreeData::_removeChunkNode(BPPAsset& asset)
+{
+ std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset);
+ int childChunksSize = childChunks.size();
+ for (size_t i = 0; i < childChunksSize; i++)
+ {
+ std::map<void*, BlastNode*>::iterator it = _blastProjectDataToNodeMap.find(childChunks[i]);
+ if (it == _blastProjectDataToNodeMap.end())
{
- BPPBond* bond = bonds[i];
- BlastBondNode* bondNode = new BlastBondNode(bond->name.buf, *bond);
- parentNode->children.push_back(bondNode);
- bondNode->setParent(parentNode);
- _blastProjectDataToNodeMap.insert(std::make_pair((void*)bond, bondNode));
+ continue;
}
- std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset, parentData.ID);
+ BlastNode* node = it->second;
+ _blastProjectDataToNodeMap.erase(it);
+ delete node;
+ }
- for (size_t i = 0; i < childChunks.size(); ++i)
+ std::vector<BPPBond*> childBonds = BlastProject::ins().getChildrenBonds(asset);
+ int childBondsSize = childBonds.size();
+ for (size_t i = 0; i < childBondsSize; i++)
+ {
+ std::map<void*, BlastNode*>::iterator it = _blastProjectDataToNodeMap.find(childBonds[i]);
+ if (it == _blastProjectDataToNodeMap.end())
{
- BPPChunk& chunk = *(childChunks[i]);
- BlastChunkNode* chunkNode = new BlastChunkNode(chunk.name.buf, chunk, assetPtr);
- parentNode->children.push_back(chunkNode);
- chunkNode->setParent(parentNode);
- _blastProjectDataToNodeMap.insert(std::make_pair((void*)&chunk, chunkNode));
- _addChunkNode(chunk, asset, chunkNode, assetPtr);
+ continue;
}
+
+ BlastNode* node = it->second;
+ _blastProjectDataToNodeMap.erase(it);
+ delete node;
}
}
@@ -951,15 +1251,15 @@ void freeChunkNode(BlastChunkNode* chunkNode)
void BlastTreeData::_freeBlastNode()
{
- if (_composite)
+ if (_assetInstancesNode)
{
- size_t count = _composite->children.size();
+ size_t count = _assetInstancesNode->children.size();
for (size_t i = 0; i < count; ++i)
{
- delete _composite->children[i];
+ delete _assetInstancesNode->children[i];
}
- delete _composite;
- _composite = nullptr;
+ delete _assetInstancesNode;
+ _assetInstancesNode = nullptr;
}
size_t count = _assets.size();
@@ -1009,76 +1309,78 @@ BlastAssetNode* BlastTreeData::_getAssetNode(const BlastAsset* asset)
return foundAssetNode;
}
-VisualButton::VisualButton(QWidget* parent, BlastNode* blastItem)
- : QWidget(parent)
- , _button(new QPushButton(parent))
- , _blastItem(blastItem)
+QRect _getVisualIconArea(const QStyleOptionViewItem &option)
{
- connect(_button, SIGNAL(toggled(bool)), this, SLOT(on_visualbility_toggled(bool)));
- _button->setCheckable(true);
- _button->setChecked(blastItem->getVisible());
- if (blastItem->getVisible())
- _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_visible.png"));
- else
- _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_notVisible.png"));
- _button->setFixedSize(20, 20);
- this->setLayoutDirection(Qt::RightToLeft);
- this->setLayout(new QHBoxLayout);
- this->layout()->setMargin(0);
- this->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
- this->layout()->addWidget(_button);
+ int iconLen = option.rect.height() - 2;
+ return QRect(option.rect.right() - iconLen, option.rect.top() + 1, iconLen, iconLen);
}
-void VisualButton::on_visualbility_toggled(bool checked)
+BlastTreeViewDelegate::BlastTreeViewDelegate(QObject* parent, QStandardItemModel* model)
+ : QStyledItemDelegate(parent)
+ , _treeModel(model)
{
- if (checked)
- {
- _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_visible.png"));
- }
- else
- {
- _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_notVisible.png"));
- }
-
- if (_blastItem)
- {
- _blastItem->setVisible(checked);
- }
+ setObjectName("BlastTreeViewDelegate");
}
-void VisualButton::_updateBlast(bool visible)
+void BlastTreeViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
- EBlastNodeType type = _blastItem->getType();
+ QStyledItemDelegate::paint(painter, option, index);
+
+ QStandardItem *treeItem = _treeModel->itemFromIndex(index);
+ BlastSceneTree* tree = BlastSceneTree::ins();
+ BlastNode* blastNode = tree->getBlastNodeByItem(treeItem);
+ PhysXSceneActor* projectileActor = tree->getProjectileActorByItem(treeItem);
- switch (type)
+ if ((nullptr == blastNode && nullptr == projectileActor))
+ return;
+
+ if(nullptr != blastNode && eChunk != blastNode->getType() && eBond != blastNode->getType())
+ return;
+
+ if (nullptr != blastNode)
+ painter->drawPixmap(_getVisualIconArea(option), blastNode->getVisible() ? sVisibleIcon : sInVisibleIcon);
+ else if (nullptr != projectileActor)
+ painter->drawPixmap(_getVisualIconArea(option), SampleManager::ins()->getSceneController().getProjectileVisible(projectileActor) ? sVisibleIcon : sInVisibleIcon);
+}
+
+bool BlastTreeViewDelegate::editorEvent(QEvent* evt, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
+{
+ if (evt->type() == QEvent::MouseButtonRelease)
{
- case eBond:
- ((BPPBond*)_blastItem->getData())->visible = visible;
- break;
- case eChunk:
- ((BPPChunk*)_blastItem->getData())->visible = visible;
- break;
- case eAsset:
- ((BPPAsset*)_blastItem->getData())->visible = visible;
- break;
- case eProjectile:
- ((BPPBond*)_blastItem->getData())->visible = visible;
- break;
- case eGraphicsMesh:
- ((BPPGraphicsMesh*)_blastItem->getData())->visible = visible;
- break;
- case eAssetInstance:
- ((BPPAssetInstance*)_blastItem->getData())->visible = visible;
- break;
- case eLandmark:
- ((BPPLandmark*)_blastItem->getData())->visible = visible;
- break;
- case eComposite:
- ((BPPComposite*)_blastItem->getData())->visible = visible;
- break;
- default:
- break;
+ QMouseEvent* mouseEvt = (QMouseEvent*)evt;
+ if (_getVisualIconArea(option).contains(mouseEvt->pos()))
+ {
+ QStandardItem *treeItem = _treeModel->itemFromIndex(index);
+ BlastSceneTree* tree = BlastSceneTree::ins();
+ BlastNode* blastNode = tree->getBlastNodeByItem(treeItem);
+ PhysXSceneActor* projectileActor = tree->getProjectileActorByItem(treeItem);
+
+ if ((nullptr == blastNode && nullptr == projectileActor))
+ return QStyledItemDelegate::editorEvent(evt, model, option, index);
+
+ if (nullptr != blastNode && eChunk != blastNode->getType() && eBond != blastNode->getType())
+ return QStyledItemDelegate::editorEvent(evt, model, option, index);
+
+ if (nullptr != blastNode)
+ {
+ blastNode->setVisible(!blastNode->getVisible());
+ }
+ else if (nullptr != projectileActor)
+ {
+ SceneController& sceneController = SampleManager::ins()->getSceneController();
+ sceneController.setProjectileVisible(projectileActor, !sceneController.getProjectileVisible(projectileActor));
+ }
+
+ BlastSceneTree::ins()->update();
+ return true;
+ }
}
+ return QStyledItemDelegate::editorEvent(evt, model, option, index);
+}
+
+bool BlastTreeViewDelegate::eventFilter(QObject* object, QEvent* event)
+{
+ return true;
}
static BlastSceneTree* sBlastSceneTree = nullptr;
@@ -1094,37 +1396,74 @@ BlastSceneTree::BlastSceneTree(QWidget *parent)
_updateData = true;
sBlastSceneTree = this;
- ui.blastSceneTree->setStyleSheet("QTreeWidget::item{height:24px}");
- ui.blastSceneTree->setColumnWidth(0, 260);
- ui.blastSceneTree->setColumnWidth(1, 20);
+ sCompositeIcon = QIcon(":/AppMainWindow/images/AssetComposite.png");
+ sAssetIcon = QIcon(":/AppMainWindow/images/Asset.png");
+ sChunkUUIcon = QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png");
+ sChunkSUIcon = QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png");
+ sChunkSSIcon = QIcon(":/AppMainWindow/images/Chunk_Support_Static.png");
+ sBondIcon = QIcon(":/AppMainWindow/images/Bond.png");
+ sProjectileIcon = QIcon(":/AppMainWindow/images/Projectile.png");
+ _treeModel = new QStandardItemModel();
+ ui.blastSceneTree->setModel(_treeModel);
+ QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel();
+ connect(selectionModel, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(on_blastSceneTree_itemSelectionChanged(const QItemSelection&, const QItemSelection&)));
+
+ BlastTreeViewDelegate* itemDelegate = new BlastTreeViewDelegate(ui.blastSceneTree, _treeModel);
+ ui.blastSceneTree->setItemDelegate((QAbstractItemDelegate*)itemDelegate);
+
+ ui.blastSceneTree->setStyleSheet("QTreeView::item{height:24px}");
ui.blastSceneTree->setContextMenuPolicy(Qt::CustomContextMenu);
- _treeChunkContextMenu = new QMenu(this);
+ _treeContextMenu = new QMenu(this);
_makeSupportAction = new QAction(tr("Make Support"), this);
- _treeChunkContextMenu->addAction(_makeSupportAction);
+ _treeContextMenu->addAction(_makeSupportAction);
connect(_makeSupportAction, SIGNAL(triggered()), this, SLOT(onMakeSupportMenuItemClicked()));
_makeStaticSupportAction = new QAction(tr("Make Static Support"), this);
- _treeChunkContextMenu->addAction(_makeStaticSupportAction);
+ _treeContextMenu->addAction(_makeStaticSupportAction);
connect(_makeStaticSupportAction, SIGNAL(triggered()), this, SLOT(onMakeStaticSupportMenuItemClicked()));
_removeSupportAction = new QAction(tr("Remove Support"), this);
- _treeChunkContextMenu->addAction(_removeSupportAction);
+ _treeContextMenu->addAction(_removeSupportAction);
connect(_removeSupportAction, SIGNAL(triggered()), this, SLOT(onRemoveSupportMenuItemClicked()));
- _treeBondContextMenu = new QMenu(this);
- _bondChunksAction = new QAction(tr("Bond Chunks"), this);
- _treeBondContextMenu->addAction(_bondChunksAction);
- connect(_bondChunksAction, SIGNAL(triggered()), this, SLOT(onBondChunksMenuItemClicked()));
+ _makeWorldAction = new QAction(tr("Make World"), this);
+ _treeContextMenu->addAction(_makeWorldAction);
+ connect(_makeWorldAction, SIGNAL(triggered()), this, SLOT(onMakeWorldMenuItemClicked()));
+
+ _removeWorldAction = new QAction(tr("Remove World"), this);
+ _treeContextMenu->addAction(_removeWorldAction);
+ connect(_removeWorldAction, SIGNAL(triggered()), this, SLOT(onRemoveWorldMenuItemClicked()));
+
+ //_bondChunksAction = new QAction(tr("Bond Chunks"), this);
+ //_treeContextMenu->addAction(_bondChunksAction);
+ //connect(_bondChunksAction, SIGNAL(triggered()), this, SLOT(onBondChunksMenuItemClicked()));
+
+
+ //_bondChunksWithJointsAction = new QAction(tr("Bond Chunks With Joints"), this);
+ //_treeContextMenu->addAction(_bondChunksWithJointsAction);
+ //connect(_bondChunksWithJointsAction, SIGNAL(triggered()), this, SLOT(onBondChunksWithJointsMenuItemClicked()));
- _bondChunksWithJointsAction = new QAction(tr("Bond Chunks With Joints"), this);
- _treeBondContextMenu->addAction(_bondChunksWithJointsAction);
- connect(_bondChunksWithJointsAction, SIGNAL(triggered()), this, SLOT(onBondChunksWithJointsMenuItemClicked()));
+ //_removeAllBondsAction = new QAction(tr("Remove All Bonds"), this);
+ //_treeContextMenu->addAction(_removeAllBondsAction);
+ //connect(_removeAllBondsAction, SIGNAL(triggered()), this, SLOT(onRemoveAllBondsMenuItemClicked()));
- _removeAllBondsAction = new QAction(tr("Remove All Bonds"), this);
- _treeBondContextMenu->addAction(_removeAllBondsAction);
- connect(_removeAllBondsAction, SIGNAL(triggered()), this, SLOT(onRemoveAllBondsMenuItemClicked()));
+ QShortcut* shortCut;
+ shortCut = new QShortcut(QKeySequence("Alt+C"), this);
+ connect(shortCut, SIGNAL(activated()), this, SLOT(onCollapseExpandClicked()));
+ /*
+ BlastAssetInstancesNode* assetInstancesNode = BlastTreeData::ins().getBlastAssetInstancesNode();
+ _compositeTreeItem = new QStandardItem();
+ _treeModel->appendRow(_compositeTreeItem);
+ _compositeTreeItem->setText(assetInstancesNode->name.c_str());
+ _compositeTreeItem->setIcon(sCompositeIcon);
+ _treeItemDataMap.insert(_compositeTreeItem, assetInstancesNode);
+ _treeDataItemMap.insert(assetInstancesNode, _compositeTreeItem);
+ */
+
+ m_pNewBlastAsset = nullptr;
+ m_NewChunkIndexes.clear();
}
BlastSceneTree::~BlastSceneTree()
@@ -1139,14 +1478,94 @@ void BlastSceneTree::updateValues(bool updataData)
BlastTreeData::ins().update();
}
+ std::map<BPPAssetInstance*, std::set<uint32_t>> selectChunks;
+
+ SelectionToolController* m_selectionToolController = &SampleManager::ins()->getSelectionToolController();
+ GizmoToolController* m_gizmoToolController = &SampleManager::ins()->getGizmoToolController();
+ BlastController* m_blastController = &SampleManager::ins()->getBlastController();
+
+ if (m_selectionToolController->IsEnabled())
+ {
+ std::set<PxActor*> actors = m_selectionToolController->getTargetActors();
+ for (PxActor* actor : actors)
+ {
+ BlastFamily* pBlastFamily = m_blastController->getFamilyByPxActor(*actor);
+ if (pBlastFamily)
+ {
+ BPPAssetInstance* assetInstance = SampleManager::ins()->getInstanceByFamily(pBlastFamily);
+ uint32_t chunkIndex = pBlastFamily->getChunkIndexByPxActor(*actor);
+ selectChunks[assetInstance].insert(chunkIndex);
+ }
+ }
+ }
+ else if (m_gizmoToolController->IsEnabled())
+ {
+ PxActor* actor = m_gizmoToolController->getTargetActor();
+
+ if (actor)
+ {
+ BlastFamily* pBlastFamily = m_blastController->getFamilyByPxActor(*actor);
+ if (pBlastFamily)
+ {
+ BPPAssetInstance* assetInstance = SampleManager::ins()->getInstanceByFamily(pBlastFamily);
+ uint32_t chunkIndex = pBlastFamily->getChunkIndexByPxActor(*actor);
+ selectChunks[assetInstance].insert(chunkIndex);
+ }
+ }
+ }
+
_updateTreeUIs();
+
+ BlastSceneTreeDataLock lock;
+ std::set<PxActor*> actors;
+ for (std::map<BPPAssetInstance*, std::set<uint32_t>>::iterator itr = selectChunks.begin(); itr != selectChunks.end(); ++itr)
+ {
+ BlastFamily* family = SampleManager::ins()->getFamilyByInstance(itr->first);
+ std::set<uint32_t>& chunkIndexes = itr->second;
+
+ if (nullptr != family)
+ {
+ for (uint32_t chunkIndex : chunkIndexes)
+ {
+ PxActor* actor = nullptr;
+ family->getPxActorByChunkIndex(chunkIndex, &actor);
+
+ if (actor)
+ actors.insert(actor);
+ }
+ }
+ }
+
+ if (m_selectionToolController->IsEnabled())
+ {
+ m_selectionToolController->setTargetActors(actors);
+ }
+ else if (m_gizmoToolController->IsEnabled())
+ {
+ if (actors.size() > 0)
+ m_gizmoToolController->setTargetActor(*actors.begin());
+ }
+}
+
+void BlastSceneTree::clear()
+{
+ _treeModel->clear();
+ _treeItemDataMap.clear();
+ _treeDataItemMap.clear();
+
+ // notify no selection
+ std::vector<BlastNode*> nodes;
+ for (size_t i = 0; i < _observers.size(); ++i)
+ {
+ _observers[i]->dataSelected(nodes);
+ }
}
void BlastSceneTree::dataSelected(std::vector<BlastNode*> selections)
{
for (size_t i = 0; i < selections.size(); ++i)
{
- _selectTreeItem(selections[i]);
+ selectTreeItem(selections[i]);
}
}
@@ -1167,7 +1586,11 @@ void BlastSceneTree::removeObserver(ISceneObserver* observer)
void BlastSceneTree::updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible)
{
- BlastTreeData::ins().updateVisible(assetIndex, chunkIndex, visible);
+ BlastNode* node = BlastTreeData::ins().getNodeByIndex(assetIndex, chunkIndex);
+ if (node != nullptr && eChunk == node->getType())
+ {
+ static_cast<BlastChunkNode*>(node)->setVisible(visible);
+ }
}
void BlastSceneTree::updateChunkItemSelection()
@@ -1188,7 +1611,7 @@ void BlastSceneTree::updateChunkItemSelection()
for (BlastChunkNode* node : chunkNodes)
{
- _selectTreeItem(node);
+ selectTreeItem(node, false);
}
_updateData = true;
@@ -1197,10 +1620,11 @@ void BlastSceneTree::updateChunkItemSelection()
void BlastSceneTree::makeSupport()
{
std::vector<BlastChunkNode*> selectedChunkNodes;
- QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems();
- for (int i = 0; i < selectedItems.size(); ++i)
+ QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel();
+ QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
+ for (int i = 0; i < selectedIndexes.count(); ++i)
{
- QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i));
+ QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i)));
if (eChunk == itr.value()->getType())
{
@@ -1209,22 +1633,36 @@ void BlastSceneTree::makeSupport()
}
std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes);
- for (size_t i = 0; i < topChunkNodes.size(); ++i)
+ std::set<BlastAsset*> assets;
+ for (BlastChunkNode* chunkNode : topChunkNodes)
{
- BlastChunkNode* chunkNode = topChunkNodes[i];
+ if (chunkNode->isSupport() && !((BPPChunk*)chunkNode->getData())->staticFlag)
+ continue;
BlastTreeData::makeSupport(chunkNode);
+ BlastAsset* pBlastAsset = BlastTreeData::ins().getAsset(chunkNode);
+ assets.insert(pBlastAsset);
}
- _updateChunkTreeItems();
+ if (0 == assets.size())
+ return;
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ for (BlastAsset* asset : assets)
+ {
+ pSampleManager->refreshAsset(asset);
+ }
+
+ return;
}
void BlastSceneTree::makeStaticSupport()
{
std::vector<BlastChunkNode*> selectedChunkNodes;
- QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems();
- for (int i = 0; i < selectedItems.size(); ++i)
+ QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel();
+ QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
+ for (int i = 0; i < selectedIndexes.count(); ++i)
{
- QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i));
+ QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i)));
if (eChunk == itr.value()->getType())
{
@@ -1233,22 +1671,36 @@ void BlastSceneTree::makeStaticSupport()
}
std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes);
- for (size_t i = 0; i < topChunkNodes.size(); ++i)
+ std::set<BlastAsset*> assets;
+ for (BlastChunkNode* chunkNode : topChunkNodes)
{
- BlastChunkNode* chunkNode = topChunkNodes[i];
+ if (chunkNode->isSupport() && ((BPPChunk*)chunkNode->getData())->staticFlag)
+ continue;
BlastTreeData::makeStaticSupport(chunkNode);
+ BlastAsset* pBlastAsset = BlastTreeData::ins().getAsset(chunkNode);
+ assets.insert(pBlastAsset);
}
- _updateChunkTreeItems();
+ if (0 == assets.size())
+ return;
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ for (BlastAsset* asset : assets)
+ {
+ pSampleManager->refreshAsset(asset);
+ }
+
+ return;
}
void BlastSceneTree::removeSupport()
{
std::vector<BlastChunkNode*> selectedChunkNodes;
- QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems();
- for (int i = 0; i < selectedItems.size(); ++i)
+ QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel();
+ QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
+ for (int i = 0; i < selectedIndexes.count(); ++i)
{
- QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i));
+ QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i)));
if (eChunk == itr.value()->getType())
{
@@ -1257,13 +1709,110 @@ void BlastSceneTree::removeSupport()
}
std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes);
- for (size_t i = 0; i < topChunkNodes.size(); ++i)
+ std::set<BlastAsset*> assets;
+ for (BlastChunkNode* chunkNode : topChunkNodes)
{
- BlastChunkNode* chunkNode = topChunkNodes[i];
+ if (!chunkNode->isSupport() || BlastTreeData::isLeaf(chunkNode))
+ continue;
BlastTreeData::removeSupport(chunkNode);
+ BlastAsset* pBlastAsset = BlastTreeData::ins().getAsset(chunkNode);
+ assets.insert(pBlastAsset);
+ }
+
+ if (0 == assets.size())
+ return;
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ for (BlastAsset* asset : assets)
+ {
+ pSampleManager->refreshAsset(asset);
+ }
+
+ return;
+}
+
+void BlastSceneTree::makeWorld()
+{
+ std::vector<BlastBondNode*> selectedBondNodes;
+ QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel();
+ QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
+ for (int i = 0; i < selectedIndexes.count(); ++i)
+ {
+ QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i)));
+
+ if (eBond == itr.value()->getType())
+ {
+ selectedBondNodes.push_back((BlastBondNode*)itr.value());
+ }
+ }
+ if (selectedBondNodes.size() == 0)
+ {
+ return;
+ }
+
+ std::vector<BlastBondNode*>::iterator itSBN;
+ std::map<BlastAsset*, BlastAsset*> UniqueAssets;
+ for (itSBN = selectedBondNodes.begin(); itSBN != selectedBondNodes.end(); itSBN++)
+ {
+ BlastBondNode* node = *itSBN;
+
+ BPPBond* bond = static_cast<BPPBond*>(node->getData());
+ bond->toChunk = 0xFFFFFFFF;
+
+ BlastAsset* pBlastAsset = BlastTreeData::ins().getAsset(node);
+ UniqueAssets[pBlastAsset] = pBlastAsset;
+ }
+
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ std::map<BlastAsset*, BlastAsset*>::iterator itUA;
+ for (itUA = UniqueAssets.begin(); itUA != UniqueAssets.end(); itUA++)
+ {
+ BlastAsset* pBlastAsset = itUA->second;
+ pSampleManager->refreshAsset(pBlastAsset);
+ }
+}
+
+void BlastSceneTree::removeWorld()
+{
+ std::vector<BlastBondNode*> selectedBondNodes;
+ QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel();
+ QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
+ for (int i = 0; i < selectedIndexes.count(); ++i)
+ {
+ QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i)));
+
+ if (eBond == itr.value()->getType())
+ {
+ selectedBondNodes.push_back((BlastBondNode*)itr.value());
+ }
}
+ if (selectedBondNodes.size() == 0)
+ {
+ return;
+ }
+
+ std::vector<BlastBondNode*>::iterator itSBN;
+ std::map<BlastAsset*, BlastAsset*> UniqueAssets;
+ for (itSBN = selectedBondNodes.begin(); itSBN != selectedBondNodes.end(); itSBN++)
+ {
+ BlastBondNode* node = *itSBN;
- _updateChunkTreeItems();
+ BPPBond* bond = static_cast<BPPBond*>(node->getData());
+ bond->toChunk = 0xFFFFFFFF - 1;
+
+ BlastAsset* pBlastAsset = BlastTreeData::ins().getAsset(node);
+ UniqueAssets[pBlastAsset] = pBlastAsset;
+ }
+
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ std::map<BlastAsset*, BlastAsset*>::iterator itUA;
+ for (itUA = UniqueAssets.begin(); itUA != UniqueAssets.end(); itUA++)
+ {
+ BlastAsset* pBlastAsset = itUA->second;
+ pSampleManager->refreshAsset(pBlastAsset);
+ }
}
void BlastSceneTree::bondChunks()
@@ -1281,84 +1830,210 @@ void BlastSceneTree::removeAllBonds()
}
+void BlastSceneTree::setChunkSelected(std::vector<uint32_t> depths, bool selected)
+{
+ std::vector<BlastNode*> nodes = BlastTreeData::ins().getNodesByDepth(depths);
+ for (BlastNode* node : nodes)
+ {
+ if (eChunk == node->getType())
+ {
+ static_cast<BlastChunkNode*>(node)->setSelected(selected);
+ selectTreeItem(node);
+ }
+ }
+}
+
+void BlastSceneTree::setChunkVisible(std::vector<uint32_t> depths, bool bVisible)
+{
+ std::vector<BlastNode*> nodes = BlastTreeData::ins().getNodesByDepth(depths);
+ for (BlastNode* node : nodes)
+ {
+ if (eChunk == node->getType())
+ {
+ static_cast<BlastChunkNode*>(node)->setVisible(bVisible);
+ }
+ }
+}
+
+void BlastSceneTree::hideAllChunks()
+{
+ std::vector<BlastNode*> nodes;
+ BlastTreeData::ins().getAllChunkNodes(nodes);
+ for (BlastNode* node : nodes)
+ {
+ if (eChunk == node->getType())
+ {
+ static_cast<BlastChunkNode*>(node)->setVisible(false);
+ }
+ }
+}
+
+void BlastSceneTree::setChunkVisibleFullCoverage(int depth)
+{
+ std::vector<BlastNode*> nodes;
+ BlastTreeData::ins().getChunkNodesFullCoverage(nodes, depth);
+ for (BlastNode* node : nodes)
+ {
+ if (eChunk == node->getType())
+ {
+ static_cast<BlastChunkNode*>(node)->setVisible(true);
+ }
+ }
+}
+
void BlastSceneTree::on_btnAsset_clicked()
{
- QMessageBox::information(NULL, "test", "on_btnAsset_clicked");
+ QMessageBox::information(NULL, "Blast Tool", "This feature isn't implemented currently!");
}
void BlastSceneTree::on_assetComposite_clicked()
{
- QMessageBox::information(NULL, "test", "on_assetComposite_clicked");
+ QMessageBox::information(NULL, "Blast Tool", "This feature isn't implemented currently!");
}
void BlastSceneTree::on_btnChunk_clicked()
{
- QMessageBox::information(NULL, "test", "on_btnChunk_clicked");
+ QMessageBox::information(NULL, "Blast Tool", "This feature isn't implemented currently!");
}
void BlastSceneTree::on_btnBond_clicked()
{
- QMessageBox::information(NULL, "test", "on_btnBond_clicked");
+ QMessageBox::information(NULL, "Blast Tool", "This feature isn't implemented currently!");
}
void BlastSceneTree::on_btnProjectile_clicked()
{
- QMessageBox::information(NULL, "test", "on_btnProjectile_clicked");
+ QMessageBox::information(NULL, "Blast Tool", "This feature isn't implemented currently!");
+}
+
+void BlastSceneTree::on_btnExpandCollapse_clicked()
+{
+ onCollapseExpandClicked();
}
void BlastSceneTree::on_blastSceneTree_customContextMenuRequested(const QPoint &pos)
{
- QList<QTreeWidgetItem*> items = ui.blastSceneTree->selectedItems();
+ QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel();
+ QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
- if (items.count() == 1)
+ std::vector<BlastChunkNode*> chunkNodes;
+ std::vector<BlastBondNode*> bondNodes;
+ for (int i = 0; i < selectedIndexes.count(); ++i)
{
- QTreeWidgetItem* curItem = items.at(0);
-
- QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(curItem);
+ QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i)));
if (itr != _treeItemDataMap.end())
{
- if (eChunk == itr.value()->getType() || eBond == itr.value()->getType())
+ if (eChunk == itr.value()->getType())
{
- _treeChunkContextMenu->exec(QCursor::pos());
+ chunkNodes.push_back((BlastChunkNode*)itr.value());
+ }
+ else if (eBond == itr.value()->getType())
+ {
+ bondNodes.push_back((BlastBondNode*)itr.value());
}
}
}
- else if (items.count() > 1)
+
{
- bool allSupportChunk = true;
- for (int i = 0; i < items.count(); ++i)
+ std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(chunkNodes);
+ _makeSupportAction->setEnabled(true);
+ _makeStaticSupportAction->setEnabled(true);
+ _removeSupportAction->setEnabled(true);
+ _makeWorldAction->setEnabled(true);
+ _removeWorldAction->setEnabled(true);
+
+ //select chunk nodes have parent child relation ship, disable all menu items
+ if (topChunkNodes.size() < chunkNodes.size())
+ {
+ _makeSupportAction->setEnabled(false);
+ _makeStaticSupportAction->setEnabled(false);
+ _removeSupportAction->setEnabled(false);
+ }
+ else
{
- QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(items.at(i));
- if (itr != _treeItemDataMap.end())
+ bool allSupported = true, allStaticSupport = true, allUnSupported = true, hasLeaf = false;
+
+ for (BlastChunkNode* chunkNode : chunkNodes)
{
- if (eChunk != itr.value()->getType())
+ BPPChunk* chunk = (BPPChunk*)(chunkNode->getData());
+ if (chunk->support)
+ {
+ allUnSupported = false;
+ }
+ else
{
- allSupportChunk = false;
- break;
+ allSupported = false;
+ }
+
+ if (!chunk->staticFlag)
+ {
+ allStaticSupport = false;
+ }
+
+ if (BlastTreeData::isLeaf(chunkNode))
+ {
+ hasLeaf = true;
}
}
- }
- if (allSupportChunk)
- {
- _treeBondContextMenu->exec(QCursor::pos());
+ if (allSupported && !allStaticSupport)
+ {
+ _makeSupportAction->setEnabled(false);
+ }
+
+ if (allStaticSupport)
+ {
+ _makeStaticSupportAction->setEnabled(false);
+ }
+
+ if (allUnSupported || hasLeaf)
+ {
+ _removeSupportAction->setEnabled(false);
+ }
}
}
+ if (chunkNodes.size() > 0 && bondNodes.size() > 0)
+ {
+ _makeSupportAction->setEnabled(false);
+ _makeStaticSupportAction->setEnabled(false);
+ _removeSupportAction->setEnabled(false);
+ _makeWorldAction->setEnabled(false);
+ _removeWorldAction->setEnabled(false);
+ }
+ else if (chunkNodes.size() > 0 && bondNodes.size() == 0)
+ {
+ _makeWorldAction->setEnabled(false);
+ _removeWorldAction->setEnabled(false);
+ }
+ else if (chunkNodes.size() == 0 && bondNodes.size() > 0)
+ {
+ _makeSupportAction->setEnabled(false);
+ _makeStaticSupportAction->setEnabled(false);
+ _removeSupportAction->setEnabled(false);
+ }
+
+ if (0 < chunkNodes.size() || 0 < bondNodes.size())
+ {
+ _treeContextMenu->exec(QCursor::pos());
+ }
+
}
-void BlastSceneTree::on_blastSceneTree_itemSelectionChanged()
+void BlastSceneTree::on_blastSceneTree_itemSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
{
if (!_updateData)
return;
SampleManager::ins()->clearChunksSelected();
- QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems();
+ QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel();
+ QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
+
std::vector<BlastNode*> nodes;
- for (int i = 0; i < selectedItems.count(); ++i)
+ for (int i = 0; i < selectedIndexes.count(); ++i)
{
- QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i));
+ QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(_treeModel->itemFromIndex(selectedIndexes.at(i)));
if (itr != _treeItemDataMap.end())
{
nodes.push_back(itr.value());
@@ -1367,10 +2042,32 @@ void BlastSceneTree::on_blastSceneTree_itemSelectionChanged()
if (eChunk == node->getType())
{
((BlastChunkNode*)node)->setSelected(true);
+
+ if (BlastTreeData::isRoot((BlastChunkNode*)node))
+ {
+ std::vector<BlastAssetInstanceNode*> instanceNodes = BlastTreeData::ins().getAssetInstanceNodes((BlastChunkNode*)node);
+ for (BlastAssetInstanceNode* instanceNode : instanceNodes)
+ {
+ selectTreeItem(instanceNode, false);
+ nodes.push_back(instanceNode);
+ }
+ }
}
else if (eAssetInstance == node->getType())
{
((BlastAssetInstanceNode*)node)->setSelected(true);
+
+ BlastSceneTreeDataLock lock;
+ std::vector<BlastChunkNode*> chunkNodes = BlastTreeData::ins().getRootChunkNodeByInstance((BlastAssetInstanceNode*)node);
+ for (BlastChunkNode* chunkNode : chunkNodes)
+ {
+ selectTreeItem(chunkNode, false);
+ nodes.push_back(chunkNode);
+ }
+ }
+ else if (eAsset == node->getType())
+ {
+ ((BlastAssetNode*)node)->setSelected(true);
}
}
}
@@ -1396,6 +2093,16 @@ void BlastSceneTree::onRemoveSupportMenuItemClicked()
removeSupport();
}
+void BlastSceneTree::onMakeWorldMenuItemClicked()
+{
+ makeWorld();
+}
+
+void BlastSceneTree::onRemoveWorldMenuItemClicked()
+{
+ removeWorld();
+}
+
void BlastSceneTree::onBondChunksMenuItemClicked()
{
bondChunks();
@@ -1411,35 +2118,54 @@ void BlastSceneTree::onRemoveAllBondsMenuItemClicked()
removeAllBonds();
}
+void BlastSceneTree::onCollapseExpandClicked()
+{
+ static bool expand = true;
+ if (expand)
+ {
+ ui.blastSceneTree->collapseAll();
+ expand = false;
+ }
+ else
+ {
+ ui.blastSceneTree->expandAll();
+ expand = true;
+ }
+}
+
void BlastSceneTree::_updateTreeUIs()
{
- ui.blastSceneTree->clear();
+#ifdef _DEBUG
+ static int gcounter = 0;
+ static char gbuf[128];
+ sprintf(gbuf, "_updateTreeUIs called %d", ++gcounter);
+ viewer_msg(gbuf);
+#endif
+ //ui.blastSceneTree->setUpdatesEnabled(false);
+ _treeModel->clear();
_treeItemDataMap.clear();
_treeDataItemMap.clear();
- BlastCompositeNode* compositeNode = BlastTreeData::ins().getCompsiteNode();
- if (compositeNode != nullptr)
+ BlastAssetInstancesNode* assetInstancesNode = BlastTreeData::ins().getBlastAssetInstancesNode();
+ if (assetInstancesNode != nullptr)
{
- QTreeWidgetItem* compositeTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree);
- compositeTreeWidgetItem->setText(0, compositeNode->name.c_str());
- compositeTreeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/AssetComposite.png"));
- VisualButton* btn = new VisualButton(this, compositeNode);
- ui.blastSceneTree->setItemWidget(compositeTreeWidgetItem, 1, btn);
- _treeItemDataMap.insert(compositeTreeWidgetItem, compositeNode);
- _treeDataItemMap.insert(compositeNode, compositeTreeWidgetItem);
-
- size_t count = compositeNode->children.size();
+ QStandardItem* compositeTreeItem = new QStandardItem();
+ compositeTreeItem->setText(assetInstancesNode->name.c_str());
+ compositeTreeItem->setIcon(sCompositeIcon);
+ _treeItemDataMap.insert(compositeTreeItem, assetInstancesNode);
+ _treeDataItemMap.insert(assetInstancesNode, compositeTreeItem);
+ _treeModel->appendRow(compositeTreeItem);
+ size_t count = assetInstancesNode->children.size();
for (size_t i = 0; i < count; ++i)
{
- BlastNode* assetInstanceNode = compositeNode->children[i];
- QTreeWidgetItem* assetInstanceWidgetItem = new QTreeWidgetItem(compositeTreeWidgetItem);
- assetInstanceWidgetItem->setText(0, assetInstanceNode->name.c_str());
+ BlastNode* assetInstanceNode = assetInstancesNode->children[i];
+ QStandardItem* assetInstanceItem = new QStandardItem();
+ compositeTreeItem->appendRow(assetInstanceItem);
+ assetInstanceItem->setText(assetInstanceNode->name.c_str());
if (assetInstanceNode->getType() == eAssetInstance)
- assetInstanceWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Asset.png"));
- VisualButton* btn = new VisualButton(this, assetInstanceNode);
- ui.blastSceneTree->setItemWidget(assetInstanceWidgetItem, 1, btn);
- _treeItemDataMap.insert(assetInstanceWidgetItem, assetInstanceNode);
- _treeDataItemMap.insert(assetInstanceNode, assetInstanceWidgetItem);
+ assetInstanceItem->setIcon(QIcon(":/AppMainWindow/images/Asset.png"));
+ _treeItemDataMap.insert(assetInstanceItem, assetInstanceNode);
+ _treeDataItemMap.insert(assetInstanceNode, assetInstanceItem);
}
}
@@ -1449,11 +2175,10 @@ void BlastSceneTree::_updateTreeUIs()
{
BlastAssetNode* assetNode = assets[i];
- QTreeWidgetItem* assetTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree);
- assetTreeWidgetItem->setText(0, assetNode->name.c_str());
- assetTreeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Asset.png"));
- VisualButton* btn = new VisualButton(this, assetNode);
- ui.blastSceneTree->setItemWidget(assetTreeWidgetItem, 1, btn);
+ QStandardItem* assetTreeWidgetItem = new QStandardItem();
+ _treeModel->appendRow(assetTreeWidgetItem);
+ assetTreeWidgetItem->setText(assetNode->name.c_str());
+ assetTreeWidgetItem->setIcon(sAssetIcon);
_treeItemDataMap.insert(assetTreeWidgetItem, assetNode);
_treeDataItemMap.insert(assetNode, assetTreeWidgetItem);
@@ -1466,13 +2191,12 @@ void BlastSceneTree::_updateTreeUIs()
{
BlastProjectileNode* projectileNode = projectiles[i];
- QTreeWidgetItem* projectileTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree);
- projectileTreeWidgetItem->setText(0, projectileNode->name.c_str());
- projectileTreeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Projectile.png"));
- VisualButton* btn = new VisualButton(this, projectileNode);
- ui.blastSceneTree->setItemWidget(projectileTreeWidgetItem, 1, btn);
- _treeItemDataMap.insert(projectileTreeWidgetItem, projectileNode);
- _treeDataItemMap.insert(projectileNode, projectileTreeWidgetItem);
+ QStandardItem* projectileTreeItem = new QStandardItem();
+ _treeModel->appendRow(projectileTreeItem);
+ projectileTreeItem->setText(projectileNode->name.c_str());
+ projectileTreeItem->setIcon(sProjectileIcon);
+ _treeItemDataMap.insert(projectileTreeItem, projectileNode);
+ _treeDataItemMap.insert(projectileNode, projectileTreeItem);
}
std::vector<BlastGraphicsMeshNode*>& graphicsMeshes = BlastTreeData::ins().getGraphicsMeshNodes();
@@ -1481,23 +2205,52 @@ void BlastSceneTree::_updateTreeUIs()
{
BlastGraphicsMeshNode* graphicsMesheNode = graphicsMeshes[i];
- QTreeWidgetItem* graphicsMesheTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree);
- graphicsMesheTreeWidgetItem->setText(0, graphicsMesheNode->name.c_str());
- VisualButton* btn = new VisualButton(this, graphicsMesheNode);
- ui.blastSceneTree->setItemWidget(graphicsMesheTreeWidgetItem, 1, btn);
+ QStandardItem* graphicsMesheTreeWidgetItem = new QStandardItem();
+ _treeModel->appendRow(graphicsMesheTreeWidgetItem);
+ graphicsMesheTreeWidgetItem->setText(graphicsMesheNode->name.c_str());
_treeItemDataMap.insert(graphicsMesheTreeWidgetItem, graphicsMesheNode);
_treeDataItemMap.insert(graphicsMesheNode, graphicsMesheTreeWidgetItem);
}
- //for (int j = 0; j < ui.blastSceneTree->topLevelItemCount(); ++j)
+ ui.blastSceneTree->expandAll();
+
+ // notify no selection
+ //std::vector<BlastNode*> nodes;
+ //for (size_t i = 0; i < _observers.size(); ++i)
//{
- // QTreeWidgetItem* topLevelItem = ui.blastSceneTree->topLevelItem(j);
- // ui.blastSceneTree->expandItem(topLevelItem);
+ // _observers[i]->dataSelected(nodes);
//}
- ui.blastSceneTree->expandAll();
+
+ bool autoSelectNewChunks = BlastProject::ins().getParams().fracture.general.autoSelectNewChunks;
+ if (!autoSelectNewChunks)
+ {
+ m_pNewBlastAsset = nullptr;
+ m_NewChunkIndexes.clear();
+ return;
+ }
+
+ if (m_pNewBlastAsset == nullptr || m_NewChunkIndexes.size() == 0)
+ {
+ return;
+ }
+
+ _updateData = false;
+ ui.blastSceneTree->clearSelection();
+ std::vector<BlastChunkNode*> chunkNodes =
+ BlastTreeData::ins().getChunkNodeByBlastChunk(m_pNewBlastAsset, m_NewChunkIndexes);
+ for (BlastChunkNode* node : chunkNodes)
+ {
+ node->setVisible(true);
+ selectTreeItem(node);
+ }
+
+ m_pNewBlastAsset = nullptr;
+ m_NewChunkIndexes.clear();
+
+ _updateData = true;
}
-void BlastSceneTree::_addChunkUI(const BlastNode* parentNode, QTreeWidgetItem* parentTreeItem)
+void BlastSceneTree::_addChunkUI(const BlastNode* parentNode, QStandardItem* parentTreeItem)
{
if (parentNode != nullptr && parentTreeItem != nullptr)
{
@@ -1507,43 +2260,47 @@ void BlastSceneTree::_addChunkUI(const BlastNode* parentNode, QTreeWidgetItem* p
if (node == nullptr)
continue;
- QTreeWidgetItem* treeWidgetItem = nullptr;
+ QStandardItem* treeWidgetItem = new QStandardItem();
+ parentTreeItem->appendRow(treeWidgetItem);
if (node->getType() == eChunk)
{
- BlastChunkNode* chunk = static_cast<BlastChunkNode*>(node);
- treeWidgetItem = new QTreeWidgetItem(parentTreeItem);
- treeWidgetItem->setText(0, chunk->name.c_str());
- if (chunk->isSupport())
+ BlastChunkNode* chunkNode = static_cast<BlastChunkNode*>(node);
+ treeWidgetItem->setText(chunkNode->name.c_str());
+
+ BPPChunk* chunk = static_cast<BPPChunk*>(chunkNode->getData());
+ if (!chunk->support)
{
- treeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png"));
+ treeWidgetItem->setIcon(sChunkUUIcon);
}
- else
+ else if (chunk->support && !chunk->staticFlag)
+ {
+ treeWidgetItem->setIcon(sChunkSUIcon);
+ }
+ else if (chunk->support && chunk->staticFlag)
{
- treeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png"));
+ treeWidgetItem->setIcon(sChunkSSIcon);
}
- _addChunkUI(chunk, treeWidgetItem);
+ _addChunkUI(chunkNode, treeWidgetItem);
}
else if (node->getType() == eBond)
{
BlastBondNode* bond = static_cast<BlastBondNode*>(node);
- treeWidgetItem = new QTreeWidgetItem(parentTreeItem);
- treeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Bond.png"));
- treeWidgetItem->setText(0, bond->name.c_str());
+ treeWidgetItem->setIcon(sBondIcon);
+ treeWidgetItem->setText(bond->name.c_str());
}
if (treeWidgetItem == nullptr)
continue;
- VisualButton* btn = new VisualButton(this, node);
- ui.blastSceneTree->setItemWidget(treeWidgetItem, 1, btn);
+
_treeItemDataMap.insert(treeWidgetItem, node);
_treeDataItemMap.insert(node, treeWidgetItem);
}
}
}
-void BlastSceneTree::_updateChunkTreeItemAndMenu(BPPChunk* chunk, QTreeWidgetItem* chunkItem)
+void BlastSceneTree::_updateChunkTreeItemAndMenu(BPPChunk* chunk, QStandardItem* chunkItem)
{
assert(chunk != nullptr);
@@ -1554,309 +2311,368 @@ void BlastSceneTree::_updateChunkTreeItemAndMenu(BPPChunk* chunk, QTreeWidgetIte
if (!chunk->support && !chunk->staticFlag)
{
_removeSupportAction->setEnabled(false);
- chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png"));
+ chunkItem->setIcon(sChunkUUIcon);
}
else if (chunk->support && !chunk->staticFlag)
{
_makeSupportAction->setEnabled(false);
- chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png"));
+ chunkItem->setIcon(sChunkSUIcon);
}
else if (chunk->support && chunk->staticFlag)
{
_makeStaticSupportAction->setEnabled(false);
- chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Static.png"));
+ chunkItem->setIcon(sChunkSSIcon);
}
}
void BlastSceneTree::_updateChunkTreeItems()
{
- for (QMap<BlastNode*, QTreeWidgetItem*>::iterator itr = _treeDataItemMap.begin(); itr != _treeDataItemMap.end(); ++itr)
+ for (QMap<BlastNode*, QStandardItem*>::iterator itr = _treeDataItemMap.begin(); itr != _treeDataItemMap.end(); ++itr)
{
BlastNode* node = itr.key();
- QTreeWidgetItem* treeItem = itr.value();
+ QStandardItem* treeItem = itr.value();
if (eChunk == node->getType())
{
BPPChunk* chunk = static_cast<BPPChunk*>(node->getData());
- if (!chunk->support && !chunk->staticFlag)
+ if (!chunk->support)
{
- treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png"));
+ treeItem->setIcon(sChunkUUIcon);
}
else if (chunk->support && !chunk->staticFlag)
{
- treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png"));
+ treeItem->setIcon(sChunkSUIcon);
}
else if (chunk->support && chunk->staticFlag)
{
- treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Static.png"));
+ treeItem->setIcon(sChunkSSIcon);
+ }
+ }
+ }
+}
+
+void BlastSceneTree::ApplyAutoSelectNewChunks(BlastAsset* pNewBlastAsset, std::vector<uint32_t>& NewChunkIndexes)
+{
+ if (pNewBlastAsset == nullptr || NewChunkIndexes.size() == 0)
+ {
+ return;
+ }
+
+ m_pNewBlastAsset = pNewBlastAsset;
+ m_NewChunkIndexes.clear();
+ for (uint32_t nci : NewChunkIndexes)
+ {
+ m_NewChunkIndexes.push_back(nci);
+ }
+}
+
+/*
+BlastAssetNode* BlastTreeData::addBlastAsset(BPPAsset& asset)
+{
+ BlastAsset* pBlastAsset = nullptr;
+ SampleManager* pSampleManager = SampleManager::ins();
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator it;
+ for (it = AssetDescMap.begin(); it != AssetDescMap.end(); it++)
+ {
+ std::string assetname = asset.name.buf;
+ if (it->second.name == assetname)
+ {
+ pBlastAsset = it->first;
+ }
+ }
+
+ BlastAssetNode* assetNode = new BlastAssetNode(asset.name.buf, asset);
+ _assets.push_back(assetNode);
+ _blastProjectDataToNodeMap.insert(std::make_pair((void*)&asset, assetNode));
+
+ std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset, -1);
+ int childChunksSize = childChunks.size();
+ for (size_t i = 0; i < childChunksSize; ++i)
+ {
+ BPPChunk& chunk = *(childChunks[i]);
+ BlastChunkNode* chunkNode = new BlastChunkNode(chunk.name.buf, chunk, pBlastAsset);
+ assetNode->children.push_back(chunkNode);
+ chunkNode->setParent(assetNode);
+ _blastProjectDataToNodeMap.insert(std::make_pair((void*)&chunk, chunkNode));
+
+ _addChunkNode(chunk, asset, chunkNode, pBlastAsset);
+ }
+
+ return assetNode;
+}
+
+void BlastTreeData::removeBlastAsset(BPPAsset& asset)
+{
+ _removeChunkNode(asset);
+
+ std::map<void*, BlastNode*>::iterator it = _blastProjectDataToNodeMap.find(&asset);
+ if (it == _blastProjectDataToNodeMap.end())
+ {
+ return;
+ }
+
+ BlastNode* node = it->second;
+ _blastProjectDataToNodeMap.erase(it);
+ std::vector<BlastAssetNode*>::iterator itAsset;
+ for (itAsset = _assets.begin(); itAsset != _assets.end(); itAsset++)
+ {
+ if (node == *itAsset)
+ {
+ _assets.erase(itAsset);
+ break;
+ }
+ }
+
+ delete node;
+}
+
+BlastAssetInstanceNode* BlastTreeData::addBlastInstance(BPPAssetInstance& instance)
+{
+ BlastAssetInstanceNode* blastAssetInstanceNode = new BlastAssetInstanceNode(instance.name.buf, instance);
+ _assetInstancesNode->children.push_back(blastAssetInstanceNode);
+ blastAssetInstanceNode->setParent(_assetInstancesNode);
+ void* pointer = (void*)&instance;
+ _blastProjectDataToNodeMap.insert(std::make_pair(pointer, blastAssetInstanceNode));
+ return blastAssetInstanceNode;
+}
+
+void BlastTreeData::removeBlastInstance(BPPAssetInstance& instance)
+{
+ void* pointer = (void*)&instance;
+ std::map<void*, BlastNode*>::iterator it = _blastProjectDataToNodeMap.find(pointer);
+ if (it == _blastProjectDataToNodeMap.end())
+ {
+ return;
+ }
+
+ BlastNode* node = it->second;
+ _blastProjectDataToNodeMap.erase(it);
+ delete node;
+
+ int count = _assetInstancesNode->children.size();
+ for (int i = count - 1; i >= 0; --i)
+ {
+ BlastNode* pBN = _assetInstancesNode->children[i];
+ if (pBN == node)
+ {
+ _assetInstancesNode->children.erase(_assetInstancesNode->children.begin() + i);
+ }
+ else
+ {
+ BlastAssetInstanceNode* blastAssetInstanceNode = dynamic_cast<BlastAssetInstanceNode*>(_assetInstancesNode->children[i]);
+ if (blastAssetInstanceNode && blastAssetInstanceNode->getData() == &instance)
+ {
+ _assetInstancesNode->children.erase(_assetInstancesNode->children.begin() + i);
}
}
}
}
-void BlastSceneTree::_selectTreeItem(BlastNode* node)
+BlastProjectileNode* BlastTreeData::addProjectile(PhysXSceneActor* projectile)
{
- QMap<BlastNode*, QTreeWidgetItem*>::iterator itr = _treeDataItemMap.find(node);
+ SceneController& sceneController = SampleManager::ins()->getSceneController();
+ BlastProjectileNode* projectileNode = new BlastProjectileNode(sceneController.getProjectileName(projectile), projectile);
+ _projectiles.push_back(projectileNode);
+ return projectileNode;
+}
+
+void BlastTreeData::clearProjectile()
+{
+ std::vector<BlastProjectileNode*>::iterator it;
+ for (it = _projectiles.begin(); it != _projectiles.end(); it++)
+ {
+ delete *it;
+ }
+ _projectiles.clear();
+}
+
+void BlastTreeData::refreshProjectDataToNodeMap(std::map<BPPAsset*, BPPAsset*>& changeMap)
+{
+ std::map<BPPAsset*, BPPAsset*>::iterator it;
+ std::map<void*, BlastNode*>::iterator itNode;
+ for (it = changeMap.begin(); it != changeMap.end(); it++)
+ {
+ itNode = _blastProjectDataToNodeMap.find(it->first);
+ if (itNode == _blastProjectDataToNodeMap.end())
+ {
+ continue;
+ }
+
+ BlastNode* node = itNode->second;
+ _blastProjectDataToNodeMap.erase(itNode);
+ _blastProjectDataToNodeMap[it->second] = node;
+ }
+}
+
+void BlastTreeData::refreshProjectDataToNodeMap(std::map<BPPAssetInstance*, BPPAssetInstance*>& changeMap)
+{
+ std::map<BPPAssetInstance*, BPPAssetInstance*>::iterator it;
+ std::map<void*, BlastNode*>::iterator itNode;
+ for (it = changeMap.begin(); it != changeMap.end(); it++)
+ {
+ itNode = _blastProjectDataToNodeMap.find(it->first);
+ if (itNode == _blastProjectDataToNodeMap.end())
+ {
+ continue;
+ }
+
+ BlastNode* node = itNode->second;
+ _blastProjectDataToNodeMap.erase(itNode);
+ _blastProjectDataToNodeMap[it->second] = node;
+ node->setData(it->second);
+ }
+}
+
+void BlastSceneTree::addBlastAsset(BPPAsset& asset)
+{
+ BlastAssetNode* assetNode = BlastTreeData::ins().addBlastAsset(asset);
+ if (assetNode == nullptr)
+ {
+ return;
+ }
+
+ QStandardItem* assetTreeWidgetItem = new QStandardItem();
+ _treeModel->appendRow(assetTreeWidgetItem);
+ assetTreeWidgetItem->setText(assetNode->name.c_str());
+ assetTreeWidgetItem->setIcon(sAssetIcon);
+ _treeItemDataMap.insert(assetTreeWidgetItem, assetNode);
+ _treeDataItemMap.insert(assetNode, assetTreeWidgetItem);
+
+ _addChunkUI(assetNode, assetTreeWidgetItem);
+
+ ui.blastSceneTree->expandAll();
+}
+
+void BlastSceneTree::removeBlastAsset(BPPAsset& asset)
+{
+ BlastNode* node = BlastTreeData::ins().getBlastNodeByProjectData(&asset);
+
+ QMap<BlastNode*, QStandardItem*>::iterator it = _treeDataItemMap.find(node);
+ if (it != _treeDataItemMap.end())
+ {
+ QStandardItem* item = it.value();
+
+ if (item != nullptr)
+ {
+ _treeModel->removeRow(_treeModel->indexFromItem(item).row());
+ ui.blastSceneTree->expandAll();
+ }
+ }
+
+ BlastTreeData::ins().removeBlastAsset(asset);
+}
+
+void BlastSceneTree::addBlastInstance(BPPAssetInstance& instance)
+{
+ BlastAssetInstanceNode* assetInstanceNode = BlastTreeData::ins().addBlastInstance(instance);
+ if (assetInstanceNode == nullptr)
+ {
+ return;
+ }
+
+ QStandardItem* assetInstanceItem = new QStandardItem();
+ _compositeTreeItem->appendRow(assetInstanceItem);
+ assetInstanceItem->setText(assetInstanceNode->name.c_str());
+ if (assetInstanceNode->getType() == eAssetInstance)
+ assetInstanceItem->setIcon(sAssetIcon);
+ _treeItemDataMap.insert(assetInstanceItem, assetInstanceNode);
+ _treeDataItemMap.insert(assetInstanceNode, assetInstanceItem);
+
+ ui.blastSceneTree->expandAll();
+}
+
+void BlastSceneTree::removeBlastInstance(BPPAssetInstance& instance)
+{
+ BlastNode* node = BlastTreeData::ins().getBlastNodeByProjectData(&instance);
+
+ QMap<BlastNode*, QStandardItem*>::iterator it = _treeDataItemMap.find(node);
+ if (it != _treeDataItemMap.end())
+ {
+ QStandardItem* item = it.value();
+
+ if (item != nullptr)
+ {
+ _compositeTreeItem->removeRow(_treeModel->indexFromItem(_compositeTreeItem).row());
+ ui.blastSceneTree->expandAll();
+ }
+ }
+
+ BlastTreeData::ins().removeBlastInstance(instance);
+}
+
+void BlastSceneTree::removeBlastInstances(BPPAsset& asset)
+{
+ std::vector<BPPAssetInstance*> instances;
+ BlastProject::ins().getAssetInstances(asset.ID, instances);
+
+ std::vector<BPPAssetInstance*>::iterator it;
+ for (it = instances.begin(); it != instances.end(); it++)
+ {
+ removeBlastInstance(**it);
+ BlastTreeData::ins().removeBlastInstance(**it);
+ }
+}
+
+void BlastSceneTree::addProjectile(PhysXSceneActor* projectile)
+{
+ BlastProjectileNode* projectileNode = BlastTreeData::ins().addProjectile(projectile);
+ if (projectileNode == nullptr)
+ {
+ return;
+ }
+
+ QStandardItem* projectileTreeItem = new QStandardItem();
+ projectileTreeItem->setText(projectileNode->name.c_str());
+ projectileTreeItem->setIcon(sProjectileIcon);
+ _treeModel->appendRow(projectileTreeItem);
+ _projectileItemActorMap[projectileTreeItem] = projectile;;
+}
+
+void BlastSceneTree::clearProjectile()
+{
+ QMap<QStandardItem*, PhysXSceneActor*>::iterator it;
+ for (it =_projectileItemActorMap.begin(); it != _projectileItemActorMap.end(); it++)
+ {
+ _treeModel->removeRow(_treeModel->indexFromItem(it.key()).row());
+ }
+ _projectileItemActorMap.clear();
+
+ BlastTreeData::ins().clearProjectile();
+}
+*/
+BlastNode* BlastSceneTree::getBlastNodeByItem(QStandardItem* item)
+{
+ QMap<QStandardItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(item);
+ if (itr == _treeItemDataMap.end())
+ return nullptr;
+
+ return itr.value();
+}
+
+PhysXSceneActor* BlastSceneTree::getProjectileActorByItem(QStandardItem* item)
+{
+ QMap<QStandardItem*, PhysXSceneActor*>::iterator itr = _projectileItemActorMap.find(item);
+ if (itr == _projectileItemActorMap.end())
+ return nullptr;
+
+ return itr.value();
+}
+
+void BlastSceneTree::selectTreeItem(BlastNode* node, bool updateData)
+{
+ _updateData = updateData;
+ QMap<BlastNode*, QStandardItem*>::iterator itr = _treeDataItemMap.find(node);
if (itr != _treeDataItemMap.end())
{
- ui.blastSceneTree->setItemSelected(itr.value(), true);
- }
-}
-
-//void BlastSceneTree::_createTestData()
-//{
-// BPPBlast& blast = BlastProject::ins().getParams().blast;
-//
-// // compoistie
-// {
-// BPPComposite& composite = blast.composite;
-// composite.composite.buf = nullptr;
-// composite.visible = true;
-//
-// copy(composite.composite, "BlastComposite");
-//
-// // asset instance array
-// {
-// BPPAssetInstanceArray& instanceArray = composite.blastAssetInstances;
-// instanceArray.buf = new BPPAssetInstance[4];
-// instanceArray.arraySizes[0] = 4;
-// instanceArray.buf[0].name.buf = nullptr;
-// instanceArray.buf[1].name.buf = nullptr;
-// instanceArray.buf[2].name.buf = nullptr;
-// instanceArray.buf[3].name.buf = nullptr;
-// instanceArray.buf[0].source.buf = nullptr;
-// instanceArray.buf[1].source.buf = nullptr;
-// instanceArray.buf[2].source.buf = nullptr;
-// instanceArray.buf[3].source.buf = nullptr;
-//
-// copy(instanceArray.buf[0].name, "BlastAsset_instance1");
-// instanceArray.buf[0].visible = true;
-//
-// copy(instanceArray.buf[1].name, "BlastAsset_instance2");
-// instanceArray.buf[1].visible = true;
-//
-// copy(instanceArray.buf[2].name, "BlastAsset1_instance1");
-// instanceArray.buf[2].visible = true;
-//
-// copy(instanceArray.buf[3].name, "BlastAsset1_instance2");
-// instanceArray.buf[3].visible = true;
-// }
-//
-// // landmark array
-// {
-// BPPLandmarkArray& landmarkArray = composite.landmarks;
-// landmarkArray.buf = new BPPLandmark[2];
-// landmarkArray.arraySizes[0] = 2;
-// landmarkArray.buf[0].name.buf = nullptr;
-// landmarkArray.buf[1].name.buf = nullptr;
-//
-// copy(landmarkArray.buf[0].name, "Landmark_1");
-// copy(landmarkArray.buf[1].name, "Landmark_2");
-// }
-// }
-//
-// // asset array
-// {
-// BPPAssetArray& assetArray = blast.blastAssets;
-// assetArray.buf = new BPPAsset[2];
-// assetArray.arraySizes[0] = 2;
-//
-// // asset 0
-// {
-// BPPAsset& asset = assetArray.buf[0];
-// asset.path.buf = nullptr;
-// asset.activePreset.buf = nullptr;
-// asset.bonds.buf = nullptr;
-// asset.chunks.buf = nullptr;
-//
-// copy(asset.path, "c:/temp/BlastAsset.asset");
-//
-// // chunks
-// {
-// asset.chunks.buf = new BPPChunk[10];
-// asset.chunks.arraySizes[0] = 10;
-// for (int i = 0; i < 10; ++i)
-// {
-// asset.chunks.buf[i].name.buf = nullptr;
-// asset.chunks.buf[i].visible = true;
-// asset.chunks.buf[i].staticFlag = false;
-// }
-//
-// copy(asset.chunks.buf[0].name, "Chunk_L0_00");
-// asset.chunks.buf[0].ID = 0;
-// asset.chunks.buf[0].parentID = -1;
-// asset.chunks.buf[0].support = false;
-//
-// copy(asset.chunks.buf[1].name, "Chunk_L0_01");
-// asset.chunks.buf[1].ID = 1;
-// asset.chunks.buf[1].parentID = -1;
-// asset.chunks.buf[1].support = false;
-//
-// copy(asset.chunks.buf[2].name, "Chunk_L1_02");
-// asset.chunks.buf[2].ID = 2;
-// asset.chunks.buf[2].parentID = 0;
-// asset.chunks.buf[2].support = false;
-//
-// copy(asset.chunks.buf[3].name, "Chunk_L1_03");
-// asset.chunks.buf[3].ID = 3;
-// asset.chunks.buf[3].parentID = 0;
-// asset.chunks.buf[3].support = false;
-//
-// copy(asset.chunks.buf[4].name, "Chunk_L1_04");
-// asset.chunks.buf[4].ID = 4;
-// asset.chunks.buf[4].parentID = 1;
-// asset.chunks.buf[4].support = false;
-//
-// copy(asset.chunks.buf[5].name, "Chunk_L1_05");
-// asset.chunks.buf[5].ID = 5;
-// asset.chunks.buf[5].parentID = 1;
-// asset.chunks.buf[5].support = false;
-//
-// copy(asset.chunks.buf[6].name, "Chunk_L2_06");
-// asset.chunks.buf[6].ID = 6;
-// asset.chunks.buf[6].parentID = 2;
-// asset.chunks.buf[6].support = true;
-//
-// copy(asset.chunks.buf[7].name, "Chunk_L2_07");
-// asset.chunks.buf[7].ID = 7;
-// asset.chunks.buf[7].parentID = 2;
-// asset.chunks.buf[7].support = true;
-//
-// copy(asset.chunks.buf[8].name, "Chunk_L2_08");
-// asset.chunks.buf[8].ID = 8;
-// asset.chunks.buf[8].parentID = 3;
-// asset.chunks.buf[8].support = true;
-//
-// copy(asset.chunks.buf[9].name, "Chunk_L2_09");
-// asset.chunks.buf[9].ID = 9;
-// asset.chunks.buf[9].parentID = 3;
-// asset.chunks.buf[9].support = true;
-// }
-//
-// // bonds
-// {
-// asset.bonds.buf = new BPPBond[4];
-// asset.bonds.arraySizes[0] = 4;
-// for (int i = 0; i < 4; ++i)
-// {
-// asset.bonds.buf[i].name.buf = nullptr;
-// asset.bonds.buf[i].visible = true;
-// asset.bonds.buf[i].support.healthMask.buf = nullptr;
-// }
-//
-// copy(asset.bonds.buf[0].name, "Chunk_L2_08");
-// asset.bonds.buf[0].fromChunk = 6;
-// asset.bonds.buf[0].toChunk = 8;
-//
-// copy(asset.bonds.buf[1].name, "Chunk_L2_06");
-// asset.bonds.buf[1].fromChunk = 6;
-// asset.bonds.buf[1].toChunk = 8;
-//
-// copy(asset.bonds.buf[2].name, "Chunk_L2_09");
-// asset.bonds.buf[2].fromChunk = 7;
-// asset.bonds.buf[2].toChunk = 9;
-//
-// copy(asset.bonds.buf[3].name, "Chunk_L2_07");
-// asset.bonds.buf[3].fromChunk = 7;
-// asset.bonds.buf[3].toChunk = 9;
-// }
-// }
-//
-// // asset 1
-// {
-// BPPAsset& asset = assetArray.buf[1];
-// asset.path.buf = nullptr;
-// asset.activePreset.buf = nullptr;
-// asset.bonds.buf = nullptr;
-// asset.chunks.buf = nullptr;
-//
-// copy(asset.path, "c:/temp/BlastAsset1.asset");
-// {
-// asset.chunks.buf = new BPPChunk[10];
-// asset.chunks.arraySizes[0] = 10;
-// for (int i = 0; i < 10; ++i)
-// {
-// asset.chunks.buf[i].name.buf = nullptr;
-// asset.chunks.buf[i].visible = true;
-// }
-//
-// copy(asset.chunks.buf[0].name, "Chunk_L0_00");
-// asset.chunks.buf[0].ID = 0;
-// asset.chunks.buf[0].parentID = -1;
-// asset.chunks.buf[0].support = false;
-//
-// copy(asset.chunks.buf[1].name, "Chunk_L0_01");
-// asset.chunks.buf[1].ID = 1;
-// asset.chunks.buf[1].parentID = -1;
-// asset.chunks.buf[1].support = false;
-//
-// copy(asset.chunks.buf[2].name, "Chunk_L1_02");
-// asset.chunks.buf[2].ID = 2;
-// asset.chunks.buf[2].parentID = 0;
-// asset.chunks.buf[2].support = false;
-//
-// copy(asset.chunks.buf[3].name, "Chunk_L1_03");
-// asset.chunks.buf[3].ID = 3;
-// asset.chunks.buf[3].parentID = 0;
-// asset.chunks.buf[3].support = false;
-//
-// copy(asset.chunks.buf[4].name, "Chunk_L1_04");
-// asset.chunks.buf[4].ID = 4;
-// asset.chunks.buf[4].parentID = 1;
-// asset.chunks.buf[4].support = false;
-//
-// copy(asset.chunks.buf[5].name, "Chunk_L1_05");
-// asset.chunks.buf[5].ID = 5;
-// asset.chunks.buf[5].parentID = 1;
-// asset.chunks.buf[5].support = false;
-//
-// copy(asset.chunks.buf[6].name, "Chunk_L2_06");
-// asset.chunks.buf[6].ID = 6;
-// asset.chunks.buf[6].parentID = 2;
-// asset.chunks.buf[6].support = true;
-//
-// copy(asset.chunks.buf[7].name, "Chunk_L2_07");
-// asset.chunks.buf[7].ID = 7;
-// asset.chunks.buf[7].parentID = 2;
-// asset.chunks.buf[7].support = true;
-//
-// copy(asset.chunks.buf[8].name, "Chunk_L2_08");
-// asset.chunks.buf[8].ID = 8;
-// asset.chunks.buf[8].parentID = 3;
-// asset.chunks.buf[8].support = true;
-//
-// copy(asset.chunks.buf[9].name, "Chunk_L2_09");
-// asset.chunks.buf[9].ID = 9;
-// asset.chunks.buf[9].parentID = 3;
-// asset.chunks.buf[9].support = true;
-// }
-// }
-// }
-//
-// // projectile
-// {
-// BPPProjectileArray& projectileArray = blast.projectiles;
-// projectileArray.buf = new BPPProjectile[1];
-// projectileArray.arraySizes[0] = 1;
-// projectileArray.buf[0].name.buf = nullptr;
-// copy(projectileArray.buf[0].name, "Projectile");
-// projectileArray.buf[0].visible = true;
-// }
-//
-// // graphics meshes
-// {
-// BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes;
-// graphicsMeshArray.buf = new BPPGraphicsMesh[3];
-// graphicsMeshArray.arraySizes[0] = 3;
-// graphicsMeshArray.buf[0].name.buf = nullptr;
-// copy(graphicsMeshArray.buf[0].name, "SurfaceMesh1");
-// graphicsMeshArray.buf[0].visible = true;
-//
-// graphicsMeshArray.buf[1].name.buf = nullptr;
-// copy(graphicsMeshArray.buf[1].name, "SurfaceMesh2");
-// graphicsMeshArray.buf[1].visible = true;
-//
-// graphicsMeshArray.buf[2].name.buf = nullptr;
-// copy(graphicsMeshArray.buf[2].name, "DisplayMesh1");
-// graphicsMeshArray.buf[2].visible = true;
-// }
-//}
+ QItemSelectionModel* selectionModel = ui.blastSceneTree->selectionModel();
+ selectionModel->select(_treeModel->indexFromItem(itr.value()), QItemSelectionModel::Select);
+ }
+
+ _updateData = true;
+}
+
+void BlastSceneTree::selectTreeItem(BlastFamily* family)
+{
+ BlastAssetInstanceNode* instanceNode = BlastTreeData::ins().getAssetInstanceNode(family);
+ selectTreeItem(instanceNode, false);
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h b/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h
index d8495ee..423c2b7 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h
@@ -7,9 +7,14 @@
#include <vector>
#include <string>
#include <QtCore/QMap>
+#include <QtGui/QStandardItemModel>
+#include <QtWidgets/QStyledItemDelegate>
class QTreeWidgetItem;
class BlastAsset;
+class PhysXSceneActor;
+class BlastNode;
+class BlastFamily;
enum EBlastNodeType
{
@@ -19,8 +24,21 @@ enum EBlastNodeType
eProjectile,
eGraphicsMesh,
eAssetInstance,
- eLandmark,
- eComposite,
+ eAssetInstances,
+};
+
+class BlastVisitorBase
+{
+public:
+ BlastVisitorBase() : _continueTraversing(true)
+ {
+ }
+
+ virtual void visit(BlastNode *pNode) { return; }
+ inline bool continueTraversing(void) const { return _continueTraversing; }
+
+protected:
+ bool _continueTraversing;
};
class BlastNode
@@ -33,9 +51,15 @@ public:
{
}
- void* getData() { return _data; }
+ virtual ~BlastNode()
+ {
+ }
+
+ inline void* getData() { return _data; }
void setParent(BlastNode* parent) { _parent = parent; }
BlastNode* getParent() { return _parent; }
+ void traverse(BlastVisitorBase& visitor);
+
virtual EBlastNodeType getType() = 0;
virtual bool getVisible() = 0;
virtual void setVisible(bool val) = 0;
@@ -44,6 +68,9 @@ public:
std::vector<BlastNode*> children;
protected:
+ inline void setData(void* data) { _data = data; }
+
+private:
void* _data;
BlastNode* _parent;
};
@@ -56,8 +83,9 @@ public:
{
}
virtual EBlastNodeType getType() { return eBond; }
- virtual bool getVisible() { return ((BPPBond*)_data)->visible; }
- virtual void setVisible(bool val) { ((BPPBond*)_data)->visible = val; }
+ virtual bool getVisible() { return ((BPPBond*)getData())->visible; }
+ virtual void setVisible(bool val) { ((BPPBond*)getData())->visible = val; }
+ bool isWolrd() { return ((BPPBond*)getData())->toChunk == 0xFFFFFFFF; }
private:
std::vector<BlastNode*> children;
@@ -72,10 +100,11 @@ public:
_assetPtr = assetPtr;
}
virtual EBlastNodeType getType() { return eChunk; }
- virtual bool getVisible() { return ((BPPChunk*)_data)->visible; }
- virtual void setVisible(bool val);// { ((BPPChunk*)_data)->visible = val; }
+ virtual bool getVisible() { return ((BPPChunk*)getData())->visible; }
+ virtual void setVisible(bool val);// { ((BPPChunk*)getData())->visible = val; }
void setSelected(bool val);
- bool isSupport() { return ((BPPChunk*)_data)->support; }
+ bool isSupport() { return ((BPPChunk*)getData())->support; }
+ bool isStatic() { return ((BPPChunk*)getData())->staticFlag; }
void* _assetPtr;
};
@@ -87,20 +116,21 @@ public:
{
}
virtual EBlastNodeType getType() { return eAsset; }
- virtual bool getVisible() { return ((BPPAsset*)_data)->visible; }
- virtual void setVisible(bool val) { ((BPPAsset*)_data)->visible = val; }
+ virtual bool getVisible() { return ((BPPAsset*)getData())->visible; }
+ virtual void setVisible(bool val) { ((BPPAsset*)getData())->visible = val; }
+ void setSelected(bool val);
};
class BlastProjectileNode : public BlastNode
{
public:
- BlastProjectileNode(const std::string& inName, BPPProjectile& inData)
- : BlastNode(inName, &inData)
+ BlastProjectileNode(const std::string& inName, PhysXSceneActor* 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; }
+ virtual bool getVisible();
+ virtual void setVisible(bool val);
};
class BlastGraphicsMeshNode : public BlastNode
@@ -111,8 +141,8 @@ public:
{
}
virtual EBlastNodeType getType() { return eGraphicsMesh; }
- virtual bool getVisible() { return ((BPPGraphicsMesh*)_data)->visible; }
- virtual void setVisible(bool val) { ((BPPGraphicsMesh*)_data)->visible = val; }
+ virtual bool getVisible() { return true; }
+ virtual void setVisible(bool val) { }
};
class BlastAssetInstanceNode : public BlastNode
@@ -122,34 +152,25 @@ public:
: 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)
+ ~BlastAssetInstanceNode()
{
}
- virtual EBlastNodeType getType() { return eLandmark; }
- virtual bool getVisible() { return ((BPPLandmark*)_data)->visible; }
- virtual void setVisible(bool val) { ((BPPLandmark*)_data)->visible = val; }
+ virtual EBlastNodeType getType() { return eAssetInstance; }
+ virtual bool getVisible() { return ((BPPAssetInstance*)getData())->visible; }
+ virtual void setVisible(bool val) { ((BPPAssetInstance*)getData())->visible = val; }
+ void setSelected(bool val);
};
-class BlastCompositeNode : public BlastNode
+class BlastAssetInstancesNode : public BlastNode
{
public:
- BlastCompositeNode(const std::string& inName, BPPComposite& inData)
- : BlastNode(inName, &inData)
+ BlastAssetInstancesNode(const std::string& inName)
+ : BlastNode(inName, nullptr)
{
}
- virtual EBlastNodeType getType() { return eComposite; }
- virtual bool getVisible() { return ((BPPComposite*)_data)->visible; }
- virtual void setVisible(bool val) { ((BPPComposite*)_data)->visible = val; }
+ virtual EBlastNodeType getType() { return eAssetInstances; }
+ virtual bool getVisible() { return true; }
+ virtual void setVisible(bool val) { return; }
};
class BlastTreeData
@@ -158,19 +179,38 @@ public:
static BlastTreeData& ins();
static bool isChild(BlastChunkNode* parent, BlastChunkNode* child);
static std::vector<BlastChunkNode*> getTopChunkNodes(std::vector<BlastChunkNode*>& nodes);
+ static int getDepth(BlastNode* node);// if node is not a chunk or bond, then depth is -1.
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);
+ static std::string getAssetName(BlastAsset* asset);
+ static BlastAsset* getAsset(std::string assetName);
BlastNode* getBlastNodeByProjectData(void* blastProjectData);
- BlastCompositeNode* getCompsiteNode() { return _composite; }
+ BlastAssetInstancesNode* getBlastAssetInstancesNode() { return _assetInstancesNode; }
std::vector<BlastAssetNode*>& getAssetNodes() { return _assets; }
BlastAsset* getAsset(BlastNode* node);
+ BlastAssetNode* getAssetNode(BlastAsset* asset);
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);
+ std::vector<BlastChunkNode*> getRootChunkNodeByInstance(const BlastAssetInstanceNode* node);
+ std::vector<BlastNode*> getNodesByDepth(BlastAssetNode* node, uint32_t depth);
+ std::vector<BlastNode*> getNodesByDepth(uint32_t depth);
+ std::vector<BlastNode*> getNodesByDepth(std::vector<uint32_t> depths);
+ BlastNode* getNodeByIndex(uint32_t assetIndex, uint32_t chunkIndex);
+ std::vector<BlastChunkNode*> getSupportChunkNodes(BlastAssetNode* node);
+ std::vector<BlastChunkNode*> getSupportChunkNodes();
+ std::vector<BlastChunkNode*> getSiblingChunkNodes(BlastChunkNode* node);
+ BlastChunkNode* getSupportAncestor(BlastChunkNode* node);
+ const std::vector<BlastNode*>& getAllChunkNodes(std::vector<BlastNode*>& res, BlastAssetNode* node);
+ const std::vector<BlastNode*>& getAllChunkNodes(std::vector<BlastNode*>& res);
+ const std::vector<BlastNode*>& getAllLeavesChunkNodes(std::vector<BlastNode*>& res, BlastAssetNode* node);
+ const std::vector<BlastNode*>& getAllLeavesChunkNodes(std::vector<BlastNode*>& res);
+ const std::vector<BlastNode*>& getChunkNodesFullCoverage(std::vector<BlastNode*>& res, BlastAssetNode* node, int depth);
+ const std::vector<BlastNode*>& getChunkNodesFullCoverage(std::vector<BlastNode*>& res, int depth);
bool isCompleteSupportAsset(const BlastAsset* asset);
bool isCompleteSupportAsset(const BlastAssetNode* node);
@@ -181,19 +221,37 @@ public:
BlastAssetInstanceNode* addAssetInstance(const BlastAsset* asset);
void remove(const BlastAssetNode* node);
void remove(const BlastAssetInstanceNode* node);
+ BlastAssetInstanceNode* getAssetInstanceNode(BlastFamily* family);
+ BlastAssetInstanceNode* getAssetInstanceNode(BPPAssetInstance* instance);
+ std::vector<BlastAssetInstanceNode*> getAssetInstanceNodes(BlastChunkNode* chunkNode);
void update();
void update(const BlastAsset* asset);
- void updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible);
-
+ /*
+ BlastAssetNode* addBlastAsset(BPPAsset& asset);
+ void removeBlastAsset(BPPAsset& asset);
+
+ BlastAssetInstanceNode* addBlastInstance(BPPAssetInstance& instance);
+ void removeBlastInstance(BPPAssetInstance& instance);
+
+ BlastProjectileNode* addProjectile(PhysXSceneActor* projectile);
+ void clearProjectile();
+
+ void refreshProjectDataToNodeMap(std::map<BPPAsset*, BPPAsset*>& changeMap);
+ void refreshProjectDataToNodeMap(std::map<BPPAssetInstance*, BPPAssetInstance*>& changeMap);
+ */
+
+ void traverse(BlastVisitorBase& visitor);
+
private:
BlastTreeData();
- void _addChunkNode(const BPPChunk& parentData, BPPAsset& asset, BlastChunkNode* parentNode, void* assetPtr);
+ void _addChunkNode(BPPChunk& parentData, BPPAsset& asset, BlastChunkNode* parentNode, void* assetPtr);
+ void _removeChunkNode(BPPAsset& asset);
void _freeBlastNode();
BlastAssetNode* _getAssetNode(const BlastAsset* asset);
private:
- BlastCompositeNode* _composite;
+ BlastAssetInstancesNode* _assetInstancesNode;
std::vector<BlastAssetNode*> _assets;
std::vector<BlastProjectileNode*> _projectiles;
std::vector<BlastGraphicsMeshNode*> _graphicsMeshes;
@@ -206,26 +264,29 @@ public:
virtual void dataSelected(std::vector<BlastNode*> selections) = 0;
};
-class VisualButton : public QWidget
+class BlastTreeViewDelegate : QStyledItemDelegate
{
Q_OBJECT
+
public:
- VisualButton(QWidget* parent, BlastNode* blastItem);
+ BlastTreeViewDelegate(QObject* parent, QStandardItemModel* model);
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ bool editorEvent(QEvent* evt, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
-protected slots:
- void on_visualbility_toggled(bool checked);
-private:
- void _updateBlast(bool visible);
+protected:
+ bool eventFilter(QObject* object, QEvent* event);
private:
- QPushButton* _button;
- BlastNode* _blastItem;
+ QStandardItemModel* _treeModel;
};
+class BlastSceneTreeDataLock;
+
class BlastSceneTree : public QDockWidget, public ISceneObserver
{
Q_OBJECT
+ friend class BlastSceneTreeDataLock;
public:
static BlastSceneTree* ins();
@@ -234,6 +295,8 @@ public:
void updateValues(bool updataData = true);
+ void clear();
+
virtual void dataSelected(std::vector<BlastNode*> selections);
void addObserver(ISceneObserver* observer);
@@ -245,49 +308,82 @@ public:
void makeSupport();
void makeStaticSupport();
void removeSupport();
+ void makeWorld();
+ void removeWorld();
void bondChunks();
void bondChunksWithJoints();
void removeAllBonds();
+ void setChunkSelected(std::vector<uint32_t> depths, bool selected);
+ void setChunkVisible(std::vector<uint32_t> depths, bool bVisible);
+
+ void setChunkVisibleFullCoverage(int depth);
+ void hideAllChunks();
+ /*
+ void addBlastAsset(BPPAsset& asset);
+ void removeBlastAsset(BPPAsset& asset);
+
+ void addBlastInstance(BPPAssetInstance& instance);
+ void removeBlastInstance(BPPAssetInstance& instance);
+ void removeBlastInstances(BPPAsset& asset);
+
+ void addProjectile(PhysXSceneActor* projectile);
+ void clearProjectile();
+ */
+ BlastNode* getBlastNodeByItem(QStandardItem* item);
+ PhysXSceneActor* getProjectileActorByItem(QStandardItem* item);
+
+ void selectTreeItem(BlastNode* node, bool updateData = true);
+ void selectTreeItem(BlastFamily* family);
+
+ void ApplyAutoSelectNewChunks(BlastAsset* pNewBlastAsset, std::vector<uint32_t>& NewChunkIndexes);
+
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 on_btnExpandCollapse_clicked();
+ void on_blastSceneTree_customContextMenuRequested(const QPoint& pos);
+ void on_blastSceneTree_itemSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
void onMakeSupportMenuItemClicked();
void onMakeStaticSupportMenuItemClicked();
void onRemoveSupportMenuItemClicked();
+ void onMakeWorldMenuItemClicked();
+ void onRemoveWorldMenuItemClicked();
void onBondChunksMenuItemClicked();
void onBondChunksWithJointsMenuItemClicked();
void onRemoveAllBondsMenuItemClicked();
+ void onCollapseExpandClicked();
private:
void _updateTreeUIs();
- void _addChunkUI(const BlastNode* parentNode, QTreeWidgetItem* parentTreeItem);
- void _updateChunkTreeItemAndMenu(BPPChunk* chunk, QTreeWidgetItem* chunkItem);
+ void _addChunkUI(const BlastNode* parentNode, QStandardItem* parentTreeItem);
+ void _updateChunkTreeItemAndMenu(BPPChunk* chunk, QStandardItem* 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;
+ QStandardItemModel* _treeModel;
+ QMap<QStandardItem*, BlastNode*> _treeItemDataMap;
+ QMap<BlastNode*, QStandardItem*> _treeDataItemMap;
+ QMenu* _treeContextMenu;
QAction* _makeSupportAction;
QAction* _makeStaticSupportAction;
QAction* _removeSupportAction;
+ QAction* _makeWorldAction;
+ QAction* _removeWorldAction;
QAction* _bondChunksAction;
QAction* _bondChunksWithJointsAction;
QAction* _removeAllBondsAction;
std::vector<ISceneObserver*> _observers;
bool _updateData;
+// QStandardItem* _compositeTreeItem;
+ QMap<QStandardItem*, PhysXSceneActor*> _projectileItemActorMap;
+
+ BlastAsset* m_pNewBlastAsset;
+ std::vector<uint32_t> m_NewChunkIndexes;
};
#endif // BLASTSCENETREE_H
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp b/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp
index c5a743a..3d48059 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp
@@ -5,8 +5,33 @@
#include "PhysXController.h"
#include "QtUtil.h"
+#include "SampleManager.h"
+#include "SceneController.h"
+#include "DamageToolController.h"
+#include "SelectionToolController.h"
+#include "ExplodeToolController.h"
+#include "GizmoToolController.h"
+#include "BlastController.h"
+#include "SourceAssetOpenDlg.h"
+#include "BlastPlugin.h"
+#include <QtWidgets/QButtonGroup>
+#include <QtWidgets/QActionGroup>
+#include "Shlwapi.h"
+#include "BlastSceneTree.h"
+#include "BlastFamily.h"
+#include "FileReferencesPanel.h"
+#include "GlobalSettings.h"
+#include "PxScene.h"
+#include "PxRigidDynamic.h"
+#include "ViewerOutput.h"
+
+#include <QtCore/QTimer>
+QTimer gDropTimer;
+int nExplodedViewState = 0;
+
BlastToolbar::BlastToolbar(QWidget* parent)
: QDockWidget(parent)
+ , m_fullCoverage(false)
{
// to hide the title bar completely must replace the default widget with a generic one
QWidget* titleWidget = new QWidget(this);
@@ -29,7 +54,7 @@ BlastToolbar::BlastToolbar(QWidget* parent)
sizePolicy1.setVerticalStretch(0);
btnOpenProject = new QPushButton(widget);
- setStyledToolTip(btnOpenProject, "Open Blast Asset");
+ setStyledToolTip(btnOpenProject, "Open Project");
const QFont& font = btnOpenProject->font();
QFont fontCopy(font);
fontCopy.setPixelSize(9);
@@ -43,7 +68,7 @@ BlastToolbar::BlastToolbar(QWidget* parent)
hLayout->addWidget(btnOpenProject);
btnSaveProject = new QPushButton(widget);
- setStyledToolTip(btnSaveProject, "Not Implement");
+ setStyledToolTip(btnSaveProject, "Save Project and assets");
btnSaveProject->setObjectName(QStringLiteral("btnSaveProject"));
sizePolicy1.setHeightForWidth(btnOpenProject->sizePolicy().hasHeightForWidth());
btnSaveProject->setSizePolicy(sizePolicy1);
@@ -53,7 +78,7 @@ BlastToolbar::BlastToolbar(QWidget* parent)
hLayout->addWidget(btnSaveProject);
btnExportAssets = new QPushButton(widget);
- setStyledToolTip(btnExportAssets, "Not Implement");
+ setStyledToolTip(btnExportAssets, "Export Blast assets");
btnExportAssets->setObjectName(QStringLiteral("btnExportAssets"));
sizePolicy1.setHeightForWidth(btnExportAssets->sizePolicy().hasHeightForWidth());
btnExportAssets->setSizePolicy(sizePolicy1);
@@ -93,6 +118,7 @@ BlastToolbar::BlastToolbar(QWidget* parent)
leExportFilepath->setMinimumSize(QSize(150, 20));
leExportFilepath->setMaximumSize(QSize(150, 20));
leExportFilepath->setText(QApplication::translate("AppMainToolbar", "", 0));
+ leExportFilepath->setEnabled(false); // do not allow direct change to make sure the folder exists.
vLayoutExport->addWidget(leExportFilepath);
hLayout->addLayout(vLayoutExport);
@@ -130,10 +156,10 @@ BlastToolbar::BlastToolbar(QWidget* parent)
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);
+ lbExactCoverage = new QLabel(widget);
+ lbExactCoverage->setObjectName(QStringLiteral("lbExactCoverage"));
+ lbExactCoverage->setText(QApplication::translate("AppMainToolbar", "Full Coverage", 0));
+ hlExactCoverage->addWidget(lbExactCoverage);
cbExactCoverage = new QCheckBox(widget);
cbExactCoverage->setObjectName(QStringLiteral("cbExactCoverage"));
@@ -151,7 +177,9 @@ BlastToolbar::BlastToolbar(QWidget* parent)
fSeparate->setFrameShape(QFrame::VLine);
fSeparate->setFrameShadow(QFrame::Sunken);
hLayout->addWidget(fSeparate);
-
+
+ QButtonGroup* gizmoGroup = new QButtonGroup(this);
+
btnSelectTool = new QPushButton(widget);
setStyledToolTip(btnSelectTool, "Switch to Selection Mode");
btnSelectTool->setObjectName(QStringLiteral("btnSelectTool"));
@@ -160,19 +188,99 @@ BlastToolbar::BlastToolbar(QWidget* parent)
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);
+ btnSelectTool->setIconSize(QSize(36, 36));
+ // because we can detect click or draw rect. we do not need menu by now.
+ //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);
+ //pointselect_action->setCheckable(true);
+ //rectselect_action->setCheckable(true);
+ //drawselect_action->setCheckable(true);
+ //QActionGroup* selectGroup = new QActionGroup(this);
+ //selectGroup->addAction(pointselect_action);
+ //selectGroup->addAction(rectselect_action);
+ //selectGroup->addAction(drawselect_action);
+ //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);
+ btnSelectTool->setCheckable(true);
+ gizmoGroup->addButton(btnSelectTool);
+
+ btnExplodedViewTool = new QPushButton(widget);
+ setStyledToolTip(btnExplodedViewTool, "Exploded View Tool");
+ 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(36, 36));
+ btnExplodedViewTool->setCheckable(true);
+ hLayout->addWidget(btnExplodedViewTool);
+ gizmoGroup->addButton(btnExplodedViewTool);
+
+ btnTranslate = new QPushButton(widget);
+ setStyledToolTip(btnTranslate, "Translate Tool");
+ btnTranslate->setObjectName(QStringLiteral("btnTranslate"));
+ sizePolicy1.setHeightForWidth(btnTranslate->sizePolicy().hasHeightForWidth());
+ btnTranslate->setSizePolicy(sizePolicy1);
+ btnTranslate->setMinimumSize(QSize(40, 40));
+ btnTranslate->setMaximumSize(QSize(40, 40));
+ btnTranslate->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnTranslate.png"));
+ btnTranslate->setIconSize(QSize(36, 36));
+ hLayout->addWidget(btnTranslate);
+ btnTranslate->setCheckable(true);
+ gizmoGroup->addButton(btnTranslate);
+
+ btnRotate = new QPushButton(widget);
+ setStyledToolTip(btnRotate, "Rotate Tool");
+ btnRotate->setObjectName(QStringLiteral("btnRotate"));
+ sizePolicy1.setHeightForWidth(btnRotate->sizePolicy().hasHeightForWidth());
+ btnRotate->setSizePolicy(sizePolicy1);
+ btnRotate->setMinimumSize(QSize(40, 40));
+ btnRotate->setMaximumSize(QSize(40, 40));
+ btnRotate->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnRotate.png"));
+ btnRotate->setIconSize(QSize(36, 36));
+ hLayout->addWidget(btnRotate);
+ btnRotate->setCheckable(true);
+ gizmoGroup->addButton(btnRotate);
+
+ btnScale = new QPushButton(widget);
+ setStyledToolTip(btnScale, "Scale Tool");
+ btnScale->setObjectName(QStringLiteral("btnScale"));
+ sizePolicy1.setHeightForWidth(btnScale->sizePolicy().hasHeightForWidth());
+ btnScale->setSizePolicy(sizePolicy1);
+ btnScale->setMinimumSize(QSize(40, 40));
+ btnScale->setMaximumSize(QSize(40, 40));
+ btnScale->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnScale.png"));
+ btnScale->setIconSize(QSize(36, 36));
+ hLayout->addWidget(btnScale);
+ btnScale->setCheckable(true);
+ gizmoGroup->addButton(btnScale);
+
+ btnGizmoWithLocal = new QPushButton(widget);
+ setStyledToolTip(btnGizmoWithLocal, "Gizmo in Global Mode");
+ btnGizmoWithLocal->setObjectName(QStringLiteral("btnGizmoWithLocal"));
+ sizePolicy1.setHeightForWidth(btnGizmoWithLocal->sizePolicy().hasHeightForWidth());
+ btnGizmoWithLocal->setSizePolicy(sizePolicy1);
+ btnGizmoWithLocal->setMinimumSize(QSize(40, 40));
+ btnGizmoWithLocal->setMaximumSize(QSize(40, 40));
+ btnGizmoWithLocal->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnGizmoWithGlobal.png"));
+ btnGizmoWithLocal->setIconSize(QSize(36, 36));
+ hLayout->addWidget(btnGizmoWithLocal);
+ btnGizmoWithLocal->setCheckable(true);
+
+ //fSeparate = new QFrame(widget);
+ //fSeparate->setObjectName(QStringLiteral("fSeparate"));
+ //fSeparate->setFrameShape(QFrame::VLine);
+ //fSeparate->setFrameShadow(QFrame::Sunken);
+ //hLayout->addWidget(fSeparate);
btnPaintbrush = new QPushButton(widget);
setStyledToolTip(btnPaintbrush, "Not Implement");
@@ -182,7 +290,7 @@ BlastToolbar::BlastToolbar(QWidget* parent)
btnPaintbrush->setMinimumSize(QSize(40, 40));
btnPaintbrush->setMaximumSize(QSize(40, 40));
btnPaintbrush->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnPaintbrush.png"));
- btnPaintbrush->setIconSize(QSize(40, 40));
+ btnPaintbrush->setIconSize(QSize(36, 36));
hLayout->addWidget(btnPaintbrush);
btnFractureTool = new QPushButton(widget);
@@ -196,17 +304,6 @@ BlastToolbar::BlastToolbar(QWidget* parent)
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"));
@@ -215,7 +312,7 @@ BlastToolbar::BlastToolbar(QWidget* parent)
btnJointsTool->setMinimumSize(QSize(40, 40));
btnJointsTool->setMaximumSize(QSize(40, 40));
btnJointsTool->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnJointsTool.png"));
- btnJointsTool->setIconSize(QSize(40, 40));
+ btnJointsTool->setIconSize(QSize(36, 36));
hLayout->addWidget(btnJointsTool);
btnFuseSelectedChunks = new QPushButton(widget);
@@ -226,7 +323,7 @@ BlastToolbar::BlastToolbar(QWidget* parent)
btnFuseSelectedChunks->setMinimumSize(QSize(40, 40));
btnFuseSelectedChunks->setMaximumSize(QSize(40, 40));
btnFuseSelectedChunks->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnFuseSelectedChunks.png"));
- btnFuseSelectedChunks->setIconSize(QSize(40, 40));
+ btnFuseSelectedChunks->setIconSize(QSize(36, 36));
hLayout->addWidget(btnFuseSelectedChunks);
fSeparate = new QFrame(widget);
@@ -235,6 +332,8 @@ BlastToolbar::BlastToolbar(QWidget* parent)
fSeparate->setFrameShadow(QFrame::Sunken);
hLayout->addWidget(fSeparate);
+ QButtonGroup* editSimModeGroup = new QButtonGroup(this);
+
btnReset = new QPushButton(widget);
setStyledToolTip(btnReset, "Reset Chunks and Switch to Edition Mode");
btnReset->setObjectName(QStringLiteral("btnReset"));
@@ -243,8 +342,10 @@ BlastToolbar::BlastToolbar(QWidget* parent)
btnReset->setMinimumSize(QSize(40, 40));
btnReset->setMaximumSize(QSize(40, 40));
btnReset->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnReset.png"));
- btnReset->setIconSize(QSize(40, 40));
+ btnReset->setIconSize(QSize(36, 36));
hLayout->addWidget(btnReset);
+ btnReset->setCheckable(true);
+ editSimModeGroup->addButton(btnReset);
btnSimulatePlay = new QPushButton(widget);
setStyledToolTip(btnSimulatePlay, "Switch to Simulate Mode");
@@ -254,8 +355,10 @@ BlastToolbar::BlastToolbar(QWidget* parent)
btnSimulatePlay->setMinimumSize(QSize(40, 40));
btnSimulatePlay->setMaximumSize(QSize(40, 40));
btnSimulatePlay->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnSimulatePlay.png"));
- btnSimulatePlay->setIconSize(QSize(40, 40));
+ btnSimulatePlay->setIconSize(QSize(36, 36));
hLayout->addWidget(btnSimulatePlay);
+ btnSimulatePlay->setCheckable(true);
+ editSimModeGroup->addButton(btnSimulatePlay);
btnFrameStepForward = new QPushButton(widget);
setStyledToolTip(btnFrameStepForward, "Switch to StepForward Mode");
@@ -265,8 +368,10 @@ BlastToolbar::BlastToolbar(QWidget* parent)
btnFrameStepForward->setMinimumSize(QSize(40, 40));
btnFrameStepForward->setMaximumSize(QSize(40, 40));
btnFrameStepForward->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnFrameStepForward.png"));
- btnFrameStepForward->setIconSize(QSize(40, 40));
+ btnFrameStepForward->setIconSize(QSize(36, 36));
hLayout->addWidget(btnFrameStepForward);
+ btnFrameStepForward->setCheckable(true);
+ editSimModeGroup->addButton(btnFrameStepForward);
fSeparate = new QFrame(widget);
fSeparate->setObjectName(QStringLiteral("fSeparate"));
@@ -274,16 +379,18 @@ BlastToolbar::BlastToolbar(QWidget* parent)
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);
+ // use btnDamage for Damage function.
+ btnDamage = new QPushButton(widget);
+ setStyledToolTip(btnDamage, "Switch on/off Damage Mode");
+ btnDamage->setObjectName(QStringLiteral("btnDamage"));
+ sizePolicy1.setHeightForWidth(btnDamage->sizePolicy().hasHeightForWidth());
+ btnDamage->setSizePolicy(sizePolicy1);
+ btnDamage->setMinimumSize(QSize(40, 40));
+ btnDamage->setMaximumSize(QSize(40, 40));
+ btnDamage->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnDamage.png"));
+ btnDamage->setIconSize(QSize(36, 36));
+ btnDamage->setCheckable(true);
+ hLayout->addWidget(btnDamage);
btnProjectile = new QPushButton(widget);
setStyledToolTip(btnProjectile, "Throw a Box to Chunks");
@@ -293,18 +400,18 @@ BlastToolbar::BlastToolbar(QWidget* parent)
btnProjectile->setMinimumSize(QSize(40, 40));
btnProjectile->setMaximumSize(QSize(40, 40));
btnProjectile->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnProjectile.png"));
- btnProjectile->setIconSize(QSize(40, 40));
+ btnProjectile->setIconSize(QSize(36, 36));
hLayout->addWidget(btnProjectile);
btnDropObject = new QPushButton(widget);
- setStyledToolTip(btnDropObject, "Not Implement");
+ setStyledToolTip(btnDropObject, "Drop the object and simulate");
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));
+ btnDropObject->setIconSize(QSize(36, 36));
hLayout->addWidget(btnDropObject);
fSeparate = new QFrame(widget);
@@ -321,7 +428,7 @@ BlastToolbar::BlastToolbar(QWidget* parent)
btnPreferences->setMinimumSize(QSize(40, 40));
btnPreferences->setMaximumSize(QSize(40, 40));
btnPreferences->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnPreferences.png"));
- btnPreferences->setIconSize(QSize(40, 40));
+ btnPreferences->setIconSize(QSize(36, 36));
hLayout->addWidget(btnPreferences);
QSpacerItem *horizontalSpacer;
@@ -330,6 +437,7 @@ BlastToolbar::BlastToolbar(QWidget* parent)
this->setWidget(widget);
+ connect(&gDropTimer, SIGNAL(timeout()), this, SLOT(on_btnDropObject_clicked()));
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()));
@@ -337,6 +445,10 @@ BlastToolbar::BlastToolbar(QWidget* parent)
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(btnTranslate, SIGNAL(clicked()), this, SLOT(on_Translate_clicked()));
+ connect(btnRotate, SIGNAL(clicked()), this, SLOT(on_Rotation_clicked()));
+ connect(btnScale, SIGNAL(clicked()), this, SLOT(on_Scale_clicked()));
+ connect(btnGizmoWithLocal, SIGNAL(clicked()), this, SLOT(on_btnGizmoWithLocal_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()));
@@ -345,96 +457,142 @@ BlastToolbar::BlastToolbar(QWidget* parent)
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(btnDamage, SIGNAL(clicked()), this, SLOT(on_btnDamage_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()));
+
+ QPushButton* unImplementButtons[] =
+ {
+ btnPaintbrush, btnFractureTool, btnJointsTool, btnFuseSelectedChunks, btnPreferences
+ };
+ int buttonSize = sizeof(unImplementButtons) / sizeof(QPushButton*);
+ for (int bs = 0; bs < buttonSize; bs++)
+ {
+ unImplementButtons[bs]->setVisible(false);
+ }
}
void BlastToolbar::updateValues()
{
-}
+ leExportFilepath->setText(GlobalSettings::Inst().m_projectFileDir.c_str());
+ btnGizmoWithLocal->setChecked(AppMainWindow::Inst().m_bGizmoWithLocal);
-#include <Sample.h>
-#include <SimpleScene.h>
-#include <SampleManager.h>
-#include <SceneController.h>
-#include <SourceAssetOpenDlg.h>
+ SampleManager* pSampleManager = SampleManager::ins();
+ DamageToolController& damageToolController = pSampleManager->getDamageToolController();
+ bool bChecked = damageToolController.IsEnabled() && damageToolController.IsEnabled() && damageToolController.isDamageMode();
+ btnDamage->setChecked(bChecked);
+}
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(dir, file, dlg.getSkinned(), t, !dlg.isAppend());
+ //BlastPlugin::OpenBpxa("", "");
+ BlastPlugin::Inst().menu_openProject();
+ // show project path in toolbar
+ updateValues();
}
void BlastToolbar::on_btnSaveProject_clicked()
{
qDebug("%s", __FUNCTION__);
+ on_btnExportAssets_clicked();
+ BlastPlugin::Inst().menu_saveProject();
}
void BlastToolbar::on_btnExportAssets_clicked()
{
qDebug("%s", __FUNCTION__);
+ FileReferencesPanel* pPanel = BlastPlugin::Inst().GetFileReferencesPanel();
+ if (pPanel)
+ {
+ BlastAssetInstancesNode* assetInstancesNode = BlastTreeData::ins().getBlastAssetInstancesNode();
+ if (assetInstancesNode != nullptr)
+ {
+ size_t count = assetInstancesNode->children.size();
+ for (size_t i = 0; i < count; ++i)
+ {
+ BlastAssetInstanceNode* assetInstanceNode = dynamic_cast<BlastAssetInstanceNode*>(assetInstancesNode->children[i]);
+ if (assetInstanceNode)
+ {
+ assetInstanceNode->setSelected(true);
+ pPanel->on_btnSave_clicked();
+ }
+ }
+ }
+ }
}
void BlastToolbar::on_btnExportFilepath_clicked()
{
qDebug("%s", __FUNCTION__);
+ AppMainWindow& window = AppMainWindow::Inst();
+ QString lastDir = leExportFilepath->text();
+ if (lastDir.length() < 1)
+ {
+ lastDir = GlobalSettings::Inst().m_projectFileDir.c_str();
+ }
+ QString pathName = QFileDialog::getExistingDirectory(&window, "Exporting Path", lastDir);
+ if (!pathName.isEmpty())
+ {
+ GlobalSettings::Inst().m_projectFileDir = pathName.toUtf8().data();
+ leExportFilepath->setText(pathName);
+ }
}
void BlastToolbar::on_ssbiDepthPreview_valueChanged(int v)
{
qDebug("%s", __FUNCTION__);
+ BlastSceneTree* pBlastSceneTree = BlastSceneTree::ins();
+ pBlastSceneTree->hideAllChunks();
+ if (m_fullCoverage)
+ {
+ pBlastSceneTree->setChunkVisibleFullCoverage(v);
+ }
+ else
+ {
+ std::vector<uint32_t> depths(1, v);
+ pBlastSceneTree->setChunkVisible(depths, true);
+ }
+ // refresh display in scene tree
+ //pBlastSceneTree->updateValues(false);
+ SampleManager::ins()->m_bNeedRefreshTree = true;
}
void BlastToolbar::on_cbExactCoverage_stateChanged(int state)
{
qDebug("%s", __FUNCTION__);
+ m_fullCoverage = (state != 0);
+ //lbExactCoverage->setText(QApplication::translate("AppMainToolbar", (m_fullCoverage? "Full Coverage" : "Exact Coverage"), 0));
+ int depth = ssbiDepthPreview->value();
+ on_ssbiDepthPreview_valueChanged(depth);
}
void BlastToolbar::on_btnSelectTool_clicked()
{
- qDebug("%s", __FUNCTION__);
+ SampleManager* pSampleManager = SampleManager::ins();
+ SelectionToolController& selectionToolController = pSampleManager->getSelectionToolController();
+ ExplodeToolController& expolodeController = pSampleManager->getExplodeToolController();
+ expolodeController.DisableController();
+ GizmoToolController& gizmoToolController = pSampleManager->getGizmoToolController();
+ gizmoToolController.showAxisRenderables(false);
+
+ if (gizmoToolController.IsEnabled())
+ {
+ gizmoToolController.DisableController();
+ selectionToolController.setTargetActor(gizmoToolController.getTargetActor());
+ }
+ selectionToolController.EnableController();
+
}
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()
@@ -442,6 +600,83 @@ void BlastToolbar::on_drawselect_action()
qDebug("%s", __FUNCTION__);
}
+bool BlastToolbar::on_Translate_clicked()
+{
+ SampleManager* pSampleManager = SampleManager::ins();
+ SelectionToolController& selectionToolController = pSampleManager->getSelectionToolController();
+ ExplodeToolController& expolodeController = pSampleManager->getExplodeToolController();
+ expolodeController.DisableController();
+ GizmoToolController& gizmoToolController = pSampleManager->getGizmoToolController();
+ gizmoToolController.showAxisRenderables(false);
+
+ if (selectionToolController.IsEnabled())
+ {
+ selectionToolController.DisableController();
+ gizmoToolController.setTargetActor(selectionToolController.getTargetActor());
+ }
+ gizmoToolController.EnableController();
+ gizmoToolController.setGizmoToolMode(GTM_Translate);
+
+ return true;
+}
+
+bool BlastToolbar::on_Rotation_clicked()
+{
+ SampleManager* pSampleManager = SampleManager::ins();
+ SelectionToolController& selectionToolController = pSampleManager->getSelectionToolController();
+ ExplodeToolController& expolodeController = pSampleManager->getExplodeToolController();
+ expolodeController.DisableController();
+ GizmoToolController& gizmoToolController = pSampleManager->getGizmoToolController();
+ gizmoToolController.showAxisRenderables(false);
+
+ if (selectionToolController.IsEnabled())
+ {
+ selectionToolController.DisableController();
+ gizmoToolController.setTargetActor(selectionToolController.getTargetActor());
+ }
+ gizmoToolController.EnableController();
+ gizmoToolController.setGizmoToolMode(GTM_Rotation);
+
+ return true;
+}
+
+bool BlastToolbar::on_Scale_clicked()
+{
+ SampleManager* pSampleManager = SampleManager::ins();
+ SelectionToolController& selectionToolController = pSampleManager->getSelectionToolController();
+ ExplodeToolController& expolodeController = pSampleManager->getExplodeToolController();
+ expolodeController.DisableController();
+ GizmoToolController& gizmoToolController = pSampleManager->getGizmoToolController();
+ gizmoToolController.showAxisRenderables(false);
+
+ if (selectionToolController.IsEnabled())
+ {
+ selectionToolController.DisableController();
+ gizmoToolController.setTargetActor(selectionToolController.getTargetActor());
+ }
+ gizmoToolController.EnableController();
+ gizmoToolController.setGizmoToolMode(GTM_Scale);
+
+ return true;
+}
+
+void BlastToolbar::on_btnGizmoWithLocal_clicked()
+{
+ AppMainWindow& app = AppMainWindow::Inst();
+ app.m_bGizmoWithLocal = !app.m_bGizmoWithLocal;
+ if (app.m_bGizmoWithLocal)
+ {
+ btnGizmoWithLocal->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnGizmoWithLocal.png"));
+ setStyledToolTip(btnGizmoWithLocal, "Gizmo in Local Mode");
+ }
+ else
+ {
+ btnGizmoWithLocal->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnGizmoWithGlobal.png"));
+ setStyledToolTip(btnGizmoWithLocal, "Gizmo in Global Mode");
+ }
+ app.updateUI();
+}
+
void BlastToolbar::on_btnPaintbrush_clicked()
{
qDebug("%s", __FUNCTION__);
@@ -454,7 +689,146 @@ void BlastToolbar::on_btnFractureTool_clicked()
void BlastToolbar::on_btnExplodedViewTool_clicked()
{
- qDebug("%s", __FUNCTION__);
+#if (1)
+ SampleManager* pSampleManager = SampleManager::ins();
+ ExplodeToolController& explodeToolController = pSampleManager->getExplodeToolController();
+ GizmoToolController& gizmoToolController = pSampleManager->getGizmoToolController();
+ gizmoToolController.showAxisRenderables(false);
+
+ pSampleManager->getSelectionToolController().DisableController();
+
+ if (gizmoToolController.IsEnabled())
+ {
+ gizmoToolController.DisableController();
+ }
+ explodeToolController.EnableController();
+#endif
+
+#if (0)
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager->IsSimulating())
+ {
+ return;
+ }
+
+ BlastAsset* pBlastAsset = nullptr;
+ int nFamilyIndex = -1;
+ pSampleManager->getCurrentSelectedInstance(&pBlastAsset, nFamilyIndex);
+ if (pBlastAsset == nullptr)
+ {
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ if (AssetDescMap.size() == 1)
+ {
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itAssetDescMap = AssetDescMap.begin();
+ pSampleManager->setCurrentSelectedInstance(itAssetDescMap->first, -1);
+ pBlastAsset = pSampleManager->getCurBlastAsset();
+ viewer_msg("no asset selected, use the only one in current scene.");
+ }
+ }
+ if (pBlastAsset == nullptr)
+ {
+ viewer_msg("please select one asset before explode.");
+ return;
+ }
+
+ std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = pSampleManager->getAssetFamiliesMap();
+ std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAFM = AssetFamiliesMap.find(pBlastAsset);
+ if (itAFM == AssetFamiliesMap.end())
+ {
+ return;
+ }
+
+ std::vector<BlastFamily*> families = itAFM->second;
+ int familySize = families.size();
+ if (familySize == 0)
+ {
+ viewer_msg("no instance for current asset.");
+ return;
+ }
+
+ if (nFamilyIndex == -1 || nFamilyIndex >= familySize)
+ {
+ nFamilyIndex = 0;
+ viewer_msg("no instance selected, use the first one of current asset.");
+ }
+
+ BlastFamily* pFamily = families[nFamilyIndex];
+
+ PxScene& scene = pSampleManager->getPhysXController().getEditPhysXScene();
+ const PxU32 actorsCountTotal = scene.getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC);
+ if (actorsCountTotal == 0)
+ {
+ return;
+ }
+
+ std::vector<PxActor*> actorsTotal(actorsCountTotal);
+ PxU32 nbActors = scene.getActors(PxActorTypeFlag::eRIGID_DYNAMIC, &actorsTotal[0], actorsCountTotal, 0);
+ PX_ASSERT(actorsCountTotal == nbActors);
+
+ std::vector<PxActor*> actors;
+ PxActor* pRootActor = nullptr;
+ for (int act = 0; act < actorsCountTotal; act++)
+ {
+ if (pFamily->find(*actorsTotal[act]))
+ {
+ if (pRootActor == nullptr)
+ {
+ uint32_t chunkIndex = pFamily->getChunkIndexByPxActor(*actorsTotal[act]);
+ std::vector<uint32_t> chunkIndexes;
+ chunkIndexes.push_back(chunkIndex);
+ std::vector<BlastChunkNode*> chunkNodes = BlastTreeData::ins().getChunkNodeByBlastChunk(pBlastAsset, chunkIndexes);
+ if (chunkNodes.size() > 0 && BlastTreeData::isRoot(chunkNodes[0]))
+ {
+ pRootActor = actorsTotal[act];
+ }
+ else
+ {
+ actors.push_back(actorsTotal[act]);
+ }
+ }
+ else
+ {
+ actors.push_back(actorsTotal[act]);
+ }
+ }
+ }
+
+ if (pRootActor == nullptr)
+ {
+ return;
+ }
+
+ ++nExplodedViewState;
+
+ BlastController& blastController = pSampleManager->getBlastController();
+
+ PxVec3 origin = pRootActor->getWorldBounds().getCenter();
+
+ int actorsCount = actors.size();
+ for (int ac = 0; ac < actorsCount; ac++)
+ {
+ PxActor* actor = actors[ac];
+ PxRigidDynamic* dynamic = actor->is<PxRigidDynamic>();
+ PX_ASSERT(dynamic != nullptr);
+ PxTransform transformOld = dynamic->getGlobalPose();
+ PxTransform transformNew = transformOld;
+
+ PxBounds3 bound = actor->getWorldBounds();
+ PxVec3 target = bound.getCenter();
+ PxVec3 tChange = (target - origin) * 0.5;
+ if (nExplodedViewState > 5)
+ {
+ tChange = (origin - target) / 3;
+ }
+ PxVec3 newTarget = target + tChange;
+ transformNew.p = transformOld.p + tChange;
+ dynamic->setGlobalPose(transformNew);
+ blastController.updateActorRenderableTransform(*actor, transformNew, false);
+ }
+ if (nExplodedViewState > 9)
+ nExplodedViewState = 0;
+
+#endif
}
void BlastToolbar::on_btnJointsTool_clicked()
@@ -469,10 +843,23 @@ void BlastToolbar::on_btnFuseSelectedChunks_clicked()
void BlastToolbar::on_btnReset_clicked()
{
- qDebug("%s", __FUNCTION__);
+ nExplodedViewState = 0;
SampleManager* pSampleManager = SampleManager::ins();
+ bool bStopSimulation = pSampleManager->IsSimulating();
pSampleManager->resetScene();
+ // only show depth 0 if stop from simulation. Otherwise, just show as previous.
+ if (bStopSimulation)
+ {
+ BlastSceneTree* pBlastSceneTree = BlastSceneTree::ins();
+ pBlastSceneTree->hideAllChunks();
+ std::vector<uint32_t> depths(1, 0);
+ pBlastSceneTree->setChunkVisible(depths, true);
+ // refresh display in scene tree
+ //pBlastSceneTree->updateValues(false);
+ SampleManager::ins()->m_bNeedRefreshTree = true;
+ }
+ updateValues();
}
void BlastToolbar::on_btnSimulatePlay_clicked()
@@ -480,7 +867,26 @@ void BlastToolbar::on_btnSimulatePlay_clicked()
qDebug("%s", __FUNCTION__);
SampleManager* pSampleManager = SampleManager::ins();
- pSampleManager->setBlastToolType(BTT_Damage);
+ if (!pSampleManager->IsSimulating())
+ {
+ // force to recreate BlastFamilyModelSimple from project data
+ pSampleManager->resetScene();
+ pSampleManager->EnableSimulating(true);
+ // set right damage mode
+ DamageToolController& damageToolController = pSampleManager->getDamageToolController();
+ bool bChecked = damageToolController.IsEnabled() && damageToolController.IsEnabled() && damageToolController.isDamageMode();
+ if (damageToolController.isDamageMode() && !bChecked)
+ {
+ on_btnDamage_clicked();
+ }
+ }
+ else
+ {
+ // pause it or continue
+ PhysXController& physx = pSampleManager->getPhysXController();
+ bool bState = physx.isPaused();
+ physx.setPaused(!bState);
+ }
}
void BlastToolbar::on_btnFrameStepForward_clicked()
@@ -488,35 +894,141 @@ void BlastToolbar::on_btnFrameStepForward_clicked()
qDebug("%s", __FUNCTION__);
SampleManager* pSampleManager = SampleManager::ins();
- pSampleManager->setBlastToolType(BTT_Damage);
- PhysXController& physXController = pSampleManager->getPhysXController();
- physXController.m_bForce = true;
+ if (!pSampleManager->IsSimulating())
+ {
+ // force to recreate BlastFamilyModelSimple from project data
+ pSampleManager->resetScene();
+ // set right damage mode
+ DamageToolController& damageToolController = pSampleManager->getDamageToolController();
+ bool bChecked = damageToolController.IsEnabled() && damageToolController.IsEnabled() && damageToolController.isDamageMode();
+ if (damageToolController.isDamageMode() && !bChecked)
+ {
+ on_btnDamage_clicked();
+ }
+ }
+ pSampleManager->EnableSimulating(true);
+ pSampleManager->EnableStepforward(true);
}
-void BlastToolbar::on_btnBomb_clicked()
+void BlastToolbar::on_btnDamage_clicked()
{
qDebug("%s", __FUNCTION__);
- // debug codes: test RepX exporting. to-do, remove me later, e.g. when implementing bomb.
SampleManager* pSampleManager = SampleManager::ins();
- PhysXController& physXController = pSampleManager->getPhysXController();
- PxPhysics& physics = physXController.getPhysics();
- PxScene& scene = physXController.getPhysXScene();
- physXController.ExportCollisionRepX("d:\\t1.RepX", &physics, &scene, false);
- // debug codes: test RepX exporting. to-do, remove me later
+ DamageToolController& damageToolController = pSampleManager->getDamageToolController();
+ if (damageToolController.IsEnabled())
+ {
+ damageToolController.DisableController();
+ damageToolController.setDamageMode(false);
+ btnDamage->setChecked(false);
+ }
+ else
+ {
+ damageToolController.EnableController();
+ damageToolController.setDamageMode(true);
+ btnDamage->setChecked(true);
+ }
+// pSampleManager->getDamageToolController().setDamageMode(!pSampleManager->getDamageToolController().isDamageMode());
}
void BlastToolbar::on_btnProjectile_clicked()
{
qDebug("%s", __FUNCTION__);
- SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager();
- SceneController& sceneController = sampleManager.getSceneController();
- sceneController.addProjectile();
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager->IsSimulating())
+ {
+ SceneController& sceneController = pSampleManager->getSceneController();
+ sceneController.addProjectile();
+ }
+ else
+ {
+ viewer_msg("Please use it when simulation runs.");
+ }
}
void BlastToolbar::on_btnDropObject_clicked()
{
qDebug("%s", __FUNCTION__);
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager->IsSimulating())
+ {
+ on_btnReset_clicked();
+ // if not use timer, it could go to strange paused state.
+ gDropTimer.start(10);
+ return;
+ }
+ gDropTimer.stop();
+ BlastAssetInstancesNode* assetInstancesNode = BlastTreeData::ins().getBlastAssetInstancesNode();
+ if (assetInstancesNode != nullptr)
+ {
+ physx::PxVec3 size = pSampleManager->getAssetExtent();
+ float fChange = size.magnitude();
+ size_t count = assetInstancesNode->children.size();
+ // find the min height first
+ float minHeight = NV_MAX_F32;
+ for (size_t i = 0; i < count; ++i)
+ {
+ BlastAssetInstanceNode* assetInstanceNode = (BlastAssetInstanceNode*)assetInstancesNode->children[i];
+ BPPAssetInstance* bppInstance = (BPPAssetInstance*)assetInstanceNode->getData();
+ if (bppInstance)
+ {
+ BlastFamily* family = SampleManager::ins()->getFamilyByInstance(bppInstance);
+ if (family)
+ {
+ physx::PxTransform t = family->getSettings().transform;
+ if(t.p.y < minHeight)
+ minHeight = t.p.y;
+ }
+ }
+ }
+ // make fChange
+ while ((minHeight + fChange) < 0.0f)
+ {
+ fChange += fChange;
+ }
+ // change position
+ for (size_t i = 0; i < count; ++i)
+ {
+ BlastAssetInstanceNode* assetInstanceNode = (BlastAssetInstanceNode*)assetInstancesNode->children[i];
+ BPPAssetInstance* bppInstance = (BPPAssetInstance*)assetInstanceNode->getData();
+ if (bppInstance)
+ {
+ BlastFamily* family = SampleManager::ins()->getFamilyByInstance(bppInstance);
+ if (family)
+ {
+ physx::PxTransform t = family->getSettings().transform;
+ t.p.y += fChange;
+ family->initTransform(t);
+ }
+ }
+ }
+ // have to reset scene to make the new positions used.
+ on_btnReset_clicked();
+ pSampleManager->EnableSimulating(true);
+ // restore original position
+ for (size_t i = 0; i < count; ++i)
+ {
+ BlastAssetInstanceNode* assetInstanceNode = (BlastAssetInstanceNode*)assetInstancesNode->children[i];
+ BPPAssetInstance* bppInstance = (BPPAssetInstance*)assetInstanceNode->getData();
+ if (bppInstance)
+ {
+ BlastFamily* family = SampleManager::ins()->getFamilyByInstance(bppInstance);
+ if (family)
+ {
+ physx::PxTransform t = family->getSettings().transform;
+ t.p.y -= fChange;
+ family->initTransform(t);
+ }
+ }
+ }
+ // set right damage mode
+ DamageToolController& damageToolController = pSampleManager->getDamageToolController();
+ bool bChecked = damageToolController.IsEnabled() && damageToolController.IsEnabled() && damageToolController.isDamageMode();
+ if (damageToolController.isDamageMode() && !bChecked)
+ {
+ on_btnDamage_clicked();
+ }
+ }
}
void BlastToolbar::on_btnPreferences_clicked()
@@ -524,5 +1036,20 @@ void BlastToolbar::on_btnPreferences_clicked()
qDebug("%s", __FUNCTION__);
SampleManager* pSampleManager = SampleManager::ins();
- pSampleManager->saveAsset();
+ BlastAsset* pBlastAsset = pSampleManager->getCurBlastAsset();
+ pSampleManager->saveAsset(pBlastAsset);
+}
+
+void BlastToolbar::updateCheckIconsStates()
+{
+ SampleManager* pSampleManager = SampleManager::ins();
+ SelectionToolController& selectionToolController = pSampleManager->getSelectionToolController();
+ btnSelectTool->setChecked(selectionToolController.IsEnabled());
+
+ GizmoToolController& gizmoToolController = pSampleManager->getGizmoToolController();
+ bool bGizmo = gizmoToolController.IsEnabled();
+ GizmoToolMode mode = gizmoToolController.getGizmoToolMode();
+ btnTranslate->setChecked(mode == GTM_Translate && bGizmo);
+ btnRotate->setChecked(mode == GTM_Rotation && bGizmo);
+ btnScale->setChecked(mode == GTM_Scale && bGizmo);
} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h b/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h
index f44dcfb..24129e8 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h
@@ -36,6 +36,11 @@ public slots:
void on_rectselect_action();
void on_drawselect_action();
+ bool on_Translate_clicked();
+ bool on_Rotation_clicked();
+ bool on_Scale_clicked();
+ void on_btnGizmoWithLocal_clicked();
+
void on_btnPaintbrush_clicked();
void on_btnFractureTool_clicked();
void on_btnExplodedViewTool_clicked();
@@ -46,12 +51,14 @@ public slots:
void on_btnSimulatePlay_clicked();
void on_btnFrameStepForward_clicked();
- void on_btnBomb_clicked();
+ void on_btnDamage_clicked();
void on_btnProjectile_clicked();
void on_btnDropObject_clicked();
void on_btnPreferences_clicked();
+ void updateCheckIconsStates();
+
private:
QHBoxLayout *hLayout;
QFrame *fSeparate;
@@ -74,9 +81,14 @@ private:
QLabel *lbExactCoverage;
QCheckBox* cbExactCoverage;
- QPushButton *btnSelectTool;
+ QPushButton *btnSelectTool;
+ QPushButton *btnTranslate;
+ QPushButton *btnRotate;
+ QPushButton *btnScale;
+ QPushButton *btnGizmoWithLocal;
+
QPushButton *btnPaintbrush;
- QPushButton *btnFractureTool;
+ QPushButton *btnFractureTool;
QPushButton *btnExplodedViewTool;
QPushButton *btnJointsTool;
QPushButton *btnFuseSelectedChunks;
@@ -85,10 +97,12 @@ private:
QPushButton *btnSimulatePlay;
QPushButton *btnFrameStepForward;
- QPushButton *btnBomb;
+ QPushButton *btnDamage;
QPushButton *btnProjectile;
QPushButton *btnDropObject;
QPushButton *btnPreferences;
+
+ bool m_fullCoverage;
};
#endif // BlastToolbar_h__
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp
index e52dfb2..5d82ce5 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp
@@ -2,12 +2,42 @@
#include "ui_DefaultDamagePanel.h"
#include "ProjectParams.h"
#include "BlastSceneTree.h"
+#include <float.h>
+
+#include "DamageToolController.h"
+
+DefaultDamagePanel* gDefaultDamagePanel = nullptr;
+DefaultDamagePanel* DefaultDamagePanel::ins()
+{
+ return gDefaultDamagePanel;
+}
+
+QComboBox* DefaultDamagePanel::getDamageProfile()
+{
+ return ui->comboBoxDamageProfile;
+}
+
+void DefaultDamagePanel::setUpdateData(bool bUpdateData)
+{
+ _updateData = bUpdateData;
+}
DefaultDamagePanel::DefaultDamagePanel(QWidget *parent) :
QWidget(parent),
- ui(new Ui::DefaultDamagePanel)
+ ui(new Ui::DefaultDamagePanel),
+ _updateData(true)
{
+ gDefaultDamagePanel = this;
+
ui->setupUi(this);
+
+ _updateData = false;
+ ui->spinBoxDamageAmount->setRange(0.0f, DBL_MAX);
+ ui->spinBoxExplosiveImpulse->setRange(0.0f, DBL_MAX);
+ ui->spinBoxDamageRadius->setRange(0.0f, DBL_MAX);
+ ui->spinBoxStressDamageForce->setRange(0.0f, DBL_MAX);
+ ui->checkBoxDamageContinuously->setChecked(false);
+ _updateData = true;
}
DefaultDamagePanel::~DefaultDamagePanel()
@@ -17,23 +47,29 @@ DefaultDamagePanel::~DefaultDamagePanel()
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);
+ _updateData = false;
+ BPPDefaultDamage& damage = BlastProject::ins().getParams().defaultDamage;
+ if (damage.damageStructs.arraySizes[0] > 0)
+ {
+ uint32_t damageProfile = damage.damageProfile;
+ BPPDamageStruct& damageStruct = damage.damageStructs.buf[damageProfile];
+ ui->spinBoxDamageAmount->setValue(damage.damageAmount);
+ ui->spinBoxExplosiveImpulse->setValue(damage.explosiveImpulse);
+ ui->spinBoxStressDamageForce->setValue(damage.stressDamageForce);
+ ui->comboBoxDamageProfile->setCurrentIndex(damageProfile);
+ ui->spinBoxDamageRadius->setValue(damageStruct.damageRadius);
+ ui->checkBoxDamageContinuously->setChecked(damageStruct.continuously);
}
else
{
- ui->spinBoxMinRadius->setValue(0.0f);
- ui->spinBoxMaxRadius->setValue(0.0f);
- ui->checkBoxMaxRadius->setChecked(false);
- ui->comboBoxFallOff->setCurrentIndex(-1);
- ui->spinBoxMaxChunkSpeed->setValue(0.0f);
+ ui->spinBoxDamageAmount->setValue(0);
+ ui->spinBoxExplosiveImpulse->setValue(0);
+ ui->spinBoxDamageRadius->setValue(0);
+ ui->spinBoxStressDamageForce->setValue(0);
+ ui->checkBoxDamageContinuously->setChecked(false);
+ ui->comboBoxDamageProfile->setCurrentIndex(0);
}
+ _updateData = true;
}
void DefaultDamagePanel::dataSelected(std::vector<BlastNode*> selections)
@@ -52,53 +88,74 @@ void DefaultDamagePanel::dataSelected(std::vector<BlastNode*> selections)
updateValues();
}
-void DefaultDamagePanel::on_spinBoxMinRadius_valueChanged(double arg1)
+void DefaultDamagePanel::on_spinBoxDamageAmount_valueChanged(double arg1)
{
- for (size_t i = 0; i < _selectedAssets.size(); ++i)
- {
- BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage;
- damage.minRadius = arg1;
- }
+ if (!_updateData)
+ return;
+
+ BPPDefaultDamage& damage = BlastProject::ins().getParams().defaultDamage;
+ damage.damageAmount = arg1;
+
+ DamageToolController::ins()->setDamageAmount(arg1);
}
-void DefaultDamagePanel::on_spinBoxMaxRadius_valueChanged(double arg1)
+void DefaultDamagePanel::on_spinBoxExplosiveImpulse_valueChanged(double arg1)
{
- for (size_t i = 0; i < _selectedAssets.size(); ++i)
- {
- BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage;
+ if (!_updateData)
+ return;
- damage.maxRadius = arg1;
+ BPPDefaultDamage& damage = BlastProject::ins().getParams().defaultDamage;
+ damage.explosiveImpulse = arg1;
- if (arg1 < damage.minRadius)
- {
- damage.maxRadius = damage.minRadius;
- }
- }
+ DamageToolController::ins()->setExplosiveImpulse(arg1);
}
-void DefaultDamagePanel::on_checkBoxMaxRadius_stateChanged(int arg1)
+void DefaultDamagePanel::on_spinBoxDamageRadius_valueChanged(double arg1)
{
- for (size_t i = 0; i < _selectedAssets.size(); ++i)
- {
- BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage;
- damage.maxRadiusEnable = (arg1 != 0 ? true: false);
- }
+ if (!_updateData)
+ return;
+
+ BPPDefaultDamage& damage = BlastProject::ins().getParams().defaultDamage;
+ uint32_t damageProfile = damage.damageProfile;
+ BPPDamageStruct& damageStruct = damage.damageStructs.buf[damageProfile];
+ damageStruct.damageRadius = arg1;
+
+ DamageToolController::ins()->setRadius(arg1);
}
-void DefaultDamagePanel::on_comboBoxFallOff_currentIndexChanged(int index)
+void DefaultDamagePanel::on_spinBoxStressDamageForce_valueChanged(double arg1)
{
- for (size_t i = 0; i < _selectedAssets.size(); ++i)
- {
- BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage;
- damage.FallOff = index;
- }
+ if (!_updateData)
+ return;
+
+ BPPDefaultDamage& damage = BlastProject::ins().getParams().defaultDamage;
+ damage.stressDamageForce = arg1;
+
+ DamageToolController::ins()->setStressForceFactor(arg1);
}
-void DefaultDamagePanel::on_spinBoxMaxChunkSpeed_valueChanged(double arg1)
+void DefaultDamagePanel::on_comboBoxDamageProfile_currentIndexChanged(int index)
{
- for (size_t i = 0; i < _selectedAssets.size(); ++i)
- {
- BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage;
- damage.maxChunkSpeed = arg1;
- }
+ if (!_updateData)
+ return;
+
+ BPPDefaultDamage& damage = BlastProject::ins().getParams().defaultDamage;
+ damage.damageProfile = index;
+
+ DamageToolController::ins()->setDamagerIndex(index);
+
+ updateValues();
+}
+
+void DefaultDamagePanel::on_checkBoxDamageContinuously_stateChanged(int arg1)
+{
+ if (!_updateData)
+ return;
+
+ BPPDefaultDamage& damage = BlastProject::ins().getParams().defaultDamage;
+ uint32_t damageProfile = damage.damageProfile;
+ BPPDamageStruct& damageStruct = damage.damageStructs.buf[damageProfile];
+ damageStruct.continuously = arg1;
+
+ DamageToolController::ins()->setDamageWhilePressed(arg1);
}
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h b/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h
index bbd4d3e..044311e 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h
@@ -2,6 +2,7 @@
#define DEFAULTDAMAGEPANEL_H
#include <QtWidgets/QWidget>
+#include <QtWidgets/QComboBox>
#include "BlastSceneTree.h"
namespace Ui {
@@ -17,22 +18,29 @@ public:
~DefaultDamagePanel();
void updateValues();
+ static DefaultDamagePanel* ins();
+ QComboBox* getDamageProfile();
+ void setUpdateData(bool bUpdateData);
+
virtual void dataSelected(std::vector<BlastNode*> selections);
private slots:
- void on_spinBoxMinRadius_valueChanged(double arg1);
+ void on_spinBoxDamageAmount_valueChanged(double arg1);
+
+ void on_spinBoxExplosiveImpulse_valueChanged(double arg1);
- void on_spinBoxMaxRadius_valueChanged(double arg1);
+ void on_spinBoxDamageRadius_valueChanged(double arg1);
- void on_checkBoxMaxRadius_stateChanged(int arg1);
+ void on_spinBoxStressDamageForce_valueChanged(double arg1);
- void on_comboBoxFallOff_currentIndexChanged(int index);
+ void on_comboBoxDamageProfile_currentIndexChanged(int index);
- void on_spinBoxMaxChunkSpeed_valueChanged(double arg1);
+ void on_checkBoxDamageContinuously_stateChanged(int arg1);
private:
- Ui::DefaultDamagePanel *ui;
- std::vector<BPPAsset*> _selectedAssets;
+ Ui::DefaultDamagePanel *ui;
+ bool _updateData;
+ std::vector<BPPAsset*> _selectedAssets;
};
#endif // DEFAULTDAMAGEPANEL_H
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp
index 62b294c..235dd23 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp
@@ -6,20 +6,38 @@
#include <QtCore/QFile>
#include <QtCore/QDebug>
#include "GlobalSettings.h"
+#include "SampleManager.h"
+#include "ViewerOutput.h"
+
+FileReferencesPanel* gFileReferencesPanel = nullptr;
+FileReferencesPanel* FileReferencesPanel::ins()
+{
+ return gFileReferencesPanel;
+}
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);
+ ui->lineEditFBX->setText("New.fbx");
+ ui->lineEditObj->setText("New.obj");
+ ui->lineEditCollision->setText("New.repx");
+ ui->lineEditLLAsset->setText("Newll.blast");
+ ui->lineEditTKAsset->setText("Newtk.blast");
+ ui->lineEditBPXA->setText("New.blast");
+ bValid = false;
+ ui->checkBoxFBX->setChecked(false);
+ ui->checkBoxObj->setChecked(false);
+ ui->checkBoxCollision->setChecked(false);
+ ui->checkBoxLLAsset->setChecked(false);
+ ui->checkBoxTKAsset->setChecked(false);
+ ui->checkBoxBPXA->setChecked(false);
+ bValid = true;
+
+ gFileReferencesPanel = this;
updateValues();
}
@@ -39,40 +57,113 @@ void FileReferencesPanel::updateValues()
else
ui->lineEditFBXSourceAsset->setText("");
- GlobalSettings& globalSettings = GlobalSettings::Inst();
- QString projectFileName = globalSettings.m_projectFileName.c_str();
+ ui->lineEditFBX->setText("");
+ ui->lineEditObj->setText("");
+ ui->lineEditCollision->setText("");
+ ui->lineEditLLAsset->setText("");
+ ui->lineEditTKAsset->setText("");
+ ui->lineEditBPXA->setText("");
+ bValid = false;
+ ui->checkBoxFBX->setChecked(false);
+ ui->checkBoxObj->setChecked(false);
+ ui->checkBoxCollision->setChecked(false);
+ ui->checkBoxLLAsset->setChecked(false);
+ ui->checkBoxTKAsset->setChecked(false);
+ ui->checkBoxBPXA->setChecked(false);
+ bValid = true;
- if (projectFileName.isEmpty())
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager == nullptr)
{
- ui->lineEditFBX->setText("New.fbx");
- ui->lineEditBlast->setText("New.Blast");
- ui->lineEditCollision->setText("New.repx");
+ return;
}
+
+ BlastAsset* pBlastAsset = pSampleManager->getCurBlastAsset();
+ if (pBlastAsset == nullptr)
+ {
+ return;
+ }
+
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = AssetDescMap.find(pBlastAsset);
+ if (itADM == AssetDescMap.end())
+ {
+ return;
+ }
+
+ AssetList::ModelAsset modelAsset = itADM->second;
+ if (modelAsset.name.empty())
+ {
+ return;
+ }
+
+ BPPAssetArray& assetArray = projectParams.blast.blastAssets;
+ BPPAsset asset;
+ int aaas = 0;
+ for (; aaas < assetArray.arraySizes[0]; aaas++)
+ {
+ asset = assetArray.buf[aaas];
+ std::string assetname = asset.name;
+ if (assetname == modelAsset.name)
+ break;
+ }
+ if (aaas == assetArray.arraySizes[0])
+ {
+ return;
+ }
+
+ QFileInfo fileInfo(modelAsset.name.c_str());
+
+ if (asset.fbx.buf != nullptr)
+ ui->lineEditFBX->setText(asset.fbx.buf);
+ else
+ {
+ ui->lineEditFBX->setText(fileInfo.baseName() + "_New.fbx");
+ }
+
+ if (asset.obj.buf != nullptr)
+ ui->lineEditObj->setText(asset.obj.buf);
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");
- }
+ ui->lineEditObj->setText(fileInfo.baseName() + "_New.obj");
}
+
+ if (asset.collision.buf != nullptr)
+ ui->lineEditCollision->setText(asset.collision.buf);
+ else
+ {
+ ui->lineEditCollision->setText(fileInfo.baseName() + "_New.repx");
+ }
+
+ if (asset.llasset.buf != nullptr)
+ ui->lineEditLLAsset->setText(asset.llasset.buf);
+ else
+ {
+ ui->lineEditLLAsset->setText(fileInfo.baseName() + "_Newll.blast");
+ }
+
+ if (asset.tkasset.buf != nullptr)
+ ui->lineEditTKAsset->setText(asset.tkasset.buf);
+ else
+ {
+ ui->lineEditTKAsset->setText(fileInfo.baseName() + "_Newtk.blast");
+ }
+
+ if (asset.bpxa.buf != nullptr)
+ ui->lineEditBPXA->setText(asset.bpxa.buf);
+ else
+ {
+ ui->lineEditBPXA->setText(fileInfo.baseName() + "_New.blast");
+ }
+
+ bValid = false;
+ ui->checkBoxFBX->setChecked(asset.exportFBX);
+ ui->checkBoxObj->setChecked(asset.exportOBJ);
+ ui->checkBoxCollision->setChecked(asset.exportCollision);
+ ui->checkBoxLLAsset->setChecked(asset.exportLLAsset);
+ ui->checkBoxTKAsset->setChecked(asset.exportTKAsset);
+ ui->checkBoxBPXA->setChecked(asset.exportBPXA);
+ bValid = true;
}
void FileReferencesPanel::on_btnOpenFile_clicked()
@@ -108,17 +199,310 @@ void FileReferencesPanel::on_btnRemove_clicked()
void FileReferencesPanel::on_checkBoxFBX_stateChanged(int arg1)
{
- _saveFBX = (arg1 == 0 ? false : true);
+ if (!bValid)
+ {
+ return;
+ }
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager == nullptr)
+ {
+ return;
+ }
+
+ BlastAsset* pBlastAsset = pSampleManager->getCurBlastAsset();
+ if (pBlastAsset == nullptr)
+ {
+ return;
+ }
+
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = AssetDescMap.find(pBlastAsset);
+ if (itADM == AssetDescMap.end())
+ {
+ return;
+ }
+
+ AssetList::ModelAsset modelAsset = itADM->second;
+ if (modelAsset.name.empty())
+ {
+ return;
+ }
+
+ BPParams& projectParams = BlastProject::ins().getParams();
+ BPPAssetArray& assetArray = projectParams.blast.blastAssets;
+ int aaas = 0;
+ for (; aaas < assetArray.arraySizes[0]; aaas++)
+ {
+ std::string assetname = assetArray.buf[aaas].name;
+ if (assetname == modelAsset.name)
+ break;
+ }
+ if (aaas == assetArray.arraySizes[0])
+ {
+ return;
+ }
+
+ BPPAsset& asset = assetArray.buf[aaas];
+ asset.exportFBX = ui->checkBoxFBX->isChecked();
}
-void FileReferencesPanel::on_checkBoxBlast_stateChanged(int arg1)
+void FileReferencesPanel::on_checkBoxObj_stateChanged(int arg1)
{
- _saveBlast = (arg1 == 0 ? false : true);
+ if (!bValid)
+ {
+ return;
+ }
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager == nullptr)
+ {
+ return;
+ }
+
+ BlastAsset* pBlastAsset = pSampleManager->getCurBlastAsset();
+ if (pBlastAsset == nullptr)
+ {
+ return;
+ }
+
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = AssetDescMap.find(pBlastAsset);
+ if (itADM == AssetDescMap.end())
+ {
+ return;
+ }
+
+ AssetList::ModelAsset modelAsset = itADM->second;
+ if (modelAsset.name.empty())
+ {
+ return;
+ }
+
+ BPParams& projectParams = BlastProject::ins().getParams();
+ BPPAssetArray& assetArray = projectParams.blast.blastAssets;
+ int aaas = 0;
+ for (; aaas < assetArray.arraySizes[0]; aaas++)
+ {
+ std::string assetname = assetArray.buf[aaas].name;
+ if (assetname == modelAsset.name)
+ break;
+ }
+ if (aaas == assetArray.arraySizes[0])
+ {
+ return;
+ }
+
+ BPPAsset& asset = assetArray.buf[aaas];
+ asset.exportOBJ = ui->checkBoxObj->isChecked();
}
void FileReferencesPanel::on_checkBoxCollision_stateChanged(int arg1)
{
- _saveCollision = (arg1 == 0 ? false : true);
+ if (!bValid)
+ {
+ return;
+ }
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager == nullptr)
+ {
+ return;
+ }
+
+ BlastAsset* pBlastAsset = pSampleManager->getCurBlastAsset();
+ if (pBlastAsset == nullptr)
+ {
+ return;
+ }
+
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = AssetDescMap.find(pBlastAsset);
+ if (itADM == AssetDescMap.end())
+ {
+ return;
+ }
+
+ AssetList::ModelAsset modelAsset = itADM->second;
+ if (modelAsset.name.empty())
+ {
+ return;
+ }
+
+ BPParams& projectParams = BlastProject::ins().getParams();
+ BPPAssetArray& assetArray = projectParams.blast.blastAssets;
+ int aaas = 0;
+ for (; aaas < assetArray.arraySizes[0]; aaas++)
+ {
+ std::string assetname = assetArray.buf[aaas].name;
+ if (assetname == modelAsset.name)
+ break;
+ }
+ if (aaas == assetArray.arraySizes[0])
+ {
+ return;
+ }
+
+ BPPAsset& asset = assetArray.buf[aaas];
+ asset.exportCollision = ui->checkBoxCollision->isChecked();
+}
+
+void FileReferencesPanel::on_checkBoxLLAsset_stateChanged(int arg1)
+{
+ if (!bValid)
+ {
+ return;
+ }
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager == nullptr)
+ {
+ return;
+ }
+
+ BlastAsset* pBlastAsset = pSampleManager->getCurBlastAsset();
+ if (pBlastAsset == nullptr)
+ {
+ return;
+ }
+
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = AssetDescMap.find(pBlastAsset);
+ if (itADM == AssetDescMap.end())
+ {
+ return;
+ }
+
+ AssetList::ModelAsset modelAsset = itADM->second;
+ if (modelAsset.name.empty())
+ {
+ return;
+ }
+
+ BPParams& projectParams = BlastProject::ins().getParams();
+ BPPAssetArray& assetArray = projectParams.blast.blastAssets;
+ int aaas = 0;
+ for (; aaas < assetArray.arraySizes[0]; aaas++)
+ {
+ std::string assetname = assetArray.buf[aaas].name;
+ if (assetname == modelAsset.name)
+ break;
+ }
+ if (aaas == assetArray.arraySizes[0])
+ {
+ return;
+ }
+
+ BPPAsset& asset = assetArray.buf[aaas];
+ asset.exportLLAsset = ui->checkBoxLLAsset->isChecked();
+}
+
+void FileReferencesPanel::on_checkBoxTKAsset_stateChanged(int arg1)
+{
+ if (!bValid)
+ {
+ return;
+ }
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager == nullptr)
+ {
+ return;
+ }
+
+ BlastAsset* pBlastAsset = pSampleManager->getCurBlastAsset();
+ if (pBlastAsset == nullptr)
+ {
+ return;
+ }
+
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = AssetDescMap.find(pBlastAsset);
+ if (itADM == AssetDescMap.end())
+ {
+ return;
+ }
+
+ AssetList::ModelAsset modelAsset = itADM->second;
+ if (modelAsset.name.empty())
+ {
+ return;
+ }
+
+ BPParams& projectParams = BlastProject::ins().getParams();
+ BPPAssetArray& assetArray = projectParams.blast.blastAssets;
+ int aaas = 0;
+ for (; aaas < assetArray.arraySizes[0]; aaas++)
+ {
+ std::string assetname = assetArray.buf[aaas].name;
+ if (assetname == modelAsset.name)
+ break;
+ }
+ if (aaas == assetArray.arraySizes[0])
+ {
+ return;
+ }
+
+ BPPAsset& asset = assetArray.buf[aaas];
+ asset.exportTKAsset = ui->checkBoxTKAsset->isChecked();
+}
+
+void FileReferencesPanel::on_checkBoxBPXA_stateChanged(int arg1)
+{
+ if (!bValid)
+ {
+ return;
+ }
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager == nullptr)
+ {
+ return;
+ }
+
+ BlastAsset* pBlastAsset = pSampleManager->getCurBlastAsset();
+ if (pBlastAsset == nullptr)
+ {
+ return;
+ }
+
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = AssetDescMap.find(pBlastAsset);
+ if (itADM == AssetDescMap.end())
+ {
+ return;
+ }
+
+ AssetList::ModelAsset modelAsset = itADM->second;
+ if (modelAsset.name.empty())
+ {
+ return;
+ }
+
+ BPParams& projectParams = BlastProject::ins().getParams();
+ BPPAssetArray& assetArray = projectParams.blast.blastAssets;
+ int aaas = 0;
+ for (; aaas < assetArray.arraySizes[0]; aaas++)
+ {
+ std::string assetname = assetArray.buf[aaas].name;
+ if (assetname == modelAsset.name)
+ break;
+ }
+ if (aaas == assetArray.arraySizes[0])
+ {
+ return;
+ }
+
+ BPPAsset& asset = assetArray.buf[aaas];
+ asset.exportBPXA = ui->checkBoxBPXA->isChecked();
+
+ if (asset.exportBPXA)
+ {
+ bValid = false;
+ ui->checkBoxObj->setChecked(true);
+ asset.exportOBJ = true;
+ bValid = true;
+ }
}
void FileReferencesPanel::on_btnSave_clicked()
@@ -128,21 +512,63 @@ void FileReferencesPanel::on_btnSave_clicked()
copy(fileReferences.fbxSourceAsset, ui->lineEditFBXSourceAsset->text().toUtf8().data());
- if (_saveFBX)
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (pSampleManager == nullptr)
+ {
+ return;
+ }
+
+ BlastAsset* pBlastAsset = pSampleManager->getCurBlastAsset();
+ if (pBlastAsset == nullptr)
+ {
+ return;
+ }
+
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>::iterator itADM = AssetDescMap.find(pBlastAsset);
+ if (itADM == AssetDescMap.end())
{
- copy(fileReferences.fbx, ui->lineEditFBX->text().toUtf8().data());
- // to do: save fbx file
+ return;
}
- if (_saveBlast)
+ AssetList::ModelAsset modelAsset = itADM->second;
+ if (modelAsset.name.empty())
{
- copy(fileReferences.blast, ui->lineEditBlast->text().toUtf8().data());
- // to do: save blast file
+ return;
}
- if (_saveCollision)
+ BPPAssetArray& assetArray = projectParams.blast.blastAssets;
+ int aaas = 0;
+ for (; aaas < assetArray.arraySizes[0]; aaas++)
+ {
+ std::string assetname = assetArray.buf[aaas].name;
+ if (assetname == modelAsset.name)
+ break;
+ }
+ if (aaas == assetArray.arraySizes[0])
{
- copy(fileReferences.collision, ui->lineEditCollision->text().toUtf8().data());
- // to do: save collision file
+ return;
}
+
+ BPPAsset& asset = assetArray.buf[aaas];
+
+ copy(asset.fbx, ui->lineEditFBX->text().toUtf8().data());
+ asset.exportFBX = ui->checkBoxFBX->isChecked();
+
+ copy(asset.obj, ui->lineEditObj->text().toUtf8().data());
+ asset.exportOBJ = ui->checkBoxObj->isChecked();
+
+ copy(asset.collision, ui->lineEditCollision->text().toUtf8().data());
+ asset.exportCollision = ui->checkBoxCollision->isChecked();
+
+ copy(asset.llasset, ui->lineEditLLAsset->text().toUtf8().data());
+ asset.exportLLAsset = ui->checkBoxLLAsset->isChecked();
+
+ copy(asset.tkasset, ui->lineEditTKAsset->text().toUtf8().data());
+ asset.exportTKAsset = ui->checkBoxTKAsset->isChecked();
+
+ copy(asset.bpxa, ui->lineEditBPXA->text().toUtf8().data());
+ asset.exportBPXA = ui->checkBoxBPXA->isChecked();
+
+ SampleManager::ins()->exportAsset();
}
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h b/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h
index e393f33..71905df 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h
@@ -16,7 +16,9 @@ public:
~FileReferencesPanel();
void updateValues();
-private slots:
+ static FileReferencesPanel* ins();
+
+public slots:
void on_btnOpenFile_clicked();
void on_btnReload_clicked();
@@ -25,17 +27,21 @@ private slots:
void on_checkBoxFBX_stateChanged(int arg1);
- void on_checkBoxBlast_stateChanged(int arg1);
+ void on_checkBoxObj_stateChanged(int arg1);
void on_checkBoxCollision_stateChanged(int arg1);
+
+ void on_checkBoxLLAsset_stateChanged(int arg1);
+
+ void on_checkBoxTKAsset_stateChanged(int arg1);
+
+ void on_checkBoxBPXA_stateChanged(int arg1);
void on_btnSave_clicked();
private:
Ui::FileReferencesPanel *ui;
- bool _saveFBX;
- bool _saveBlast;
- bool _saveCollision;
+ bool bValid;
};
#endif // FILEREFERENCESPANEL_H
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp b/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp
index a537140..daf4397 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp
@@ -1,10 +1,12 @@
#include "FiltersDockWidget.h"
#include "ui_FiltersDockWidget.h"
-#include "ProjectParams.h"
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMessageBox>
#include "SampleManager.h"
+#include "BlastSceneTree.h"
+#include "BlastFamily.h"
+#include "ViewerOutput.h"
const QString LISTITEM_NORMAL_STYLESHEET = ":enabled { background: rgb(68,68,68); }";
@@ -12,7 +14,245 @@ const QString LISTITEM_SELECTED_STYLESHEET = ":enabled { background: rgba(118,18
const QString LISTITEM_BUTTON_STYLESHEET = ":enabled { border: 0px; }";
-class FilterItemWidget;
+class FilterOperation
+{
+public:
+ virtual void execute(BlastNode *node) = 0;
+};
+
+class FilterVisitor : public BlastVisitorBase
+{
+public:
+ FilterVisitor(FilterPreset& filterPreset, FilterOperation& filterOperation)
+ : resultCount(0)
+ , _filterPreset(filterPreset)
+ , _filterOperation(filterOperation)
+
+ {
+
+ }
+
+ virtual void visit(BlastNode *node);
+
+ int resultCount;
+private:
+ bool _canSatisfyFilter(BlastNode *node);
+
+ FilterPreset& _filterPreset;
+ FilterOperation& _filterOperation;
+};
+
+void FilterVisitor::visit(BlastNode *node)
+{
+ if (_canSatisfyFilter(node))
+ {
+ _filterOperation.execute(node);
+ ++resultCount;
+ }
+}
+
+bool FilterVisitor::_canSatisfyFilter(BlastNode *node)
+{
+ EFilterRestriction restrictions = eFilterRestriction_Invalid;
+
+ for (std::vector<EFilterRestriction>::iterator itr = _filterPreset.filters.begin(); itr != _filterPreset.filters.end(); ++itr)
+ {
+ restrictions = (EFilterRestriction)(restrictions | (*itr));
+ }
+
+ bool matchDepth = false, matchItemType = false;
+
+ // jude whether current node can be filtered by depth restrictions
+ if (restrictions & eFilterRestriction_DepthAll)
+ {
+ matchDepth = true;
+ }
+ else
+ {
+ int nodeDepth = BlastTreeData::getDepth(node);
+ int allDepthRestrictions = eFilterRestriction_Depth0 | eFilterRestriction_Depth1 | eFilterRestriction_Depth2 | eFilterRestriction_Depth3 | eFilterRestriction_Depth4 | eFilterRestriction_Depth5;
+
+ if ((restrictions & eFilterRestriction_AllDescendants) && (restrictions & eFilterRestriction_AllParents))
+ {
+ if (restrictions & allDepthRestrictions)
+ {
+ matchDepth = true;
+ }
+ }
+ else if ((restrictions & eFilterRestriction_AllDescendants) && !(restrictions & eFilterRestriction_AllParents))
+ {
+ int expectMinDepthRestirction = 5;
+ if ((restrictions & eFilterRestriction_Depth0))
+ {
+ expectMinDepthRestirction = 0;
+ }
+ else if ((restrictions & eFilterRestriction_Depth1))
+ {
+ expectMinDepthRestirction = 1;
+ }
+ else if ((restrictions & eFilterRestriction_Depth2))
+ {
+ expectMinDepthRestirction = 2;
+ }
+ else if ((restrictions & eFilterRestriction_Depth3))
+ {
+ expectMinDepthRestirction = 3;
+ }
+ else if ((restrictions & eFilterRestriction_Depth4))
+ {
+ expectMinDepthRestirction = 4;
+ }
+ else if ((restrictions & eFilterRestriction_Depth5))
+ {
+ expectMinDepthRestirction = 5;
+ }
+
+ if (expectMinDepthRestirction <= nodeDepth)
+ {
+ matchDepth = true;
+ }
+ }
+ else if (!(restrictions & eFilterRestriction_AllDescendants) && (restrictions & eFilterRestriction_AllParents))
+ {
+ int expectMaxDepthRestirction = 0;
+ if ((restrictions & eFilterRestriction_Depth5))
+ {
+ expectMaxDepthRestirction = 5;
+ }
+ else if ((restrictions & eFilterRestriction_Depth4))
+ {
+ expectMaxDepthRestirction = 4;
+ }
+ else if ((restrictions & eFilterRestriction_Depth3))
+ {
+ expectMaxDepthRestirction = 3;
+ }
+ else if ((restrictions & eFilterRestriction_Depth2))
+ {
+ expectMaxDepthRestirction = 2;
+ }
+ else if ((restrictions & eFilterRestriction_Depth1))
+ {
+ expectMaxDepthRestirction = 1;
+ }
+ else if ((restrictions & eFilterRestriction_Depth0))
+ {
+ expectMaxDepthRestirction = 0;
+ }
+
+ if (nodeDepth <= expectMaxDepthRestirction)
+ {
+ matchDepth = true;
+ }
+ }
+ else if (!(restrictions & eFilterRestriction_AllDescendants) && !(restrictions & eFilterRestriction_AllParents))
+ {
+ EFilterRestriction expectDepthRestriction = (EFilterRestriction)(eFilterRestriction_Depth0 << nodeDepth);
+
+ if (restrictions & expectDepthRestriction)
+ {
+ matchDepth = true;
+ }
+ }
+ }
+
+ // jude whether current node can be filtered by item type restrictions
+ if ((restrictions & eFilterRestriction_ItemTypeAll))
+ {
+ matchItemType = true;
+ }
+ else
+ {
+ EBlastNodeType nodeType = node->getType();
+ if (eChunk == nodeType)
+ {
+ BlastChunkNode* chunkNode = (BlastChunkNode*)node;
+ if (restrictions & eFilterRestriction_Chunk)
+ {
+ matchItemType = true;
+ }
+ else if (restrictions & eFilterRestriction_SupportChunk)
+ {
+ if (chunkNode->isSupport())
+ {
+ matchItemType = true;
+ }
+ }
+ else if (restrictions & eFilterRestriction_StaticSupportChunk)
+ {
+ if (chunkNode->isSupport() && chunkNode->isStatic())
+ {
+ matchItemType = true;
+ }
+ }
+ }
+ else if (eBond == nodeType)
+ {
+ BlastBondNode* bondNode = (BlastBondNode*)node;
+ if (restrictions & eFilterRestriction_Bond)
+ {
+ matchItemType = true;
+ }
+ else if (restrictions & eFilterRestriction_WorldBond)
+ {
+ if (bondNode->isWolrd())
+ {
+ matchItemType = true;
+ }
+ }
+ }
+ }
+
+ if ((restrictions & eFilterRestriction_EqualTo) && (restrictions & eFilterRestriction_NotEquaTo))
+ {
+ return true;
+ }
+ else if (!(restrictions & eFilterRestriction_EqualTo) && !(restrictions & eFilterRestriction_NotEquaTo)
+ || (restrictions & eFilterRestriction_EqualTo))
+ {
+ if (matchDepth && matchItemType)
+ return true;
+ }
+ else if ((restrictions & eFilterRestriction_NotEquaTo))
+ {
+ if (!(matchDepth && matchItemType))
+ return true;
+ }
+
+ return false;
+}
+
+class FilterSelectOperation : public FilterOperation
+{
+public:
+ virtual void execute(BlastNode *node)
+ {
+ if (nullptr != node)
+ {
+ BlastSceneTree::ins()->selectTreeItem(node);
+ }
+ }
+};
+
+class FilterVisibilityOperation : public FilterOperation
+{
+public:
+ FilterVisibilityOperation(bool visible)
+ : _visible(visible)
+ {
+ }
+
+ virtual void execute(BlastNode *node)
+ {
+ if (nullptr != node)
+ {
+ node->setVisible(_visible);
+ }
+ }
+
+private:
+ bool _visible;
+};
struct FilterItemInfo
{
@@ -27,11 +267,11 @@ public:
QString text;
};
-FilterItemWidget::FilterItemWidget(FiltersDockWidget* parent, QListWidgetItem* item, const QString& filterPreset, int depth)
+FilterItemWidget::FilterItemWidget(FiltersDockWidget* parent, QListWidgetItem* item, const QString& filterPreset, EFilterRestriction restriction)
: QWidget(parent)
, _relatedListWidgetItem(item)
, _filterPreset(filterPreset)
- , _depth(depth)
+ , _restriction(restriction)
{
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
@@ -76,21 +316,32 @@ void FilterItemWidget::onRemoveButtonClicked()
FiltersDockWidget::FiltersDockWidget(QWidget *parent) :
QDockWidget(parent),
ui(new Ui::FiltersDockWidget),
+ _updateData(true),
_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);
+ _restrictionActionMap[eFilterRestriction_AllDescendants] = ui->actionAllDescendants;
+ _restrictionActionMap[eFilterRestriction_AllParents] = ui->actionAllParents;
+ _restrictionActionMap[eFilterRestriction_DepthAll] = ui->actionDepthAll;
+ _restrictionActionMap[eFilterRestriction_Depth0] = ui->actionDepth0;
+ _restrictionActionMap[eFilterRestriction_Depth1] = ui->actionDepth1;
+ _restrictionActionMap[eFilterRestriction_Depth2] = ui->actionDepth2;
+ _restrictionActionMap[eFilterRestriction_Depth3] = ui->actionDepth3;
+ _restrictionActionMap[eFilterRestriction_Depth4] = ui->actionDepth4;
+ _restrictionActionMap[eFilterRestriction_Depth5] = ui->actionDepth5;
+ _restrictionActionMap[eFilterRestriction_ItemTypeAll] = ui->actionItemTypeAll;
+ _restrictionActionMap[eFilterRestriction_Chunk] = ui->actionChunk;
+ _restrictionActionMap[eFilterRestriction_SupportChunk] = ui->actionSupportChunk;
+ _restrictionActionMap[eFilterRestriction_StaticSupportChunk] = ui->actionStaticSupportChunk;
+ _restrictionActionMap[eFilterRestriction_Bond] = ui->actionBond;
+ _restrictionActionMap[eFilterRestriction_WorldBond] = ui->actionWorldBond;
+ _restrictionActionMap[eFilterRestriction_EqualTo] = ui->actionEqualTo;
+ _restrictionActionMap[eFilterRestriction_NotEquaTo] = ui->actionNotEquaTo;
_updateFilterItemList();
- _updateFilterDepthBtns();
}
FiltersDockWidget::~FiltersDockWidget()
@@ -100,18 +351,32 @@ FiltersDockWidget::~FiltersDockWidget()
void FiltersDockWidget::updateValues()
{
- BPParams& projectParams = BlastProject::ins().getParams();
- BPPFilterPresetArray& filterPresetArray = projectParams.filter.filters;
-
+ _updateData = false;
ui->comboBoxFilterPreset->clear();
+ std::vector<FilterPreset>& filterPresets = BlastProject::ins().getFilterPresets();
QStringList filterNames;
- int count = filterPresetArray.arraySizes[0];
+ filterNames.append("Default");
+ int count = (int)filterPresets.size();
for (int i = 0; i < count; ++i)
{
- filterNames.append(filterPresetArray.buf[i].name.buf);
+ filterNames.append(filterPresets[i].name.c_str());
}
ui->comboBoxFilterPreset->addItems(filterNames);
+ BPParams& projectParams = BlastProject::ins().getParams();
+ if (nullptr == projectParams.filter.activeFilter.buf
+ || 0 == strlen(projectParams.filter.activeFilter.buf)
+ || !(BlastProject::ins().isFilterPresetNameExist(projectParams.filter.activeFilter.buf)))
+ {
+ ui->comboBoxFilterPreset->setCurrentIndex(0);
+ }
+ else
+ {
+ ui->comboBoxFilterPreset->setCurrentText(projectParams.filter.activeFilter.buf);
+ }
+
+ _updateFilterItemList();
+
if (count > 0)
{
ui->btnModifyFilterPreset->setEnabled(true);
@@ -122,15 +387,18 @@ void FiltersDockWidget::updateValues()
ui->btnModifyFilterPreset->setEnabled(false);
ui->btnRemoveFilterPreset->setEnabled(false);
}
+ _updateData = true;
}
void FiltersDockWidget::on_comboBoxFilterPreset_currentIndexChanged(int index)
{
+ if (!_updateData)
+ return;
+
BPParams& projectParams = BlastProject::ins().getParams();
- projectParams.filter.activeFilter = index;
+ copy(projectParams.filter.activeFilter, ui->comboBoxFilterPreset->currentText().toUtf8().data());
_updateFilterItemList();
- _updateFilterDepthBtns();
}
void FiltersDockWidget::on_btnAddFilterPrest_clicked()
@@ -161,6 +429,12 @@ void FiltersDockWidget::on_btnAddFilterPrest_clicked()
void FiltersDockWidget::on_btnModifyFilterPreset_clicked()
{
+ if (ui->comboBoxFilterPreset->currentIndex() < 1)
+ {
+ QMessageBox::warning(this, "Blast Tool", "You should select an filter preset!");
+ return;
+ }
+
QByteArray tmp = ui->comboBoxFilterPreset->currentText().toUtf8();
const char* oldName = tmp.data();
@@ -191,87 +465,274 @@ void FiltersDockWidget::on_btnModifyFilterPreset_clicked()
void FiltersDockWidget::on_btnRemoveFilterPreset_clicked()
{
+ if (ui->comboBoxFilterPreset->currentIndex() < 1)
+ {
+ QMessageBox::warning(this, "Blast Tool", "You should select an filter preset!");
+ return;
+ }
+
QByteArray tmp = ui->comboBoxFilterPreset->currentText().toUtf8();
const char* name = tmp.data();
BlastProject::ins().removeFilterPreset(name);
updateValues();
}
-void FiltersDockWidget::on_btnDepth0_clicked(bool val)
+void FiltersDockWidget::on_btnSaveFilterPreset_clicked()
{
- _addRemoveDepthFilter(0, val);
+ BlastProject::ins().saveFilterPreset();
}
-void FiltersDockWidget::on_btnDepth1_clicked(bool val)
+void FiltersDockWidget::on_actionAllDescendants_triggered(bool checked)
{
- _addRemoveDepthFilter(1, val);
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_AllDescendants, checked);
}
-void FiltersDockWidget::on_btnDepth2_clicked(bool val)
+void FiltersDockWidget::on_actionAllParents_triggered(bool checked)
{
- _addRemoveDepthFilter(2, val);
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_AllParents, checked);
}
-void FiltersDockWidget::on_btnDepth3_clicked(bool val)
+void FiltersDockWidget::on_actionDepthAll_triggered(bool checked)
{
- _addRemoveDepthFilter(3, val);
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_DepthAll, checked);
}
-void FiltersDockWidget::on_btnDepth4_clicked(bool val)
+void FiltersDockWidget::on_actionDepth0_triggered(bool checked)
{
- _addRemoveDepthFilter(4, val);
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_Depth0, checked);
}
-void FiltersDockWidget::on_btnDepth5_clicked(bool val)
+void FiltersDockWidget::on_actionDepth1_triggered(bool checked)
{
- _addRemoveDepthFilter(5, val);
+ _addRemoveRestriction(eFilterRestriction_Depth1, checked);
}
-void FiltersDockWidget::on_btnAddDepthFilter_clicked()
+void FiltersDockWidget::on_actionDepth2_triggered(bool checked)
{
+ if (!_updateData)
+ return;
+ _addRemoveRestriction(eFilterRestriction_Depth2, checked);
}
-void FiltersDockWidget::on_btnAddFilter_clicked()
+void FiltersDockWidget::on_actionDepth3_triggered(bool checked)
{
+ if (!_updateData)
+ return;
+ _addRemoveRestriction(eFilterRestriction_Depth3, checked);
+}
+
+void FiltersDockWidget::on_actionDepth4_triggered(bool checked)
+{
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_Depth4, checked);
+}
+
+void FiltersDockWidget::on_actionDepth5_triggered(bool checked)
+{
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_Depth5, checked);
+}
+
+void FiltersDockWidget::on_actionItemTypeAll_triggered(bool checked)
+{
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_ItemTypeAll, checked);
+}
+
+void FiltersDockWidget::on_actionChunk_triggered(bool checked)
+{
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_Chunk, checked);
+}
+
+void FiltersDockWidget::on_actionSupportChunk_triggered(bool checked)
+{
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_SupportChunk, checked);
+}
+
+void FiltersDockWidget::on_actionStaticSupportChunk_triggered(bool checked)
+{
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_StaticSupportChunk, checked);
+}
+
+void FiltersDockWidget::on_actionBond_triggered(bool checked)
+{
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_Bond, checked);
+}
+
+void FiltersDockWidget::on_actionWorldBond_triggered(bool checked)
+{
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_WorldBond, checked);
+}
+
+void FiltersDockWidget::on_actionEqualTo_triggered(bool checked)
+{
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_EqualTo, checked);
+}
+
+void FiltersDockWidget::on_actionNotEquaTo_triggered(bool checked)
+{
+ if (!_updateData)
+ return;
+
+ _addRemoveRestriction(eFilterRestriction_NotEquaTo, checked);
}
void FiltersDockWidget::on_btnSelect_clicked()
{
- std::vector<uint32_t> depths;
- int row = ui->listWidget->currentRow();
- if (-1 != row)
+ FilterPreset filterPreset("Default");
+ FilterPreset* filterPresetPtr = BlastProject::ins().getFilterPreset(ui->comboBoxFilterPreset->currentText().toUtf8().data());
+ if (nullptr == filterPresetPtr)
+ {
+ BPPFilter& bppFilter = BlastProject::ins().getParams().filter;
+ for (int i = 0; i < bppFilter.filterRestrictions.arraySizes[0]; ++i)
+ {
+ filterPreset.filters.push_back(convertStringToFilterRestriction(bppFilter.filterRestrictions.buf[i]));
+ }
+ }
+ else
{
- depths.push_back(_filterItemWidgets[row]->_depth);
+ filterPreset = *filterPresetPtr;
}
- SampleManager::ins()->setChunkSelected(depths, true);
+
+ // clear old selection
+ BlastSceneTree::ins()->updateValues(false);
+
+ FilterSelectOperation operation;
+ FilterVisitor visitor(filterPreset, operation);
+ BlastTreeData::ins().traverse(visitor);
+
+ if (0 == visitor.resultCount)
+ {
+ viewer_msg("No items statify current filters");
+ }
+ //BlastSceneTree::ins()->updateValues(false);
+
+ //std::vector<uint32_t> depths;
+ //for (FilterItemWidget* itemWidget : _filterItemWidgets)
+ //{
+ // depths.push_back(itemWidget->_restriction);
+ //}
+ ////SampleManager::ins()->setChunkSelected(depths, true);
+ //BlastSceneTree::ins()->setChunkSelected(depths, true);
}
void FiltersDockWidget::on_btnVisible_clicked()
{
- std::vector<uint32_t> depths;
- int row = ui->listWidget->currentRow();
- if (-1 != row)
+ FilterPreset filterPreset("Default");
+ FilterPreset* filterPresetPtr = BlastProject::ins().getFilterPreset(ui->comboBoxFilterPreset->currentText().toUtf8().data());
+ if (nullptr == filterPresetPtr)
+ {
+ BPPFilter& bppFilter = BlastProject::ins().getParams().filter;
+ for (int i = 0; i < bppFilter.filterRestrictions.arraySizes[0]; ++i)
+ {
+ filterPreset.filters.push_back(convertStringToFilterRestriction(bppFilter.filterRestrictions.buf[i]));
+ }
+ }
+ else
+ {
+ filterPreset = *filterPresetPtr;
+ }
+
+ FilterVisibilityOperation operation(true);
+ FilterVisitor visitor(filterPreset, operation);
+ BlastTreeData::ins().traverse(visitor);
+ BlastSceneTree::ins()->updateValues(false);
+ if (0 == visitor.resultCount)
{
- depths.push_back(_filterItemWidgets[row]->_depth);
+ viewer_msg("No items statify current filters");
}
- SampleManager::ins()->setChunkVisible(depths, true);
+ //std::vector<uint32_t> depths;
+ //for (FilterItemWidget* itemWidget : _filterItemWidgets)
+ //{
+ // depths.push_back(itemWidget->_restriction);
+ //}
+ ////SampleManager::ins()->setChunkVisible(depths, true);
+ //BlastSceneTree::ins()->setChunkVisible(depths, true);
+ //// refresh display in scene tree
+ //BlastSceneTree* pBlastSceneTree = BlastSceneTree::ins();
+ //pBlastSceneTree->updateValues(false);
}
void FiltersDockWidget::on_btnInVisible_clicked()
{
- std::vector<uint32_t> depths;
- int row = ui->listWidget->currentRow();
- if (-1 != row)
+ FilterPreset filterPreset("Default");
+ FilterPreset* filterPresetPtr = BlastProject::ins().getFilterPreset(ui->comboBoxFilterPreset->currentText().toUtf8().data());
+ if (nullptr == filterPresetPtr)
+ {
+ BPPFilter& bppFilter = BlastProject::ins().getParams().filter;
+ for (int i = 0; i < bppFilter.filterRestrictions.arraySizes[0]; ++i)
+ {
+ filterPreset.filters.push_back(convertStringToFilterRestriction(bppFilter.filterRestrictions.buf[i]));
+ }
+ }
+ else
{
- depths.push_back(_filterItemWidgets[row]->_depth);
+ filterPreset = *filterPresetPtr;
}
- SampleManager::ins()->setChunkVisible(depths, false);
+
+ FilterVisibilityOperation operation(false);
+ FilterVisitor visitor(filterPreset, operation);
+ BlastTreeData::ins().traverse(visitor);
+ BlastSceneTree::ins()->updateValues(false);
+ if (0 == visitor.resultCount)
+ {
+ viewer_msg("No items statify current filters");
+ }
+ //std::vector<uint32_t> depths;
+ //for (FilterItemWidget* itemWidget : _filterItemWidgets)
+ //{
+ // depths.push_back(itemWidget->_restriction);
+ //}
+ ////SampleManager::ins()->setChunkVisible(depths, false);
+ //BlastSceneTree::ins()->setChunkVisible(depths, false);
+ //// refresh display in scene tree
+ //BlastSceneTree* pBlastSceneTree = BlastSceneTree::ins();
+ //pBlastSceneTree->updateValues(false);
}
void FiltersDockWidget::on_listWidget_currentRowChanged(int index)
{
+ if (!_updateData)
+ return;
+
if (-1 != _lastSelectRow && _lastSelectRow < _filterItemWidgets.size())
static_cast<FilterItemWidget*>(_filterItemWidgets[_lastSelectRow])->deSelect();
@@ -292,10 +753,14 @@ void FiltersDockWidget::onListWidgetRemoveBtnClicked(QListWidgetItem* item)
_filterItemWidgets.erase(std::find(_filterItemWidgets.begin(), _filterItemWidgets.end(), toRemoveItem->second->itemWidget));
- if (ui->comboBoxFilterPreset->currentIndex() != -1)
+ if (0 < ui->comboBoxFilterPreset->currentIndex())
{
QByteArray filterPreset = itemWidget->_filterPreset.toUtf8();
- BlastProject::ins().removeFilterDepth(filterPreset.data(), itemWidget->_depth);
+ BlastProject::ins().removeFilterRestriction(filterPreset.data(), itemWidget->_restriction);
+ }
+ else if (0 == ui->comboBoxFilterPreset->currentIndex())
+ {
+ removeItem(BlastProject::ins().getParams().filter.filterRestrictions, convertFilterRestrictionToString(itemWidget->_restriction));
}
ui->listWidget->takeItem(ui->listWidget->row(item));
@@ -304,13 +769,14 @@ void FiltersDockWidget::onListWidgetRemoveBtnClicked(QListWidgetItem* item)
delete itemWidget;
_filterUIItems.erase(toRemoveItem);
- //_updateFilterItemList();
- _updateFilterDepthBtns();
+ _updateFilterItemList();
+
}
}
void FiltersDockWidget::_updateFilterItemList()
{
+ _updateData = false;
/// remove former ui info
map<QListWidgetItem*, FilterItemInfo*>::iterator theEnd = _filterUIItems.end();
for (map<QListWidgetItem*, FilterItemInfo*>::iterator itr = _filterUIItems.begin(); itr != theEnd; ++itr)
@@ -324,66 +790,88 @@ void FiltersDockWidget::_updateFilterItemList()
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];
+ FilterPreset* filterPreset = BlastProject::ins().getFilterPreset(ui->comboBoxFilterPreset->currentText().toUtf8().data());
- int filterCount = filterPresset.depthFilters.arraySizes[0];
-
- for (int i = 0; i < filterCount; ++i)
+ if (nullptr != filterPreset)
{
- 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);
+ for (EFilterRestriction restriction : filterPreset->filters)
+ {
+ _addFilterListItem(filterPreset->name.c_str(), restriction);
+ }
+ }
+ else
+ {
+ BPParams& projectParams = BlastProject::ins().getParams();
+ BPPStringArray& filterRestrictions = projectParams.filter.filterRestrictions;
- ui->listWidget->addItem(item);
- ui->listWidget->setItemWidget(item, itemWidget);
+ for (int i = 0; i < filterRestrictions.arraySizes[0]; ++i)
+ {
+ _addFilterListItem("Default", convertStringToFilterRestriction(filterRestrictions.buf[i].buf));
+ }
}
+
+ _updateFilterUIs();
+
+ _updateData = true;
}
-void FiltersDockWidget::_updateFilterDepthBtns()
+void FiltersDockWidget::_addFilterListItem(const char* filterPresetName, EFilterRestriction restriction)
{
- for (int i = 0; i <= 5; ++i)
- _depthButtons[i]->setChecked(false);
+ QListWidgetItem* item = new QListWidgetItem(NULL);
+ FilterItemWidget* itemWidget = new FilterItemWidget(this, item, filterPresetName, restriction);
- int filterPresetIndex = ui->comboBoxFilterPreset->currentIndex();
- if (filterPresetIndex < 0)
- return;
+ QString depthFilterLabel = convertFilterRestrictionToString(restriction);
+ _filterUIItems.insert(std::make_pair(item, new FilterItemInfo(itemWidget, depthFilterLabel)));
+ itemWidget->setText(depthFilterLabel);
+ _filterItemWidgets.push_back(itemWidget);
- BPParams& projectParams = BlastProject::ins().getParams();
- BPPFilterPresetArray& filterPresetArray = projectParams.filter.filters;
- BPPFilterPreset& filterPresset = filterPresetArray.buf[filterPresetIndex];
+ ui->listWidget->addItem(item);
+ ui->listWidget->setItemWidget(item, itemWidget);
+}
- int filterCount = filterPresset.depthFilters.arraySizes[0];
+void FiltersDockWidget::_updateFilterUIs()
+{
+ for (map<EFilterRestriction, QAction*>::iterator itr = _restrictionActionMap.begin(); itr != _restrictionActionMap.end(); ++itr)
+ itr->second->setChecked(false);
+
+ FilterPreset* filterPreset = BlastProject::ins().getFilterPreset(ui->comboBoxFilterPreset->currentText().toUtf8().data());
- for (int i = 0; i < filterCount; ++i)
+ if (nullptr != filterPreset)
{
- int depth = filterPresset.depthFilters.buf[i];
+ for (EFilterRestriction restriction : filterPreset->filters)
+ {
+ _restrictionActionMap[restriction]->setChecked(true);
+ }
+ }
+ else
+ {
+ BPPStringArray& filterRestrictions = BlastProject::ins().getParams().filter.filterRestrictions;
- _depthButtons[depth]->setChecked(true);
+ for (int i = 0; i < filterRestrictions.arraySizes[0]; ++i)
+ {
+ _restrictionActionMap[convertStringToFilterRestriction(filterRestrictions.buf[i].buf)]->setChecked(true);
+ }
}
}
-void FiltersDockWidget::_addRemoveDepthFilter(int depth, bool add)
+void FiltersDockWidget::_addRemoveRestriction(EFilterRestriction restriction, bool add)
{
- if (ui->comboBoxFilterPreset->currentIndex() != -1)
+ if (0 < ui->comboBoxFilterPreset->currentIndex())
{
QByteArray filterPreset = ui->comboBoxFilterPreset->currentText().toUtf8();
if (add)
- BlastProject::ins().addFilterDepth(filterPreset.data(), depth);
+ BlastProject::ins().addFilterRestriction(filterPreset.data(), restriction);
else
- BlastProject::ins().removeFilterDepth(filterPreset.data(), depth);
-
- _updateFilterItemList();
+ BlastProject::ins().removeFilterRestriction(filterPreset.data(), restriction);
+ }
+ else if (0 == ui->comboBoxFilterPreset->currentIndex())
+ {
+ BPPFilter& filter = BlastProject::ins().getParams().filter;
+ if (add)
+ addItem(filter.filterRestrictions, convertFilterRestrictionToString(restriction));
+ else
+ removeItem(filter.filterRestrictions, convertFilterRestrictionToString(restriction));
}
+ _updateFilterItemList();
}
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h b/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h
index cf25073..43606dc 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h
@@ -4,6 +4,7 @@
#include <QtWidgets/QDockWidget>
#include <vector>
#include <map>
+#include "ProjectParams.h"
using namespace std;
namespace Ui {
@@ -13,6 +14,7 @@ class FiltersDockWidget;
class QLabel;
class QPushButton;
class QListWidgetItem;
+class QAction;
struct FilterItemInfo;
class FilterItemWidget;
class FiltersDockWidget;
@@ -21,7 +23,7 @@ class FilterItemWidget : public QWidget
{
Q_OBJECT
public:
- FilterItemWidget(FiltersDockWidget* parent, QListWidgetItem* item, const QString& filterPreset, int depth);
+ FilterItemWidget(FiltersDockWidget* parent, QListWidgetItem* item, const QString& filterPreset, EFilterRestriction restriction);
~FilterItemWidget()
{
}
@@ -41,7 +43,7 @@ public:
QPushButton* _removeBtn;
QListWidgetItem* _relatedListWidgetItem;
QString _filterPreset;
- int _depth;
+ EFilterRestriction _restriction;
};
class FiltersDockWidget : public QDockWidget
@@ -54,51 +56,47 @@ public:
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_comboBoxFilterPreset_currentIndexChanged(int index);
+ void on_btnAddFilterPrest_clicked();
+ void on_btnModifyFilterPreset_clicked();
+ void on_btnRemoveFilterPreset_clicked();
+ void on_btnSaveFilterPreset_clicked();
+ void on_actionAllDescendants_triggered(bool checked);
+ void on_actionAllParents_triggered(bool checked);
+ void on_actionDepthAll_triggered(bool checked);
+ void on_actionDepth0_triggered(bool checked);
+ void on_actionDepth1_triggered(bool checked);
+ void on_actionDepth2_triggered(bool checked);
+ void on_actionDepth3_triggered(bool checked);
+ void on_actionDepth4_triggered(bool checked);
+ void on_actionDepth5_triggered(bool checked);
+ void on_actionItemTypeAll_triggered(bool checked);
+ void on_actionChunk_triggered(bool checked);
+ void on_actionSupportChunk_triggered(bool checked);
+ void on_actionStaticSupportChunk_triggered(bool checked);
+ void on_actionBond_triggered(bool checked);
+ void on_actionWorldBond_triggered(bool checked);
+ void on_actionEqualTo_triggered(bool checked);
+ void on_actionNotEquaTo_triggered(bool checked);
+ 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);
+ void _addFilterListItem(const char* filterPresetName, EFilterRestriction restriction);
+ void _updateFilterUIs();
+ void _addRemoveRestriction(EFilterRestriction restriction, bool add);
private:
Ui::FiltersDockWidget *ui;
+ bool _updateData;
map<QListWidgetItem*, FilterItemInfo*> _filterUIItems;
vector<FilterItemWidget*> _filterItemWidgets;
int _lastSelectRow;
- vector<QPushButton*> _depthButtons;
+ map<EFilterRestriction, QAction*> _restrictionActionMap;
};
#endif // FILTERSDOCKWIDGET_H
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.cpp
deleted file mode 100644
index ea24278..0000000
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-#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/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.h b/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.h
deleted file mode 100644
index 7faf2ae..0000000
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#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/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp
index 1f7068d..8a92933 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp
@@ -1,12 +1,42 @@
#include "FractureGeneralPanel.h"
#include "ui_FractureGeneralPanel.h"
#include "ProjectParams.h"
+#include "BlastPlugin.h"
+#include <QtWidgets/QInputDialog>
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QMessageBox>
+#include "FractureVoronoiSettingsPanel.h"
+#include "FractureSliceSettingsPanel.h"
+#include "FractureVisualizersPanel.h"
+#include "ExpandablePanel.h"
+#include "SampleManager.h"
+
+FractureGeneralPanel* pFractureGeneralPanel = nullptr;
+FractureGeneralPanel* FractureGeneralPanel::ins()
+{
+ return pFractureGeneralPanel;
+}
FractureGeneralPanel::FractureGeneralPanel(QWidget *parent) :
QWidget(parent),
- ui(new Ui::FractureGeneralPanel)
+ ui(new Ui::FractureGeneralPanel),
+ _updateData(true),
+ _voronoiPanel(nullptr),
+ _slicePanel(nullptr),
+ _visualizersPanel(nullptr),
+ _fractureVoronoiSettingsExpandlePanel(nullptr),
+ _fractureSliceSettingsExpandlePanel(nullptr)
{
ui->setupUi(this);
+ pFractureGeneralPanel = this;
+ m_bValid = true;
+
+ QStringList types;
+ types << "Voronoi" << "Slice";
+ _updateData = false;
+ ui->comboBoxFractureType->addItems(types);
+ ui->comboBoxFractureType->setCurrentIndex(0);
+ _updateData = true;
}
FractureGeneralPanel::~FractureGeneralPanel()
@@ -16,48 +46,258 @@ FractureGeneralPanel::~FractureGeneralPanel()
void FractureGeneralPanel::updateValues()
{
+ _updateData = false;
+ m_bValid = false;
+ ui->comboBoxApplyMaterial->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->comboBoxApplyMaterial->insertItems(0, materialNames);
+ m_bValid = true;
+
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);
+ std::vector<FracturePreset> presets = BlastProject::ins().getFracturePresets();
+ ui->comboBoxFracturePreset->clear();
+ QStringList presetNames;
+ presetNames.append("Default");
+ int countPresets = (int)presets.size();
+ if (countPresets > 0)
+ {
+ for (int i = 0; i < countPresets; ++i)
+ {
+ presetNames.append(presets[i].name.c_str());
+ }
+ }
+ ui->comboBoxFracturePreset->addItems(presetNames);
+
+ if (nullptr == fractureGeneral.fracturePreset.buf
+ || 0 == strlen(fractureGeneral.fracturePreset.buf)
+ || !(BlastProject::ins().isFracturePresetNameExist(fractureGeneral.fracturePreset.buf)))
+ {
+ ui->comboBoxFracturePreset->setCurrentIndex(0);
+ }
+ else
+ {
+ ui->comboBoxFracturePreset->setCurrentText(fractureGeneral.fracturePreset.buf);
+ }
+ _updateFractureUIs();
ui->comboBoxApplyMaterial->setCurrentIndex(fractureGeneral.applyMaterial);
+
+ bool checked = BlastProject::ins().getParams().fracture.general.autoSelectNewChunks;
+ ui->checkBoxAutoSelectNewChunks->setChecked(checked);
+ _updateData = true;
+}
+
+void FractureGeneralPanel::setFracturePanels(FractureVoronoiSettingsPanel* voronoiPanel, FractureSliceSettingsPanel* slicePanel, FractureVisualizersPanel* visulizersPanel)
+{
+ _voronoiPanel = voronoiPanel;
+ _slicePanel = slicePanel;
+ _visualizersPanel = visulizersPanel;
+}
+
+void FractureGeneralPanel::setFractureExpandablePanels(ExpandablePanel* voronoiPanel, ExpandablePanel* slicePanel)
+{
+ _fractureVoronoiSettingsExpandlePanel = voronoiPanel;
+ _fractureSliceSettingsExpandlePanel = slicePanel;
}
void FractureGeneralPanel::on_comboBoxFracturePreset_currentIndexChanged(int index)
{
+ if (!_updateData)
+ return;
+
BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general;
- fractureGeneral.fracturePreset = index;
+ copy(fractureGeneral.fracturePreset, ui->comboBoxFracturePreset->currentText().toStdString().c_str());
+ _updateFractureUIs();
}
-void FractureGeneralPanel::on_comboBoxFractureType_currentIndexChanged(int index)
+
+void FractureGeneralPanel::on_btnAddPreset_clicked()
{
- BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general;
- fractureGeneral.fractureType = index;
+ bool ok = false;
+ QString name = QInputDialog::getText(this,
+ tr("Blast Tool"),
+ tr("Please input name for new fracture preset:"),
+ QLineEdit::Normal,
+ "",
+ &ok);
+ bool nameExist = BlastProject::ins().isFracturePresetNameExist(name.toUtf8().data());
+ if (ok && !name.isEmpty() && !nameExist)
+ {
+ BlastProject::ins().addFracturePreset(name.toUtf8().data(), (FractureType)ui->comboBoxFractureType->currentIndex());
+ updateValues();
+ ui->comboBoxFracturePreset->setCurrentIndex(ui->comboBoxFracturePreset->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 FractureGeneralPanel::on_checkBoxAddDepth_stateChanged(int arg1)
+void FractureGeneralPanel::on_btnModifyPreset_clicked()
{
- BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general;
- fractureGeneral.addDepth = (arg1 != 0 ? true : false);
+ if (ui->comboBoxFracturePreset->currentIndex() < 1)
+ {
+ QMessageBox::warning(this, "Blast Tool", "You should select an fracture preset!");
+ return;
+ }
+
+ QByteArray tmp = ui->comboBoxFracturePreset->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 fracture preset:"),
+ QLineEdit::Normal,
+ oldName,
+ &ok);
+ bool nameExist = BlastProject::ins().isUserPresetNameExist(newName.toUtf8().data());
+ if (ok && !newName.isEmpty() && !nameExist)
+ {
+ int curIndex = ui->comboBoxFracturePreset->currentIndex() - 1;
+ if(curIndex >= 0)
+ {
+ std::vector<FracturePreset>& presets = BlastProject::ins().getFracturePresets();
+ presets[curIndex].name = newName.toUtf8().data();
+ updateValues();
+ ui->comboBoxFracturePreset->setCurrentIndex(curIndex + 1);
+ }
+ }
+ 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 preset!");
+ }
}
-void FractureGeneralPanel::on_checkBoxPerChunk_stateChanged(int arg1)
+void FractureGeneralPanel::on_btnSavePreset_clicked()
{
- BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general;
- fractureGeneral.perChunk = (arg1 != 0 ? true : false);
+ BlastProject::ins().saveFracturePreset();
}
-void FractureGeneralPanel::on_checkBoxNewMatID_stateChanged(int arg1)
+void FractureGeneralPanel::on_comboBoxFractureType_currentIndexChanged(int index)
{
+ if (!_updateData)
+ return;
+
BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general;
- fractureGeneral.newMatID = (arg1 != 0 ? true:false);
+ fractureGeneral.fractureType = index;
+
+ FracturePreset* fracturePreset = getCurrentFracturePreset();
+ if (fracturePreset != nullptr)
+ {
+ fracturePreset->setType((FractureType)index);
+ }
+ _showFracturePanel(ui->comboBoxFractureType->currentText());
}
void FractureGeneralPanel::on_comboBoxApplyMaterial_currentIndexChanged(int index)
{
+ if (!m_bValid)
+ return;
+
+ if (!_updateData)
+ return;
+
BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general;
fractureGeneral.applyMaterial = index;
}
+
+void FractureGeneralPanel::on_checkBoxAutoSelectNewChunks_stateChanged(int arg1)
+{
+ BlastProject::ins().getParams().fracture.general.autoSelectNewChunks = arg1;
+}
+
+FracturePreset* FractureGeneralPanel::getCurrentFracturePreset()
+{
+ int currentPreset = ui->comboBoxFracturePreset->currentIndex();
+
+ if (0 < currentPreset)
+ {
+ std::vector<FracturePreset>& presets = BlastProject::ins().getFracturePresets();
+ if (presets.size() > 0)
+ {
+ return &(presets[currentPreset - 1]);
+ }
+ }
+
+ return nullptr;
+}
+
+FracturePreset* FractureGeneralPanel::_getFracturePreset(const char* name)
+{
+ std::vector<FracturePreset>& presets = BlastProject::ins().getFracturePresets();
+
+ for (size_t i = 0; i < presets.size(); ++i)
+ {
+ if (presets[i].name == name)
+ return &(presets[i]);
+ }
+
+ return nullptr;
+}
+
+void FractureGeneralPanel::_updateFractureUIs()
+{
+ _updateData = false;
+
+ FracturePreset* fracturePreset = getCurrentFracturePreset();
+ if (fracturePreset != nullptr)
+ {
+ if (eFractureType_Voronoi == fracturePreset->type)
+ {
+ ui->comboBoxFractureType->setCurrentIndex(0);
+ }
+ else if (eFractureType_Slice == fracturePreset->type)
+ {
+ ui->comboBoxFractureType->setCurrentIndex(1);
+ }
+ }
+ else
+ {
+ BPPFracture& fracture = BlastProject::ins().getParams().fracture;
+ ui->comboBoxFractureType->setCurrentIndex(fracture.general.fractureType);
+ }
+
+ _showFracturePanel(ui->comboBoxFractureType->currentText());
+ _visualizersPanel->updateValues();
+ _updateData = true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void FractureGeneralPanel::_showFracturePanel(const QString& fractireType)
+{
+ _fractureVoronoiSettingsExpandlePanel->hide();
+ _fractureSliceSettingsExpandlePanel->hide();
+ QString fractireTypeLower = fractireType.toLower();
+ if (fractireTypeLower == "voronoi")
+ {
+ _voronoiPanel->updateValues();
+ _fractureVoronoiSettingsExpandlePanel->show();
+ }
+ else if (fractireTypeLower == "slice")
+ {
+ _slicePanel->updateValues();
+ _fractureSliceSettingsExpandlePanel->show();
+ }
+}
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h b/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h
index 4b51f5e..1ab9f24 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h
@@ -2,35 +2,61 @@
#define FRACTUREGENERALPANEL_H
#include <QtWidgets/QWidget>
+#include "ProjectParams.h"
namespace Ui {
class FractureGeneralPanel;
}
+class FractureVoronoiSettingsPanel;
+class FractureSliceSettingsPanel;
+class FractureVisualizersPanel;
+class ExpandablePanel;
+
class FractureGeneralPanel : public QWidget
{
Q_OBJECT
public:
+ static FractureGeneralPanel* ins();
+
explicit FractureGeneralPanel(QWidget *parent = 0);
~FractureGeneralPanel();
void updateValues();
+ void setFracturePanels(FractureVoronoiSettingsPanel* voronoiPanel, FractureSliceSettingsPanel* slicePanel, FractureVisualizersPanel* visulizersPanel);
+ void setFractureExpandablePanels(ExpandablePanel* voronoiPanel, ExpandablePanel* slicePanel);
+
+ FracturePreset* getCurrentFracturePreset();
private slots:
void on_comboBoxFracturePreset_currentIndexChanged(int index);
- void on_comboBoxFractureType_currentIndexChanged(int index);
+ void on_btnAddPreset_clicked();
- void on_checkBoxAddDepth_stateChanged(int arg1);
+ void on_btnModifyPreset_clicked();
- void on_checkBoxPerChunk_stateChanged(int arg1);
+ void on_btnSavePreset_clicked();
- void on_checkBoxNewMatID_stateChanged(int arg1);
+ void on_comboBoxFractureType_currentIndexChanged(int index);
void on_comboBoxApplyMaterial_currentIndexChanged(int index);
+
+ void on_checkBoxAutoSelectNewChunks_stateChanged(int arg1);
+
+private:
+ FracturePreset* _getFracturePreset(const char* name);
+ void _updateFractureUIs();
+ void _showFracturePanel(const QString& fractireType);
private:
- Ui::FractureGeneralPanel *ui;
+ Ui::FractureGeneralPanel *ui;
+ bool m_bValid;
+ bool _updateData;
+ FractureVoronoiSettingsPanel* _voronoiPanel;
+ FractureSliceSettingsPanel* _slicePanel;
+ FractureVisualizersPanel* _visualizersPanel;
+ ExpandablePanel* _fractureVoronoiSettingsExpandlePanel;
+ ExpandablePanel* _fractureSliceSettingsExpandlePanel;
};
#endif // FRACTUREGENERALPANEL_H
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.cpp
deleted file mode 100644
index c08e3ba..0000000
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#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/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.h b/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.h
deleted file mode 100644
index a664adb..0000000
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#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/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp
index fa82ee2..103c01c 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp
@@ -1,13 +1,16 @@
#include "FractureSliceSettingsPanel.h"
#include "ui_FractureSliceSettingsPanel.h"
-#include "ProjectParams.h"
#include "SimpleScene.h"
#include "SampleManager.h"
#include <QtWidgets/QMessageBox>
+#include "FractureGeneralPanel.h"
+#include "BlastFamily.h"
FractureSliceSettingsPanel::FractureSliceSettingsPanel(QWidget *parent) :
QWidget(parent),
- ui(new Ui::FractureSliceSettingsPanel)
+ ui(new Ui::FractureSliceSettingsPanel),
+ _updateData(true),
+ _generalPanel(nullptr)
{
ui->setupUi(this);
}
@@ -19,87 +22,177 @@ FractureSliceSettingsPanel::~FractureSliceSettingsPanel()
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);
+ _updateData = false;
+ BPPSlice* slice = _getBPPSlice();
+
+ ui->spinBoxNumSlicesX->setValue(slice->numSlicesX);
+ ui->spinBoxNumSlicesY->setValue(slice->numSlicesY);
+ ui->spinBoxNumSlicesZ->setValue(slice->numSlicesZ);
+ ui->spinBoxOffsetVariation->setValue(slice->offsetVariation);
+ ui->spinBoxRotationVariation->setValue(slice->rotationVariation);
+ ui->spinBoxNoiseAmplitude->setValue(slice->noiseAmplitude);
+ ui->spinBoxNoiseFrequency->setValue(slice->noiseFrequency);
+ ui->spinBoxNoiseOctaveNumber->setValue(slice->noiseOctaveNumber);
+ ui->spinBoxNoiseSeed->setValue(slice->noiseSeed);
+ ui->spinBoxSurfaceResolution->setValue(slice->surfaceResolution);
+ _updateData = true;
}
-void FractureSliceSettingsPanel::on_spinBoxNumSlices_valueChanged(int arg1)
+void FractureSliceSettingsPanel::on_spinBoxNumSlicesX_valueChanged(int arg1)
{
- BPPSlice& slice = BlastProject::ins().getParams().fracture.slice;
- slice.numSlices = arg1;
+ if (!_updateData)
+ return;
+
+ BPPSlice* slice = _getBPPSlice();
+ slice->numSlicesX = arg1;
+}
+
+void FractureSliceSettingsPanel::on_spinBoxNumSlicesY_valueChanged(int arg1)
+{
+ if (!_updateData)
+ return;
+
+ BPPSlice* slice = _getBPPSlice();
+ slice->numSlicesY = arg1;
+}
+
+void FractureSliceSettingsPanel::on_spinBoxNumSlicesZ_valueChanged(int arg1)
+{
+ if (!_updateData)
+ return;
+
+ BPPSlice* slice = _getBPPSlice();
+ slice->numSlicesZ = arg1;
}
void FractureSliceSettingsPanel::on_spinBoxOffsetVariation_valueChanged(double arg1)
{
- BPPSlice& slice = BlastProject::ins().getParams().fracture.slice;
- slice.offsetVariation = arg1;
+ if (!_updateData)
+ return;
+
+ BPPSlice* slice = _getBPPSlice();
+ slice->offsetVariation = arg1;
}
void FractureSliceSettingsPanel::on_spinBoxRotationVariation_valueChanged(double arg1)
{
- BPPSlice& slice = BlastProject::ins().getParams().fracture.slice;
- slice.rotationVariation = arg1;
+ if (!_updateData)
+ return;
+
+ BPPSlice* slice = _getBPPSlice();
+ slice->rotationVariation = arg1;
}
void FractureSliceSettingsPanel::on_spinBoxNoiseAmplitude_valueChanged(double arg1)
{
- BPPSlice& slice = BlastProject::ins().getParams().fracture.slice;
- slice.noiseAmplitude = arg1;
+ if (!_updateData)
+ return;
+
+ BPPSlice* slice = _getBPPSlice();
+ slice->noiseAmplitude = arg1;
}
void FractureSliceSettingsPanel::on_spinBoxNoiseFrequency_valueChanged(double arg1)
{
- BPPSlice& slice = BlastProject::ins().getParams().fracture.slice;
- slice.noiseFrequency = arg1;
+ if (!_updateData)
+ return;
+
+ BPPSlice* slice = _getBPPSlice();
+ slice->noiseFrequency = arg1;
+}
+
+void FractureSliceSettingsPanel::on_spinBoxNoiseOctaveNumber_valueChanged(int arg1)
+{
+ if (!_updateData)
+ return;
+
+ BPPSlice* slice = _getBPPSlice();
+ slice->noiseOctaveNumber = arg1;
}
void FractureSliceSettingsPanel::on_spinBoxNoiseSeed_valueChanged(int arg1)
{
- BPPSlice& slice = BlastProject::ins().getParams().fracture.slice;
- slice.noiseSeed = arg1;
+ if (!_updateData)
+ return;
+
+ BPPSlice* slice = _getBPPSlice();
+ slice->noiseSeed = arg1;
+}
+
+void FractureSliceSettingsPanel::on_spinBoxSurfaceResolution_valueChanged(int arg1)
+{
+ if (!_updateData)
+ return;
+
+ BPPSlice* slice = _getBPPSlice();
+ slice->surfaceResolution = arg1;
}
void FractureSliceSettingsPanel::on_btnApplyFracture_clicked()
{
- BPPSlice& slice = BlastProject::ins().getParams().fracture.slice;
+ BPPSlice* slice = _getBPPSlice();
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);
+ executor.setBPPSlice(slice);
+
+ SampleManager* pSampleManager = SampleManager::ins();
+ std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = pSampleManager->getAssetFamiliesMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ BPParams& projectParams = BlastProject::ins().getParams();
+ BPPGraphicsMaterialArray& theArray = projectParams.graphicsMaterials;
+ BPPFractureGeneral& fractureGeneral = projectParams.fracture.general;
+ int32_t nMaterialIndex = fractureGeneral.applyMaterial;
+ std::string materialName = "";
+ RenderMaterial* pRenderMaterial = nullptr;
+ if (nMaterialIndex > 0)
+ {
+ BPPGraphicsMaterial& item = theArray.buf[nMaterialIndex - 1];
+ materialName = item.name.buf;
+ pRenderMaterial = pSampleManager->getRenderMaterial(materialName);
+ }
- 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)
+ for (; itrAssetSelectedChunks != selectedChunks.end(); itrAssetSelectedChunks++)
{
- multiplyChunksSelected = true;
+ if (itrAssetSelectedChunks->second.size() == 0)
+ {
+ continue;
+ }
+
+ if (pRenderMaterial != nullptr)
+ {
+ BlastAsset* pBlastAsset = itrAssetSelectedChunks->first;
+ std::vector<BlastFamily*> families = AssetFamiliesMap[pBlastAsset];
+ int familySize = families.size();
+ for (int fs = 0; fs < familySize; fs++)
+ {
+ BlastFamily* pBlastFamily = families[fs];
+ pBlastFamily->setMaterial(pRenderMaterial, false);
+
+ AssetList::ModelAsset modelAsset = AssetDescMap[pBlastAsset];
+ int assetID = BlastProject::ins().getAssetIDByName(modelAsset.name.c_str());
+ BPPAssetInstance* instance = BlastProject::ins().getAssetInstance(assetID, fs);
+ copy(instance->inMaterial, materialName.c_str());
+ }
+ }
+
+ executor.setSourceAsset(itrAssetSelectedChunks->first);
+ executor.setTargetChunks(itrAssetSelectedChunks->second);
+ executor.execute();
}
- else if (selectedChunks.size() == 1 && itrAssetSelectedChunks->second.size() > 1)
+}
+
+BPPSlice* FractureSliceSettingsPanel::_getBPPSlice()
+{
+ BPPSlice* slice = nullptr;
+ FracturePreset* preset = _generalPanel->getCurrentFracturePreset();
+ if (nullptr != preset)
{
- multiplyChunksSelected = true;
+ slice = &(preset->fracture.slice);
}
- else if((selectedChunks.size() == 1 && itrAssetSelectedChunks->second.size() == 0) || (selectedChunks.size() == 0))
+ else
{
- return;
+ slice = &(BlastProject::ins().getParams().fracture.slice);
}
-
- 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();
+ return slice;
}
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h b/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h
index b85b58f..5b68575 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h
@@ -2,10 +2,12 @@
#define FRACTURESLICESETTINGSPANEL_H
#include <QtWidgets/QWidget>
+#include "ProjectParams.h"
namespace Ui {
class FractureSliceSettingsPanel;
}
+class FractureGeneralPanel;
class FractureSliceSettingsPanel : public QWidget
{
@@ -15,9 +17,12 @@ public:
explicit FractureSliceSettingsPanel(QWidget *parent = 0);
~FractureSliceSettingsPanel();
void updateValues();
+ void setFractureGeneralPanel(FractureGeneralPanel* generalPanel) { _generalPanel = generalPanel; }
private slots:
- void on_spinBoxNumSlices_valueChanged(int arg1);
+ void on_spinBoxNumSlicesX_valueChanged(int arg1);
+ void on_spinBoxNumSlicesY_valueChanged(int arg1);
+ void on_spinBoxNumSlicesZ_valueChanged(int arg1);
void on_spinBoxOffsetVariation_valueChanged(double arg1);
@@ -27,12 +32,21 @@ private slots:
void on_spinBoxNoiseFrequency_valueChanged(double arg1);
+ void on_spinBoxNoiseOctaveNumber_valueChanged(int arg1);
+
void on_spinBoxNoiseSeed_valueChanged(int arg1);
+ void on_spinBoxSurfaceResolution_valueChanged(int arg1);
+
void on_btnApplyFracture_clicked();
private:
- Ui::FractureSliceSettingsPanel *ui;
+ BPPSlice* _getBPPSlice();
+
+private:
+ Ui::FractureSliceSettingsPanel *ui;
+ bool _updateData;
+ FractureGeneralPanel* _generalPanel;
};
#endif // FRACTURESLICESETTINGSPANEL_H
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp
index 0f77e27..52d5431 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp
@@ -1,9 +1,12 @@
#include "FractureVisualizersPanel.h"
#include "ui_FractureVisualizersPanel.h"
#include "ProjectParams.h"
+#include "FractureGeneralPanel.h"
+#include "SampleManager.h"
FractureVisualizersPanel::FractureVisualizersPanel(QWidget *parent) :
- QWidget(parent),
+ QWidget(parent),
+ _updateData(true),
ui(new Ui::FractureVisualizersPanel)
{
ui->setupUi(this);
@@ -16,21 +19,57 @@ FractureVisualizersPanel::~FractureVisualizersPanel()
void FractureVisualizersPanel::updateValues()
{
- BPPFractureVisualization& fractureVisualization = BlastProject::ins().getParams().fracture.visualization;
+ _updateData = false;
+/*
+ BPPFractureVisualization* fractureVisualization = _getBPPVisualization();
- ui->checkBoxFracturePreview->setChecked(fractureVisualization.fracturePreview);
- ui->checkBoxDisplayFractureWidget->setChecked(fractureVisualization.displayFractureWidget);
+ ui->checkBoxFracturePreview->setChecked(fractureVisualization->fracturePreview);
+ ui->checkBoxDisplayFractureWidget->setChecked(fractureVisualization->displayFractureWidget);
+*/
+ bool checked = BlastProject::ins().getParams().fracture.general.selectionDepthTest;
+ ui->checkBoxSelectionDepthTest->setChecked(checked);
+ _updateData = true;
}
-
+/*
void FractureVisualizersPanel::on_checkBoxFracturePreview_stateChanged(int arg1)
{
- BPPFractureVisualization& fractureVisualization = BlastProject::ins().getParams().fracture.visualization;
- fractureVisualization.fracturePreview = (arg1 != 0 ? true : false);
+ if (!_updateData)
+ return;
+
+ BPPFractureVisualization* fractureVisualization = _getBPPVisualization();
+ 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);
+ if (!_updateData)
+ return;
+
+ BPPFractureVisualization* fractureVisualization = _getBPPVisualization();
+ fractureVisualization->displayFractureWidget = (arg1 != 0 ? true : false);
+}
+*/
+void FractureVisualizersPanel::on_checkBoxSelectionDepthTest_stateChanged(int arg1)
+{
+ BlastProject::ins().getParams().fracture.general.selectionDepthTest = arg1;
+ SampleManager* pSampleManager = SampleManager::ins();
+ if (nullptr != pSampleManager)
+ {
+ SampleManager::ins()->ApplySelectionDepthTest();
+ }
}
+BPPFractureVisualization* FractureVisualizersPanel::_getBPPVisualization()
+{
+ BPPFractureVisualization* visualization = nullptr;
+ FracturePreset* preset = _generalPanel->getCurrentFracturePreset();
+ if (nullptr != preset)
+ {
+ visualization = &(preset->visualization);
+ }
+ else
+ {
+ visualization = &(BlastProject::ins().getParams().fracture.visualization);
+ }
+ return visualization;
+}
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h b/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h
index d542d7f..9d944d1 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h
@@ -2,10 +2,12 @@
#define FRACTUREVISUALIZERSPANEL_H
#include <QtWidgets/QWidget>
+#include "ProjectParams.h"
namespace Ui {
class FractureVisualizersPanel;
}
+class FractureGeneralPanel;
class FractureVisualizersPanel : public QWidget
{
@@ -15,14 +17,22 @@ public:
explicit FractureVisualizersPanel(QWidget *parent = 0);
~FractureVisualizersPanel();
void updateValues();
+ void setFractureGeneralPanel(FractureGeneralPanel* generalPanel) { _generalPanel = generalPanel; }
private slots:
+/*
void on_checkBoxFracturePreview_stateChanged(int arg1);
void on_checkBoxDisplayFractureWidget_stateChanged(int arg1);
+*/
+ void on_checkBoxSelectionDepthTest_stateChanged(int arg1);
private:
- Ui::FractureVisualizersPanel *ui;
+ BPPFractureVisualization* _getBPPVisualization();
+private:
+ Ui::FractureVisualizersPanel *ui;
+ bool _updateData;
+ FractureGeneralPanel* _generalPanel;
};
#endif // FRACTUREVISUALIZERSPANEL_H
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp
index 2142f80..7f18b8d 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp
@@ -6,14 +6,16 @@
#include <QtWidgets/QMessageBox>
#include <QtCore/QFileInfo>
#include "AppMainWindow.h"
-#include "ProjectParams.h"
#include "SimpleScene.h"
#include "SampleManager.h"
+#include "FractureGeneralPanel.h"
+#include "BlastFamily.h"
FractureVoronoiSettingsPanel::FractureVoronoiSettingsPanel(QWidget *parent) :
QWidget(parent),
ui(new Ui::FractureVoronoiSettingsPanel),
- _updateData(true)
+ _updateData(true),
+ _generalPanel(nullptr)
{
ui->setupUi(this);
@@ -28,24 +30,16 @@ FractureVoronoiSettingsPanel::~FractureVoronoiSettingsPanel()
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);
+ BPPVoronoi* voronoi = _getBPPVoronoi();
- _updatePaintMaskComboBox();
+ ui->comboBoxSiteGeneration->setCurrentIndex(voronoi->siteGeneration);
+ _showCurrentSiteGenerationUI();
+ ui->spinBoxNumberOfSites->setValue(voronoi->numSites);
- _updateMeshCutterComboBox();
- ui->checkBoxFractureInsideCutter->setChecked(voronoi.fractureInsideCutter);
- ui->checkBoxFractureOutsideCutter->setChecked(voronoi.fractureOutsideCutter);
+ ui->spinBoxNumberOfClusters->setValue(voronoi->numberOfClusters);
+ ui->spinBoxSitesPerCluster->setValue(voronoi->sitesPerCluster);
+ ui->spinBoxClusterRadius->setValue(voronoi->clusterRadius);
- ui->spinBoxTextureSites->setValue(voronoi.numTextureSites);
-
- _updateTextureListWidget();
_updateData = true;
}
@@ -64,291 +58,133 @@ 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;
+ BPPVoronoi* voronoi = _getBPPVoronoi();
+ voronoi->siteGeneration = index;
+ _showCurrentSiteGenerationUI();
}
-void FractureVoronoiSettingsPanel::on_spinBoxFrequency_valueChanged(int arg1)
-{
- BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi;
- voronoi.frequency = arg1;
-}
-
-void FractureVoronoiSettingsPanel::on_comboBoxPaintMasks_currentIndexChanged(int index)
+void FractureVoronoiSettingsPanel::on_spinBoxNumberOfSites_valueChanged(int arg1)
{
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();
- }
+ BPPVoronoi* voronoi = _getBPPVoronoi();
+ voronoi->numSites = arg1;
}
-void FractureVoronoiSettingsPanel::on_comboBoxMeshCutter_currentIndexChanged(int index)
+void FractureVoronoiSettingsPanel::on_spinBoxNumberOfClusters_valueChanged(int arg1)
{
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);
+ BPPVoronoi* voronoi = _getBPPVoronoi();
+ voronoi->numberOfClusters = arg1;
}
-void FractureVoronoiSettingsPanel::on_checkBoxFractureOutsideCutter_stateChanged(int arg1)
+void FractureVoronoiSettingsPanel::on_spinBoxSitesPerCluster_valueChanged(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())
+ if (!_updateData)
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()
-{
-
+ BPPVoronoi* voronoi = _getBPPVoronoi();
+ voronoi->sitesPerCluster = arg1;
}
-void FractureVoronoiSettingsPanel::on_btnTextureMap_clicked()
+void FractureVoronoiSettingsPanel::on_spinBoxClusterRadius_valueChanged(double arg1)
{
+ if (!_updateData)
+ return;
+ BPPVoronoi* voronoi = _getBPPVoronoi();
+ voronoi->clusterRadius = arg1;
}
void FractureVoronoiSettingsPanel::on_btnApplyFracture_clicked()
{
- BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi;
+ BPPVoronoi* voronoi = _getBPPVoronoi();
VoronoiFractureExecutor executor;
- executor.setCellsCount(voronoi.numSites);
+ executor.setBPPVoronoi(voronoi);
- 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)
+ SampleManager* pSampleManager = SampleManager::ins();
+ std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = pSampleManager->getAssetFamiliesMap();
+ std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap();
+ BPParams& projectParams = BlastProject::ins().getParams();
+ BPPGraphicsMaterialArray& theArray = projectParams.graphicsMaterials;
+ BPPFractureGeneral& fractureGeneral = projectParams.fracture.general;
+ int32_t nMaterialIndex = fractureGeneral.applyMaterial;
+ std::string materialName = "";
+ RenderMaterial* pRenderMaterial = nullptr;
+ if (nMaterialIndex > 0)
{
- multiplyChunksSelected = true;
- }
- else if ((selectedChunks.size() == 1 && itrAssetSelectedChunks->second.size() == 0) || (selectedChunks.size() == 0))
- {
- return;
+ BPPGraphicsMaterial& item = theArray.buf[nMaterialIndex - 1];
+ materialName = item.name.buf;
+ pRenderMaterial = pSampleManager->getRenderMaterial(materialName);
}
- if (multiplyChunksSelected)
+ 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++)
{
- QMessageBox::warning(NULL, "Blast Tool", "Now, this tool can only fracture one chunk!");
- return;
- }
+ if (itrAssetSelectedChunks->second.size() == 0)
+ {
+ continue;
+ }
- executor.setSourceAsset(itrAssetSelectedChunks->first);
- executor.setTargetChunk(itrAssetSelectedChunks->second.at(0));
- executor.execute();
-}
+ if (pRenderMaterial != nullptr)
+ {
+ BlastAsset* pBlastAsset = itrAssetSelectedChunks->first;
+ std::vector<BlastFamily*> families = AssetFamiliesMap[pBlastAsset];
+ int familySize = families.size();
+ for (int fs = 0; fs < familySize; fs++)
+ {
+ BlastFamily* pBlastFamily = families[fs];
+ pBlastFamily->setMaterial(pRenderMaterial, false);
-QString FractureVoronoiSettingsPanel::_getTexturePathByName(const QString& name)
-{
- BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi;
- BPPStringArray& textureArray = voronoi.textureSites;
+ AssetList::ModelAsset modelAsset = AssetDescMap[pBlastAsset];
+ int assetID = BlastProject::ins().getAssetIDByName(modelAsset.name.c_str());
+ BPPAssetInstance* instance = BlastProject::ins().getAssetInstance(assetID, fs);
+ copy(instance->inMaterial, materialName.c_str());
+ }
+ }
- 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;
+ executor.setSourceAsset(itrAssetSelectedChunks->first);
+ executor.setTargetChunks(itrAssetSelectedChunks->second);
+ executor.execute();
}
-
- return "";
}
-void FractureVoronoiSettingsPanel::_updatePaintMaskComboBox()
+BPPVoronoi* FractureVoronoiSettingsPanel::_getBPPVoronoi()
{
- BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi;
-
- ui->comboBoxPaintMasks->clear();
- QStringList items;
- for (int i = 0; i < voronoi.paintMasks.arraySizes[0]; ++i)
+ BPPVoronoi* voronoi = nullptr;
+ FracturePreset* preset = _generalPanel->getCurrentFracturePreset();
+ if (nullptr != preset)
{
- items.append(voronoi.paintMasks.buf[i].buf);
+ voronoi = &(preset->fracture.voronoi);
}
- 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)
+ else
{
- items.append(voronoi.meshCutters.buf[i].buf);
+ voronoi = &(BlastProject::ins().getParams().fracture.voronoi);
}
- ui->comboBoxMeshCutter->addItems(items);
- ui->comboBoxMeshCutter->setCurrentIndex(voronoi.activeMeshCutter);
+ return voronoi;
}
-void FractureVoronoiSettingsPanel::_updateTextureListWidget()
+void FractureVoronoiSettingsPanel::_showCurrentSiteGenerationUI()
{
- BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi;
-
- ui->listWidgetTexture->clear();
- QStringList items;
- for (int i = 0; i < voronoi.textureSites.arraySizes[0]; ++i)
+ ui->widgetUniform->hide();
+ ui->widgetClusters->hide();
+ BPPVoronoi* voronoi = _getBPPVoronoi();
+ switch(voronoi->siteGeneration)
{
- QFileInfo fileInfo(voronoi.textureSites.buf[i].buf);
- QByteArray ba = fileInfo.baseName().toLocal8Bit();
- const char* texture = (const char*)(ba);
- items.append(texture);
+ case 0:
+ ui->widgetUniform->show();
+ break;
+ case 1:
+ ui->widgetClusters->show();
+ break;
}
- ui->listWidgetTexture->addItems(items);
}
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h b/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h
index 6a0668d..0f9b252 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h
@@ -2,10 +2,12 @@
#define FRACTUREVORONOISETTINGSPANEL_H
#include <QtWidgets/QWidget>
+#include "ProjectParams.h"
namespace Ui {
class FractureVoronoiSettingsPanel;
}
+class FractureGeneralPanel;
class FractureVoronoiSettingsPanel : public QWidget
{
@@ -15,6 +17,7 @@ public:
explicit FractureVoronoiSettingsPanel(QWidget *parent = 0);
~FractureVoronoiSettingsPanel();
void updateValues();
+ void setFractureGeneralPanel(FractureGeneralPanel* generalPanel) { _generalPanel = generalPanel; }
private slots:
void on_checkBoxGridPreview_stateChanged(int arg1);
@@ -23,57 +26,26 @@ private slots:
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_comboBoxSiteGeneration_currentIndexChanged(int index);
- 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_spinBoxNumberOfSites_valueChanged(int arg1);
- void on_spinBoxTextureSites_valueChanged(int arg1);
+ void on_spinBoxNumberOfClusters_valueChanged(int arg1);
- void on_listWidgetTexture_itemSelectionChanged();
+ void on_spinBoxSitesPerCluster_valueChanged(int arg1);
- void on_btnTextureMap_clicked();
+ void on_spinBoxClusterRadius_valueChanged(double arg1);
void on_btnApplyFracture_clicked();
private:
- QString _getTexturePathByName(const QString& name);
- void _updatePaintMaskComboBox();
- void _updateMeshCutterComboBox();
- void _updateTextureListWidget();
+ BPPVoronoi* _getBPPVoronoi();
+ void _showCurrentSiteGenerationUI();
private:
Ui::FractureVoronoiSettingsPanel *ui;
bool _updateData;
+ FractureGeneralPanel* _generalPanel;
};
#endif // FRACTUREVORONOISETTINGSPANEL_H
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp
index 88915f1..aa6af69 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp
@@ -3,10 +3,12 @@
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMessageBox>
+#include "SampleManager.h"
GeneralPanel::GeneralPanel(QWidget *parent) :
QWidget(parent),
- ui(new Ui::GeneralPanel)
+ ui(new Ui::GeneralPanel),
+ _updateData(true)
{
ui->setupUi(this);
}
@@ -18,48 +20,71 @@ GeneralPanel::~GeneralPanel()
void GeneralPanel::updateValues()
{
- std::vector<StressSolverUserPreset> presets = BlastProject::ins().getUserPresets();
+ _updateData = false;
ui->comboBoxUserPreset->clear();
+ QStringList userPresets;
+ userPresets.append("Default");
+ std::vector<StressSolverUserPreset> presets = BlastProject::ins().getUserPresets();
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);
}
+ ui->comboBoxUserPreset->addItems(userPresets);
- std::vector<BPPAsset*> selectedAssets = BlastProject::ins().getSelectedBlastAssets();
- if (selectedAssets.size() > 0)
+ if (_selectedAssets.size() > 0)
{
- ui->comboBoxUserPreset->setCurrentText(selectedAssets[0]->activePreset.buf);
+ if (nullptr == _selectedAssets[0]->activeUserPreset.buf
+ || 0 == strlen(_selectedAssets[0]->activeUserPreset.buf)
+ || !BlastProject::ins().isUserPresetNameExist(_selectedAssets[0]->activeUserPreset.buf))
+ {
+ ui->comboBoxUserPreset->setCurrentIndex(0);
+ }
+ else
+ {
+ ui->comboBoxUserPreset->setCurrentText(_selectedAssets[0]->activeUserPreset.buf);
+ }
_updateStressSolverUIs();
}
else
{
- ui->comboBoxUserPreset->setCurrentIndex(-1);
+ ui->comboBoxUserPreset->setCurrentIndex(0);
+ }
+ _updateData = true;
+}
+
+void GeneralPanel::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 GeneralPanel::on_comboBoxUserPreset_currentIndexChanged(int index)
{
- std::vector<BPPAsset*> assets = BlastProject::ins().getSelectedBlastAssets();
- for (size_t i = 0; i < assets.size(); ++i)
+ if (!_updateData)
+ return;
+
+ for (size_t i = 0; i < _selectedAssets.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);
- }
+ copy(_selectedAssets[i]->activeUserPreset, tem.data());
}
_updateStressSolverUIs();
+ _updateStressSolverToBlast();
}
void GeneralPanel::on_btnAddUserPreset_clicked()
@@ -90,7 +115,7 @@ void GeneralPanel::on_btnAddUserPreset_clicked()
void GeneralPanel::on_btnModifyUserPreset_clicked()
{
- if (ui->comboBoxUserPreset->currentIndex() == -1)
+ if (ui->comboBoxUserPreset->currentIndex() < 1)
{
QMessageBox::warning(this, "Blast Tool", "You should select an user preset!");
return;
@@ -109,12 +134,14 @@ void GeneralPanel::on_btnModifyUserPreset_clicked()
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);
+ int curIndex = ui->comboBoxUserPreset->currentIndex() - 1;
+ if (curIndex >= 0)
+ {
+ std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets();
+ presets[curIndex].name = newName.toUtf8().data();
+ updateValues();
+ ui->comboBoxUserPreset->setCurrentIndex(curIndex + 1);
+ }
}
else if (ok && nameExist)
{
@@ -122,130 +149,133 @@ void GeneralPanel::on_btnModifyUserPreset_clicked()
}
else if (ok && newName.isEmpty())
{
- QMessageBox::warning(this, "Blast Tool", "You need input a name for the selected graphics material!");
+ QMessageBox::warning(this, "Blast Tool", "You need input a name for the selected preset!");
}
}
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)
+void GeneralPanel::on_spinBoxMaterialHardness_valueChanged(double arg1)
{
- BPPStressSolver* stressSolver = _getCurrentStressSolver();
+ if (!_updateData)
+ return;
+
+ BPPStressSolver* stressSolver = _getCurrentUserPresetStressSolver();
if (stressSolver)
{
- stressSolver->solverMode = index;
+ stressSolver->hardness = arg1;
+ }
+ else
+ {
+ for (BPPAsset* asset : _selectedAssets)
+ {
+ asset->stressSolver.hardness = arg1;
+ }
}
+
+ _updateStressSolverToBlast();
}
void GeneralPanel::on_spinBoxLinearFactor_valueChanged(double arg1)
{
- BPPStressSolver* stressSolver = _getCurrentStressSolver();
+ if (!_updateData)
+ return;
+
+ BPPStressSolver* stressSolver = _getCurrentUserPresetStressSolver();
if (stressSolver)
{
stressSolver->linearFactor = arg1;
}
-
+ else
+ {
+ for (BPPAsset* asset : _selectedAssets)
+ {
+ asset->stressSolver.linearFactor = arg1;
+ }
+ }
+
+ _updateStressSolverToBlast();
}
void GeneralPanel::on_spinBoxAngularFactor_valueChanged(double arg1)
{
- BPPStressSolver* stressSolver = _getCurrentStressSolver();
+ if (!_updateData)
+ return;
+
+ BPPStressSolver* stressSolver = _getCurrentUserPresetStressSolver();
if (stressSolver)
{
stressSolver->angularFactor = arg1;
}
-}
-
-void GeneralPanel::on_spinBoxMeanError_valueChanged(double arg1)
-{
- BPPStressSolver* stressSolver = _getCurrentStressSolver();
-
- if (stressSolver)
+ else
{
- stressSolver->meanError = arg1;
+ for (BPPAsset* asset : _selectedAssets)
+ {
+ asset->stressSolver.angularFactor = arg1;
+ }
}
-}
-void GeneralPanel::on_spinBoxVarianceError_valueChanged(double arg1)
-{
- BPPStressSolver* stressSolver = _getCurrentStressSolver();
-
- if (stressSolver)
- {
- stressSolver->varianceError = arg1;
- }
+ _updateStressSolverToBlast();
}
-void GeneralPanel::on_spinBoxBondsPerFrame_valueChanged(int arg1)
+void GeneralPanel::on_spinBoxBondIterations_valueChanged(int arg1)
{
- BPPStressSolver* stressSolver = _getCurrentStressSolver();
+ if (!_updateData)
+ return;
+
+ BPPStressSolver* stressSolver = _getCurrentUserPresetStressSolver();
if (stressSolver)
{
- stressSolver->bondsPerFrame = arg1;
+ stressSolver->bondIterationsPerFrame = arg1;
}
-}
-
-void GeneralPanel::on_spinBoxBondsIterations_valueChanged(int arg1)
-{
- BPPStressSolver* stressSolver = _getCurrentStressSolver();
-
- if (stressSolver)
+ else
{
- stressSolver->bondsIterations = arg1;
+ for (BPPAsset* asset : _selectedAssets)
+ {
+ asset->stressSolver.bondIterationsPerFrame = arg1;
+ }
}
+
+ _updateStressSolverToBlast();
}
-BPPStressSolver* GeneralPanel::_getCurrentStressSolver()
+void GeneralPanel::on_spinBoxGraphReductionLevel_valueChanged(int arg1)
{
- int currentUserPreset = ui->comboBoxUserPreset->currentIndex();
+ if (!_updateData)
+ return;
- if (-1 != currentUserPreset)
+ BPPStressSolver* stressSolver = _getCurrentUserPresetStressSolver();
+
+ if (stressSolver)
{
- std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets();
- return &(presets[currentUserPreset].stressSolver);
+ stressSolver->graphReductionLevel = arg1;
}
else
{
- std::vector<BPPAsset*> assets = BlastProject::ins().getSelectedBlastAssets();
-
- if (assets.size() > 0)
+ for (BPPAsset* asset : _selectedAssets)
{
- return &(assets[0]->stressSolver);
+ asset->stressSolver.graphReductionLevel = arg1;
}
}
- return nullptr;
+ _updateStressSolverToBlast();
}
-BPPStressSolver* GeneralPanel::_getUserPreset(const char* name)
+BPPStressSolver* GeneralPanel::_getCurrentUserPresetStressSolver()
{
- std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets();
+ int currentUserPreset = ui->comboBoxUserPreset->currentIndex();
- for (size_t i = 0; i < presets.size(); ++i)
+ if (0 < currentUserPreset)
{
- if (presets[i].name == name)
- return &(presets[i].stressSolver);
+ std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets();
+ return &(presets[currentUserPreset - 1].stressSolver);
}
return nullptr;
@@ -253,29 +283,33 @@ BPPStressSolver* GeneralPanel::_getUserPreset(const char* name)
void GeneralPanel::_updateStressSolverUIs()
{
- BPPStressSolver* stressSolver = _getCurrentStressSolver();
- if (stressSolver != nullptr)
+ BPPStressSolver noStressSolver;
+ init(noStressSolver);
+ BPPStressSolver* stressSolver = _getCurrentUserPresetStressSolver();
+ 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);
+ if (0 < _selectedAssets.size())
+ {
+ copy(noStressSolver, _selectedAssets[0]->stressSolver);
+ }
+ stressSolver = &noStressSolver;
}
- else
+
+ _updateData = false;
+ ui->spinBoxMaterialHardness->setValue(stressSolver->hardness);
+ ui->spinBoxLinearFactor->setValue(stressSolver->linearFactor);
+ ui->spinBoxAngularFactor->setValue(stressSolver->angularFactor);
+ ui->spinBoxBondIterations->setValue(stressSolver->bondIterationsPerFrame);
+ ui->spinBoxGraphReductionLevel->setValue(stressSolver->graphReductionLevel);
+ _updateData = true;
+}
+
+void GeneralPanel::_updateStressSolverToBlast()
+{
+ BPPStressSolver* stressSolver = _getCurrentUserPresetStressSolver();
+
+ for (BPPAsset* asset : _selectedAssets)
{
- 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);
+ SampleManager::ins()->updateAssetFamilyStressSolver(asset, nullptr != stressSolver? *stressSolver : asset->stressSolver);
}
-
}
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h b/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h
index a7a52e3..9651185 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h
@@ -3,12 +3,13 @@
#include <QtWidgets/QWidget>
#include "ProjectParams.h"
+#include "BlastSceneTree.h"
namespace Ui {
class GeneralPanel;
}
-class GeneralPanel : public QWidget
+class GeneralPanel : public QWidget, public ISceneObserver
{
Q_OBJECT
@@ -17,6 +18,8 @@ public:
~GeneralPanel();
void updateValues();
+ virtual void dataSelected(std::vector<BlastNode*> selections);
+
private slots:
void on_comboBoxUserPreset_currentIndexChanged(int index);
@@ -26,27 +29,25 @@ private slots:
void on_btnSaveUserPreset_clicked();
- void on_comboBoxSolverMode_currentIndexChanged(int index);
+ void on_spinBoxMaterialHardness_valueChanged(double arg1);
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_spinBoxBondIterations_valueChanged(int arg1);
- void on_spinBoxBondsIterations_valueChanged(int arg1);
+ void on_spinBoxGraphReductionLevel_valueChanged(int arg1);
private:
- BPPStressSolver* _getCurrentStressSolver();
- BPPStressSolver* _getUserPreset(const char* name);
+ BPPStressSolver* _getCurrentUserPresetStressSolver();
void _updateStressSolverUIs();
+ void _updateStressSolverToBlast();
private:
- Ui::GeneralPanel *ui;
+ Ui::GeneralPanel *ui;
+ bool _updateData;
+ std::vector<BPPAsset*> _selectedAssets;
};
#endif // GENERALPANEL_H
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp
index 6095f67..0ecfaf0 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp
@@ -1,9 +1,9 @@
#include "MaterialAssignmentsPanel.h"
#include "ui_MaterialAssignmentsPanel.h"
#include "ProjectParams.h"
-#include "RenderMaterial.h"
#include "SampleManager.h"
#include "MaterialLibraryPanel.h"
+#include <assert.h>
MaterialAssignmentsPanel* pMaterialAssignmentsPanel = nullptr;
MaterialAssignmentsPanel* MaterialAssignmentsPanel::ins()
@@ -37,7 +37,11 @@ void MaterialAssignmentsPanel::getMaterialNameAndPaths(std::vector<std::string>&
{
BPPGraphicsMaterial& item = theArray.buf[i];
std::string name = item.name.buf;
- std::string path = item.diffuseTextureFilePath.buf;
+ std::string path = "";
+ if (item.diffuseTextureFilePath.buf != nullptr)
+ {
+ path = item.diffuseTextureFilePath.buf;
+ }
if (name1 == name)
{
path1 = path;
@@ -52,10 +56,23 @@ void MaterialAssignmentsPanel::getMaterialNameAndPaths(std::vector<std::string>&
}
}
- materialNames.push_back(name1);
- materialNames.push_back(name2);
- materialPaths.push_back(path1);
- materialPaths.push_back(path2);
+ materialNames[0] = name1;
+ materialPaths[0] = path1;
+
+ BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general;
+ int32_t nMaterialIndex = fractureGeneral.applyMaterial;
+ assert(theArray.buf != nullptr);
+ if (nMaterialIndex > 0 && theArray.buf)
+ {
+ BPPGraphicsMaterial& item = theArray.buf[nMaterialIndex - 1];
+ name2 = item.name.buf;
+ if (item.diffuseTextureFilePath.buf)
+ {
+ path2 = item.diffuseTextureFilePath.buf;
+ }
+ }
+ materialNames[1] = name2;
+ materialPaths[1] = path2;
}
MaterialAssignmentsPanel::~MaterialAssignmentsPanel()
@@ -68,8 +85,27 @@ void MaterialAssignmentsPanel::updateValues()
m_bValid = false;
ui->comboBoxMaterialID1->clear();
ui->comboBoxMaterialID2->clear();
+ ui->comboBoxMaterialID1->setEnabled(false);
+ ui->comboBoxMaterialID2->setEnabled(false);
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;
+ }
+
+ ui->comboBoxMaterialID1->setEnabled(true);
+ ui->comboBoxMaterialID2->setEnabled(true);
+
QStringList materialNames;
materialNames.append("None");
BPParams& projectParams = BlastProject::ins().getParams();
@@ -85,35 +121,12 @@ void MaterialAssignmentsPanel::updateValues()
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" };
+ std::string strMaterialNames[] = { "", "" };
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;
- }
- }
+ pSampleManager->getMaterialForCurrentFamily(strMaterialNames[i], ex[i]);
}
m_bValid = false;
@@ -129,33 +142,31 @@ void MaterialAssignmentsPanel::updateValues()
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);
+ //BPPMaterialAssignmentsArray& 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)
@@ -173,24 +184,8 @@ void MaterialAssignmentsPanel::on_comboBoxMaterialID1_currentIndexChanged(int in
{
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);
+ pSampleManager->setMaterialForCurrentFamily(name, true);
return;
assignMaterialToMaterialID(0, index - 1);
@@ -211,24 +206,8 @@ void MaterialAssignmentsPanel::on_comboBoxMaterialID2_currentIndexChanged(int in
{
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);
+ pSampleManager->setMaterialForCurrentFamily(name, false);
return;
assignMaterialToMaterialID(1, index - 1);
@@ -256,10 +235,10 @@ void MaterialAssignmentsPanel::assignMaterialToMaterialID(int materialID, int ma
if (materialIndex >= graphicsMaterialArray.arraySizes[0])
return;
- BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes;
+ //BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes;
- if (_selectedGraphicsMesh > -1 && _selectedGraphicsMesh < graphicsMeshArray.arraySizes[0])
- {
- graphicsMeshArray.buf[_selectedGraphicsMesh].materialAssignments.materialIndexes[materialID] = materialIndex;
- }
+ //if (_selectedGraphicsMesh > -1 && _selectedGraphicsMesh < graphicsMeshArray.arraySizes[0])
+ //{
+ // graphicsMeshArray.buf[_selectedGraphicsMesh].materialAssignments.materialIndexes[materialID] = materialIndex;
+ //}
}
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp
index b9ad5e8..f062ad4 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp
@@ -6,12 +6,10 @@
#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"
+#include "FractureGeneralPanel.h"
+#include "ResourceManager.h"
enum ETextureType
{
eDiffuseTexture,
@@ -45,7 +43,6 @@ void OnTextureButtonClicked(BPPGraphicsMaterial& material, ETextureType t, QPush
else
pButton->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png"));
- SimpleScene::Inst()->SetFurModified(true);
}
void OnTextureReload(BPPGraphicsMaterial& material, ETextureType t, QPushButton* pButton)
@@ -72,7 +69,6 @@ void OnTextureReload(BPPGraphicsMaterial& material, ETextureType t, QPushButton*
else
pButton->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png"));
- SimpleScene::Inst()->SetFurModified(true);
}
void OnTextureClear(BPPGraphicsMaterial& material, ETextureType t, QPushButton* pButton)
@@ -95,7 +91,6 @@ void OnTextureClear(BPPGraphicsMaterial& material, ETextureType t, QPushButton*
pButton->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png"));
- SimpleScene::Inst()->SetFurModified(true);
}
MaterialLibraryPanel* pMaterialLibraryPanel = nullptr;
@@ -104,65 +99,6 @@ 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);
- delete it->second;
- MaterialLibraryPanel::ins()->removeMaterial(materialName);
- }
- }
-
- m_NeedDeleteRenderMaterials.clear();
-}
-
-void MaterialLibraryPanel::deleteMaterialMap()
-{
- std::map<std::string, RenderMaterial*>::iterator itRMM;
- for (itRMM = m_RenderMaterialMap.begin(); itRMM != m_RenderMaterialMap.end(); itRMM++)
- {
- RenderMaterial* pRenderMaterial = itRMM->second;
- std::string materialName = pRenderMaterial->getMaterialName();
- MaterialLibraryPanel::ins()->removeMaterial(materialName);
- delete pRenderMaterial;
- }
- m_RenderMaterialMap.clear();
- m_NeedDeleteRenderMaterials.clear();
-}
-
MaterialLibraryPanel::MaterialLibraryPanel(QWidget *parent) :
QWidget(parent),
ui(new Ui::MaterialLibraryPanel)
@@ -203,6 +139,7 @@ void MaterialLibraryPanel::updateValues()
}
MaterialAssignmentsPanel::ins()->updateValues();
+ FractureGeneralPanel::ins()->updateValues();
}
void MaterialLibraryPanel::on_btnAddMat_clicked()
@@ -217,10 +154,13 @@ void MaterialLibraryPanel::on_btnAddMat_clicked()
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;
+ if (!BlastProject::ins().isGraphicsMaterialNameExist(strName.c_str()))
+ {
+ BlastProject::ins().addGraphicsMaterial(strName.c_str());
+ updateValues();
+ ui->listWidget->setCurrentRow(ui->listWidget->count() - 1);
+ }
}
else if (ok && nameExist)
{
@@ -256,15 +196,6 @@ void MaterialLibraryPanel::on_btnModifyMat_clicked()
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);
- pRenderMaterial->setMaterialName(strNewName);
- m_RenderMaterialMap[strNewName] = pRenderMaterial;
- }
-
SampleManager::ins()->renameRenderMaterial(strOldName, strNewName);
BlastProject::ins().renameGraphicsMaterial(oldName, newName.toUtf8().data());
@@ -291,15 +222,12 @@ void MaterialLibraryPanel::on_btnRemoveMat_clicked()
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);
- }
+
+ SampleManager::ins()->removeRenderMaterial(strName);
+
+ BlastProject::ins().removeGraphicsMaterial(strName.c_str());
+ updateValues();
+ ui->listWidget->setCurrentRow(ui->listWidget->count() - 1);
}
void MaterialLibraryPanel::on_listWidget_currentRowChanged(int currentRow)
@@ -315,6 +243,13 @@ void MaterialLibraryPanel::on_btnDiffuseColor_clicked()
atcore_float4* color = (atcore_float4*)&(material->diffuseColor);
pickColor(*color);
setButtonColor(ui->btnDiffuseColor, color->x, color->y, color->z);
+
+ QString qName = material->name.buf;
+ std::string strName = qName.toUtf8().data();
+
+ BlastProject::ins().reloadDiffuseColor(strName.c_str(), color->x, color->y, color->z);
+
+ SampleManager::ins()->reloadRenderMaterial(strName, color->x, color->y, color->z);
}
}
@@ -324,6 +259,15 @@ void MaterialLibraryPanel::on_btnDiffuseColorTex_clicked()
if (material)
{
OnTextureButtonClicked(*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();
+
+ BlastProject::ins().reloadDiffuseTexture(strName.c_str(), strTexture.c_str());
+
+ SampleManager::ins()->reloadRenderMaterial(strName, strTexture);
}
}
@@ -338,13 +282,10 @@ void MaterialLibraryPanel::on_btnDiffuseColorTexReload_clicked()
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);
- }
+
+ SampleManager::ins()->reloadRenderMaterial(strName, "");
+ ResourceManager::ins()->releaseTexture(strTexture.c_str());
+ SampleManager::ins()->reloadRenderMaterial(strName, strTexture);
}
}
@@ -357,15 +298,10 @@ void MaterialLibraryPanel::on_btnDiffuseColorTexClear_clicked()
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);
- }
+ BlastProject::ins().reloadDiffuseTexture(strName.c_str(), "");
+
+ SampleManager::ins()->reloadRenderMaterial(strName, "");
}
}
@@ -377,6 +313,13 @@ void MaterialLibraryPanel::on_btnSpecularColor_clicked()
atcore_float4* color = (atcore_float4*)&(material->specularColor);
pickColor(*color);
setButtonColor(ui->btnSpecularColor, color->x, color->y, color->z);
+
+ QString qName = material->name.buf;
+ std::string strName = qName.toUtf8().data();
+
+ BlastProject::ins().reloadSpecularColor(strName.c_str(), color->x, color->y, color->z);
+
+ SampleManager::ins()->reloadRenderMaterial(strName, color->x, color->y, color->z, false);
}
}
@@ -386,6 +329,15 @@ void MaterialLibraryPanel::on_btnSpecularColorTex_clicked()
if (material)
{
OnTextureButtonClicked(*material, eSpecularTexture, ui->btnSpecularColorTex);
+
+ QString qName = material->name.buf;
+ std::string strName = qName.toUtf8().data();
+ QString qTexture = material->specularTextureFilePath.buf;
+ std::string strTexture = qTexture.toUtf8().data();
+
+ BlastProject::ins().reloadSpecularTexture(strName.c_str(), strTexture.c_str());
+
+ SampleManager::ins()->reloadRenderMaterial(strName, strTexture, RenderMaterial::TT_Specular);
}
}
@@ -395,6 +347,15 @@ void MaterialLibraryPanel::on_btnSpecularColorTexReload_clicked()
if (material)
{
OnTextureReload(*material, eSpecularTexture, ui->btnSpecularColorTex);
+
+ QString qName = material->name.buf;
+ std::string strName = qName.toUtf8().data();
+ QString qTexture = material->specularTextureFilePath.buf;
+ std::string strTexture = qTexture.toUtf8().data();
+
+ SampleManager::ins()->reloadRenderMaterial(strName, "", RenderMaterial::TT_Specular);
+ ResourceManager::ins()->releaseTexture(strTexture.c_str());
+ SampleManager::ins()->reloadRenderMaterial(strName, strTexture, RenderMaterial::TT_Specular);
}
}
@@ -404,6 +365,13 @@ void MaterialLibraryPanel::on_btnSpecularColorTexClear_clicked()
if (material)
{
OnTextureClear(*material, eSpecularTexture, ui->btnSpecularColorTex);
+
+ QString qName = material->name.buf;
+ std::string strName = qName.toUtf8().data();
+
+ BlastProject::ins().reloadSpecularTexture(strName.c_str(), "");
+
+ SampleManager::ins()->reloadRenderMaterial(strName, "", RenderMaterial::TT_Specular);
}
}
@@ -412,7 +380,13 @@ void MaterialLibraryPanel::on_spinSpecularShin_valueChanged(double arg1)
BPPGraphicsMaterial* material = _getSelectedMaterial();
if (material)
{
- material->specularShininess = (float)arg1;
+ float specularShininess = (float)arg1;
+
+ material->specularShininess = specularShininess;
+
+ QString qName = material->name.buf;
+ std::string strName = qName.toUtf8().data();
+ SampleManager::ins()->reloadRenderMaterial(strName, specularShininess);
}
}
@@ -422,6 +396,15 @@ void MaterialLibraryPanel::on_btnNormalColorTex_clicked()
if (material)
{
OnTextureButtonClicked(*material, eNormalTexture, ui->btnNormalColorTex);
+
+ QString qName = material->name.buf;
+ std::string strName = qName.toUtf8().data();
+ QString qTexture = material->normalTextureFilePath.buf;
+ std::string strTexture = qTexture.toUtf8().data();
+
+ BlastProject::ins().reloadNormalTexture(strName.c_str(), strTexture.c_str());
+
+ SampleManager::ins()->reloadRenderMaterial(strName, strTexture, RenderMaterial::TT_Normal);
}
}
@@ -431,6 +414,15 @@ void MaterialLibraryPanel::on_btnNormalColorTexReload_clicked()
if (material)
{
OnTextureReload(*material, eNormalTexture, ui->btnNormalColorTex);
+
+ QString qName = material->name.buf;
+ std::string strName = qName.toUtf8().data();
+ QString qTexture = material->normalTextureFilePath.buf;
+ std::string strTexture = qTexture.toUtf8().data();
+
+ SampleManager::ins()->reloadRenderMaterial(strName, "", RenderMaterial::TT_Normal);
+ ResourceManager::ins()->releaseTexture(strTexture.c_str());
+ SampleManager::ins()->reloadRenderMaterial(strName, strTexture, RenderMaterial::TT_Normal);
}
}
@@ -440,6 +432,13 @@ void MaterialLibraryPanel::on_btnNormalColorTexClear_clicked()
if (material)
{
OnTextureClear(*material, eNormalTexture, ui->btnNormalColorTex);
+
+ QString qName = material->name.buf;
+ std::string strName = qName.toUtf8().data();
+
+ BlastProject::ins().reloadNormalTexture(strName.c_str(), "");
+
+ SampleManager::ins()->reloadRenderMaterial(strName, "", RenderMaterial::TT_Normal);
}
}
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h b/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h
index edf1df9..9012294 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h
@@ -20,11 +20,6 @@ public:
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();
- void deleteMaterialMap();
private slots:
void on_btnAddMat_clicked();
@@ -63,9 +58,6 @@ private:
void _refreshMaterialValues(int idx);
BPPGraphicsMaterial* _getSelectedMaterial();
- std::map<std::string, RenderMaterial*> m_RenderMaterialMap;
- std::vector<std::string> m_NeedDeleteRenderMaterials;
-
private:
Ui::MaterialLibraryPanel *ui;
};
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp b/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp
index db40407..9db55c2 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp
@@ -2,18 +2,51 @@
#include "ui_SourceAssetOpenDlg.h"
#include <QtWidgets/QFileDialog>
#include "AppMainWindow.h"
+#include "GlobalSettings.h"
-SourceAssetOpenDlg::SourceAssetOpenDlg(bool bOpenBlastFile, QWidget *parent) :
+SourceAssetOpenDlg::SourceAssetOpenDlg(int usefor, QWidget *parent) :
QDialog(parent),
ui(new Ui::SourceAssetOpenDlg)
{
ui->setupUi(this);
- m_bOpenBlastFile = bOpenBlastFile;
+ m_usefor = usefor;
ui->buttonBox->button(QDialogButtonBox::Ok)->setFixedWidth(100);
ui->buttonBox->button(QDialogButtonBox::Cancel)->setFixedWidth(100);
ui->spinBoxDegree->setMaximum(180);
ui->spinBoxDegree->setMinimum(-180);
+
+ ui->spinBoxXPosition->setRange(-DBL_MAX, DBL_MAX);
+ ui->spinBoxYPosition->setRange(-DBL_MAX, DBL_MAX);
+ ui->spinBoxZPosition->setRange(-DBL_MAX, DBL_MAX);
+ ui->spinBoxXAxis->setRange(-DBL_MAX, DBL_MAX);
+ ui->spinBoxYAxis->setRange(-DBL_MAX, DBL_MAX);
+ ui->spinBoxZAxis->setRange(-DBL_MAX, DBL_MAX);
+
+ if (m_usefor == 2)
+ {
+ ui->fileLabel->setVisible(false);
+ ui->lineEditFile->setVisible(false);
+ ui->btnOpenFile->setVisible(false);
+
+ ui->skinnedLabel->setVisible(false);
+ ui->checkBoxSkinned->setVisible(false);
+
+ ui->appendLabel->setVisible(false);
+ ui->checkBoxAppend->setVisible(false);
+
+ ui->preFracturedLabel->setVisible(false);
+ ui->checkBoxPreFractured->setVisible(false);
+ }
+
+ GlobalSettings& globalSettings = GlobalSettings::Inst();
+ ui->cbSceneUnit->setCurrentIndex(globalSettings.m_sceneUnitIndex);
+
+ if (m_usefor != 0)
+ {
+ ui->autoComputeLabel->setVisible(false);
+ ui->checkBoxAutoCompute->setVisible(false);
+ }
}
SourceAssetOpenDlg::~SourceAssetOpenDlg()
@@ -21,6 +54,11 @@ SourceAssetOpenDlg::~SourceAssetOpenDlg()
delete ui;
}
+void SourceAssetOpenDlg::setDefaultFile(const QString& fn)
+{
+ ui->lineEditFile->setText(fn);
+}
+
QString SourceAssetOpenDlg::getFile()
{
return ui->lineEditFile->text();
@@ -46,20 +84,35 @@ double SourceAssetOpenDlg::getRotationDegree()
return ui->spinBoxDegree->value();
}
+int SourceAssetOpenDlg::sceneUnitIndex()
+{
+ return ui->cbSceneUnit->currentIndex();
+}
+
bool SourceAssetOpenDlg::isAppend()
{
return ui->checkBoxAppend->isChecked();
}
+bool SourceAssetOpenDlg::isPreFractured()
+{
+ return ui->checkBoxPreFractured->isChecked();
+}
+
+bool SourceAssetOpenDlg::isAutoCompute()
+{
+ return ui->checkBoxAutoCompute->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)
+ if (m_usefor == 1)
{
- filetype = "Source Asset (*.bpxa)";
+ filetype = "Source Asset (*.blast)";
}
QString fileName = QFileDialog::getOpenFileName(this, titleStr, lastDir, filetype);
if (!fileName.isEmpty())
@@ -80,3 +133,19 @@ void SourceAssetOpenDlg::on_buttonBox_rejected()
{
}
+
+void SourceAssetOpenDlg::on_checkBoxPreFractured_stateChanged(int arg1)
+{
+ if (!ui->checkBoxPreFractured->isChecked())
+ {
+ ui->checkBoxAutoCompute->setChecked(false);
+ }
+}
+
+void SourceAssetOpenDlg::on_checkBoxAutoCompute_stateChanged(int arg1)
+{
+ if (ui->checkBoxAutoCompute->isChecked())
+ {
+ ui->checkBoxPreFractured->setChecked(true);
+ }
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h b/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h
index ec03ee9..ed6da9c 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h
+++ b/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h
@@ -13,15 +13,19 @@ class SourceAssetOpenDlg : public QDialog
Q_OBJECT
public:
- explicit SourceAssetOpenDlg(bool bOpenBlastFile = true, QWidget *parent = 0);
+ explicit SourceAssetOpenDlg(int usefor, QWidget *parent = 0);
~SourceAssetOpenDlg();
+ void setDefaultFile(const QString& fn);
QString getFile();
bool getSkinned();
QVector3D getPosition();
QVector3D getRotationAxis();
double getRotationDegree();
bool isAppend();
+ bool isPreFractured();
+ bool isAutoCompute();
+ int sceneUnitIndex();
private slots:
void on_btnOpenFile_clicked();
@@ -30,9 +34,18 @@ private slots:
void on_buttonBox_rejected();
+ void on_checkBoxPreFractured_stateChanged(int arg1);
+ void on_checkBoxAutoCompute_stateChanged(int arg1);
+
private:
Ui::SourceAssetOpenDlg *ui;
- bool m_bOpenBlastFile;
+ /*
+ m_usefor:
+ 0 for open fbx file
+ 1 for open blast file
+ 2 for add BlastFamily
+ */
+ int m_usefor;
};
#endif // SOURCEASSETOPENDLG_H
diff --git a/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp b/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp
index 424dbb3..556da33 100644
--- a/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp
+++ b/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp
@@ -7,6 +7,12 @@ SupportPanel::SupportPanel(QWidget *parent) :
{
ui->setupUi(this);
+ //ui->labelHealthMask->setEnabled(false);
+ //ui->comboBoxHealthMask->setEnabled(false);
+ //ui->btnAddHealthMask->setEnabled(false);
+ //ui->btnPen->setEnabled(false);
+ //ui->btnRemove->setEnabled(false);
+
_selectedBonds.clear();
}
@@ -23,15 +29,15 @@ void SupportPanel::updateValues()
{
BPPBond* bond = _selectedBonds[0];
- ui->comboBoxHealthMask->clear();
- ui->comboBoxHealthMask->addItem(bond->name.buf);
+ //ui->comboBoxHealthMask->clear();
+ //ui->comboBoxHealthMask->addItem(bond->name.buf);
ui->spinBoxBondStrength->setValue(bond->support.bondStrength);
ui->checkBoxEnableJoint->setChecked(bond->support.enableJoint);
}
else
{
- ui->comboBoxHealthMask->clear();
- ui->comboBoxHealthMask->addItem("None");
+ //ui->comboBoxHealthMask->clear();
+ //ui->comboBoxHealthMask->addItem("None");
ui->spinBoxBondStrength->setValue(1.0f);
ui->checkBoxEnableJoint->setChecked(false);
}
diff --git a/tools/ArtistTools/source/BlastPlugin/blastplugin.json b/tools/ArtistTools/source/BlastPlugin/blastplugin.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/tools/ArtistTools/source/BlastPlugin/blastplugin.json
@@ -0,0 +1 @@
+{}
diff --git a/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp b/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp
index 5ab1563..f070f42 100644
--- a/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp
+++ b/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp
@@ -58,7 +58,7 @@ void AnimationCache::Initialize(int numBones, NvInt32 frameStart, NvInt32 frameE
void AnimationCache::Allocate()
{
m_pBoneMatrices = new atcore_float4x4[m_numFrames * m_numBones];
-// m_pBoneNames = new char[NV_HAIR_MAX_STRING * m_numBones];
+ m_pBoneNames = new char[NV_HAIR_MAX_STRING * m_numBones];
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -104,14 +104,12 @@ int AnimationCache::FindBone(const char *toFind) const
{
if (!toFind)
return -1;
- /*
for (int i = 0; i < m_numBones; i++)
{
const char* boneName = GetBoneName(i);
if (!strcmp(boneName, toFind))
return i;
}
- */
return -1;
}
@@ -122,7 +120,7 @@ bool AnimationCache::FindBoneMapping( int numBones, const NvChar* boneNames, int
for (int i = 0; i < numBones; i++)
{
- //mappedBoneId[i] = FindBone(boneNames + i * NV_HAIR_MAX_STRING);
+ mappedBoneId[i] = FindBone(boneNames + i * NV_HAIR_MAX_STRING);
}
return true;
@@ -140,7 +138,7 @@ void BoneData::Allocate(NvUInt32 numBones)
m_pBoneMatrices = new atcore_float4x4[numBones];
m_pSkinDQs = new atcore_dualquaternion[numBones];
- //m_pBoneNames = new char[NV_HAIR_MAX_STRING * m_numBones];
+ m_pBoneNames = new char[NV_HAIR_MAX_STRING * m_numBones];
m_pMappedBoneId = new int[numBones];
for (int i = 0; i < numBones; i++)
diff --git a/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h b/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h
index 8de718c..5fd239b 100644
--- a/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h
+++ b/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h
@@ -29,8 +29,7 @@
#include "MathUtil.h"
#include <string.h>
-
-//#include <Nv/Blast/NvHairSdk.h>
+#define NV_HAIR_MAX_STRING 128
////////////////////////////////////////////////////////////////////////////////////////
// cache for animated bone data
@@ -67,7 +66,7 @@ struct CORELIB_EXPORT AnimationCache
const atcore_float4x4* GetNodeMatrices(int index) const { return m_pBoneMatrices + index * m_numBones; }
atcore_float4x4* GetNodeMatrices(int index) { return m_pBoneMatrices + index * m_numBones; }
- /*
+
const char* GetBoneName(int index) const
{
return m_pBoneNames + index * NV_HAIR_MAX_STRING;
@@ -78,7 +77,7 @@ struct CORELIB_EXPORT AnimationCache
char* str = m_pBoneNames + index * NV_HAIR_MAX_STRING;
strcpy_s(str, NV_HAIR_MAX_STRING, boneName);
}
- */
+
int FindBone(const char *boneName) const;
bool FindBoneMapping( int numBones, const NvChar* boneNames, int* mappedBoneId) const;
@@ -117,7 +116,7 @@ public:
void Allocate(NvUInt32 numBones);
void Release();
- /*
+
const char* getBoneName(int index)
{
return m_pBoneNames + index * NV_HAIR_MAX_STRING;
@@ -128,7 +127,7 @@ public:
char* str = m_pBoneNames + index * NV_HAIR_MAX_STRING;
strcpy_s(str, NV_HAIR_MAX_STRING, boneName);
}
- */
+
void InitializeAnimationCache(AnimationCache* pGlobalCache, const char* nodeName);
bool Update(float frameTime, const char* rootBoneName, bool bindPose, bool zup);
@@ -164,6 +163,7 @@ struct CORELIB_EXPORT MeshDesc
atcore_float3* m_pVertexNormals;
atcore_float3* m_pFaceNormals;
atcore_float3* m_pTangents;
+ atcore_float3 m_ColorRGB;
NvUInt32* m_pIndices;
atcore_float2* m_pTexCoords;
@@ -180,7 +180,9 @@ public:
m_pIndices(nullptr),
m_pTexCoords(nullptr)
- {}
+ {
+ m_ColorRGB = gfsdk_makeFloat3(0, 0, 0);
+ }
void Allocate(NvUInt32 numVertices, NvUInt32 numTriangles);
void Release();
diff --git a/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp b/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp
index 97ba7d8..1d78d5c 100644
--- a/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp
+++ b/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp
@@ -35,8 +35,7 @@
#include "FbxUtil.h"
#include "MathUtil.h"
-
-//#include <Nv/Blast/NvHairSdk.h>
+#include "GlobalSettings.h"
// local functions used only in this file
namespace {
@@ -138,7 +137,8 @@ FbxUtil::Release(void)
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool FbxUtil::Initialize(const char* fbxFileName, float sceneUnit)
+//// if fbx uses one unit which is not supported, we will also convert its unit.
+bool FbxUtil::Initialize(const char* fbxFileName, nvidia::Float& fbxSceneUnit, nvidia::Float toScneUnit, bool bConvertUnit)
{
if (fbxFileName)
{
@@ -162,12 +162,15 @@ bool FbxUtil::Initialize(const char* fbxFileName, float sceneUnit)
FbxGlobalSettings& settings = s_FbxScene->GetGlobalSettings();
FbxSystemUnit fbxUnit = settings.GetSystemUnit();
-
- if ((sceneUnit > 0.0f) && (sceneUnit != fbxUnit.GetScaleFactor()))
- {
- FbxSystemUnit convertUnit(sceneUnit);
- convertUnit.ConvertScene(s_FbxScene);
- }
+ fbxSceneUnit = fbxUnit.GetScaleFactor();
+ bool bSupported = GlobalSettings::Inst().isSupportedUnitByUnitInCm(fbxSceneUnit);
+ bool bNeedConvert = ((toScneUnit > 0.0f) && bConvertUnit && (fabs(toScneUnit - fbxSceneUnit) > 0.001f));
+ if (bNeedConvert || !bSupported)
+ {
+ // if FBX has a non-supported unit, we still convert its unit
+ FbxSystemUnit convertUnit(toScneUnit);
+ convertUnit.ConvertScene(s_FbxScene);
+ }
s_FbxImporter->Destroy();
@@ -186,9 +189,6 @@ bool FbxUtil::Initialize(const char* fbxFileName, float sceneUnit)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool FbxUtil::GetGlobalSettings(float* pStartFrame, float* pEndFrame, float *pFps, int *upAxis, char* rootBoneName)
{
- return false;
-
- /*
if ( !s_FbxScene)
return false;
@@ -237,7 +237,6 @@ bool FbxUtil::GetGlobalSettings(float* pStartFrame, float* pEndFrame, float *pFp
}
return true;
- */
}
/////////////////////////////////////////////////////////////////////////////
@@ -245,9 +244,6 @@ bool FbxUtil::GetGlobalSettings(float* pStartFrame, float* pEndFrame, float *pFp
bool
FbxUtil::InitializeAnimationCache(AnimationCache& animCache)
{
- return false;
-
- /*
if (!s_FbxScene)
return false;
@@ -284,7 +280,6 @@ FbxUtil::InitializeAnimationCache(AnimationCache& animCache)
}
return true;
- */
}
////////////////////////////////////////////////////////////////////////////////////////
@@ -326,9 +321,6 @@ static int GetNumMeshPoints( FbxNode* pFbxNode)
////////////////////////////////////////////////////////////////////////////////////////
static bool GetBoneData(FbxSkin *pFbxSkin, FbxNode* pFbxNode, NvChar* pBoneNames, atcore_float4x4 *pBindPoses)
{
- return false;
-
- /*
if (!pFbxSkin || !pFbxNode)
return false;
@@ -361,7 +353,6 @@ static bool GetBoneData(FbxSkin *pFbxSkin, FbxNode* pFbxNode, NvChar* pBoneNames
}
}
return true;
- */
}
////////////////////////////////////////////////////////////////////////////////////////
@@ -455,9 +446,6 @@ static bool GetSkinningWeights(FbxSkin* pFbxSkin, atcore_float4* boneIndices, at
////////////////////////////////////////////////////////////////////////////////////////
bool FbxUtil::InitializeSkinData( const char* meshName, SkinData& skinData)
{
- return false;
-
- /*
FbxNode* pFbxNode = FindNodeByName(s_FbxScene, meshName);
if (!pFbxNode)
return false;
@@ -506,11 +494,10 @@ bool FbxUtil::InitializeSkinData( const char* meshName, SkinData& skinData)
}
return true;
- */
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool FbxUtil::GetMeshInfo(int* numMeshes, char** meshNames, char** skinned)
+bool FbxUtil::GetMeshInfo(int* numMeshes, char** meshNames, char** parents, char** skinned)
{
int cnt = 0;
@@ -524,6 +511,9 @@ bool FbxUtil::GetMeshInfo(int* numMeshes, char** meshNames, char** skinned)
char *pNameBuffer = new char[cnt * 128];
char *pSkinnedBuffer = new char[cnt];
+ char *pParentBuffer = new char[cnt * 128];
+ memset(pParentBuffer, 0, cnt * 128);
+
cnt = 0;
for (int i = 0; i < s_FbxScene->GetNodeCount(); i++)
{
@@ -534,6 +524,12 @@ bool FbxUtil::GetMeshInfo(int* numMeshes, char** meshNames, char** skinned)
strcpy(pNameBuffer + cnt * 128, pNode->GetName());
+ FbxNode* pParentNode = pNode->GetParent();
+ if (pParentNode != nullptr)
+ {
+ strcpy(pParentBuffer + cnt * 128, pParentNode->GetName());
+ }
+
pSkinnedBuffer[cnt] = checkSkinned(pNode);
cnt++;
@@ -548,6 +544,7 @@ bool FbxUtil::GetMeshInfo(int* numMeshes, char** meshNames, char** skinned)
delete []pSkinnedBuffer;
*meshNames = pNameBuffer;
+ *parents = pParentBuffer;
return true;
}
@@ -563,6 +560,8 @@ bool FbxUtil::GetMeshMaterials( const NvChar* meshName, int *numMaterials, MeshM
return false;
int numMats = pNode->GetMaterialCount();
+ if (numMats == 0)
+ return false;
*materials = new MeshMaterial[numMats];
@@ -663,6 +662,9 @@ bool FbxUtil::CreateMeshDescriptor(const char* meshName, MeshDesc &desc)
if (!pMesh)
return false;
+ FbxDouble3 meshColor = pMesh->Color.Get();
+ desc.m_ColorRGB = gfsdk_makeFloat3(meshColor[0], meshColor[1], meshColor[2]);
+
int cpCount = pMesh->GetControlPointsCount();
int triCount = 0;
@@ -677,8 +679,12 @@ bool FbxUtil::CreateMeshDescriptor(const char* meshName, MeshDesc &desc)
// read positions
FbxVector4* points = pMesh->GetControlPoints();
+ FbxAMatrix matrixGeo = pNode->EvaluateGlobalTransform();
for (int i = 0; i < desc.m_NumVertices; i++)
- desc.m_pVertices[i] = gfsdk_makeFloat3(float(points[i].mData[0]), float(points[i].mData[1]), float(points[i].mData[2]));
+ {
+ FbxVector4 v = matrixGeo.MultT(points[i]);
+ desc.m_pVertices[i] = gfsdk_makeFloat3(v.mData[0], v.mData[1], v.mData[2]);
+ }
memset(desc.m_pTexCoords, 0, sizeof(atcore_float2) * desc.m_NumTriangles * 3);
diff --git a/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h b/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h
index 26e61a9..5cbf18c 100644
--- a/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h
+++ b/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h
@@ -29,7 +29,6 @@
#include "AnimUtil.h"
-//#include <Nv/Blast/NvHairSdk.h>
////////////////////////////////////////////////////////////////////////////////////////
// Helper for fbx file load
@@ -38,7 +37,7 @@ class CORELIB_EXPORT FbxUtil
public:
/// initialize fbx loader.
- static bool Initialize(const nvidia::Char* fbxFileName, nvidia::Float sceneUnit = 0.0f);
+ static bool Initialize(const nvidia::Char* fbxFileName, nvidia::Float& fbxSceneUnit, float toScneUnit = 0.0f, bool bConvertUnit = true);
static bool Release(void);
static bool InitializeAnimationCache(AnimationCache& cache);
@@ -53,7 +52,7 @@ public:
static bool CreateMeshDescriptor(const nvidia::Char* meshName, MeshDesc &meshDesc);
/// get all the renderable meshes from the fbx scene
- static bool GetMeshInfo(int* numMeshes, char** meshNames, char** skinned = 0);
+ static bool GetMeshInfo(int* numMeshes, char** meshNames, char** parents, char** skinned);
/// get mesh material info from fbx scene
static bool GetMeshMaterials(const nvidia::Char* meshName, int *numMaterials, MeshMaterial** materials);
diff --git a/tools/ArtistTools/source/CoreLib/CoreLib.cpp b/tools/ArtistTools/source/CoreLib/CoreLib.cpp
index b94b1d9..057439c 100644
--- a/tools/ArtistTools/source/CoreLib/CoreLib.cpp
+++ b/tools/ArtistTools/source/CoreLib/CoreLib.cpp
@@ -259,7 +259,7 @@ static void ShowUsage()
"FurViewer Command-line Options:\n\n"
"Usage: FurViewer.[win64|win32].exe [file] [options]...\n\n"
"[file]: \n"
- "\t: File to load. .furproj, .apx or .apb are supported.\n\t ex) media/HairBall/Hairball.furproj\n\n"
+ "\t: File to load. .blastProj, .apx or .apb are supported.\n\t ex) media/Ball/ball.blastProj\n\n"
"[options]:\n"
"-size <width>x<height>\n\t: Window resolution\t ex) -size 1024x768\n"
"-aa <1|2|4|8>\n\t: MSAA anti-aliasing options. 1 for off.\t ex) -aa 4 or -aa 1\n"
@@ -421,20 +421,20 @@ bool ParseCommandLineOptions(int argc, char* argv[])
char* extension = strrchr(argv[idx], '.');
if (extension)
{
- if (!_stricmp(extension, ".furproj"))
+ if (!_stricmp(extension, ".blastProj"))
{
oaValue value;
value.String = argv[idx];
settings.SetOptionValue("User/ProjectPath", OA_TYPE_STRING, &value);
isValid = true;
}
- else if (!_stricmp(extension, ".apx") || !_stricmp(extension, ".apb"))
- {
- oaValue value;
- value.String = argv[idx];
- settings.SetOptionValue("User/FurAssetPath", OA_TYPE_STRING, &value);
- isValid = true;
- }
+ //else if (!_stricmp(extension, ".apx") || !_stricmp(extension, ".apb"))
+ //{
+ // oaValue value;
+ // value.String = argv[idx];
+ // settings.SetOptionValue("User/FurAssetPath", OA_TYPE_STRING, &value);
+ // isValid = true;
+ //}
}
if (!isValid)
{
@@ -880,12 +880,12 @@ bool CoreLib::Gamepad_ResetScene()
return true;
}
-bool CoreLib::Gamepad_StartAnimation()
+bool CoreLib::Gamepad_PlaySample()
{
std::map<QString, PluginInterface*>::iterator it;
for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
{
- if (!(it->second)->Gamepad_StartAnimation())
+ if (!(it->second)->Gamepad_PlaySample())
break;
}
return true;
@@ -997,10 +997,24 @@ bool CoreLib::SimpleScene_Draw_DX11()
}
bool CoreLib::SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents)
{
+ bool valid = true;
std::map<QString, PluginInterface*>::iterator it;
for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
{
if (!(it->second)->SimpleScene_FitCamera(center, extents))
+ {
+ valid = false;
+ break;
+ }
+ }
+ return valid;
+}
+bool CoreLib::SimpleScene_UpdateCamera()
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->SimpleScene_UpdateCamera())
break;
}
return true;
@@ -1035,6 +1049,14 @@ bool CoreLib::SimpleScene_DrawAxis()
}
return true;
}
+void CoreLib::SimpleScene_OpenFilesByDrop(const QStringList& fileNames)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ (it->second)->SimpleScene_OpenFilesByDrop(fileNames);
+ }
+}
bool CoreLib::SimpleScene_LoadSceneFromFbx(const char* dir, const char* fbxName)
{
std::map<QString, PluginInterface*>::iterator it;
@@ -1347,6 +1369,18 @@ bool CoreLib::AppMainWindow_closeEvent(QCloseEvent *event)
return true;
}
+
+bool CoreLib::menu_item_triggered(QAction* action)
+{
+ std::map<QString, PluginInterface*>::iterator it;
+ for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++)
+ {
+ if (!(it->second)->AppMainWindow_menu_item_triggered(action))
+ break;
+ }
+ return true;
+}
+
bool CoreLib::AppMainWindow_menu_about()
{
std::map<QString, PluginInterface*>::iterator it;
diff --git a/tools/ArtistTools/source/CoreLib/CoreLib.h b/tools/ArtistTools/source/CoreLib/CoreLib.h
index 3d86bcf..385ac73 100644
--- a/tools/ArtistTools/source/CoreLib/CoreLib.h
+++ b/tools/ArtistTools/source/CoreLib/CoreLib.h
@@ -51,12 +51,13 @@ public:
bool Gamepad_ToggleSimulation();
bool Gamepad_LoadSamples(QString fn);
bool Gamepad_ResetScene();
- bool Gamepad_StartAnimation();
+ bool Gamepad_PlaySample();
bool GamepadHandler_ShowHair();
bool GamepadHandler_SpinWindStrength(float windStrength);
bool Gamepad_ResetAnimation();
bool Gamepad_PlayPauseAnimation();
-
+
+ void SimpleScene_OpenFilesByDrop(const QStringList& fileNames);
bool SimpleScene_SimpleScene();
bool SimpleScene_Initialize(int backdoor);
bool SimpleScene_Shutdown();
@@ -64,6 +65,7 @@ public:
bool SimpleScene_Draw_DX12();
bool SimpleScene_Draw_DX11();
bool SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents);
+ bool SimpleScene_UpdateCamera();
bool SimpleScene_DrawGround();
bool SimpleScene_DrawWind();
bool SimpleScene_DrawAxis();
@@ -104,6 +106,7 @@ public:
bool AppMainWindow_shortcut_expert(bool mode);
bool AppMainWindow_updateMainToolbar();
+ bool menu_item_triggered(QAction* action);
bool AppMainWindow_menu_about();
bool AppMainWindow_menu_opendoc();
#if USE_CURVE_EDITOR
diff --git a/tools/ArtistTools/source/CoreLib/Parameters/HackNvParamBug.cpp b/tools/ArtistTools/source/CoreLib/Parameters/HackNvParamBug.cpp
new file mode 100644
index 0000000..2ee7769
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Parameters/HackNvParamBug.cpp
@@ -0,0 +1,6 @@
+#include <string.h>
+
+int GetHackElementSize(const char* data)
+{
+ return 0;
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/Parameters/PlaylistParams.pl b/tools/ArtistTools/source/CoreLib/Parameters/PlaylistParams.pl
new file mode 100644
index 0000000..a4618aa
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Parameters/PlaylistParams.pl
@@ -0,0 +1,33 @@
+{
+ header =>
+ {
+ className => 'PlaylistParams',
+ implementStorage => 1,
+
+ # Version history
+ # 0.0 Initial Version
+ classVersion => '0.0',
+
+ hints =>
+ {
+ },
+ },
+
+ structs =>
+ [
+ ],
+
+ parameters =>
+ [
+ {
+ name => 'blastProjFilePaths',
+ type => 'STRING',
+ isArray => 1,
+ arraySize => '-1',
+ hints =>
+ {
+ shortDescription => "BlastProj file paths",
+ },
+ },
+ ]
+}
diff --git a/tools/ArtistTools/source/CoreLib/Parameters/go.bat b/tools/ArtistTools/source/CoreLib/Parameters/go.bat
new file mode 100644
index 0000000..600bf18
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Parameters/go.bat
@@ -0,0 +1,6 @@
+SET SRC_ROOT=..\..\..\..\..
+SET EXTERNAL_ROOT=%SRC_ROOT%\..\..\external
+SET BUILDTOOL_ROOT=%SRC_ROOT%\..\..\external
+
+@if "%PERL%"=="" set PERL=%BUILDTOOL_ROOT%\perl\5.8.8_822\bin\perl
+@%PERL% %EXTERNAL_ROOT%\NvParameterized\1.1\trunk\build\scripts\GenParameterized.pl -force PlaylistParams.pl . . \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/PluginInterface.h b/tools/ArtistTools/source/CoreLib/PluginInterface.h
index aae8da8..0fc531c 100644
--- a/tools/ArtistTools/source/CoreLib/PluginInterface.h
+++ b/tools/ArtistTools/source/CoreLib/PluginInterface.h
@@ -34,6 +34,7 @@ class QDragMoveEvent;
class QDragLeaveEvent;
class QDropEvent;
class QContextMenuEvent;
+class QAction;
class PluginInterface
{
@@ -62,7 +63,7 @@ public:
virtual bool Gamepad_ToggleSimulation() = 0;
virtual bool Gamepad_ResetScene() = 0;
NV_AT_UNUSED virtual bool Gamepad_LoadSamples(QString fn) = 0;
- virtual bool Gamepad_StartAnimation() = 0;
+ virtual bool Gamepad_PlaySample() = 0;
virtual bool GamepadHandler_ShowHair() = 0;
virtual bool GamepadHandler_SpinWindStrength(float windStrength) = 0;
virtual bool Gamepad_ResetAnimation() = 0;
@@ -71,6 +72,7 @@ public:
virtual bool Light_loadParameters(NvParameterized::Handle& handle, Light* pLight) = 0;
virtual bool Light_saveParameters(NvParameterized::Handle& handle, Light* pLight) = 0;
+ virtual void SimpleScene_OpenFilesByDrop(const QStringList& fileNames) = 0;
virtual bool SimpleScene_SimpleScene() = 0;
virtual bool SimpleScene_Initialize(int backdoor) = 0;
virtual bool SimpleScene_Shutdown() = 0;
@@ -78,6 +80,7 @@ public:
virtual bool SimpleScene_Draw_DX12() = 0;
virtual bool SimpleScene_Draw_DX11() = 0;
virtual bool SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents) = 0;
+ virtual bool SimpleScene_UpdateCamera() = 0;
virtual bool SimpleScene_LoadSceneFromFbx(const char* dir, const char* fbxName) = 0;
virtual bool SimpleScene_LoadProject(const char* dir, const char* file) = 0;
virtual bool SimpleScene_SaveProject(const char* dir, const char* file) = 0;
@@ -118,6 +121,7 @@ public:
virtual bool AppMainWindow_shortcut_expert(bool mode) = 0;
virtual bool AppMainWindow_updateMainToolbar() = 0;
+ virtual bool AppMainWindow_menu_item_triggered(QAction* action) = 0;
virtual bool AppMainWindow_menu_about() = 0;
virtual bool AppMainWindow_menu_opendoc() = 0;
#if USE_CURVE_EDITOR
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp
index 71d1b7d..292de1a 100644
--- a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp
@@ -225,11 +225,26 @@ HRESULT UseGoodGPUDevice()
std::wstring adapterName = adapterDesc.Description;
#endif
- D3D_FEATURE_LEVEL fl;
- HRESULT hr = D3D11CreateDevice(g_pAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
+ D3D_FEATURE_LEVEL fl = D3D_FEATURE_LEVEL_9_1;
+ HRESULT hr = 0;
+
+ hr = D3D11CreateDevice(g_pAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
createDeviceFlags, 0, 0,
D3D11_SDK_VERSION, &g_d3dDevice, &fl, &g_d3dDeviceContext);
+ if (g_d3dDevice == nullptr)
+ {
+ // here is the codes to make it run on a WARP device(Windows DirectX CPU - based emulation).
+ if (g_pAdapter)
+ {
+ g_pAdapter->Release();
+ g_pAdapter = nullptr;
+ }
+ hr = D3D11CreateDevice(g_pAdapter, D3D_DRIVER_TYPE_WARP, nullptr,
+ createDeviceFlags, 0, 0,
+ D3D11_SDK_VERSION, &g_d3dDevice, &fl, &g_d3dDeviceContext);
+ }
+
if(g_d3dDevice)
{
IDXGIDevice* dxgiDevice = nullptr;
@@ -237,6 +252,11 @@ HRESULT UseGoodGPUDevice()
if (SUCCEEDED(hr))
{
g_dxgiDevice = dxgiDevice;
+ if (g_pAdapter == nullptr)
+ {
+ // when running on WARP device, need find out adapter.
+ hr = dxgiDevice->GetAdapter(&g_pAdapter);
+ }
return hr;
}
else
diff --git a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp
index eba1184..f3e210b 100644
--- a/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp
+++ b/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp
@@ -30,7 +30,6 @@
#include "MeshShaderParam.h"
#include "LightShaderParam.h"
-//#include <Nv/Blast/NvHairSdk.h>
#include "D3D11RenderShader.h"
using namespace RenderInterface;
@@ -39,7 +38,7 @@ using namespace RenderInterface;
// Common shader settings
//static D3D11RenderShader* g_pShaders[SHADER_TYPE_END];
static std::map<int, D3D11RenderShader*> g_pShaders;
-/*
+
namespace BodyShaderBlobs
{
#include "Shaders/BodyShader_VS.h"
@@ -76,22 +75,9 @@ namespace ColorBlobs
#include "Shaders/Color_PS.h"
}
-#ifndef NV_ARTISTTOOLS
-namespace BlastShaderBlobs
-{
-#include "Shaders/BlastShader_PS.h"
-}
-
-namespace BlastShadowBlobs
-{
-#include "Shaders/BlastShadow_PS.h"
-}
-#endif // NV_ARTISTTOOLS
-*/
//////////////////////////////////////////////////////////////////////////
bool InitializeShadersD3D11()
{
- /*
D3D11_INPUT_ELEMENT_DESC layoutBodyRender[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
@@ -142,23 +128,6 @@ bool InitializeShadersD3D11()
sizeof(SimpleShaderParam), 0,
&layout_Position_And_Color[0], numElements2);
-#ifndef NV_ARTISTTOOLS
- g_pShaders[SHADER_TYPE_HAIR_SHADER_DEFAULT] = D3D11RenderShader::Create(
- "hairShaderDefault", 0, 0,
- (void*)BlastShaderBlobs::g_ps_main, sizeof(BlastShaderBlobs::g_ps_main),
- sizeof(NvHair::ShaderConstantBuffer),
- sizeof(LightShaderParam)
- );
-
- g_pShaders[SHADER_TYPE_HAIR_SHADER_SHADOW] = D3D11RenderShader::Create(
- "hairShadow", 0, 0,
- (void*)BlastShadowBlobs::g_ps_main, sizeof(BlastShadowBlobs::g_ps_main),
- sizeof(NvHair::ShaderConstantBuffer),
- 0);
-#else
- CoreLib::Inst()->D3D11Shaders_InitializeShadersD3D11(g_pShaders);
-#endif // NV_ARTISTTOOLS
- */
return true;
}
diff --git a/tools/ArtistTools/source/CoreLib/Resource/AppMainWindow.qrc b/tools/ArtistTools/source/CoreLib/Resource/AppMainWindow.qrc
new file mode 100644
index 0000000..cffd039
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Resource/AppMainWindow.qrc
@@ -0,0 +1,4 @@
+<RCC>
+ <qresource prefix="AppMainWindow">
+ </qresource>
+</RCC>
diff --git a/tools/ArtistTools/source/CoreLib/Resource/D3DQt-CC.ico b/tools/ArtistTools/source/CoreLib/Resource/D3DQt-CC.ico
new file mode 100644
index 0000000..4477340
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Resource/D3DQt-CC.ico
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/Resource/resource.rc b/tools/ArtistTools/source/CoreLib/Resource/resource.rc
new file mode 100644
index 0000000..abc138a
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Resource/resource.rc
@@ -0,0 +1,2 @@
+IDI_ICON1 ICON DISCARDABLE "D3DQt-CC.ico"
+
diff --git a/tools/ArtistTools/source/CoreLib/Scene/Camera.cpp b/tools/ArtistTools/source/CoreLib/Scene/Camera.cpp
index 74d93f4..2dba89a 100644
--- a/tools/ArtistTools/source/CoreLib/Scene/Camera.cpp
+++ b/tools/ArtistTools/source/CoreLib/Scene/Camera.cpp
@@ -136,9 +136,9 @@ D3DXMATRIX * D3DXMatrixLookAtLH(
D3DXVECTOR3 yaxis = gfsdk_cross(zaxis, xaxis);
gfsdk_makeIdentity(*pOut);
- pOut->_11 = zaxis.x;
- pOut->_21 = zaxis.y;
- pOut->_31 = zaxis.z;
+ pOut->_11 = xaxis.x;
+ pOut->_21 = xaxis.y;
+ pOut->_31 = xaxis.z;
pOut->_12 = yaxis.x;
pOut->_22 = yaxis.y;
pOut->_32 = yaxis.z;
diff --git a/tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp b/tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp
index 01e3323..246ce04 100644
--- a/tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp
+++ b/tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp
@@ -263,7 +263,7 @@ void ToggleSimulation()
#endif // NV_ARTISTTOOLS
}
-void StartAnimation()
+void PlaySample()
{
#ifndef NV_ARTISTTOOLS
GlobalSettings::Inst().toggleSimulation();
@@ -282,7 +282,7 @@ void StartAnimation()
// reset animation
//toolbar->on_btnResetAnimation_clicked();
#else
- CoreLib::Inst()->Gamepad_StartAnimation();
+ CoreLib::Inst()->Gamepad_PlaySample();
#endif // NV_ARTISTTOOLS
}
@@ -353,7 +353,7 @@ void LoadSamples(bool bNext)
continue;
QString fn = t.toLower();
std::string strFN = fn.toUtf8().data();
- const char* ptest = strstr(strFN.c_str(), ".furproj");
+ const char* ptest = strstr(strFN.c_str(), ".blastProj");
if (ptest)
{
const char* pchar = strchr(strFN.c_str(), ':');
@@ -397,7 +397,7 @@ void LoadSamples(bool bNext)
if(!projectPath.isEmpty())
{
QStringList filters;
- filters<<QString("*.furproj");
+ filters<<QString("*.blastProj");
QDirIterator dir_iterator(projectPath, filters, QDir::Files | QDir::NoSymLinks,QDirIterator::Subdirectories);
while(dir_iterator.hasNext())
{
@@ -1259,13 +1259,13 @@ void Gamepad::DemoModeOnOff()
void Gamepad::DemoNext()
{
LoadSamples(true);
- StartAnimation();
+ PlaySample();
}
void Gamepad::DemoPrev()
{
LoadSamples(false);
- StartAnimation();
+ PlaySample();
}
void Gamepad::SetDemoMode(bool onOff)
@@ -1278,9 +1278,6 @@ void Gamepad::SetDemoMode(bool onOff)
{
curentPrjIdx = -1; // make it start from first demo
DemoNext();
-
- // turn off FPS display
- GlobalSettings::Inst().m_showFPS = false;
}
else
{
diff --git a/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp b/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp
index 1903d32..6a826ca 100644
--- a/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp
+++ b/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp
@@ -250,11 +250,49 @@ void GlobalSettings::setSceneUnitIndex(int i)
///////////////////////////////////////////////////////////////////////////////
+bool GlobalSettings::isSupportedUnitByUnitInCm(float fUnitInCm)
+{
+ int unit = identifyUnitByUnitInCm(fUnitInCm);
+ return unit != SCENE_UNIT_UNKNOWN;
+}
+
+int GlobalSettings::identifyUnitByUnitInCm(float fUnitInCm)
+{
+ float fError = 0.001f;
+ if (fabs(fUnitInCm - 1.0f) < fError)
+ {
+ return SCENE_UNIT_CENTIMETER;
+ }
+ if (fabs(fUnitInCm - 2.54f) < fError)
+ {
+ return SCENE_UNIT_INCH;
+ }
+ if (fabs(fUnitInCm - 100.0f) < fError)
+ {
+ return SCENE_UNIT_METER;
+ }
+ if (fabs(fUnitInCm - 10.0f) < fError)
+ {
+ return SCENE_UNIT_DECIMETER;
+ }
+ return SCENE_UNIT_UNKNOWN; // should never happen
+}
+
+void GlobalSettings::setSceneUnitByUnitInCm(float fUnitInCm)
+{
+ m_sceneUnitIndex = identifyUnitByUnitInCm(fUnitInCm);
+}
+
float GlobalSettings::getSceneUnitInCentimeters()
{
+ return getSceneUnitInCentimeters(m_sceneUnitIndex);
+}
+
+float GlobalSettings::getSceneUnitInCentimeters(int unitIndex)
+{
float unit = 1.0f;
- switch (m_sceneUnitIndex)
+ switch (unitIndex)
{
case SCENE_UNIT_CENTIMETER:
unit = 1.0f;
diff --git a/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h b/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h
index c83143b..7c1e666 100644
--- a/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h
+++ b/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h
@@ -148,7 +148,11 @@ public:
bool isBindPose() { return m_animationIndex == 0; }
float getSceneUnitInCentimeters();
+ static float getSceneUnitInCentimeters(int unitIndex);
void setSceneUnitIndex(int i);
+ void setSceneUnitByUnitInCm(float fUnitInCm);
+ static int identifyUnitByUnitInCm(float fUnitInCm);
+ static bool isSupportedUnitByUnitInCm(float fUnitInCm);
void setTimeStep(float timeStep) { m_timeStep = timeStep; }
diff --git a/tools/ArtistTools/source/CoreLib/Scene/Light.cpp b/tools/ArtistTools/source/CoreLib/Scene/Light.cpp
index e18314e..5f17e66 100644
--- a/tools/ArtistTools/source/CoreLib/Scene/Light.cpp
+++ b/tools/ArtistTools/source/CoreLib/Scene/Light.cpp
@@ -512,7 +512,7 @@ bool Light::SetEnvTextureFromFilePath(const char* textureFilePath)
m_envTextureFilePath = (textureFilePath) ? textureFilePath : "";
SAFE_RELEASE(m_pEnvTextureSRV);
- if ((!textureFilePath) && (strlen(textureFilePath) > 0))
+ if ((textureFilePath) && (strlen(textureFilePath) > 0))
m_pEnvTextureSRV = RenderInterface::CreateTextureResource(textureFilePath);
return true;
diff --git a/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp b/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp
index a633770..ddbf517 100644
--- a/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp
+++ b/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp
@@ -171,8 +171,8 @@ bool SimpleScene::Initialize( HWND hWnd, int backdoor)
if(!InitCameraMouse(hWnd))
return false;
-// if (!SimpleRenderable::Initialize())
-// return false;
+ if (!SimpleRenderable::Initialize())
+ return false;
Light::Initialize();
@@ -189,30 +189,7 @@ bool SimpleScene::Initialize( HWND hWnd, int backdoor)
SetFurModified(false);
SetProjectModified(false);
-#ifndef NV_ARTISTTOOLS
- if (!InitializeBlastSDK(&g_logHandler, backdoor))
- return false;
-
- g_projectParamsContext = CreateProjectParamsContext();
- if (!g_projectParamsContext) return false;
-
- {
- NvHair::Sdk* hairSdk = GetHairSDK();
- if (hairSdk)
- {
- const NvHair::BuildInfo& buildInfo = GetHairSDK()->getBuildInfo();
-
- viewer_info(GetHairSDK()->getBuildInfo().m_buildString);
-
- char releaseVersion[100] = "Blast Release:";
- buildInfo.m_versionToStringFunc(buildInfo.m_releaseVersion, releaseVersion + strlen(releaseVersion));
-
- viewer_info(releaseVersion);
- }
- }
-#else
CoreLib::Inst()->SimpleScene_Initialize(backdoor);
-#endif // NV_ARTISTTOOLS
AppMainWindow::Inst().updateUI();
@@ -324,22 +301,6 @@ Timer& SimpleScene::GetTimer()
///////////////////////////////////////////////////////////////////////////////
void SimpleScene::Draw()
{
- CoreLib* pCore = CoreLib::Inst();
- pCore->D3DWidget_paintEvent(NULL);
-#ifndef NV_ARTISTTOOLS
-#else
- //pCore->SimpleScene_Draw_DX12();
-
- //RenderInterface::SwitchToDX11();
-
- //pCore->SimpleScene_Draw_DX11();
-
- //RenderInterface::FlushDX11();
-#endif
- // present current window
- //RenderInterface::PresentRenderWindow();
- return;
-
if (IsSceneLoading())
return;
@@ -364,9 +325,6 @@ void SimpleScene::Draw()
// update camera
UpdateCamera();
- // draw lights
- Light::DrawLights(m_pCamera);
-
// show ground grid
if (globalSettings.m_showGrid)
DrawGround();
@@ -386,23 +344,6 @@ void SimpleScene::Draw()
if (GlobalSettings::Inst().m_visualizeShadowMap)
Light::RenderShadowMap();
-#ifndef NV_ARTISTTOOLS
- // init profiler stats
- FurRenderer::ResetFrameTimer();
- // the main loop to simulate and render hairs and meshes
- FurRenderer::UpdateFrame();
- FurRenderer::Render(m_pCamera);
-
- RenderInterface::SwitchToDX11();
- // draw bone name for first hair (hacky, needs to go into SDK)
- HairInstance* pInstance = GetFurCharacter().GetFirstSelectedHairInstance();
- if (pInstance && globalSettings.m_visualizeBoneNames)
- pInstance->DrawBoneNames(m_pCamera);
-
- // draw HUD.
- FurRenderer::DrawHUD();
- RenderInterface::FlushDX11();
-#else
CoreLib::Inst()->SimpleScene_Draw_DX12();
RenderInterface::SwitchToDX11();
@@ -411,7 +352,8 @@ void SimpleScene::Draw()
RenderInterface::FlushDX11();
-#endif // NV_ARTISTTOOLS
+ // draw lights
+ Light::DrawLights(m_pCamera);
// present current window
RenderInterface::PresentRenderWindow();
@@ -512,18 +454,13 @@ SimpleScene::LoadSceneFromFbx(const char* dir, const char* fbxName)
///////////////////////////////////////////////////////////////////////////////
bool SimpleScene::LoadProject(const char* dir, const char* file)
{
- GlobalSettings& globalSettings = GlobalSettings::Inst();
+ Clear();
+ GlobalSettings& globalSettings = GlobalSettings::Inst();
globalSettings.m_projectFileDir = dir;
globalSettings.m_projectFileName = file;
-#ifndef NV_ARTISTTOOLS
- nvidia::parameterized::HairProjectParametersNS::ParametersStruct params;
- if (!ProjectParamsLoad(g_projectParamsContext, globalSettings.getAbsoluteFilePath().c_str(), this))
- return false;
-#else
CoreLib::Inst()->SimpleScene_LoadProject(dir, file);
-#endif // NV_ARTISTTOOLS
SetProjectModified(false);
@@ -950,18 +887,20 @@ void SimpleScene::UpdateCamera()
float minZ = 1.0f;
float maxZ = 10000.0f; // should calculate dynamically
-
+/*
if (sceneUnit != 0.0f)
{
minZ /= sceneUnit;
maxZ /= sceneUnit;
}
-
+*/
m_pCamera->SetAspetRatio(aspect);
m_pCamera->SetZFar(maxZ);
m_pCamera->SetZNear(minZ);
m_pCamera->Perspective();
+
+ CoreLib::Inst()->SimpleScene_UpdateCamera();
}
void SimpleScene::FitCamera()
@@ -975,7 +914,11 @@ void SimpleScene::FitCamera()
if (m_pFurCharacter)
m_pFurCharacter->ComputeBounds(center, extents, false);
#else
- CoreLib::Inst()->SimpleScene_FitCamera(center, extents);
+ bool valid = CoreLib::Inst()->SimpleScene_FitCamera(center, extents);
+ if (!valid)
+ {
+ return;
+ }
#endif // NV_ARTISTTOOLS
m_pCamera->FitBounds(center, extents);
diff --git a/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h b/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h
index 8d01970..79597d2 100644
--- a/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h
+++ b/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h
@@ -34,6 +34,7 @@
#include <QtCore/QMap>
#include "Camera.h"
#include "Timer.h"
+#include <DirectXMath.h>
class FurCharacter;
class DeviceManager;
@@ -141,6 +142,34 @@ public:
Timer& GetTimer();
+ DirectX::XMMATRIX GetViewMatrix() const
+ {
+ atcore_float4x4& matrix = m_pCamera->_viewMatrix;
+ return DirectX::XMMATRIX(
+ matrix._11, matrix._12, matrix._13, matrix._14,
+ matrix._21, matrix._22, matrix._23, matrix._24,
+ matrix._31, matrix._32, matrix._33, matrix._34,
+ matrix._41, matrix._42, matrix._43, matrix._44);
+ }
+ DirectX::XMMATRIX GetProjMatrix() const
+ {
+ atcore_float4x4& matrix = m_pCamera->_projectionMatrix;
+ return DirectX::XMMATRIX(
+ matrix._11, matrix._12, matrix._13, matrix._14,
+ matrix._21, matrix._22, matrix._23, matrix._24,
+ matrix._31, matrix._32, matrix._33, matrix._34,
+ matrix._41, matrix._42, matrix._43, matrix._44);
+ }
+ DirectX::XMVECTOR GetEyePt() const
+ {
+ return DirectX::XMLoadFloat3(
+ reinterpret_cast<const DirectX::XMFLOAT3*>(&m_pCamera->_eye));
+ }
+ DirectX::XMVECTOR GetLookAtPt() const
+ {
+ return DirectX::XMLoadFloat3(
+ reinterpret_cast<const DirectX::XMFLOAT3*>(&m_pCamera->_at));
+ }
private:
// initialize scene components
bool InitCameraMouse(HWND hAppWnd);
diff --git a/tools/ArtistTools/source/CoreLib/UI/AppMainWindow.qrc b/tools/ArtistTools/source/CoreLib/UI/AppMainWindow.qrc
new file mode 100644
index 0000000..3ec3217
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/AppMainWindow.qrc
@@ -0,0 +1,36 @@
+<RCC>
+ <qresource prefix="AppMainWindow">
+ <file>images/TextureBox.bmp</file>
+ <file>images/CheckBox.png</file>
+ <file>images/ArrowUp.png</file>
+ <file>images/ArrowDown.png</file>
+ <file>images/transportLoop.png</file>
+ <file>images/transportPlay.png</file>
+ <file>images/transportRewind.png</file>
+ <file>images/transportStepForward.png</file>
+ <file>images/transportStop.png</file>
+ <file>images/simulationPlay.png</file>
+ <file>images/simulationStop.png</file>
+ <file>images/simulationStep.png</file>
+ <file>images/DarkBorder.png</file>
+ <file>images/openFile.png</file>
+ <file>images/importFile.png</file>
+ <file>images/saveDisc.png</file>
+ <file>images/refreshReload.png</file>
+ <file>images/TextureEnabled_icon.png</file>
+ <file>images/TextureDisabled_icon.png</file>
+ <file>images/TextureIsUsed_icon.png</file>
+ <file>images/Remove_icon.png</file>
+ <file>images/Refresh_icon.png</file>
+ <file>images/CurveEditor.png</file>
+ <file>images/Add.png</file>
+ <file>images/Up.png</file>
+ <file>images/Down.png</file>
+ <file>images/EditWrench.png</file>
+ <file>images/playlist.png</file>
+ <file>images/visibilityToggle_notVisible.png</file>
+ <file>images/visibilityToggle_visible.png</file>
+ <file>ThemeDark.qss</file>
+ </qresource>
+</RCC>
+ \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/UI/AppMainWindow.ui b/tools/ArtistTools/source/CoreLib/UI/AppMainWindow.ui
new file mode 100644
index 0000000..da546fa
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/AppMainWindow.ui
@@ -0,0 +1,428 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AppMainWindowClass</class>
+ <widget class="QMainWindow" name="AppMainWindowClass">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1078</width>
+ <height>683</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Blast Viewer</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="renderLayout"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menuBar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1078</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusBar"/>
+ <widget class="QDockWidget" name="dockWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>370</width>
+ <height>140</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>524287</width>
+ <height>10000</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="features">
+ <set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
+ </property>
+ <property name="allowedAreas">
+ <set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set>
+ </property>
+ <property name="windowTitle">
+ <string>Attributes</string>
+ </property>
+ <attribute name="dockWidgetArea">
+ <number>2</number>
+ </attribute>
+ <widget class="QWidget" name="dockWidgetContents">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="leftMargin">
+ <number>3</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="sideBarTab">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <!--
+ <widget class="QWidget" name="tabFur">
+ <attribute name="title">
+ <string>Hair</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item row="1" column="0">
+ <widget class="QFrame" name="furMaterialEditorArea">
+ <layout class="QVBoxLayout" name="furMaterialEditorAreaLayout">
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QScrollArea" name="furScrollArea">
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAsNeeded</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="furScrollAreaContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>359</width>
+ <height>481</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="furScrollAreaLayout">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ -->
+ <widget class="QWidget" name="tabDisplay">
+ <attribute name="title">
+ <string>Settings</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QScrollArea" name="displayScrollArea">
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAsNeeded</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="displayScrollAreaContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>359</width>
+ <height>491</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="displayScrollAreaLayout">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <widget class="QDockWidget" name="dockOutputWindow">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>256</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="features">
+ <set>QDockWidget::AllDockWidgetFeatures</set>
+ </property>
+ <property name="allowedAreas">
+ <set>Qt::AllDockWidgetAreas</set>
+ </property>
+ <property name="windowTitle">
+ <string>Output Window</string>
+ </property>
+ <attribute name="dockWidgetArea">
+ <number>8</number>
+ </attribute>
+ <widget class="QWidget" name="dockWidgetContents_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Ignored" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="OutputWindow" name="outputWindow" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="openExternalLinks" stdset="0">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <!--
+ <widget class="QDockWidget" name="dockWidgetCurveEditor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>160</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Curve Editor</string>
+ </property>
+ <attribute name="dockWidgetArea">
+ <number>8</number>
+ </attribute>
+ <widget class="QWidget" name="dockWidgetContents_3">
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="furCurveEditorArea">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="furCurveEditorAreaLayout">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ -->
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+ <customwidget>
+ <class>OutputWindow</class>
+ <extends>QWidget</extends>
+ <header>outputwindow.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="AppMainWindow.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/CoreLib/UI/CameraBookmarksDialog.ui b/tools/ArtistTools/source/CoreLib/UI/CameraBookmarksDialog.ui
new file mode 100644
index 0000000..e914b60
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/CameraBookmarksDialog.ui
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CameraBookmarksDialog</class>
+ <widget class="QDialog" name="CameraBookmarksDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>CameraBookmarksDialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QListWidget" name="listWidgetBookmarks"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="labelBookmarkName">
+ <property name="text">
+ <string>Bookmark name:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="editBookmarkName"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="btnRename">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>23</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>rename</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnDelete">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>23</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>delete</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/CoreLib/UI/DisplayLightPanel.ui b/tools/ArtistTools/source/CoreLib/UI/DisplayLightPanel.ui
new file mode 100644
index 0000000..41514f5
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/DisplayLightPanel.ui
@@ -0,0 +1,645 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DisplayLightPanel</class>
+ <widget class="QWidget" name="DisplayLightPanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>340</width>
+ <height>315</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="10" column="0" colspan="2">
+ <widget class="QListWidget" name="listSelectedLight">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>320</width>
+ <height>60</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>320</width>
+ <height>60</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="1">
+ <widget class="QCheckBox" name="btnLightEnable">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="20" column="0">
+ <widget class="QLabel" name="label_1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Color</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="20" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnLightColor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="accessibleName">
+ <string/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnLightColorTex">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="accessibleName">
+ <string/>
+ </property>
+ <property name="accessibleDescription">
+ <string/>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnLightColorTexReload">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="accessibleName">
+ <string/>
+ </property>
+ <property name="accessibleDescription">
+ <string/>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnLightColorTexClear">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="accessibleName">
+ <string/>
+ </property>
+ <property name="accessibleDescription">
+ <string/>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="30" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Intensity</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="30" column="1">
+ <widget class="SlideSpinBox&lt;QDoubleSpinBox, double&gt;" name="spinLightIntensity" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="40" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Cast Shadow</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="40" column="1">
+ <widget class="QCheckBox" name="btnLightUseShadow">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="50" column="0">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>138</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Shadow Map Resolution</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="50" column="1">
+ <widget class="QComboBox" name="cbShadowMapResolution">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <item>
+ <property name="text">
+ <string>2048 (Default)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>4096</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>1024</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>512</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>8192</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>16384</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="12" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Enable</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Link Light</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="1">
+ <widget class="QCheckBox" name="btnLinkLightEnable">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>320</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>Visualize</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Light</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QCheckBox" name="btnVisualizeLight">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="0">
+ <widget class="QLabel" name="label_shadow">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="text">
+ <string>Shadow Map</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="1">
+ <widget class="QCheckBox" name="btnVisualizeShadowMap">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="30" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Distance</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="30" column="1">
+ <widget class="SlideSpinBox&lt;QDoubleSpinBox, double&gt;" name="spinLightDistance" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>SlideSpinBox&lt;QDoubleSpinBox, double&gt;</class>
+ <extends>QWidget</extends>
+ <header>SlideSpinBox.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/CoreLib/UI/DisplayPreferencesPanel.ui b/tools/ArtistTools/source/CoreLib/UI/DisplayPreferencesPanel.ui
new file mode 100644
index 0000000..0cdbcac
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/DisplayPreferencesPanel.ui
@@ -0,0 +1,885 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DisplayPreferencesPanel</class>
+ <widget class="QWidget" name="DisplayPreferencesPanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>320</width>
+ <height>515</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetFixedSize</enum>
+ </property>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="cbAntialiasing">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <item>
+ <property name="text">
+ <string>Hardware MSAA</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Custom MSAA 2x</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Custom MSAA 4x</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Custom MSAA 8x</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelRenderPlayRateFPS">
+ <property name="text">
+ <string>Render Play Rate FPS</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="spinRenderPlayRateFPS">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="decimals">
+ <number>0</number>
+ </property>
+ <property name="minimum">
+ <double>10.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>1000.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>60.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnBackgroundTex">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnBackgroundTexClear">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>110</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>138</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Navigation Style</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelCustomMSAA">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>138</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Custom Hair MSAA</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="cbUpAxis">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <item>
+ <property name="text">
+ <string>Y</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Z</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>138</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Background Image</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="SlideSpinBox&lt;QDoubleSpinBox, double&gt;" name="spinCameraFOV" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QComboBox" name="cbHandedness">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <item>
+ <property name="text">
+ <string>Right Handed</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Left Handed</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="cbSceneUnit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="currentText">
+ <string>Unknown</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>Unknown</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Centimeter</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Meter</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Inch</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>138</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Handedness</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>138</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Scene Unit</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>138</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Up Axis</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QComboBox" name="cbNavigationStyle">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <item>
+ <property name="text">
+ <string>Maya</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>3ds Max</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="labelCameraFOV">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>138</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Camera FOV</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelSimulationRateFPS">
+ <property name="text">
+ <string>Simulation Rate FPS</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="spinSimulationRateFPS">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>80</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="decimals">
+ <number>0</number>
+ </property>
+ <property name="minimum">
+ <double>10.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>1000.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>60.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>300</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>Playlists</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="30" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPlaylistAddProj">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPlaylistRemoveProj">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPlaylistProjGoUp">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPlaylistProjGoDown">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QPushButton" name="btnPlaylistsRename">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPlaylistsAdd">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPlaylistsReload">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPlaylistsRemove">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QComboBox" name="cbPlaylists">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" rowspan="3" colspan="2">
+ <widget class="TipListView" name="listWidgetPlaylist" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>280</width>
+ <height>90</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="31" column="1">
+ <widget class="QPushButton" name="btnPlaylistsPlay">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>SlideSpinBox&lt;QDoubleSpinBox, double&gt;</class>
+ <extends>QWidget</extends>
+ <header>SlideSpinBox.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>TipListView</class>
+ <extends>QWidget</extends>
+ <header>tiplistview.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/CoreLib/UI/DisplayScenePanel.ui b/tools/ArtistTools/source/CoreLib/UI/DisplayScenePanel.ui
new file mode 100644
index 0000000..5b24c41
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/DisplayScenePanel.ui
@@ -0,0 +1,616 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DisplayScenePanel</class>
+ <widget class="QWidget" name="DisplayScenePanel">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>320</width>
+ <height>282</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="12" column="1">
+ <widget class="QCheckBox" name="btnComputeProfile">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="1">
+ <widget class="QCheckBox" name="btnShowAxis">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="QCheckBox" name="btnShowGrid">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Show Grid</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QCheckBox" name="btnVisualizeWind">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Show HUD</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Show Axis</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="1">
+ <widget class="QCheckBox" name="btnShowHUD">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="2">
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>138</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Visualize Wind</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Compute Stats</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="1">
+ <widget class="QCheckBox" name="btnComputeStats">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Compute Profile</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="0">
+ <widget class="QLabel" name="labelGizmoWithLocal">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Gizmo With Local</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="1">
+ <widget class="QCheckBox" name="checkBoxGizmoWithLocal"/>
+ </item>
+ <item row="14" column="0">
+ <widget class="QLabel" name="labelGizmoWithDepthTest">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Gizmo With DepthTest</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="1">
+ <widget class="QCheckBox" name="checkBoxGizmoWithDepthTest"/>
+ </item>
+ <item row="15" column="0">
+ <widget class="QLabel" name="labelShowPlane">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Show Plane</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="1">
+ <widget class="QCheckBox" name="checkBoxShowPlane"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>Mesh Rendering</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Render Type</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="cbRenderType">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <property name="frame">
+ <bool>true</bool>
+ </property>
+ <item>
+ <property name="text">
+ <string>Wireframe</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Flat</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Shaded</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Textured</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Show Wireframe Over</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QCheckBox" name="btnShowWireframe">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Use Mesh Lighting</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QCheckBox" name="btnUseLighting">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Show Graphics Mesh</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="QCheckBox" name="btnShowGraphicsMesh">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QLabel" name="label_12">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Use Skinned Mesh Only</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="1">
+ <widget class="QCheckBox" name="btnShowSkinnedOnly">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0">
+ <widget class="QLabel" name="label_13">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
+ </property>
+ <property name="text">
+ <string>Use DQ Skinning</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="1">
+ <widget class="QCheckBox" name="btnSkinningDQ">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/CoreLib/UI/OutputWindow.ui b/tools/ArtistTools/source/CoreLib/UI/OutputWindow.ui
new file mode 100644
index 0000000..accef7b
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/OutputWindow.ui
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OutputWindow</class>
+ <widget class="QTextBrowser" name="textBrowser">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>676</width>
+ <height>430</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/ArtistTools/source/CoreLib/UI/ThemeDark.qss b/tools/ArtistTools/source/CoreLib/UI/ThemeDark.qss
new file mode 100644
index 0000000..f742ff0
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/ThemeDark.qss
@@ -0,0 +1,457 @@
+AppMainWindow *
+{
+ background-color:rgb(68,68,68); color:rgb(200,200,200);
+}
+
+AppMainWindow::separator
+{
+ background-color: rgb(68, 68, 68);
+
+ /*trick: qdockwidget stylesheet seems to have bugs, use the separator border*/
+
+ border-right-width: 2px;
+ border-image: url(:/AppMainWindow/images/DarkBorder.png) 2;
+}
+
+AppMainWindow::separator:hover
+{
+ background-color: #666666;
+}
+
+AppMainWindow QDockWidget::title
+{
+ text-align: center;
+ /*
+ border-top-color: rgb(45,45,45);
+ border-top-width: 2px;
+ border-top-style: groove;
+ */
+
+ background-color: rgb(68,68,68);
+ border-width: 2px;
+ border-image: url(:/AppMainWindow/images/DarkBorder.png) 2;
+
+}
+
+AppMainWindow QTextBrowser
+{
+ /*
+ border-width: 1px;
+ border-image: url(:/AppMainWindow/images/DarkBorder.png) 2;
+ */
+ border: 1px solid gray;
+ background-color:rgb(40,40,40);
+}
+
+AppMainWindow QCheckBox::indicator::unchecked
+{
+ background-color:rgb(40,40,40);
+}
+
+AppMainWindow QCheckBox::indicator::checked
+{
+ image:url(:/AppMainWindow/images/CheckBox.png);
+}
+
+AppMainWindow QPushButton
+{
+ border: 1px solid gray;
+}
+
+AppMainWindow QPushButton:pressed
+{
+ border: 2px solid rgb(118,185,0);
+ /*background-color: rgb(118,185,0);*/
+}
+
+AppMainWindow QPushButton:checked
+{
+ border: 2px solid rgb(118,185,0);
+ /*background-color: rgb(118,185,0);*/
+}
+
+/****** QScrollbar Styles ******/
+AppMainWindow QScrollBar:vertical
+{
+ width: 22px;
+ /*
+ border-width: 2px;
+ border-image: url(:/AppMainWindow/images/DarkBorder.png) 2;
+ */
+ border: 1px solid rgb(40,40,40);
+ margin: 20px 1px 20px 0px;
+}
+
+AppMainWindow QScrollBar::handle:vertical
+{
+ border-top: 1px solid rgb(40,40,40);
+ border-bottom: 1px solid rgb(40,40,40);
+ background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
+ stop:0 rgb(116,116,116), stop: 1 rgb(95,95,95));
+ min-height: 20px;
+}
+
+AppMainWindow QScrollBar::add-line:vertical
+{
+ border: 1px solid rgb(40,40,40);
+ background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
+ stop:0 rgb(116,116,116), stop: 1 rgb(95,95,95));
+
+ margin-right: 1px;
+ margin-bottom: 1px;
+ height: 18px;
+ subcontrol-position: bottom;
+ subcontrol-origin: margin;
+}
+
+AppMainWindow QScrollBar::sub-line:vertical
+{
+ margin-top: 1px;
+ margin-right: 1px;
+ border: 1px solid rgb(40,40,40);
+ background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
+ stop:0 rgb(116,116,116), stop: 1 rgb(95,95,95));
+ height: 18px;
+ subcontrol-position: top;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::up-arrow:vertical
+{
+ image: url(:/AppMainWindow/images/ArrowUp.png);
+}
+
+QScrollBar::up-arrow:vertical:pressed
+{
+ top: 1px;
+}
+
+QScrollBar::down-arrow:vertical
+{
+ image: url(:/AppMainWindow/images/ArrowDown.png);
+}
+
+QScrollBar::down-arrow:vertical:pressed
+{
+ top: 1px;
+}
+
+AppMainWindow QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical
+{
+ background: none;
+}
+
+/****** ListWidget Styles ******/
+AppMainWindow QListWidget {
+ alternate-background-color: yellow;
+ border: 1px solid gray;
+ border-radius: 0px;
+ }
+
+AppMainWindow QListWidget {
+ show-decoration-selected: 1; /* make the selection span the entire width of the view */
+ }
+
+ AppMainWindow QListWidget::item:alternate {
+ background: #EEEEEE;
+ }
+
+ AppMainWindow QListWidget::item:selected {
+ border: 1px solid #6a6ea9;
+ }
+
+ AppMainWindow QListWidget::item:selected:!active {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #00aa00, stop: 1 #00dd00);
+ }
+
+ AppMainWindow QListWidget::item:selected:active {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #00aa00, stop: 1 #00dd00);
+ }
+
+ AppMainWindow QListWidget::item:hover {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #DDFFDD, stop: 1 #CCFFCC);
+ }
+
+ /****** TreeWidget Styles ******/
+AppMainWindow QTreeWidget {
+ alternate-background-color: yellow;
+ border: 1px solid gray;
+ border-radius: 0px;
+ }
+
+AppMainWindow QTreeWidget {
+ show-decoration-selected: 1; /* make the selection span the entire width of the view */
+ }
+
+ AppMainWindow QTreeWidget::item:alternate {
+ background: #EEEEEE;
+ }
+
+ AppMainWindow QTreeWidget::item:selected {
+ border: 1px solid #6a6ea9;
+ }
+
+ AppMainWindow QTreeWidget::item:selected:!active {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #00aa00, stop: 1 #00dd00);
+ }
+
+ AppMainWindow QTreeWidget::item:selected:active {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #00aa00, stop: 1 #00dd00);
+ }
+
+ AppMainWindow QTreeWidget::item:hover {
+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #DDFFDD, stop: 1 #CCFFCC);
+ }
+
+/****** ComboBox Styles ******/
+AppMainWindow QComboBox {
+ border: 1px solid gray;
+ border-radius: 0px;
+ }
+
+AppMainWindow QComboBox QAbstractItemView
+{
+ background-color: rgb(68,68,68);
+ selection-background-color: rgb(118,185,0);
+}
+
+ AppMainWindow QComboBox::drop-down {
+ subcontrol-origin: padding;
+ subcontrol-position: top right;
+ /*width: 15px;*/
+
+ border-left-width: 1px;
+ border-left-color: gray;
+ border-left-style: solid;
+
+ }
+
+AppMainWindow QComboBox::down-arrow {
+ image: url(:/AppMainWindow/images/ArrowDown.png);
+ }
+
+AppMainWindow QComboBox::down-arrow:on {
+ top: 1px;
+
+ }
+
+/****** QTabWidget Styles ******/
+AppMainWindow QTabWidget::pane
+{
+ /* The tab widget frame */
+ border-top: 0px solid transparent;
+
+}
+
+AppMainWindow QTabWidget::tab-bar
+{
+ left: 5px;
+}
+
+AppMainWindow QTabBar::tab {
+ margin-top: 1px;
+ background-color: rgb(68,68,68);
+ border: 1px solid gray;
+ border-bottom-color: rgb(68,68,68); /* same as the pane color */
+ min-width: 10ex;
+ padding: 2px 8px;
+}
+
+AppMainWindow QTabBar::tab:selected
+{
+ background-color: #666666;
+ border-color: gray;
+ border-bottom-color: transparent;
+}
+
+AppMainWindow QTabBar::tab:!selected {
+ margin-top: 3px; /* make non-selected tabs look smaller */
+}
+
+/****** Spin And DoubleSpin Styles ******/
+
+AppMainWindow QDoubleSpinBox
+ {
+ border: 1px solid gray;
+ background-color: rgb(40,40,40);
+ }
+
+AppMainWindow QSpinBox
+ {
+ border: 1px solid gray;
+ background-color: rgb(40,40,40);
+ }
+
+AppMainWindow QSpinBox::up-button
+{
+ background-color:rgb(68,68,68);
+ border: 1px solid gray;
+ margin-top: 1px;
+ margin-right: 1px;
+}
+
+AppMainWindow QSpinBox::up-button:pressed {
+ border: 1px solid rgb(118,185,0);
+}
+
+AppMainWindow QSpinBox::down-button
+{
+ background-color:rgb(68,68,68);
+ border: 1px solid gray;
+ margin-bottom: 1px;
+ margin-right: 1px;
+}
+
+AppMainWindow QSpinBox::down-button:pressed {
+ border: 1px solid rgb(118,185,0);
+}
+
+AppMainWindow QSpinBox::up-arrow
+{
+ image: url(:/AppMainWindow/images/ArrowUp.png);
+ width: 4px;
+}
+AppMainWindow QSpinBox::down-arrow
+{
+ image: url(:/AppMainWindow/images/ArrowDown.png);
+ width: 4px;
+}
+
+AppMainWindow QDoubleSpinBox::up-button
+{
+ background-color:rgb(68,68,68);
+ border: 1px solid gray;
+ margin-top: 1px;
+ margin-right: 1px;
+}
+
+AppMainWindow QDoubleSpinBox::up-button:pressed {
+ border: 1px solid rgb(118,185,0);
+}
+
+AppMainWindow QDoubleSpinBox::down-button
+{
+ background-color:rgb(68,68,68);
+ border: 1px solid gray;
+ margin-bottom: 1px;
+ margin-right: 1px;
+}
+
+AppMainWindow QDoubleSpinBox::down-button:pressed {
+ border: 1px solid rgb(118,185,0);
+}
+
+AppMainWindow QDoubleSpinBox::up-arrow
+{
+ image: url(:/AppMainWindow/images/ArrowUp.png);
+ width: 4px;
+}
+
+AppMainWindow QDoubleSpinBox::down-arrow
+{
+ image: url(:/AppMainWindow/images/ArrowDown.png);
+ width: 4px;
+}
+
+AppMainWindow QDoubleSpinBox::disabled
+{
+ background-color:rgb(32,32,32);
+ color:rgb(68,68,68);
+ border: 1px solid rgb(68,68,68);
+}
+
+AppMainWindow QDoubleSpinBox::up-button:disabled {
+ border: 1px solid rgb(68,68,68);
+}
+
+AppMainWindow QDoubleSpinBox::down-button:disabled {
+ border: 1px solid rgb(68,68,68);
+}
+
+/****** Menu Styles ******/
+QMenuBar
+{
+ border-image: url(:/AppMainWindow/images/DarkBorder.png) 2;
+ border-bottom-width: 2px;
+}
+
+AppMainWindow QMenuBar::item
+{
+ spacing: 3px; /* spacing between menu bar items */
+ padding: 1px 4px;
+ margin-bottom: 2px;
+ background: transparent;
+ border-radius: 0px;
+}
+
+AppMainWindow QMenuBar::item:selected:enabled { /* when selected using mouse or keyboard */
+ background: #666666;
+}
+
+AppMainWindow QMenuBar::item:pressed:enabled {
+ background: rgb(118,185,0);
+}
+
+AppMainWindow QMenu {
+ border: 1px solid rgb(50,50,50);
+
+}
+
+AppMainWindow QMenuBar:disabled
+{
+ color:rgb(0,0,0);
+}
+
+AppMainWindow QMenu:disabled
+{
+ color:rgb(0,0,0);
+}
+
+AppMainWindow QMenu::item {
+ padding: 2px 25px 2px 20px;
+ border: 1px solid transparent; /* reserve space for selection border */
+}
+
+AppMainWindow QMenu::item:selected:enabled {
+ border-color: rgb(70,70,70);
+ background: rgba(118,185,0, 250);
+}
+/****** ExpandablePanel Styles ******/
+
+AppMainWindow QGroupBox
+{
+ margin-top: 1.5ex;
+ border: 1px solid gray;
+ border-radius: 0px;
+}
+
+AppMainWindow QGroupBox::title
+{
+ subcontrol-origin: margin;
+ left: 10px;
+ padding: 0px 3px;
+}
+
+/*
+ExpandablePanel QPushButton[flat="true"]
+{
+ border-color: rgb(40,40,40);
+ image:url(:/AppMainWindow/images/TextureBox.bmp)
+}
+
+ExpandablePanel QPushButton[flat="true"]:pressed
+{
+ margin: 2px;
+}
+*/
+
+ExpandablePanel TitleLabel
+{
+ background:rgb(78, 78, 78);
+}
diff --git a/tools/ArtistTools/source/CoreLib/UI/ThemeDefault.qss b/tools/ArtistTools/source/CoreLib/UI/ThemeDefault.qss
new file mode 100644
index 0000000..f59dd25
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/ThemeDefault.qss
@@ -0,0 +1,76 @@
+/****** General Styles ******/
+
+AppMainWindow QPushButton
+{
+ /*border: 1px solid gray;*/
+ background-color: rgb(230,230,230);
+ border-left: 1px solid rgb(200,200,200);
+ border-top: 1px solid rgb(200,200,200);
+ border-right: 1px solid rgb(60,60,60);
+ border-bottom: 1px solid rgb(60,60,60);
+}
+
+
+AppMainWindow QPushButton:pressed
+{
+ /*border: 2px solid gray;*/
+ border-left: 1px solid rgb(60,60,60);
+ border-top: 1px solid rgb(60,60,60);
+ border-right: 1px solid rgb(200,200,200);
+ border-bottom: 1px solid rgb(200,200,200);
+}
+
+AppMainWindow QPushButton:checked
+{
+ border: 1px solid gray;
+ border-left: 1px solid rgb(60,60,60);
+ border-top: 1px solid rgb(60,60,60);
+ border-right: 1px solid rgb(200,200,200);
+ border-bottom: 1px solid rgb(200,200,200);
+}
+/****** MainToolbar Styles ******/
+
+MainToolbar QPushButton[flat="true"]
+{
+ border:0px;
+}
+
+
+/****** ExpandablePanel Styles ******/
+
+ExpandablePanel
+{
+ background:rgb(240,240,240);
+}
+
+ExpandablePanel QGroupBox
+{
+ margin-top: 1.5ex;
+ border: 1px solid gray;
+ border-radius: 0px;
+}
+
+ExpandablePanel QGroupBox::title
+{
+ subcontrol-origin: margin;
+ left: 10px;
+ padding: 0px 3px;
+}
+
+ExpandablePanel QPushButton[flat="true"]
+{
+ border: 1px solid rgb(60,60,60);
+ image:url(:/AppMainWindow/images/TextureBox.bmp)
+}
+
+ExpandablePanel QPushButton[flat="true"]:pressed
+{
+ border: 2px solid rgb(60,60,60);
+ image:url(:/AppMainWindow/images/TextureBox.bmp)
+}
+
+ExpandablePanel TitleLabel
+{
+ background:rgb(219, 219, 219);
+ border-bottom:1px solid rgb(185,185,185);
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/Add.png b/tools/ArtistTools/source/CoreLib/UI/images/Add.png
new file mode 100644
index 0000000..35fd8ed
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/Add.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/ArrowDown.png b/tools/ArtistTools/source/CoreLib/UI/images/ArrowDown.png
new file mode 100644
index 0000000..9b55420
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/ArrowDown.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/ArrowUp.png b/tools/ArtistTools/source/CoreLib/UI/images/ArrowUp.png
new file mode 100644
index 0000000..fea1fbe
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/ArrowUp.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/CheckBox.png b/tools/ArtistTools/source/CoreLib/UI/images/CheckBox.png
new file mode 100644
index 0000000..ac53487
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/CheckBox.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/CurveEditor.png b/tools/ArtistTools/source/CoreLib/UI/images/CurveEditor.png
new file mode 100644
index 0000000..f92c6e4
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/CurveEditor.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/DarkBorder.png b/tools/ArtistTools/source/CoreLib/UI/images/DarkBorder.png
new file mode 100644
index 0000000..9771804
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/DarkBorder.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/Down.png b/tools/ArtistTools/source/CoreLib/UI/images/Down.png
new file mode 100644
index 0000000..376a821
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/Down.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/EditWrench.png b/tools/ArtistTools/source/CoreLib/UI/images/EditWrench.png
new file mode 100644
index 0000000..563a602
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/EditWrench.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/Refresh_icon.png b/tools/ArtistTools/source/CoreLib/UI/images/Refresh_icon.png
new file mode 100644
index 0000000..c189dd5
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/Refresh_icon.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/Remove_icon.png b/tools/ArtistTools/source/CoreLib/UI/images/Remove_icon.png
new file mode 100644
index 0000000..ebb63d9
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/Remove_icon.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/TextureBox.bmp b/tools/ArtistTools/source/CoreLib/UI/images/TextureBox.bmp
new file mode 100644
index 0000000..43f95b2
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/TextureBox.bmp
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/TextureDisabled_icon.png b/tools/ArtistTools/source/CoreLib/UI/images/TextureDisabled_icon.png
new file mode 100644
index 0000000..3a727f4
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/TextureDisabled_icon.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/TextureEnabled_icon.png b/tools/ArtistTools/source/CoreLib/UI/images/TextureEnabled_icon.png
new file mode 100644
index 0000000..a8f11d5
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/TextureEnabled_icon.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/TextureIsUsed_icon.png b/tools/ArtistTools/source/CoreLib/UI/images/TextureIsUsed_icon.png
new file mode 100644
index 0000000..75d52dc
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/TextureIsUsed_icon.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/Up.png b/tools/ArtistTools/source/CoreLib/UI/images/Up.png
new file mode 100644
index 0000000..6f8903c
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/Up.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/importFile.png b/tools/ArtistTools/source/CoreLib/UI/images/importFile.png
new file mode 100644
index 0000000..e4ffc91
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/importFile.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/openFile.png b/tools/ArtistTools/source/CoreLib/UI/images/openFile.png
new file mode 100644
index 0000000..b91e69c
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/openFile.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/playlist.png b/tools/ArtistTools/source/CoreLib/UI/images/playlist.png
new file mode 100644
index 0000000..3c6db13
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/playlist.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/refreshReload.png b/tools/ArtistTools/source/CoreLib/UI/images/refreshReload.png
new file mode 100644
index 0000000..745c9cb
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/refreshReload.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/saveDisc.png b/tools/ArtistTools/source/CoreLib/UI/images/saveDisc.png
new file mode 100644
index 0000000..c0dc719
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/saveDisc.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/simulationPlay.png b/tools/ArtistTools/source/CoreLib/UI/images/simulationPlay.png
new file mode 100644
index 0000000..e5bc551
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/simulationPlay.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/simulationStep.png b/tools/ArtistTools/source/CoreLib/UI/images/simulationStep.png
new file mode 100644
index 0000000..8ab9e49
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/simulationStep.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/simulationStop.png b/tools/ArtistTools/source/CoreLib/UI/images/simulationStop.png
new file mode 100644
index 0000000..8576b5b
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/simulationStop.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/transportLoop.png b/tools/ArtistTools/source/CoreLib/UI/images/transportLoop.png
new file mode 100644
index 0000000..3e13e2f
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/transportLoop.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/transportPlay.png b/tools/ArtistTools/source/CoreLib/UI/images/transportPlay.png
new file mode 100644
index 0000000..e5e593e
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/transportPlay.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/transportRewind.png b/tools/ArtistTools/source/CoreLib/UI/images/transportRewind.png
new file mode 100644
index 0000000..95664d2
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/transportRewind.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/transportStepForward.png b/tools/ArtistTools/source/CoreLib/UI/images/transportStepForward.png
new file mode 100644
index 0000000..4d35753
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/transportStepForward.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/transportStop.png b/tools/ArtistTools/source/CoreLib/UI/images/transportStop.png
new file mode 100644
index 0000000..27f3cbd
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/transportStop.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/visibilityToggle_notVisible.png b/tools/ArtistTools/source/CoreLib/UI/images/visibilityToggle_notVisible.png
new file mode 100644
index 0000000..56b24fe
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/visibilityToggle_notVisible.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/UI/images/visibilityToggle_visible.png b/tools/ArtistTools/source/CoreLib/UI/images/visibilityToggle_visible.png
new file mode 100644
index 0000000..3e5a88e
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/UI/images/visibilityToggle_visible.png
Binary files differ
diff --git a/tools/ArtistTools/source/CoreLib/Utils/XMLHelper.cpp b/tools/ArtistTools/source/CoreLib/Utils/XMLHelper.cpp
new file mode 100644
index 0000000..c48b0dc
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/XMLHelper.cpp
@@ -0,0 +1,121 @@
+#include "XMLHelper.h"
+#include <QtXml\QtXml>
+#include "ViewerOutput.h"
+
+static int gcounter = 0;
+static char gbuf[256];
+
+XMLFile::XMLFile(const QString& rootName)
+ : _rootName(rootName)
+{
+}
+
+void XMLFile::load(const QString& filePath)
+{
+ QFile file(filePath);
+
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ return;
+ }
+
+ QDomDocument xmlDoc;
+ if (!xmlDoc.setContent(&file))
+ {
+ file.close();
+ return;
+ }
+ file.close();
+
+ if (xmlDoc.isNull() || xmlDoc.documentElement().tagName() != _rootName)
+ {
+ sprintf(gbuf, "The file you selected is empty or not a speficied file: %s.", filePath.toStdString().c_str());
+ viewer_msg(gbuf);
+ return;
+ }
+
+ loadItems(xmlDoc);
+
+ //QDomNodeList elms = xmlDoc.documentElement().elementsByTagName(QObject::tr("StressSolverPreset"));
+ //for (int i = 0; i < elms.count(); ++i)
+ //{
+ // StressSolverUserPreset preset("");
+ // _userPresets.push_back(preset);
+ // _loadStressSolverPreset(elms.at(i).toElement(), _userPresets[i]);
+ //}
+}
+
+void XMLFile::save(const QString& filePath)
+{
+ std::string rr = filePath.toStdString();
+ rr;
+
+ QFileInfo fileInfo(filePath);
+ QDir fileDir = fileInfo.absoluteDir();
+
+ QString tt = fileDir.absolutePath();
+ std::string hh = tt.toStdString();
+ hh;
+
+ if (!fileDir.exists())
+ {
+ if (!fileDir.mkdir(fileDir.absolutePath()))
+ {
+ sprintf(gbuf, "Failed to crreate the folder: %s.", filePath.toStdString().c_str());
+ viewer_msg(gbuf);
+ return;
+ }
+ }
+ QFile file(filePath);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ {
+ return;
+ }
+ QTextStream out(&file);
+
+ QDomDocument xmlDoc;
+ QDomElement rootElm = xmlDoc.createElement(_rootName);
+ xmlDoc.appendChild(rootElm);
+
+ saveItems(xmlDoc);
+
+ // 4 is count of indent
+ xmlDoc.save(out, 4);
+}
+
+SingleItemKindFile::SingleItemKindFile(const QString& rootName, const QString& itemName)
+ : XMLFile(rootName)
+ , _itemName(itemName)
+{
+}
+
+void SingleItemKindFile::loadItems(QDomDocument xmlDoc)
+{
+ QDomNodeList elms = xmlDoc.documentElement().elementsByTagName(_itemName);
+ for (int i = 0; i < elms.count(); ++i)
+ {
+ QDomElement elm = elms.at(i).toElement();
+ _items.push_back(elm.attribute(QObject::tr("Value")));
+ }
+}
+
+void SingleItemKindFile::saveItems(QDomDocument xmlDoc)
+{
+ for (int i = 0; i < _items.count(); ++i)
+ {
+ QDomElement elm = xmlDoc.createElement(_itemName);
+ elm.setAttribute(QObject::tr("Value"), _items.at(i));
+ xmlDoc.documentElement().appendChild(elm);
+ }
+}
+
+bool SingleItemKindFile::isItemExist(const QString& item)
+{
+ for (int i = 0; i < _items.count(); ++i)
+ {
+ if (_items.at(i) == item)
+ return true;
+ }
+
+ return false;
+}
diff --git a/tools/ArtistTools/source/CoreLib/Utils/XMLHelper.h b/tools/ArtistTools/source/CoreLib/Utils/XMLHelper.h
new file mode 100644
index 0000000..ca43033
--- /dev/null
+++ b/tools/ArtistTools/source/CoreLib/Utils/XMLHelper.h
@@ -0,0 +1,39 @@
+#pragma once
+#include <QtCore\QString>
+#include <QtCore\QList>
+#include "corelib_global.h"
+
+class QDomDocument;
+
+class CORELIB_EXPORT XMLFile
+{
+public:
+ XMLFile(const QString& rootName);
+
+ void load(const QString& filePath);
+ void save(const QString& filePath);
+
+protected:
+ virtual void loadItems(QDomDocument xmlDoc) = 0;
+ virtual void saveItems(QDomDocument xmlDoc) = 0;
+protected:
+ QString _rootName;
+};
+
+class CORELIB_EXPORT SingleItemKindFile : public XMLFile
+{
+public:
+ SingleItemKindFile(const QString& rootName, const QString& itemName);
+
+ virtual void loadItems(QDomDocument xmlDoc);
+ virtual void saveItems(QDomDocument xmlDoc);
+
+ void addItemBack(const QString& item) { _items.push_back(item); }
+ void addItemFront(const QString& item) { _items.push_back(item); }
+ QList<QString>& getItems() { return _items; }
+ bool isItemExist(const QString& item);
+
+private:
+ QString _itemName;
+ QList<QString> _items;
+};
diff --git a/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp
index 3a85d8b..31a5dc5 100644
--- a/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp
+++ b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp
@@ -151,6 +151,8 @@ AppMainWindow::AppMainWindow(QWidget *parent, Qt::WindowFlags flags)
,_bookmarkActionGroup(0)
,_actionAddBookmark(0)
,_actionEditBookmarks(0)
+ , _recentMenu(NV_NULL)
+ , _recentFileRecordFile("RecentFiles", "File")
{
setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
@@ -178,6 +180,8 @@ AppMainWindow::AppMainWindow(QWidget *parent, Qt::WindowFlags flags)
_progressDialog.close(); // prevent show one empty progress dialog when it runs.
m_bGizmoWithLocal = false;
+ m_bGizmoWithDepthTest = false;
+ m_bShowPlane = false;
}
void AppMainWindow::InitUI()
@@ -279,6 +283,8 @@ void AppMainWindow::InitMenuItems()
if (_connectionMode != 1)
{
+ connect(ui.menuBar, SIGNAL(triggered(QAction*)), this, SLOT(menu_item_triggered(QAction*)));
+
act = new QAction("Clear scene", this);
act->setShortcut(QKeySequence::New);
connect(act, SIGNAL(triggered()), this, SLOT(menu_clearScene()));
@@ -292,6 +298,15 @@ void AppMainWindow::InitMenuItems()
fileMenu->addSeparator();
+ act = new QAction("Recents", this);
+ fileMenu->addAction(act);
+ _recentMenu = new QMenu("Recents", this);
+ act->setMenu(_recentMenu);
+
+ fileMenu->addSeparator();
+
+ _loadRecentFile();
+
#ifndef NV_ARTISTTOOLS
fileMenu->addSeparator();
act = new QAction("Open project file", this);
@@ -559,6 +574,7 @@ void AppMainWindow::InitMainTab()
panel->AddContent(_displayMeshesPanel);
ui.displayScrollAreaLayout->insertWidget(idx++, panel);
panel->SetTitle("Display Meshes");
+ panel->setVisible(false);
}
if (_connectionMode != 1)
@@ -792,9 +808,10 @@ bool AppMainWindow::openProject(QString fileName)
return false;
}
-void AppMainWindow::processDragAndDrop(QString fname)
+void AppMainWindow::processDragAndDrop(const QStringList& fileNames)
{
- openProject(fname);
+ CoreLib::Inst()->SimpleScene_OpenFilesByDrop(fileNames);
+ updateUI();
}
void AppMainWindow::removeBookmark(const QString& name)
@@ -861,6 +878,33 @@ void AppMainWindow::ShowCurveEditor(int paramId)
}
#endif
+void AppMainWindow::menu_item_triggered(QAction* action)
+{
+ qDebug("%s", __FUNCTION__);
+#ifdef NV_ARTISTTOOLS
+
+ bool clickRecent = false;
+ for (int i = 0; i < _recentFileActions.count(); ++i)
+ {
+ if (_recentFileActions.at(i) == action)
+ {
+ clickRecent = true;
+ break;
+ }
+ }
+
+ if (clickRecent)
+ {
+ QStringList recentFile;
+ recentFile.push_back(action->text());
+ CoreLib::Inst()->SimpleScene_OpenFilesByDrop(recentFile);
+ return;
+ }
+
+ CoreLib::Inst()->menu_item_triggered(action);
+#endif // NV_ARTISTTOOLS
+}
+
void AppMainWindow::menu_clearScene()
{
SimpleScene::Inst()->Clear();
@@ -905,7 +949,9 @@ bool AppMainWindow::menu_openfbx()
*/
// dir and file will get in blast open asset dialog
- return SimpleScene::Inst()->LoadSceneFromFbx("", "");
+ bool res = SimpleScene::Inst()->LoadSceneFromFbx("", "");
+ updateUI();
+ return res;
}
void AppMainWindow::menu_addBookmark()
@@ -1146,7 +1192,8 @@ char AppMainWindow::TestMouseScheme( Qt::KeyboardModifiers modifiers, Qt::MouseB
if (op != 0)
return op;
- if (modifiers == Qt::KeyboardModifier(Qt::ControlModifier))
+ bool isKeyL = (GetAsyncKeyState('L') && 0x8000);
+ if (isKeyL) //if(modifiers == Qt::KeyboardModifier(Qt::ControlModifier)) // ctrl is used by Selection Tool
{
if (buttons == Qt::MouseButton(Qt::LeftButton))
return 'L';
@@ -1174,16 +1221,114 @@ char AppMainWindow::TestDragCamera( Qt::KeyboardModifiers modifiers, Qt::MouseBu
if(scheme == MAYA_SCHEME)
{
auto itr = _mayaScheme.find(input);
- if(itr != _mayaScheme.end()) return itr.value();
+ if(itr != _mayaScheme.end())
+ return itr.value();
}
else
{
auto itr = _maxScheme.find(input);
- if(itr != _maxScheme.end()) return itr.value();
+ if(itr != _maxScheme.end())
+ return itr.value();
}
return 0;
}
+void AppMainWindow::addRecentFile(const QString filePath)
+{
+ if (filePath.isEmpty())
+ return;
+
+ if (_recentFileRecordFile.getItems().count() > 0 && _recentFileRecordFile.getItems().first() == filePath)
+ return;
+
+ if (_recentFileActions.count() == 8)
+ {
+ QAction* act = _recentFileActions.last();
+ _recentMenu->removeAction(act);
+
+ _recentFileRecordFile.getItems().pop_back();
+ _recentFileActions.pop_back();
+ }
+
+ if (_recentFileRecordFile.isItemExist(filePath))
+ {
+ _resetRecentFile(filePath);
+ return;
+ }
+
+ QAction* act = new QAction(filePath, _recentMenu);
+ if (_recentFileActions.count() > 0)
+ _recentMenu->insertAction(_recentFileActions.first(), act);
+ else
+ _recentMenu->addAction(act);
+
+ _recentFileActions.push_front(act);
+
+ _recentFileRecordFile.getItems().push_front(filePath);
+
+ _saveRecentFile();
+}
+
+void AppMainWindow::_resetRecentFile(const QString filePath)
+{
+ if (filePath.isEmpty())
+ return;
+
+ if (_recentFileRecordFile.getItems().count() > 0 && _recentFileRecordFile.getItems().first() == filePath)
+ return;
+
+ if (!_recentFileRecordFile.isItemExist(filePath))
+ return;
+
+ QList<QAction*> actions;
+ for (int i = 0; i < _recentFileActions.count(); ++i)
+ {
+ QAction* act = _recentFileActions.at(i);
+ if (act->text() == filePath)
+ actions.push_front(act);
+ else
+ actions.push_back(act);
+ }
+
+ _recentMenu->addActions(actions);
+ _recentFileActions = actions;
+
+ QList<QString> filesTMP;
+ QList<QString>& filesCurrent = _recentFileRecordFile.getItems();
+ for (int i = 0; i < filesCurrent.count(); ++i)
+ {
+ QString item = filesCurrent.at(i);
+ if (item == filePath)
+ filesTMP.push_front(item);
+ else
+ filesTMP.push_back(item);
+ }
+ filesCurrent.clear();
+ filesCurrent = filesTMP;
+
+ _saveRecentFile();
+}
+
+void AppMainWindow::_loadRecentFile()
+{
+ QString recentFileRecordFile = QCoreApplication::applicationDirPath() + "/RecentFiles.rfs";
+ _recentFileRecordFile.load(recentFileRecordFile);
+
+ QList<QString> recentFiles = _recentFileRecordFile.getItems();
+ _recentFileRecordFile.getItems().clear();
+
+ for (int i = recentFiles.count() - 1; i >= 0; --i)
+ {
+ addRecentFile(recentFiles.at(i));
+ }
+}
+
+void AppMainWindow::_saveRecentFile()
+{
+ QString recentFileRecordFile = QCoreApplication::applicationDirPath() + "/RecentFiles.rfs";
+ _recentFileRecordFile.save(recentFileRecordFile);
+}
+
QString AppMainWindow::OpenTextureFile(QString title)
{
QString lastDir = _lastFilePath;
@@ -1268,7 +1413,7 @@ void AppMainWindow::updateMainToolbar()
bool AppMainWindow::menu_openProject()
{
QString lastDir = _lastFilePath;
- QString fileName = QFileDialog::getOpenFileName(this, "Open Hair Project File", lastDir, "Hair Project File (*.furproj)");
+ QString fileName = QFileDialog::getOpenFileName(this, "Open Project File", lastDir, "Project File (*.blastProj)");
return openProject(fileName);
}
@@ -1318,7 +1463,7 @@ bool AppMainWindow::menu_saveProjectAs()
char message[1024];
QString lastDir = _lastFilePath;
- QString fileName = QFileDialog::getSaveFileName(this, "Save Hair Project File", lastDir, "Hair Project File (*.furproj)");
+ QString fileName = QFileDialog::getSaveFileName(this, "Save Project File", lastDir, "Project File (*.blastProj)");
if (!fileName.isEmpty())
{
QFileInfo fileInfo(fileName);
diff --git a/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h
index 4183fc2..823c14f 100644
--- a/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h
+++ b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h
@@ -6,6 +6,7 @@
#include "ui_AppMainWindow.h"
#include "UIGlobal.h"
+#include "XMLHelper.h"
class StyleMaterialPanel;
class AssetControlPanel;
@@ -72,7 +73,7 @@ public:
CORELIB_EXPORT void quit();
CORELIB_EXPORT void updateMainToolbar();
- CORELIB_EXPORT void processDragAndDrop(QString fname);
+ CORELIB_EXPORT void processDragAndDrop(const QStringList& fileNames);
CORELIB_EXPORT bool openProject(QString fileName);
CORELIB_EXPORT static void setConnectionMode(int);
@@ -96,6 +97,7 @@ signals:
void aboutToQuit();
public slots:
+ CORELIB_EXPORT void menu_item_triggered(QAction* action);
CORELIB_EXPORT void menu_clearScene();
CORELIB_EXPORT bool menu_openfbx();
CORELIB_EXPORT void menu_addBookmark();
@@ -125,9 +127,14 @@ signals:
CORELIB_EXPORT void onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex);
#endif
+ CORELIB_EXPORT void addRecentFile(const QString filePath);
private:
char TestDragCamera(Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons);
+ void _resetRecentFile(const QString filePath);
+ void _loadRecentFile();
+ void _saveRecentFile();
+
public:
void InitMenuItems();
void InitToolbar();
@@ -140,6 +147,10 @@ public:
Ui::AppMainWindowClass ui;
D3DWidget* _d3dWidget;
+ QMenu* _recentMenu;
+ QList<QAction*> _recentFileActions;
+ SingleItemKindFile _recentFileRecordFile;
+
QMenu* _bookmarksMenu;
DisplayMeshesPanel* _displayMeshesPanel;
@@ -203,6 +214,8 @@ private:
#endif // NV_ARTISTTOOLS
bool m_bGizmoWithLocal;
+ bool m_bGizmoWithDepthTest;
+ bool m_bShowPlane;
};
#endif // APPMAINWINDOW_H
diff --git a/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp b/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp
index 69be706..73aabfc 100644
--- a/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp
+++ b/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp
@@ -58,21 +58,18 @@ void D3DWidget::dropEvent(QDropEvent *e)
return;
QList<QUrl> urlList = data->urls();
- QString text;
+ QStringList fileNames;
for (int i = 0; i < urlList.size() && i < 32; ++i) {
- QString url = urlList.at(i).toLocalFile();
- text += url;
+ fileNames.append(urlList.at(i).toLocalFile());
}
e->acceptProposedAction();
- AppMainWindow::Inst().processDragAndDrop(text);
+ AppMainWindow::Inst().processDragAndDrop(fileNames);
}
void D3DWidget::paintEvent( QPaintEvent* e )
{
- CoreLib::Inst()->D3DWidget_paintEvent(e);
-
SimpleScene::Inst()->Draw();
}
@@ -98,40 +95,42 @@ void D3DWidget::resizeEvent( QResizeEvent* e )
void D3DWidget::mouseMoveEvent( QMouseEvent* e )
{
- CoreLib::Inst()->D3DWidget_mouseMoveEvent(e);
-
atcore_float2 pos = gfsdk_makeFloat2(e->x(), e->y());
SimpleScene::Inst()->onMouseMove(pos);
Q_ASSERT(_appWindow != NV_NULL);
char mode = _appWindow->TestMouseScheme(e->modifiers(), e->buttons());
-
+ CoreLib::Inst()->D3DWidget_mouseMoveEvent(e);
+ if (!e->isAccepted())
+ {
+ return;
+ }
if(mode == 0) return;
SimpleScene::Inst()->Drag(mode);
}
void D3DWidget::wheelEvent(QWheelEvent* e)
{
- CoreLib::Inst()->D3DWidget_wheelEvent(e);
-
SimpleScene::Inst()->onMouseWheel(e->delta());
SimpleScene::Inst()->WheelZoom();
+
+ CoreLib::Inst()->D3DWidget_wheelEvent(e);
}
void D3DWidget::mousePressEvent( QMouseEvent* e )
{
- CoreLib::Inst()->D3DWidget_mousePressEvent(e);
-
atcore_float2 pos = gfsdk_makeFloat2(e->x(), e->y());
SimpleScene::Inst()->onMouseDown(pos);
+
+ CoreLib::Inst()->D3DWidget_mousePressEvent(e);
}
void D3DWidget::mouseReleaseEvent( QMouseEvent* e )
{
- CoreLib::Inst()->D3DWidget_mouseReleaseEvent(e);
-
atcore_float2 pos = gfsdk_makeFloat2(e->x(), e->y());
SimpleScene::Inst()->onMouseUp(pos);
+
+ CoreLib::Inst()->D3DWidget_mouseReleaseEvent(e);
}
void D3DWidget::keyPressEvent( QKeyEvent* e )
diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp b/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp
index fe4b808..3f010fb 100644
--- a/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp
+++ b/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp
@@ -397,7 +397,7 @@ void DisplayPreferencesPanel::on_btnPlaylistAddProj_clicked()
{
lastPath = PlaylistsLoader::mediaPath;
}
- QString fileNameInput = QFileDialog::getOpenFileName(this, "Open Hair Project File", lastPath, "Hair Project File (*.furproj)");
+ QString fileNameInput = QFileDialog::getOpenFileName(this, "Open Project File", lastPath, "Project File (*.blastProj)");
if (!QFile::exists(fileNameInput))
return;
std::string tmp = fileNameInput.toUtf8().data();
@@ -561,6 +561,7 @@ void PlaylistsLoader::ReleasePlaylistParamsContext()
void PlaylistsLoader::loadPlaylistsFromMediaPath()
{
+ std::string t1 = projectPath.toUtf8().data();
if (projectPath.isEmpty())
{
QString appDir = qApp->applicationDirPath();
@@ -579,7 +580,12 @@ void PlaylistsLoader::loadPlaylistsFromMediaPath()
projectPath = dirTmp.absolutePath();
}
}
- if (!projectPath.isEmpty())
+ if (projectPath.isEmpty())
+ {
+ projectPath = qApp->applicationDirPath();
+ mediaPath = projectPath;
+ }
+ else
{
if (dirTmp.cd(".."))
{
@@ -688,30 +694,30 @@ bool PlaylistsLoader::saveProjectsInPlaylist(int idx, QList<QString>& projects)
objects[numObjects++] = params;
NvParameterized::Interface* iface = static_cast<NvParameterized::Interface*>(params);
+ std::vector<std::string> strArray;
+ std::vector<const char*> strOutput;
+
if (1)
{
nvidia::parameterized::PlaylistParams* params = static_cast<nvidia::parameterized::PlaylistParams*>(iface);
nvidia::parameterized::PlaylistParamsNS::ParametersStruct& targetDesc = params->parameters();
NvParameterized::Handle handle(iface);
- if (iface->getParameterHandle("furprojFilePaths", handle) == NvParameterized::ERROR_NONE)
+ if (iface->getParameterHandle("blastProjFilePaths", handle) == NvParameterized::ERROR_NONE)
{
int num = projects.size();
-
- std::vector<std::string> strArray;
- const char** strOutput = new const char*[num];
+ strArray.resize(num);
+ strOutput.resize(num);
for (int i = 0; i < num; i++)
{
std::string proj = projects[i].toUtf8().data();
- strArray.push_back(proj);
+ strArray[i] = proj;
strOutput[i] = strArray[i].c_str();
}
handle.resizeArray(num);
- handle.setParamStringArray(strOutput, num);
-
- delete[] strOutput;
+ handle.setParamStringArray(&strOutput[0], num);
}
}
@@ -762,6 +768,8 @@ QString PlaylistsLoader::convertToAbsoluteFilePath(QString& filePath)
QString PlaylistsLoader::convertToSaveingFilePath(QString& filePath)
{
+ std::string t1 = mediaPath.toUtf8().data();
+ std::string t2 = projectPath.toUtf8().data();
QString fname;
bool bCanBeRelativePath = false;
bool bAbsPath = (filePath.indexOf(':') >= 0);
@@ -771,7 +779,7 @@ QString PlaylistsLoader::convertToSaveingFilePath(QString& filePath)
{
QFileInfo fi(filePath);
int pos = fi.absoluteFilePath().indexOf(mediaPath, Qt::CaseInsensitive);
- if (pos >= 0)
+ if (pos >= 0 && mediaPath.length())
{
// convert to relative path
fname = filePath.right(filePath.size() - (pos + mediaPath.size() + 1));
@@ -800,6 +808,7 @@ QString PlaylistsLoader::convertToSaveingFilePath(QString& filePath)
{
fname = filePath;
}
+ std::string tmp3 = fname.toUtf8().data();
QFileInfo fi(mediaPath + "/" + fname);
std::string tmp = fi.absoluteFilePath().toUtf8().data();
if (!QFile::exists(fi.absoluteFilePath()))
@@ -853,7 +862,7 @@ int PlaylistsLoader::getProjectsInPlaylist(int idx, QList<QString>& projects)
nvidia::parameterized::PlaylistParams* params = static_cast<nvidia::parameterized::PlaylistParams*>(iface);
nvidia::parameterized::PlaylistParamsNS::ParametersStruct& srcDesc = params->parameters();
NvParameterized::Handle handle(iface);
- if (iface->getParameterHandle("furprojFilePaths", handle) == NvParameterized::ERROR_NONE)
+ if (iface->getParameterHandle("blastProjFilePaths", handle) == NvParameterized::ERROR_NONE)
{
int arraySize;
handle.getArraySize(arraySize);
diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp
index b118b6b..7c0e382 100644
--- a/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp
+++ b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp
@@ -76,6 +76,17 @@ void DisplayScenePanel::on_btnSkinningDQ_stateChanged(int state)
void DisplayScenePanel::on_checkBoxGizmoWithLocal_stateChanged(int state)
{
AppMainWindow::Inst().m_bGizmoWithLocal = state;
+ CoreLib::Inst()->AppMainWindow_updateMainToolbar();
+}
+
+void DisplayScenePanel::on_checkBoxGizmoWithDepthTest_stateChanged(int state)
+{
+ AppMainWindow::Inst().m_bGizmoWithDepthTest = state;
+}
+
+void DisplayScenePanel::on_checkBoxShowPlane_stateChanged(int state)
+{
+ AppMainWindow::Inst().m_bShowPlane = state;
}
void DisplayScenePanel::updateValues()
@@ -90,4 +101,6 @@ void DisplayScenePanel::updateValues()
ui.btnUseLighting->setChecked(globalSettings.m_useLighting);
ui.btnShowGraphicsMesh->setChecked( globalSettings.m_showGraphicsMesh);
ui.btnShowSkinnedOnly->setChecked( globalSettings.m_showSkinnedMeshOnly);
+ ui.checkBoxGizmoWithLocal->setChecked(AppMainWindow::Inst().m_bGizmoWithLocal);
+ ui.checkBoxGizmoWithDepthTest->setChecked(AppMainWindow::Inst().m_bGizmoWithDepthTest);
}
diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h
index 6614eca..cd277b6 100644
--- a/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h
+++ b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h
@@ -30,6 +30,8 @@ public:
CORELIB_EXPORT void on_btnShowSkinnedOnly_stateChanged(int state);
CORELIB_EXPORT void on_btnSkinningDQ_stateChanged(int state);
CORELIB_EXPORT void on_checkBoxGizmoWithLocal_stateChanged(int state);
+ CORELIB_EXPORT void on_checkBoxGizmoWithDepthTest_stateChanged(int state);
+ CORELIB_EXPORT void on_checkBoxShowPlane_stateChanged(int state);
private:
diff --git a/tools/ArtistTools/source/Shaders/BodyShader.hlsl b/tools/ArtistTools/source/Shaders/BodyShader.hlsl
new file mode 100644
index 0000000..3f9b60f
--- /dev/null
+++ b/tools/ArtistTools/source/Shaders/BodyShader.hlsl
@@ -0,0 +1,370 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+//#define USE_GFSDK_SHADOWLIB
+
+///////////////////////////////////////////////////////////////////////////////////
+// Textures
+///////////////////////////////////////////////////////////////////////////////////
+Buffer<float4> g_BoneIndices : register(t0);
+Buffer<float4> g_BoneWeights : register(t1);
+
+Texture2D g_DiffuseTexture : register(t2);
+Texture2D g_SpecularTexture : register(t3);
+Texture2D g_NormalTexture : register(t4);
+Texture2D g_EnvTexture : register(t5);
+
+Texture2D g_ShadowTexture0 : register(t6);
+Texture2D g_ShadowTexture1 : register(t7);
+Texture2D g_ShadowTexture2 : register(t8);
+Texture2D g_ShadowTexture3 : register(t9);
+
+#include "Light.hlsl"
+#include "BodyShaderCommon.hlsl"
+
+///////////////////////////////////////////////////////////////////////////////////
+// constant buffer
+///////////////////////////////////////////////////////////////////////////////////
+cbuffer cbPerFrame : register(b0)
+{
+ row_major float4x4 g_ViewProjection;
+ row_major float4x4 g_BodyTransformation;
+
+//////////////////////////////////////////////////
+ Light g_Light[4];
+
+//////////////////////////////////////////////////
+ float3 g_eyePosition;
+ float g_specularShininess;
+
+ int g_useDiffuseTextures;
+ int g_useSpecularTextures;
+ int g_useNormalTextures;
+ int g_useTextures;
+
+
+ float4 g_ambientColor;
+ float4 g_diffuseColor;
+ float4 g_specularColor;
+
+ int g_wireFrame;
+ int g_useLighting;
+ int g_wireFrameOver;
+ float g_unitScale;
+
+ int g_useDQs;
+ int g_diffuseChannel;
+ int g_flatNormal;
+ int g_usePinPos;
+
+ row_major float4x4 g_boneMatrices[MAX_BONE_MATRICES];
+ DQ g_boneDQs[MAX_BONE_MATRICES];
+}
+
+#define FLT_EPSILON 1e-7
+
+SamplerState samLinear : register(s0);
+SamplerState samPointClamp : register(s1);
+
+//////////////////////////////////////////////////////////////////////////////
+// shadow sampling functions
+//////////////////////////////////////////////////////////////////////////////
+float softDepthCmp(float sampledDepth, float calcDepth, float bias, float gain)
+{
+ float delta = gain * (sampledDepth - (calcDepth + bias));
+
+ float s = clamp(1.0 - delta / abs(bias), 0.0f, 1.0f);
+ return s;
+}
+
+float softDepthCmpRHS(float sampledDepth, float calcDepth)
+{
+ float bias = g_unitScale;
+
+ float delta = sampledDepth - (calcDepth + bias);
+
+ float s = clamp(1.0 - delta / bias, 0.0f, 1.0f);
+ return s;
+}
+
+float softDepthCmpLHS(float sampledDepth, float calcDepth)
+{
+ float bias = g_unitScale;
+
+ float delta = (calcDepth - bias) - sampledDepth;
+
+ float s = clamp(1.0 - delta / bias, 0.0f, 1.0f);
+ return s;
+}
+
+float ShadowPCF(float2 texcoord, float calcDepth, float bias, float gain, Texture2D shadowTexture)
+{
+ float shadow = 0;
+ float n = 0;
+
+ [unroll]
+ for (int dx = - 3; dx <= 3; dx += 2) {
+ for (int dy = -3; dy <= 3; dy += 2) {
+ float4 S = shadowTexture.Gather(samPointClamp, texcoord, int2(dx, dy));
+ shadow += softDepthCmp(S.x, calcDepth, bias, gain);
+ shadow += softDepthCmp(S.y, calcDepth, bias, gain);
+ shadow += softDepthCmp(S.z, calcDepth, bias, gain);
+ shadow += softDepthCmp(S.w, calcDepth, bias, gain);
+ n += 4;
+ }
+ }
+
+ return shadow / n;
+}
+
+float getShadow(float3 wPos, Light L, Texture2D stex)
+{
+ float2 texcoords = mul(float4(wPos, 1), L.m_lightMatrix).xy;
+ float z = mul(float4(wPos, 1), L.m_viewMatrix).z;
+
+ float bias = L.m_depthBias;
+ float gain = L.m_depthGain;
+ float shadow = ShadowPCF(texcoords, z, bias, gain, stex);
+
+ return shadow;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+inline float getIllumination(Light L, float3 wPos, Texture2D stex)
+{
+ float lit = 1.0f;
+
+ if (L.m_useShadows)
+ {
+ float2 texcoords = mul(float4(wPos, 1), L.m_lightMatrix).xy;
+ float z = mul(float4(wPos, 1), L.m_viewMatrix).z;
+ lit = getShadow(wPos, L, stex);
+ }
+
+ return lit;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////
+inline float3 computeDiffuseLighting(
+ float3 I,
+ float3 L, // light direction
+ float3 N // surface normal
+ )
+{
+ float diffuse = max(0, dot(N, L));
+
+ return diffuse * I;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+inline float3 computeSpecularLighting(
+ float3 I, // light color
+ float3 L, // light direction
+ float3 N, // surface normal
+ float3 E, // view vector
+ float3 Ms, // specularity
+
+ float shininess)
+{
+ float3 H = normalize(E+N);
+ float NdotH = max(0, dot(H, N));
+ float specular = pow(NdotH, shininess);
+
+ float3 output = specular * I * Ms;
+
+ return output;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+struct BodyRenderVSIn
+{
+ float3 Position : POSITION;
+ float3 vertexNormal : VERTEX_NORMAL;
+ float3 faceNormal : FACE_NORMAL;
+ float3 Tangent : TANGENT;
+ float2 texCoord : TEXCOORD;
+ float vid : VERTEX_ID;
+};
+
+struct BodyRenderVSOut
+{
+ float4 Position : SV_Position;
+ float3 Normal : Normal;
+ float3 Tangent : TANGENT;
+ float3 wpos : WPOS;
+ float2 texCoord : TEXCOORD;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////
+// vertex shader
+/////////////////////////////////////////////////////////////////////////////////////
+BodyRenderVSOut vs_main(BodyRenderVSIn vertexIn)
+{
+ BodyRenderVSOut vertex;
+
+ float3 pos = vertexIn.Position.xyz;
+
+ float3 normal = g_flatNormal ? normalize(vertexIn.faceNormal) : normalize(vertexIn.vertexNormal);
+ float3 tangent = normalize(vertexIn.Tangent);
+
+ float3 skinnedPos, skinnedNormal, skinnedTangent;
+
+ float4 boneIndex = g_BoneIndices.Load(vertexIn.vid);
+ float4 boneWeight = g_BoneWeights.Load(vertexIn.vid);
+
+ if (g_useDQs)
+ computeSkinningDQ(boneIndex, boneWeight, g_boneDQs, skinnedPos, skinnedNormal, skinnedTangent, pos, normal, tangent);
+ else
+ computeSkinningLinear(boneIndex, boneWeight, g_boneMatrices, skinnedPos, skinnedNormal, skinnedTangent, pos, normal, tangent);
+
+ if (!g_usePinPos)
+ pos = skinnedPos;
+ pos = mul(float4(pos, 1), g_BodyTransformation);
+ vertex.wpos = pos;
+
+ vertex.Position = mul(float4(pos, 1), g_ViewProjection);
+
+ vertex.Normal = normalize(skinnedNormal);
+ vertex.Tangent = normalize(skinnedTangent);
+ vertex.texCoord = vertexIn.texCoord;
+
+ return vertex;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// pixel shader
+/////////////////////////////////////////////////////////////////////////////////////
+
+float4 ps_main(BodyRenderVSOut vertex) : SV_Target
+{
+ float4 output = float4(0,0,0,1);
+
+ if (g_wireFrameOver)
+ return output;
+
+ float3 diffuseColor = g_diffuseColor.xyz;
+ if (g_useDiffuseTextures)
+ {
+ if (g_diffuseChannel == 0)
+ diffuseColor.xyz = g_DiffuseTexture.SampleLevel(samLinear,vertex.texCoord, 0).xyz;
+ else if (g_diffuseChannel == 1)
+ diffuseColor.xyz = g_DiffuseTexture.SampleLevel(samLinear,vertex.texCoord, 0).rrr;
+ else if (g_diffuseChannel == 2)
+ diffuseColor.xyz = g_DiffuseTexture.SampleLevel(samLinear,vertex.texCoord, 0).ggg;
+ else if (g_diffuseChannel == 3)
+ diffuseColor.xyz = g_DiffuseTexture.SampleLevel(samLinear,vertex.texCoord, 0).bbb;
+ else if (g_diffuseChannel == 4)
+ diffuseColor.xyz = g_DiffuseTexture.SampleLevel(samLinear,vertex.texCoord, 0).aaa;
+ }
+
+ float3 specularColor = g_specularColor.xyz;
+ if (g_useSpecularTextures)
+ specularColor.xyz = g_SpecularTexture.SampleLevel(samLinear,vertex.texCoord, 0).xyz;
+
+ if (!g_useLighting)
+ return float4(diffuseColor, 1.0f);
+
+ float3 N = normalize(vertex.Normal.xyz);
+
+ if (g_useNormalTextures)
+ {
+ float3 normalColor = g_NormalTexture.SampleLevel(samLinear,vertex.texCoord, 0).xyz;
+ normalColor = (normalColor - 0.5) * 2.0f;
+
+ float3 T = normalize(vertex.Tangent.xyz);
+ float3 B = normalize(cross(T, N));
+
+ float3 PN = N;
+
+ PN += normalColor.x * T;
+ PN += normalColor.y * B;
+ PN += normalColor.z * N;
+
+ N = normalize(PN);
+ }
+
+ float3 P = vertex.wpos.xyz;
+ float3 E = normalize(g_eyePosition.xyz - P);
+ float shininess = g_specularShininess;
+
+ // sum all lights
+ Texture2D stex[4] =
+ {
+ g_ShadowTexture0,
+ g_ShadowTexture1,
+ g_ShadowTexture2,
+ g_ShadowTexture3
+ };
+
+ float3 albedo = diffuseColor.rgb;
+ float3 specularity = specularColor.rgb;
+
+ float3 diffuse = 0;
+ float3 specular = 0;
+ float3 ambient = 0;
+
+ [unroll]
+ for (int i = 0; i < 4; i++)
+ {
+ Light L = g_Light[i];
+
+ if (L.m_enable)
+ {
+ float3 Ldiffuse = 0;
+ float3 Lspecular = 0;
+ float3 Ldir = 0;
+
+ if (L.m_isEnvLight)
+ {
+ Ldir = N;
+
+ bool zup = true;
+ float2 texcoords = GetLightTexCoord(Ldir, zup);
+ float3 Lcolor = (L.m_useEnvMap) ? g_EnvTexture.SampleLevel(samLinear,texcoords.xy,0).rgb : L.m_color;
+ Lcolor *= L.m_intensity;
+ Ldiffuse = Lspecular = Lcolor;
+ }
+ else
+ {
+ float I = getIllumination(L, P, stex[i]);
+ Ldiffuse = Lspecular = I * L.m_intensity * L.m_color;
+ Ldir = 1.0f * L.m_dir;
+ }
+
+ diffuse += computeDiffuseLighting( Ldiffuse, Ldir, N);
+ specular += computeSpecularLighting( Lspecular, Ldir, N, E, specularity, shininess);
+
+ ambient += L.m_ambientColor;
+ }
+ }
+
+ output.rgb = (ambient + diffuse) * albedo + specular;
+
+ return output;
+}
diff --git a/tools/ArtistTools/source/Shaders/BodyShaderCommon.hlsl b/tools/ArtistTools/source/Shaders/BodyShaderCommon.hlsl
new file mode 100644
index 0000000..e113881
--- /dev/null
+++ b/tools/ArtistTools/source/Shaders/BodyShaderCommon.hlsl
@@ -0,0 +1,204 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+struct DQ
+{
+ float4 q0;
+ float4 q1;
+};
+
+#define MAX_BONE_MATRICES 512
+#define FLT_EPSILON 1e-7
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+// apply linear blending based skinning
+void computeSkinningLinear(
+ float4 boneIndex,
+ float4 boneWeight,
+ row_major float4x4 boneMatrices[MAX_BONE_MATRICES],
+ out float3 skinnedPosition,
+ out float3 skinnedNormal,
+ out float3 skinnedTangent,
+ float3 restPosition, float3 restNormal, float3 restTangent)
+{
+
+ float weightSum = boneWeight.x + boneWeight.y + boneWeight.z + boneWeight.w ;
+ float invWeightSum = 1.0f / (weightSum + FLT_EPSILON);
+
+ skinnedPosition = float3(0, 0, 0);
+ skinnedNormal = float3(0, 0, 0);
+ skinnedTangent = float3(0, 0, 0);
+
+ [unroll(4)]
+ for (int b = 0; b < 4; b++)
+ {
+ row_major float4x4 bone = boneMatrices[boneIndex[b]];
+ float w = boneWeight[b];
+
+ float3 p = (mul(float4(restPosition.xyz,1), bone)).xyz;
+ skinnedPosition.xyz += w * p;
+ float3 n = (mul(float4(restNormal.xyz,0), bone)).xyz;
+ skinnedNormal.xyz += w * n;
+ float3 t = (mul(float4(restTangent.xyz,0), bone)).xyz;
+ skinnedTangent.xyz += w * t;
+ }
+
+ skinnedPosition.xyz *= invWeightSum;
+ skinnedNormal.xyz *= invWeightSum;
+ skinnedTangent.xyz *= invWeightSum;
+
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+// apply linear blending based skinning
+void computeSkinningLinear(
+ float4 boneIndex,
+ float4 boneWeight,
+ row_major float4x4 boneMatrices[MAX_BONE_MATRICES],
+ out float3 skinnedPosition,
+ float3 restPosition)
+{
+
+ float weightSum = boneWeight.x + boneWeight.y + boneWeight.z + boneWeight.w ;
+ float invWeightSum = 1.0f / (weightSum + FLT_EPSILON);
+
+ skinnedPosition = float3(0, 0, 0);
+
+ [unroll(4)]
+ for (int b = 0; b < 4; b++)
+ {
+ row_major float4x4 bone = boneMatrices[boneIndex[b]];
+
+ float3 p = boneWeight[b] * invWeightSum * (mul(float4(restPosition.xyz,1), bone)).xyz;
+ skinnedPosition.xyz += p;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+// apply dual quaternion skinning
+void computeSkinningDQ(
+ float4 boneIndex,
+ float4 boneWeight,
+ DQ boneDQs[MAX_BONE_MATRICES],
+ inout float3 skinnedPosition,
+ inout float3 skinnedNormal,
+ inout float3 skinnedTangent,
+ float3 restPosition,
+ float3 restNormal,
+ float3 restTangent)
+{
+ DQ dq;
+ dq.q0 = float4(0,0,0,0);
+ dq.q1 = float4(0,0,0,0);
+
+ [unroll(4)]
+ for (int b = 0; b < 4; b++)
+ {
+ float w = boneWeight[b];
+ DQ boneDQ = boneDQs[boneIndex[b]];
+
+ boneDQ.q0 *= w;
+ boneDQ.q1 *= w;
+
+ // hemispherization
+ float sign = (dot(dq.q0, boneDQ.q0) < -FLT_EPSILON) ? -1.0f: 1.0f;
+
+ dq.q0 += sign * boneDQ.q0;
+ dq.q1 += sign * boneDQ.q1;
+ }
+
+ // normalize
+ float mag = dot(dq.q0, dq.q0);
+ float deLen = 1.0f / sqrt(mag+FLT_EPSILON);
+ dq.q0 *= deLen;
+ dq.q1 *= deLen;
+
+ // transform
+ float3 d0 = dq.q0.xyz;
+ float3 de = dq.q1.xyz;
+ float a0 = dq.q0.w;
+ float ae = dq.q1.w;
+
+ float3 tempPos = cross(d0, restPosition.xyz) + a0 * restPosition.xyz;
+ float3 tempPos2 = 2.0f * (de * a0 - d0 * ae + cross(d0, de));
+ float3 tempNormal = cross(d0, restNormal.xyz) + a0 * restNormal.xyz;
+ float3 tempTangent = cross(d0, restTangent.xyz) + a0 * restTangent.xyz;
+
+ skinnedPosition.xyz = restPosition.xyz + tempPos2 + cross(2.0f * d0, tempPos);
+ skinnedNormal.xyz = restNormal.xyz + 2.0 * cross( d0, tempNormal);
+ skinnedTangent.xyz = restTangent.xyz + 2.0 * cross( d0, tempTangent);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+// apply dual quaternion skinning
+void computeSkinningDQ(
+ float4 boneIndex,
+ float4 boneWeight,
+ DQ boneDQs[MAX_BONE_MATRICES],
+ inout float3 skinnedPosition,
+ float3 restPosition)
+{
+ DQ dq;
+ dq.q0 = float4(0,0,0,0);
+ dq.q1 = float4(0,0,0,0);
+
+ [unroll(4)]
+ for (int b = 0; b < 4; b++)
+ {
+ float w = boneWeight[b];
+ DQ boneDQ = boneDQs[boneIndex[b]];
+
+ boneDQ.q0 *= w;
+ boneDQ.q1 *= w;
+
+ // hemispherization
+ float sign = (dot(dq.q0, boneDQ.q0) < -FLT_EPSILON) ? -1.0f: 1.0f;
+
+ dq.q0 += sign * boneDQ.q0;
+ dq.q1 += sign * boneDQ.q1;
+ }
+
+ // normalize
+ float mag = dot(dq.q0, dq.q0);
+ float deLen = 1.0f / sqrt(mag+FLT_EPSILON);
+ dq.q0 *= deLen;
+ dq.q1 *= deLen;
+
+ // transform
+ float3 d0 = dq.q0.xyz;
+ float3 de = dq.q1.xyz;
+ float a0 = dq.q0.w;
+ float ae = dq.q1.w;
+
+ float3 tempPos = cross(d0, restPosition.xyz) + a0 * restPosition.xyz;
+ float3 tempPos2 = 2.0f * (de * a0 - d0 * ae + cross(d0, de));
+ skinnedPosition.xyz = restPosition.xyz + tempPos2 + cross(2.0f * d0, tempPos);
+}
+
+
+
diff --git a/tools/ArtistTools/source/Shaders/BodyShadow.hlsl b/tools/ArtistTools/source/Shaders/BodyShadow.hlsl
new file mode 100644
index 0000000..4d7629e
--- /dev/null
+++ b/tools/ArtistTools/source/Shaders/BodyShadow.hlsl
@@ -0,0 +1,109 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+Buffer<float4> g_BoneIndices : register(t0);
+Buffer<float4> g_BoneWeights : register(t1);
+
+#include "BodyShaderCommon.hlsl"
+
+///////////////////////////////////////////////////////////////////////////////////
+// constant buffer
+///////////////////////////////////////////////////////////////////////////////////
+cbuffer cbPerFrame : register(b0)
+{
+ row_major float4x4 g_ViewProjection;
+ row_major float4x4 g_ViewMatrix;
+ row_major float4x4 g_BodyTransformation;
+
+ int g_useDQs;
+ int g_usePinPos;
+ float _reserved2;
+ float _reserved3;
+
+ row_major float4x4 g_boneMatrices[MAX_BONE_MATRICES];
+ DQ g_boneDQs[MAX_BONE_MATRICES];
+}
+
+struct VSIn
+{
+ float3 Position : POSITION;
+ float3 vertexNormal : VERTEX_NORMAL;
+ float3 faceNormal : FACE_NORMAL;
+ float3 Tangent : TANGENT;
+ float2 texCoord : TEXCOORD;
+ float vid : VERTEX_ID;
+};
+
+struct VSOut
+{
+ float4 Position : SV_Position;
+ float Depth : texcoord;
+};
+
+struct PSOut
+{
+ float Z: SV_Target0;
+};
+
+float WorldToDepth(float3 wPos)
+{
+ float z = mul(float4(wPos, 1), g_ViewMatrix).z;
+ return z;
+
+}
+
+VSOut vs_main(VSIn vertexIn)
+{
+ VSOut vertex;
+
+ float4 boneIndex = g_BoneIndices.Load(vertexIn.vid);
+ float4 boneWeight = g_BoneWeights.Load(vertexIn.vid);
+
+ float3 pos = vertexIn.Position.xyz;
+ float3 skinnedPos;
+
+ if (g_useDQs)
+ computeSkinningDQ(boneIndex, boneWeight, g_boneDQs, skinnedPos, pos);
+ else
+ computeSkinningLinear(boneIndex, boneWeight, g_boneMatrices, skinnedPos, pos);
+
+ if (g_usePinPos)
+ skinnedPos = pos;
+
+ float3 wPos = mul(float4(skinnedPos, 1), g_BodyTransformation).xyz;
+ vertex.Position = mul(float4(wPos, 1), g_ViewProjection);
+ vertex.Depth = WorldToDepth(wPos);
+ return vertex;
+}
+
+PSOut ps_main(VSOut vertex)
+{
+ PSOut output;
+ output.Z = vertex.Depth;
+ return output;
+}
diff --git a/tools/ArtistTools/source/Shaders/Light.hlsl b/tools/ArtistTools/source/Shaders/Light.hlsl
new file mode 100644
index 0000000..85c71f0
--- /dev/null
+++ b/tools/ArtistTools/source/Shaders/Light.hlsl
@@ -0,0 +1,69 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+///////////////////////////////////////////////////////////////////////////////////
+struct Light
+{
+ int m_enable;
+ float3 m_dir;
+
+ int m_useShadows;
+ float3 m_color;
+
+ float3 m_ambientColor;
+ int m_isEnvLight;
+
+ int m_lhs;
+ int _reserved1;
+ int _reserved2;
+ int _reserved3;
+
+ float m_depthBias;
+ float m_depthGain;
+ int m_useEnvMap;
+ float m_intensity;
+
+ row_major float4x4 m_viewMatrix;
+ row_major float4x4 m_lightMatrix;
+};
+
+float2 GetLightTexCoord(float3 Ldir, bool zup = true)
+{
+ const float M_PI = 3.1415923;
+
+ float coord0 = zup ? Ldir.x : Ldir.x;
+ float coord1 = zup ? Ldir.y : Ldir.z;
+ float coord2 = zup ? Ldir.z : Ldir.y;
+
+ float u = 0.5f + 0.5f * atan2(coord1, coord0) / M_PI;
+ float v = 0.5f - 0.5f * coord2;
+
+ return float2(u,v);
+}
+
+
diff --git a/tools/ArtistTools/source/Shaders/ScreenQuad.hlsl b/tools/ArtistTools/source/Shaders/ScreenQuad.hlsl
new file mode 100644
index 0000000..e1ab62f
--- /dev/null
+++ b/tools/ArtistTools/source/Shaders/ScreenQuad.hlsl
@@ -0,0 +1,66 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+///////////////////////////////////////////////////////////////////////////////////
+// Textures
+///////////////////////////////////////////////////////////////////////////////////
+Texture2D g_ColorTexture : register(t0);
+
+struct VSOut
+{
+ float4 pos : SV_Position;
+ float2 tex : TEXCOORD;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////
+// vertex shader
+/////////////////////////////////////////////////////////////////////////////////////
+VSOut vs_main( uint id : SV_VertexID )
+{
+ VSOut output;
+ output.tex = float2( (id << 1) & 2, id & 2 );
+ output.pos = float4( output.tex * float2( 2.0f, -2.0f ) + float2( -1.0f, 1.0f), 0.0f, 1.0f );
+
+ return output;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// pixel shader
+/////////////////////////////////////////////////////////////////////////////////////
+//SamplerState samLinear;
+SamplerState samPointClamp;
+
+float4 ps_main(VSOut input) : SV_Target
+{
+ float4 color;
+
+ color.rgb = g_ColorTexture.Sample(samPointClamp,input.tex).rgb;
+ color.a = 1.0f;
+
+ return color;
+}
diff --git a/tools/ArtistTools/source/Shaders/ScreenQuadColor.hlsl b/tools/ArtistTools/source/Shaders/ScreenQuadColor.hlsl
new file mode 100644
index 0000000..e019b65
--- /dev/null
+++ b/tools/ArtistTools/source/Shaders/ScreenQuadColor.hlsl
@@ -0,0 +1,71 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+
+///////////////////////////////////////////////////////////////////////////////////
+// Textures
+///////////////////////////////////////////////////////////////////////////////////
+Texture2D g_ColorTexture : register(t0);
+
+struct VSOut
+{
+ float4 pos : SV_Position;
+ float2 tex : TEXCOORD;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////
+// vertex shader
+/////////////////////////////////////////////////////////////////////////////////////
+VSOut vs_main( uint id : SV_VertexID )
+{
+ VSOut output;
+ output.tex = float2( (id << 1) & 2, id & 2 );
+ output.pos = float4( output.tex * float2( 2.0f, -2.0f ) + float2( -1.0f, 1.0f), 0.0f, 1.0f );
+
+ return output;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// pixel shader
+/////////////////////////////////////////////////////////////////////////////////////
+//SamplerState samLinear;
+SamplerState samPointClamp;
+
+float4 ps_main(VSOut input) : SV_Target
+{
+ float4 color;
+
+ float3 top = float3(0.49f, 0.569f, 0.700f);
+ float3 btm = float3(0.098f, 0.098f, 0.098f);
+
+ float height = input.tex.y;
+ color.rgb = lerp(top, btm, height);
+
+ color.a = 1.0f;
+
+ return color;
+} \ No newline at end of file
diff --git a/tools/ArtistTools/source/Shaders/VisualizeShadow.hlsl b/tools/ArtistTools/source/Shaders/VisualizeShadow.hlsl
new file mode 100644
index 0000000..04bf9f9
--- /dev/null
+++ b/tools/ArtistTools/source/Shaders/VisualizeShadow.hlsl
@@ -0,0 +1,81 @@
+// This code contains NVIDIA Confidential Information and is disclosed
+// under the Mutual Non-Disclosure Agreement.
+//
+// Notice
+// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
+// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
+// expressly authorized by NVIDIA. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
+//
+// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
+// rights in and to this software and related documentation and any modifications thereto.
+// Any use, reproduction, disclosure or distribution of this software and related
+// documentation without an express license agreement from NVIDIA Corporation is
+// strictly prohibited.
+//
+///////////////////////////////////////////////////////////////////////////////////
+// constant buffer
+///////////////////////////////////////////////////////////////////////////////////
+cbuffer cbPerFrame : register(b0)
+{
+ float g_zNear;
+ float g_zFar;
+ float g_unitScale;
+ float g_dummy;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// Textures
+///////////////////////////////////////////////////////////////////////////////////
+Texture2D g_ColorTexture : register(t0);
+
+struct VSOut
+{
+ float4 pos : SV_Position;
+ float2 tex : TEXCOORD;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////
+// vertex shader
+/////////////////////////////////////////////////////////////////////////////////////
+VSOut vs_main( uint id : SV_VertexID )
+{
+ VSOut output;
+ output.tex = float2( (id << 1) & 2, id & 2 );
+ output.pos = float4( output.tex * float2( 2.0f, -2.0f ) + float2( -1.0f, 1.0f), 0.0f, 1.0f );
+
+ return output;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// pixel shader
+/////////////////////////////////////////////////////////////////////////////////////
+//SamplerState samLinear;
+SamplerState samPointClamp;
+
+float4 ps_main(VSOut input) : SV_Target
+{
+ float4 color;
+
+ color.rgb = g_ColorTexture.Sample(samPointClamp,input.tex).rgb;
+
+ float depth = color.r;
+ float near = g_zNear;
+ float far = g_zFar;
+
+ color.rgb = (depth - near) / (far - near);
+ color.a = 1.0f;
+ return color;
+}
diff --git a/tools/ArtistTools/source/Shaders/color.hlsl b/tools/ArtistTools/source/Shaders/color.hlsl
new file mode 100644
index 0000000..b1fa057
--- /dev/null
+++ b/tools/ArtistTools/source/Shaders/color.hlsl
@@ -0,0 +1,67 @@
+////////////////////////////////////////////////////////////////////////////////
+// Filename: color.vs
+////////////////////////////////////////////////////////////////////////////////
+
+
+/////////////
+// GLOBALS //
+/////////////
+cbuffer MatrixBuffer
+{
+ row_major matrix worldMatrix;
+ row_major matrix viewMatrix;
+ row_major matrix projectionMatrix;
+ float4 g_color;
+
+ int g_useVertexColor;
+ int g_dummy2;
+ int g_dummy3;
+ int g_dummy4;
+};
+
+
+//////////////
+// TYPEDEFS //
+//////////////
+struct VertexInputType
+{
+ float3 position : POSITION;
+ float4 color : COLOR;
+};
+
+struct PixelInputType
+{
+ float4 position : SV_POSITION;
+ float4 color : COLOR;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Vertex Shader
+////////////////////////////////////////////////////////////////////////////////
+PixelInputType vs_main(VertexInputType input)
+{
+ PixelInputType output;
+
+ // Calculate the position of the vertex against the world, view, and projection matrices.
+ output.position = mul(float4(input.position,1.0), worldMatrix);
+ output.position = mul(float4(output.position.xyz,1.0f), viewMatrix);
+ output.position = mul(float4(output.position.xyz,1.0f), projectionMatrix);
+
+ // Store the input color for the pixel shader to use.
+ output.color = input.color;
+
+ if (!g_useVertexColor)
+ output.color = g_color;
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Pixel Shader
+////////////////////////////////////////////////////////////////////////////////
+float4 ps_main(PixelInputType input) : SV_TARGET
+{
+ return input.color;
+}