diff options
| author | Bryan Galdrikian <[email protected]> | 2017-02-21 12:07:59 -0800 |
|---|---|---|
| committer | Bryan Galdrikian <[email protected]> | 2017-02-21 12:07:59 -0800 |
| commit | 446ce137c6823ba9eff273bdafdaf266287c7c98 (patch) | |
| tree | d20aab3e2ed08d7b3ca71c2f40db6a93ea00c459 /NvBlast/tools/ArtistTools/source | |
| download | blast-1.0.0-beta.tar.xz blast-1.0.0-beta.zip | |
first commitv1.0.0-beta
Diffstat (limited to 'NvBlast/tools/ArtistTools/source')
267 files changed, 59356 insertions, 0 deletions
diff --git a/NvBlast/tools/ArtistTools/source/ArtistTools/main.cpp b/NvBlast/tools/ArtistTools/source/ArtistTools/main.cpp new file mode 100644 index 0000000..74c9d89 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/ArtistTools/main.cpp @@ -0,0 +1,6 @@ +#include "CoreLib.h" + +int main(int argc, char *argv[]) +{ + return CoreLib::Inst()->CoreMain(argc, argv); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/BlastPlugin.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/BlastPlugin.cpp new file mode 100644 index 0000000..78aa6d0 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/BlastPlugin.cpp @@ -0,0 +1,1736 @@ +#include <QtCore/QtPlugin> +#include <QtCore/QFileInfo> +#include <QtCore/QDir> +#include <QtWidgets/QMenuBar> +#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> +#include <QtWidgets/QComboBox> +#include <QtWidgets/QFrame> +#include <QtWidgets/QGridLayout> +#include <QtWidgets/QHBoxLayout> +#include <QtWidgets/QHeaderView> +#include <QtWidgets/QLabel> +#include <QtWidgets/QSpacerItem> +#include <QtWidgets/QVBoxLayout> +#include <QtWidgets/QWidget> + +#include "PluginBlast.h" +#include "BlastPlugin.h" +#include "SlideSpinBox.h" +#include "Utils.h" +#include "CorelibUtils.h" +#include "Settings.h" +#include "GlobalSettings.h" +#include "SimpleScene.h" +#include "Camera.h" +#include "Light.h" +#include "ProjectParams.h" +#include "FoundationHolder.h" +#include "AppMainWindow.h" +#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" + +// A singleton, sort of... To pass the events from WindowProc to the object. +DeviceManager* g_DeviceManagerInstance = NULL; + +HWND g_hWnd = 0; + +DeviceManager* GetDeviceManager() +{ + return g_DeviceManagerInstance; +} + +QString BlastPlugin::GetPluginName() +{ + return BlastPluginName; +} + +bool BlastPlugin::CoreLib_RunApp() +{ + return true; +} + +bool BlastPlugin::LoadRenderPlugin(std::string api) +{ + return PluginBlast::Create(api); +} + +bool BlastPlugin::GetBoneNames(std::vector<std::string>& BoneNames) +{ + return true; +} + +bool BlastPlugin::MainToolbar_updateValues() +{ + return true; +} + +bool BlastPlugin::CurveEditor_updateValues(int _paramId, float* _values) +{ + return true; +} + +bool BlastPlugin::CurveEditor_onUpdateValues(int _paramId, float* _values) +{ + return true; +} + +bool BlastPlugin::DisplayMeshesPanel_updateValues() +{ + return true; +} +bool BlastPlugin::DisplayMeshesPanel_EmitToggleSignal(unsigned int id, bool visible) +{ + return true; +} + +bool BlastPlugin::Camera_LoadParameters(void* ptr, Camera* pCamera) +{ + nvidia::parameterized::BlastProjectParametersNS::Camera_Type* param = + static_cast<nvidia::parameterized::BlastProjectParametersNS::Camera_Type*>(ptr); + + pCamera->_zup = param->flags == 1; + pCamera->_fov = param->fov; + pCamera->_aspectRatio = param->aspectRatio; + pCamera->_znear = param->znear; + pCamera->_zfar = param->zfar; + pCamera->_isPerspective = param->isPerspective; + memcpy(&pCamera->_eye, ¶m->eye, sizeof(pCamera->_eye)); + memcpy(&pCamera->_at, ¶m->at, sizeof(pCamera->_at)); + pCamera->_lookDistance = param->lookDistance; + memcpy(&pCamera->_orientation, ¶m->orientation, sizeof(pCamera->_orientation)); + memcpy(&pCamera->_viewMatrix, ¶m->viewMatrix, sizeof(pCamera->_viewMatrix)); + memcpy(&pCamera->_projectionMatrix, ¶m->projectionMatrix, sizeof(pCamera->_projectionMatrix)); + + return true; +} + +bool BlastPlugin::Camera_SaveParameters(void * ptr, Camera* pCamera) +{ + nvidia::parameterized::BlastProjectParametersNS::Camera_Type* outParam = + static_cast<nvidia::parameterized::BlastProjectParametersNS::Camera_Type*>(ptr); + + outParam->flags = (pCamera->_zup ? 1 : 2); + outParam->fov = pCamera->_fov; + outParam->aspectRatio = pCamera->_aspectRatio; + outParam->znear = pCamera->_znear; + outParam->zfar = pCamera->_zfar; + outParam->width = 0; + outParam->height = 0; + outParam->isPerspective = pCamera->_isPerspective; + memcpy(&outParam->eye, &pCamera->_eye, sizeof(outParam->eye)); + memcpy(&outParam->at, &pCamera->_at, sizeof(outParam->at)); + outParam->lookDistance = pCamera->_lookDistance; + memcpy(&outParam->orientation, &pCamera->_orientation, sizeof(outParam->orientation)); + memcpy(&outParam->viewMatrix, &pCamera->_viewMatrix, sizeof(outParam->viewMatrix)); + memcpy(&outParam->projectionMatrix, &pCamera->_projectionMatrix, sizeof(outParam->projectionMatrix)); + return true; +} + +bool BlastPlugin::Gamepad_ToggleSimulation() +{ + return true; +} + +bool BlastPlugin::Gamepad_LoadSamples(QString fn) +{ + return true; +} + +bool BlastPlugin::Gamepad_ResetScene() +{ + return true; +} + +bool BlastPlugin::Gamepad_StartAnimation() +{ + return true; +} + +bool BlastPlugin::GamepadHandler_ShowHair() +{ + return true; +} + +bool BlastPlugin::GamepadHandler_SpinWindStrength(float windStrength) +{ + return true; +} + +bool BlastPlugin::Gamepad_ResetAnimation() +{ + return true; +} + +bool BlastPlugin::Gamepad_PlayPauseAnimation() +{ + return true; +} + +bool BlastPlugin::Light_loadParameters(NvParameterized::Handle& handle, Light* pLight) +{ + if (pLight == nullptr) + return false; + + NvParameterized::NvParameters* params = static_cast<NvParameterized::NvParameters*>(handle.getInterface()); + size_t offset = 0; + nvidia::parameterized::BlastProjectParametersNS::Light_Type* param = nullptr; + params->getVarPtr(handle, (void*&)param, offset); + + pLight->m_enable = param->enable; + pLight->m_useShadows = param->useShadows; + pLight->m_visualize = param->visualize; + pLight->m_intensity = param->intensity; + + memcpy(&pLight->m_color, ¶m->color, sizeof(atcore_float3)); + + atcore_float3 axisX, axisY, axisZ, lightPos; + memcpy(&axisX, ¶m->lightAxisX, sizeof(atcore_float3)); + memcpy(&axisY, ¶m->lightAxisY, sizeof(atcore_float3)); + memcpy(&axisZ, ¶m->lightAxisZ, sizeof(atcore_float3)); + memcpy(&lightPos, ¶m->lightPos, sizeof(atcore_float3)); + + pLight->SetShadowMapResolution(param->shadowMapResolution); + + pLight->m_lightCamera.SetEye(lightPos); + pLight->m_lightCamera.SetViewMatrix(axisX, axisY, axisZ); + pLight->m_lightCamera.BuildViewMatrix(); + return true; +} + +bool BlastPlugin::Light_saveParameters(NvParameterized::Handle& handle, Light* pLight) +{ + if (pLight == nullptr) + return false; + + NvParameterized::NvParameters* params = static_cast<NvParameterized::NvParameters*>(handle.getInterface()); + size_t offset = 0; + nvidia::parameterized::BlastProjectParametersNS::Light_Type* param = nullptr; + params->getVarPtr(handle, (void*&)param, offset); + memset((void*)param, 0, sizeof(nvidia::parameterized::BlastProjectParametersNS::Light_Type)); + + param->enable = pLight->m_enable; + param->useShadows = pLight->m_useShadows; + param->visualize = pLight->m_visualize; + param->intensity = pLight->m_intensity; + + param->shadowMapResolution = pLight->m_shadowMapResolutionIndex; + + memcpy(¶m->color, &pLight->m_color, sizeof(atcore_float3)); + + { + atcore_float3 axisX = pLight->m_lightCamera.GetXAxis(); + atcore_float3 axisY = pLight->m_lightCamera.GetYAxis(); + atcore_float3 axisZ = pLight->m_lightCamera.GetZAxis(); + atcore_float3 lightPos = pLight->m_lightCamera.GetEye(); + + memcpy(¶m->lightAxisX, &axisX, sizeof(atcore_float3)); + memcpy(¶m->lightAxisY, &axisY, sizeof(atcore_float3)); + memcpy(¶m->lightAxisZ, &axisZ, sizeof(atcore_float3)); + memcpy(¶m->lightPos, &lightPos, sizeof(atcore_float3)); + } + return true; +} + +bool BlastPlugin::SimpleScene_SimpleScene() +{ + return true; +} + + +#include "Timer.h" +Timer g_fpsTimer; + +#include "D3DWidget.h" +#include "SampleManager.h" + +#include <QtWidgets/QShortcut> + +bool BlastPlugin::SimpleScene_Initialize(int backdoor) +{ + if (!CreateProjectParamsContext()) + return false; + + D3DWidget* d3dWidget = AppMainWindow::Inst().GetRenderWidget(); + g_hWnd = (HWND)d3dWidget->winId(); + + RECT rc; + GetClientRect((HWND)g_hWnd, &rc); + int wBuf = rc.right - rc.left; + int hBuf = rc.bottom - rc.top; + + DeviceCreationParameters deviceParams; + deviceParams.swapChainFormat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + deviceParams.swapChainSampleCount = 4; + deviceParams.startFullscreen = false; + deviceParams.hWnd = g_hWnd; + deviceParams.backBufferWidth = wBuf; + deviceParams.backBufferHeight = hBuf; +#if defined(DEBUG) | defined(_DEBUG) + deviceParams.createDeviceFlags = D3D11_CREATE_DEVICE_DEBUG; +#endif + deviceParams.featureLevel = D3D_FEATURE_LEVEL_11_0; + + DeviceManager* pDeviceManager = new DeviceManager; + //pDeviceManager->CreateWindowDeviceAndSwapChain(deviceParams); + RenderPlugin* pPlugin = RenderPlugin::Instance(); + D3DHandles handles; + pDeviceManager->SetWindowHandle(g_hWnd); + pDeviceManager->SetWindowDeviceAndSwapChain(pPlugin->GetDeviceHandles(handles)); + g_DeviceManagerInstance = pDeviceManager; + SimpleScene::Inst()->SetDeviceManager(pDeviceManager); + + SampleManager* pSampleManager = new SampleManager(pDeviceManager); + SimpleScene::Inst()->SetSampleManager(pSampleManager); + + // post build will copy samples\resources to bin\resources. If debug in VS, need set working directory to binary's folder + + pSampleManager->init(); + + 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())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_W), d3dWidget); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_Translate())); + shortCut = new QShortcut(QKeySequence(Qt::Key_E), d3dWidget); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_Rotation())); + 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())); + + _chunkContextMenu = new QMenu(); + action_Make_Support = new QAction(tr("Make Support"), d3dWidget); + _chunkContextMenu->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); + 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); + 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_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_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() +{ + SampleManager& sm = SimpleScene::Inst()->GetSampleManager(); + sm.free(); + //SimpleScene::Inst()->SetSampleManager(NV_NULL); + + ReleaseProjectParamsContext(); + + g_DeviceManagerInstance = NV_NULL; + + return true; +} + +//#include "SceneController.h" +bool BlastPlugin::SimpleScene_Clear() +{ + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + sampleManager.clearScene(); +// SceneController& sceneController = sampleManager.getSceneController(); +// sceneController.ClearScene(); + + BlastProject::ins().clear(); + + return true; +} + +bool BlastPlugin::SimpleScene_Draw_DX12() +{ + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +#include <Stats.h> +namespace +{ + Stats g_StatsCPU; + Stats g_StatsGPU; + + Stats g_FrameStatsCPU; + Stats g_FrameStatsGPU; +} + +////////////////////////////////////////////////////////////////////////////// +void BlastPlugin::ResetFrameTimer() +{ + g_StatsCPU.reset(); + g_StatsGPU.reset(); +} + +void BlastPlugin::DrawHUD() +{ + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + if (!globalSettings.m_showHUD) + return; + + // finish frame timer + g_FrameStatsCPU.add(g_StatsCPU); + g_FrameStatsGPU.add(g_StatsGPU); + + wchar_t sz[1000]; + + RenderInterface::TxtHelperBegin(); + RenderInterface::TxtHelperSetInsertionPos(2, 0); + RenderInterface::TxtHelperSetForegroundColor(1.0f, 1.0f, 1.0f, 1.0f); + + if (RenderInterface::GetDeviceInfoString(sz)) + RenderInterface::TxtHelperDrawTextLine(sz); + + { + // const NvHair::BuildInfo& buildInfo = GetHairSDK()->getBuildInfo(); + + // char releaseVersion[NvHair::BuildInfo::VERSION_BUFFER_SIZE]; + // buildInfo.m_versionToStringFunc(buildInfo.m_releaseVersion, releaseVersion); + + swprintf_s(sz, 1000, L"Lib build: %S Release version: %S\n", "n.a.", "1.0.0"); + RenderInterface::TxtHelperDrawTextLine(sz); + } + + swprintf_s(sz, 1000, L"Current frame time %3.2f[%d-%d:%2.2f]\n", + globalSettings.m_frameTime, + (int)globalSettings.m_frameStartTime, + (int)globalSettings.m_frameEndTime, + globalSettings.m_animationSpeed); + + RenderInterface::TxtHelperDrawTextLine(sz); + + bool computeProfile = globalSettings.m_computeProfile; + + //FurCharacter& character = SimpleScene::Inst()->GetFurCharacter(); + //std::vector<HairInstance*> validInstances; + //character.GetValidHairInstances(validInstances); + + if (globalSettings.m_computeStatistics && globalSettings.m_showHUD) + { + + //for (int i = 0; i < validInstances.size(); i++) + //{ + // HairInstance* pHairInstance = validInstances[i]; + + // NvHair::Stats& hairStats = pHairInstance->m_hairStats; + + // int totalHairs = hairStats.m_numHairs; + // int totalFaces = hairStats.m_numFaces; + + // float averageNumCVsPerHair = hairStats.m_averageNumCvsPerHair; + // float averageDensity = hairStats.m_averageDensity; + // float averageHairsPerFace = hairStats.m_averageHairsPerFace; + // float distanceLODFactor = hairStats.m_distanceLodFactor; + // float detailLODFactor = hairStats.m_detailLodFactor; + // float camDistance = hairStats.m_camDistance; + + // int m = pHairInstance->getDescriptor().m_splineMultiplier; + // float vertsPerHair = m * (averageNumCVsPerHair - 1.0f) + 1; + // float totalLines = totalHairs * vertsPerHair; + + // const char* hairName = pHairInstance->m_assetName.c_str(); + // std::wstring hairNameW; + // std::copy(hairName, hairName + strlen(hairName), back_inserter(hairNameW)); + + // swprintf_s(sz, 1000, L"Asset Name (%s), %d hairs, %d faces, %.1f lines", + // hairNameW.c_str(), totalHairs, totalFaces, totalLines); + // RenderInterface::TxtHelperDrawTextLine(sz); + + // swprintf_s(sz, 1000, L" average density %.2f, avg hairs per face %.2f, avg CVs per hair %2.1f, avg render vertices per hair %3.1f", + // averageDensity, averageHairsPerFace, averageNumCVsPerHair, vertsPerHair); + // RenderInterface::TxtHelperDrawTextLine(sz); + + // swprintf_s(sz, 1000, L" distance LOD Factor: %.2f, detail LOD Factor: %.2f, camera distance: %.2f", + // distanceLODFactor, detailLODFactor, camDistance); + // RenderInterface::TxtHelperDrawTextLine(sz); + //} + } + + if (globalSettings.m_showFPS) + { + static double fps = 0; + static double lastFrames = GlobalSettings::Inst().m_renderFrameCnt; + Timer& g_fpsTimer = SimpleScene::Inst()->GetTimer(); + static double lastFpsTime = g_fpsTimer.GetTimeInSeconds(); + static int numFrames = 1; + + static Stats lastStatsCPU; + static Stats lastStatsGPU; + + Stats& statsGPU = g_FrameStatsGPU; + Stats& statsCPU = g_FrameStatsCPU; + + double currentFpsTime = g_fpsTimer.GetTimeInSeconds(); + if ((currentFpsTime - lastFpsTime) > 1.0) + { + double currentFrames = GlobalSettings::Inst().m_renderFrameCnt; + numFrames = currentFrames - lastFrames; + + fps = numFrames / (currentFpsTime - lastFpsTime); + + lastFrames = currentFrames; + lastFpsTime = currentFpsTime; + + lastStatsGPU = statsGPU; + lastStatsCPU = statsCPU; + + lastStatsGPU.average((float)numFrames); + lastStatsCPU.average((float)numFrames); + + statsGPU.reset(); + statsCPU.reset(); + } + + if (globalSettings.m_computeProfile) + { + swprintf_s(sz, 1000, L"Render time (GPU/CPU): Total %.2f/%.2fms, Hair %.2f/%.2fms, Mesh %.2f/%.2fms, Shadow %.2f/%.2fms, Stats %.2f/%.2fms", + lastStatsGPU.m_totalRenderTime, lastStatsCPU.m_totalRenderTime, + lastStatsGPU.m_hairRenderTime, lastStatsCPU.m_hairRenderTime, + lastStatsGPU.m_meshRenderTime, lastStatsCPU.m_meshRenderTime, + lastStatsGPU.m_shadowRenderTime, lastStatsCPU.m_shadowRenderTime, + lastStatsGPU.m_hairStatsTime, lastStatsCPU.m_hairStatsTime); + + RenderInterface::TxtHelperDrawTextLine(sz); + + swprintf_s(sz, 1000, L"Update time (GPU/CPU): Total %.2f/%.2fms, Hair Update %.2f/%.2fms, Mesh Skinning %.2f/%.2fms, Sim %.2f/%.2fms", + lastStatsGPU.m_totalUpdateTime, lastStatsCPU.m_totalUpdateTime, + lastStatsGPU.m_hairSkinningTime, lastStatsCPU.m_hairSkinningTime, + lastStatsGPU.m_meshSkinningTime, lastStatsCPU.m_meshSkinningTime, + lastStatsGPU.m_hairSimulationTime, lastStatsCPU.m_hairSimulationTime); + RenderInterface::TxtHelperDrawTextLine(sz); + + { + float cpuMeshTime = lastStatsCPU.m_meshRenderTime + lastStatsCPU.m_meshSkinningTime; + float gpuMeshTime = lastStatsGPU.m_meshRenderTime + lastStatsGPU.m_meshSkinningTime; + + float cpuHairTime = lastStatsCPU.m_totalRenderTime + lastStatsCPU.m_totalUpdateTime - cpuMeshTime; + float gpuHairTime = lastStatsGPU.m_totalRenderTime + lastStatsGPU.m_totalUpdateTime - gpuMeshTime; + + float gpuFPS = 1000.0f / gpuHairTime; + RenderInterface::TxtHelperSetForegroundColor(0.2f, 1.0f, 0.2f, 1.0f); + swprintf_s(sz, 1000, L"Hair: GPU Fps %.2f, GPU time %.2fms, CPU time %.2fms", + gpuFPS, gpuHairTime, cpuHairTime); + RenderInterface::TxtHelperDrawTextLine(sz); + } + + float gpuTime = lastStatsGPU.m_totalRenderTime + lastStatsGPU.m_totalUpdateTime; + float gpuFPS = 1000.0f / gpuTime; + RenderInterface::TxtHelperSetForegroundColor(1.0f, 0.5f, 0.5f, 1.0f); + swprintf_s(sz, 1000, L"Total: GPU Fps %.2f, GPU time %.2fms, CPU time %.2fms", + gpuFPS, + lastStatsGPU.m_totalRenderTime + lastStatsGPU.m_totalUpdateTime, + lastStatsCPU.m_totalRenderTime + lastStatsCPU.m_totalUpdateTime + ); + RenderInterface::TxtHelperDrawTextLine(sz); + + } + else + { + swprintf_s(sz, 1000, L"Fps %.2f", fps); + RenderInterface::TxtHelperDrawTextLine(sz); + } + } + + RenderInterface::TxtHelperEnd(); +} + +bool BlastPlugin::SimpleScene_Draw_DX11() +{ + BlastPlugin::DrawHUD(); + return true; +} + +bool BlastPlugin::SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents) +{ + return true; +} +bool BlastPlugin::SimpleScene_DrawGround() +{ + return true; +} +bool BlastPlugin::SimpleScene_DrawWind() +{ + return true; +} +bool BlastPlugin::SimpleScene_DrawAxis() +{ + return true; +} + +#include <Shlwapi.h> +#include <FbxUtil.h> +#include <MeshData.h> +#include <PxVec2.h> +#include <SourceAssetOpenDlg.h> +bool BlastPlugin::SimpleScene_LoadSceneFromFbx(const char* d, const char* f) +{ + SourceAssetOpenDlg dlg(false, &AppMainWindow::Inst()); + int res = dlg.exec(); + if (res != QDialog::Accepted || dlg.getFile().isEmpty()) + return false; + + QFileInfo fileInfo(dlg.getFile()); + std::string dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + std::string fbxName = fileInfo.fileName().toLocal8Bit(); + + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + char fbxFilePath[MAX_PATH]; + + float sceneUnit = globalSettings.getSceneUnitInCentimeters(); + + PathCombineA(fbxFilePath, dir.c_str(), fbxName.c_str()); + + AppMainWindow::Inst().setProgress("Initializing FBX loader", 0); + FbxUtil::Initialize(fbxFilePath, sceneUnit); + + char rootBoneName[MAX_PATH]; + int upAxis = 0; + + FbxUtil::GetGlobalSettings( + &globalSettings.m_frameStartTime, + &globalSettings.m_frameEndTime, + &globalSettings.m_animationFps, + &upAxis, rootBoneName); + + if (upAxis == 1) + SimpleScene::Inst()->ResetUpDir(false); + else if (upAxis = 2) + SimpleScene::Inst()->ResetUpDir(true); + + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + + int numMeshes = 0; + char* meshNames = 0; + char* skinned = 0; + FbxUtil::GetMeshInfo(&numMeshes, &meshNames, &skinned); + if (numMeshes > 1) + { + //return false; + } + + // to do later when numMeshes is more than one + numMeshes = 1; + + for (int i = 0; i < numMeshes; i++) + { + const char* meshName = meshNames + i * 128; + + MeshDesc meshDesc; + FbxUtil::CreateMeshDescriptor(meshName, meshDesc); + + MeshMaterial* materials = 0; + int numMaterials = 0; + FbxUtil::GetMeshMaterials(meshName, &numMaterials, &materials); + + SkinData skinData; + FbxUtil::InitializeSkinData(meshName, skinData); + + meshDesc.UpdateNormal(false); + + std::vector<physx::PxVec3> positions; + std::vector<physx::PxVec3> normals; + std::vector<physx::PxVec2> uv; + std::vector<unsigned int> indices; + + for (uint32_t i = 0; i < meshDesc.m_NumVertices; ++i) + { + atcore_float3 pos = meshDesc.m_pVertices[i]; + atcore_float3 vertexNormal = meshDesc.m_pVertexNormals[i]; + atcore_float2 texcoord = meshDesc.m_pTexCoords[i]; + + 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)); + } + + for (uint32_t i = 0; i < meshDesc.m_NumTriangles; ++i) + { + 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]); + } + + sampleManager.createAsset(meshName, positions, normals, uv, indices); + + 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); + } + sampleManager.addModelAsset(meshName, dlg.getSkinned(), t, !dlg.isAppend()); + } + + FbxUtil::Release(); + + globalSettings.m_sceneLoaded = true; + globalSettings.m_animationIndex = 1; + globalSettings.m_firstFrame = true; + + globalSettings.resetAnimation(); + + return true; +} + +bool BlastPlugin::SimpleScene_LoadProject(const char* dir, const char* file) +{ + GlobalSettings& globalSettings = GlobalSettings::Inst(); + SimpleScene* pScene = SimpleScene::Inst(); + nvidia::parameterized::BlastProjectParametersNS::ParametersStruct params; + if (!ProjectParamsLoad(globalSettings.getAbsoluteFilePath().c_str(), pScene)) + return false; + + return true; +} +bool BlastPlugin::SimpleScene_SaveProject(const char* dir, const char* file) +{ + GlobalSettings& globalSettings = GlobalSettings::Inst(); + SimpleScene* pScene = SimpleScene::Inst(); + + QString saveFilePath = globalSettings.getAbsoluteFilePath().c_str(); + QString tempFilePath = utils::GetTempFilePath().c_str(); + if (ProjectParamsSave(tempFilePath.toUtf8().data(), pScene)) + { + if (!utils::RenameFile(tempFilePath.toUtf8().data(), saveFilePath.toUtf8().data(), true /* overwrite */)) + { + return false; + } + pScene->SetProjectModified(false); + return true; + } + + 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) + { + BPPAsset& asset = srcDesc.blast.blastAssets.buf[i]; + QFileInfo fileInfo(asset.path.buf); + QByteArray tmp = fileInfo.baseName().toUtf8(); + const char* fileName = tmp.data(); + physx::PxTransform t(physx::PxIdentity); + BPPAssetInstance* instance = BlastProject::ins().getAssetInstance(asset.path.buf, 0); + if (instance != nullptr) + { + nvidia::NvVec3& postion = instance->transform.position; + 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); + } + SimpleScene::Inst()->GetSampleManager().addModelAsset(fileName, false, t, true); + } + + SimpleScene* pScene = SimpleScene::Inst(); + + if (pScene->m_pCamera) + { + pScene->m_pCamera->LoadParameters(&srcDesc.camera); + } + + pScene->LoadCameraBookmarks(iface); + + if (pScene->m_pWindCamera) + { + pScene->m_pWindCamera->LoadParameters(&srcDesc.windCamera); + } + + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + // Load scene settings + globalSettings.m_repeatAnimation = srcDesc.scene.repeatAnimation; + globalSettings.m_animationSpeed = srcDesc.scene.animationSpeed; + globalSettings.m_showGrid = srcDesc.scene.showGrid; + globalSettings.m_showAxis = srcDesc.scene.showAxis; + globalSettings.m_zup = srcDesc.scene.upAxis == 1; + globalSettings.m_sceneUnitIndex = srcDesc.scene.sceneUnitIndex; + + // Load render settings + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle("renderer", handle) == NvParameterized::ERROR_NONE) + { + globalSettings.m_computeStatistics = srcDesc.renderer.showStatistics; + globalSettings.m_showGraphicsMesh = srcDesc.renderer.showGraphicsMesh; + globalSettings.m_useLighting = srcDesc.renderer.useLighting; + globalSettings.m_showSkinnedMeshOnly = srcDesc.renderer.showSkinnedMeshOnly; + globalSettings.m_renderFps = srcDesc.renderer.renderFps; + globalSettings.m_simulationFps = srcDesc.renderer.simulationFps; + + Light::LoadParameters(handle); + } + + //// Load fbx paths + //if (iface->getParameterHandle("fbxFilePaths", handle) == NvParameterized::ERROR_NONE) + //{ + // int arraySize; + // handle.getArraySize(arraySize); + // char** strArray = new char*[arraySize]; + // handle.getParamStringArray(strArray, arraySize); + // for (int idx = 0; idx < arraySize; ++idx) + // { + // pScene->LoadSceneFromFbx( + // globalSettings.m_projectFileDir.c_str(), + // strArray[idx]); + // } + // delete[] strArray; + //} + + //// get fur character mesh setting + //if (false == pScene->GetFurCharacter().LoadMeshParameters(handle)) + // return false; + + //// Load apx paths (hair instances) + //if (iface->getParameterHandle("apxFilePaths", handle) == NvParameterized::ERROR_NONE) + //{ + // 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); + nvidia::parameterized::BlastProjectParametersNS::ParametersStruct& targetDesc = params->parameters(); + memset(&targetDesc, sizeof(BPParams), 0); + BPParams& srcParams = BlastProject::ins().getParams(); + copy(targetDesc, srcParams); + + SimpleScene* pScene = SimpleScene::Inst(); + + if (pScene->m_pCamera) + pScene->m_pCamera->SaveParameters(&targetDesc.camera); + + pScene->SaveCameraBookmarks(iface); + + if (pScene->m_pWindCamera) + pScene->m_pWindCamera->SaveParameters(&targetDesc.windCamera); + + // Save scene settings + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + targetDesc.scene.repeatAnimation = globalSettings.m_repeatAnimation; + targetDesc.scene.animationSpeed = globalSettings.m_animationSpeed; + targetDesc.scene.showGrid = globalSettings.m_showGrid; + targetDesc.scene.showAxis = globalSettings.m_showAxis; + targetDesc.scene.upAxis = (globalSettings.m_zup) ? 1 : 2; + targetDesc.scene.sceneUnitIndex = globalSettings.m_sceneUnitIndex; + + // Save render settings + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle("renderer", handle) == NvParameterized::ERROR_NONE) + { + targetDesc.renderer.renderFps = globalSettings.m_renderFps; + targetDesc.renderer.simulationFps = globalSettings.m_simulationFps; + targetDesc.renderer.showStatistics = globalSettings.m_computeStatistics; + targetDesc.renderer.showGraphicsMesh = globalSettings.m_showGraphicsMesh; + targetDesc.renderer.useLighting = globalSettings.m_useLighting; + targetDesc.renderer.showSkinnedMeshOnly = globalSettings.m_showSkinnedMeshOnly; + + Light::SaveParameters(handle); + } + + //if (iface->getParameterHandle("renderer.textureFilePath", handle) == NvParameterized::ERROR_NONE) + //{ + // std::string textureFilePath = globalSettings.getRelativePath(globalSettings.m_backgroundTextureFilePath.c_str()); + // handle.setParamString(textureFilePath.c_str()); + //} + + //// save hair path + //if (iface->getParameterHandle("apxFilePaths", handle) == NvParameterized::ERROR_NONE) + // character.SaveHairParameters(handle); + + return true; +} + +bool BlastPlugin::SimpleScene_LoadCameraBookmarks(NvParameterized::Interface* iface) +{ + return true; +} + +bool BlastPlugin::SimpleScene_SaveCameraBookmarks(NvParameterized::Interface* iface) +{ + SimpleScene* pScene = SimpleScene::Inst(); + + nvidia::parameterized::BlastProjectParameters* params = static_cast<nvidia::parameterized::BlastProjectParameters*>(iface); + nvidia::parameterized::BlastProjectParametersNS::ParametersStruct& srcDesc = params->parameters(); + nvidia::parameterized::BlastProjectParametersNS::CameraBookmark_DynamicArray1D_Type& bookmarks = srcDesc.cameraBookmarks; + + NvParameterized::Handle cameraBookmarksHandle(iface); + if (iface->getParameterHandle("cameraBookmarks", cameraBookmarksHandle) != NvParameterized::ERROR_NONE) + return false; + + int numCameraBookmarks = pScene->m_cameraBookmarks.size(); + cameraBookmarksHandle.resizeArray(numCameraBookmarks); + + for (int idx = 0; idx < numCameraBookmarks; ++idx) + { + NvParameterized::Handle cameraBookmarkHandle(cameraBookmarksHandle); + if (cameraBookmarksHandle.getChildHandle(idx, cameraBookmarkHandle) == NvParameterized::ERROR_NONE) + { + NvParameterized::Handle tempHandle(cameraBookmarkHandle); + CameraBookmark& bookmark = pScene->m_cameraBookmarks[idx]; + + if (ParamGetChild(cameraBookmarkHandle, tempHandle, "name")) + { + tempHandle.setParamString(bookmark.name.toStdString().c_str()); + } + + bookmark.camera.SaveParameters((void*)&(bookmarks.buf[idx].camera)); + } + } + + return true; +} + +bool BlastPlugin::D3DWidget_resizeEvent(QResizeEvent* e) +{ + DeviceManager& deviceManager = SimpleScene::Inst()->GetDeviceManager(); + + int w = e->size().width(); + int h = e->size().height(); + WPARAM wParam = MAKEWPARAM(w, h); + LPARAM lParam = MAKELPARAM(w, h); + deviceManager.MsgProc(g_hWnd, WM_SIZE, wParam, lParam); + + return true; +} + +bool BlastPlugin::D3DWidget_paintEvent(QPaintEvent* e) +{ + SampleManager& pSampleManager = SimpleScene::Inst()->GetSampleManager(); + pSampleManager.run(); + + if (pSampleManager.m_bNeedRefreshTree) + { + _blastSceneTree->updateValues(); + pSampleManager.m_bNeedRefreshTree = false; + } + + return true; +} + +bool BlastPlugin::D3DWidget_mousePressEvent(QMouseEvent* e) +{ + UINT uMsg = WM_LBUTTONDOWN; + if (e->button() == Qt::RightButton) + { + uMsg = WM_RBUTTONDOWN; + } + else if (e->button() == Qt::MidButton) + { + uMsg = WM_MBUTTONDOWN; + } + + int x = e->x(); + int y = e->y(); + WPARAM wParam = MAKEWPARAM(x, y); + LPARAM lParam = MAKELPARAM(x, y); + + DeviceManager& deviceManager = SimpleScene::Inst()->GetDeviceManager(); + deviceManager.MsgProc(g_hWnd, uMsg, wParam, lParam); + + return true; +} + +bool BlastPlugin::D3DWidget_mouseReleaseEvent(QMouseEvent* e) +{ + UINT uMsg = WM_LBUTTONUP; + if (e->button() == Qt::RightButton) + { + uMsg = WM_RBUTTONUP; + } + else if (e->button() == Qt::MidButton) + { + uMsg = WM_MBUTTONUP; + } + + int x = e->x(); + int y = e->y(); + WPARAM wParam = MAKEWPARAM(x, y); + LPARAM lParam = MAKELPARAM(x, y); + + DeviceManager& deviceManager = SimpleScene::Inst()->GetDeviceManager(); + deviceManager.MsgProc(g_hWnd, uMsg, wParam, lParam); + + return true; +} + +bool BlastPlugin::D3DWidget_mouseMoveEvent(QMouseEvent* e) +{ + DeviceManager& deviceManager = SimpleScene::Inst()->GetDeviceManager(); + + int x = e->x(); + int y = e->y(); + WPARAM wParam = MAKEWPARAM(x, y); + LPARAM lParam = MAKELPARAM(x, y); + deviceManager.MsgProc(g_hWnd, WM_MOUSEMOVE, wParam, lParam); + + return true; +} + +bool BlastPlugin::D3DWidget_wheelEvent(QWheelEvent * e) +{ + DeviceManager& deviceManager = SimpleScene::Inst()->GetDeviceManager(); + + int delta = e->delta(); + WPARAM wParam = MAKEWPARAM(delta, delta); + LPARAM lParam = MAKELPARAM(delta, delta); + deviceManager.MsgProc(g_hWnd, WM_MOUSEWHEEL, wParam, lParam); + + return true; +} + +bool BlastPlugin::D3DWidget_keyPressEvent(QKeyEvent* e) +{ return true; } +bool BlastPlugin::D3DWidget_keyReleaseEvent(QKeyEvent* e) +{ return true; } +bool BlastPlugin::D3DWidget_dragEnterEvent(QDragEnterEvent *e) +{ return true; } +bool BlastPlugin::D3DWidget_dragMoveEvent(QDragMoveEvent *e) +{ return true; } +bool BlastPlugin::D3DWidget_dragLeaveEvent(QDragLeaveEvent *e) +{ return true; } +bool BlastPlugin::D3DWidget_dropEvent(QDropEvent *e) +{ return true; } + +bool BlastPlugin::D3DWidget_contextMenuEvent(QContextMenuEvent *e) +{ + QPoint pos = QCursor::pos(); + + 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(); + BlastAsset* asset = itr->first; + std::vector<uint32_t> selectChunks = itr->second; + + std::vector<BlastChunkNode*> chunkNodes = BlastTreeData::ins().getChunkNodeByBlastChunk(asset, selectChunks); + if (1 == chunkNodes.size()) + { + _chunkContextMenu->exec(pos); + } + else if (1 < chunkNodes.size()) + { + bool allSupportChunk = true; + for (size_t i = 0; i < chunkNodes.size(); ++i) + { + BlastChunkNode* chunkNode = chunkNodes[i]; + if (eChunk != chunkNode->getType()) + { + allSupportChunk = false; + break; + } + } + + if (allSupportChunk) + { + _bondContextMenu->exec(QCursor::pos()); + } + } + } + e->accept(); + return true; +} + +#ifdef NV_ARTISTTOOLS +bool BlastPlugin::D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap) +{ + return PluginBlast::Instance()->D3D11Shaders_InitializeShadersD3D11(ShaderMap); +} +#endif // NV_ARTISTTOOLS + +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; + + return true; +} + +bool BlastPlugin::AppMainWindow_InitMenuItems(QMenuBar* pMenuBar) +{ + QMenu *pMenu = pMenuBar->addMenu("&Blast"); + QAction *act; + + act = new QAction("Open project file", this); + act->setShortcut(QKeySequence::Open); + connect(act, SIGNAL(triggered()), this, SLOT(menu_openProject())); + pMenu->addAction(act); + + act = new QAction("Save project file", this); + act->setShortcut(QKeySequence::Save); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveProject())); + pMenu->addAction(act); + + act = new QAction("Save project file as...", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveProjectAs())); + pMenu->addAction(act); + + pMenu->addSeparator(); + + return true; +} + +bool BlastPlugin::AppMainWindow_InitMainTab(QWidget *displayScrollAreaContents, QVBoxLayout *displayScrollAreaLayout, int idx) +{ + ExpandablePanel* panel = new ExpandablePanel(displayScrollAreaContents); + displayScrollAreaLayout->insertWidget(idx++, panel); + panel->SetTitle("Display Mesh Materials"); + + return true; +} + +bool BlastPlugin::AppMainWindow_InitPluginTab(QTabWidget* sideBarTab) +{ + { + QWidget *tabMaterial; + QGridLayout *gridLayoutMaterial; + QFrame *materialEditorArea; + QVBoxLayout *materialEditorAreaLayout; + QScrollArea *materialScrollArea; + QWidget *materialScrollAreaContents; + QVBoxLayout *materialScrollAreaLayout; + QSpacerItem *verticalSpacerMaterial; + + tabMaterial = new QWidget(); + tabMaterial->setObjectName(QStringLiteral("tabMaterial")); + gridLayoutMaterial = new QGridLayout(tabMaterial); + gridLayoutMaterial->setSpacing(6); + gridLayoutMaterial->setContentsMargins(11, 11, 11, 11); + gridLayoutMaterial->setObjectName(QStringLiteral("gridLayoutMaterial")); + gridLayoutMaterial->setContentsMargins(0, 0, 0, 0); + materialEditorArea = new QFrame(tabMaterial); + materialEditorArea->setObjectName(QStringLiteral("materialEditorArea")); + materialEditorAreaLayout = new QVBoxLayout(materialEditorArea); + materialEditorAreaLayout->setSpacing(6); + materialEditorAreaLayout->setContentsMargins(11, 11, 11, 11); + materialEditorAreaLayout->setObjectName(QStringLiteral("materialEditorAreaLayout")); + materialEditorAreaLayout->setContentsMargins(2, 2, 2, 2); + + gridLayoutMaterial->addWidget(materialEditorArea, 1, 0, 1, 1); + + materialScrollArea = new QScrollArea(tabMaterial); + materialScrollArea->setObjectName(QStringLiteral("materialScrollArea")); + materialScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + materialScrollArea->setWidgetResizable(true); + materialScrollAreaContents = new QWidget(); + materialScrollAreaContents->setObjectName(QStringLiteral("materialScrollAreaContents")); + materialScrollAreaContents->setGeometry(QRect(0, 0, 359, 481)); + materialScrollAreaLayout = new QVBoxLayout(materialScrollAreaContents); + materialScrollAreaLayout->setSpacing(3); + materialScrollAreaLayout->setContentsMargins(11, 11, 11, 11); + materialScrollAreaLayout->setObjectName(QStringLiteral("materialScrollAreaLayout")); + materialScrollAreaLayout->setContentsMargins(2, 2, 2, 2); + verticalSpacerMaterial = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + materialScrollAreaLayout->addItem(verticalSpacerMaterial); + + materialScrollArea->setWidget(materialScrollAreaContents); + + 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; + + panel = new ExpandablePanel(materialScrollAreaContents); + _materialLibraryPanel = new MaterialLibraryPanel(panel); + panel->AddContent(_materialLibraryPanel); + materialScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Material Library"); + + panel = new ExpandablePanel(materialScrollAreaContents); + _materialAssignmentsPanel = new MaterialAssignmentsPanel(panel); + panel->AddContent(_materialAssignmentsPanel); + materialScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Material Assignments"); + } + + { + QWidget *tabBlast; + QGridLayout *gridLayout; + QFrame *blastMaterialEditorArea; + QVBoxLayout *blastMaterialEditorAreaLayout; + QScrollArea *blastScrollArea; + QWidget *blastScrollAreaContents; + QVBoxLayout *blastScrollAreaLayout; + QSpacerItem *verticalSpacer; + + tabBlast = new QWidget(); + tabBlast->setObjectName(QStringLiteral("tabBlast")); + gridLayout = new QGridLayout(tabBlast); + gridLayout->setSpacing(6); + gridLayout->setContentsMargins(11, 11, 11, 11); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + gridLayout->setContentsMargins(0, 0, 0, 0); + blastMaterialEditorArea = new QFrame(tabBlast); + blastMaterialEditorArea->setObjectName(QStringLiteral("blastMaterialEditorArea")); + blastMaterialEditorAreaLayout = new QVBoxLayout(blastMaterialEditorArea); + blastMaterialEditorAreaLayout->setSpacing(6); + blastMaterialEditorAreaLayout->setContentsMargins(11, 11, 11, 11); + blastMaterialEditorAreaLayout->setObjectName(QStringLiteral("blastMaterialEditorAreaLayout")); + blastMaterialEditorAreaLayout->setContentsMargins(2, 2, 2, 2); + + gridLayout->addWidget(blastMaterialEditorArea, 1, 0, 1, 1); + + blastScrollArea = new QScrollArea(tabBlast); + blastScrollArea->setObjectName(QStringLiteral("blastScrollArea")); + blastScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + blastScrollArea->setWidgetResizable(true); + blastScrollAreaContents = new QWidget(); + blastScrollAreaContents->setObjectName(QStringLiteral("blastScrollAreaContents")); + blastScrollAreaContents->setGeometry(QRect(0, 0, 359, 481)); + blastScrollAreaLayout = new QVBoxLayout(blastScrollAreaContents); + blastScrollAreaLayout->setSpacing(3); + blastScrollAreaLayout->setContentsMargins(11, 11, 11, 11); + blastScrollAreaLayout->setObjectName(QStringLiteral("blastScrollAreaLayout")); + blastScrollAreaLayout->setContentsMargins(2, 2, 2, 2); + verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + blastScrollAreaLayout->addItem(verticalSpacer); + + blastScrollArea->setWidget(blastScrollAreaContents); + + 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; + + panel = new ExpandablePanel(blastScrollAreaContents); + _fileReferencesPanel = new FileReferencesPanel(panel); + panel->AddContent(_fileReferencesPanel); + blastScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("File References"); + + panel = new ExpandablePanel(blastScrollAreaContents); + _generalPanel = new GeneralPanel(panel); + panel->AddContent(_generalPanel); + blastScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("General"); + + panel = new ExpandablePanel(blastScrollAreaContents); + _supportPanel = new SupportPanel(panel); + panel->AddContent(_supportPanel); + blastScrollAreaLayout->insertWidget(pannelCnt++, panel); + 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); + blastScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Shell Cut Settings"); + + panel = new ExpandablePanel(blastScrollAreaContents); + _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"); + + panel = new ExpandablePanel(blastScrollAreaContents); + _fractureVisualizersPanel = new FractureVisualizersPanel(panel); + panel->AddContent(_fractureVisualizersPanel); + blastScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Visualizers"); + } + + { + QWidget *tabDamage; + QGridLayout *gridLayoutDamage; + QFrame *damageEditorArea; + QVBoxLayout *damageEditorAreaLayout; + QScrollArea *damageScrollArea; + QWidget *damageScrollAreaContents; + QVBoxLayout *damageScrollAreaLayout; + QSpacerItem *verticalSpacerDamage; + + tabDamage = new QWidget(); + tabDamage->setObjectName(QStringLiteral("tabDamage")); + gridLayoutDamage = new QGridLayout(tabDamage); + gridLayoutDamage->setSpacing(6); + gridLayoutDamage->setContentsMargins(11, 11, 11, 11); + gridLayoutDamage->setObjectName(QStringLiteral("gridLayoutDamage")); + gridLayoutDamage->setContentsMargins(0, 0, 0, 0); + damageEditorArea = new QFrame(tabDamage); + damageEditorArea->setObjectName(QStringLiteral("damageEditorArea")); + damageEditorAreaLayout = new QVBoxLayout(damageEditorArea); + damageEditorAreaLayout->setSpacing(6); + damageEditorAreaLayout->setContentsMargins(11, 11, 11, 11); + damageEditorAreaLayout->setObjectName(QStringLiteral("damageEditorAreaLayout")); + damageEditorAreaLayout->setContentsMargins(2, 2, 2, 2); + + gridLayoutDamage->addWidget(damageEditorArea, 1, 0, 1, 1); + + damageScrollArea = new QScrollArea(tabDamage); + damageScrollArea->setObjectName(QStringLiteral("damageScrollArea")); + damageScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + damageScrollArea->setWidgetResizable(true); + damageScrollAreaContents = new QWidget(); + damageScrollAreaContents->setObjectName(QStringLiteral("damageScrollAreaContents")); + damageScrollAreaContents->setGeometry(QRect(0, 0, 359, 481)); + damageScrollAreaLayout = new QVBoxLayout(damageScrollAreaContents); + damageScrollAreaLayout->setSpacing(3); + damageScrollAreaLayout->setContentsMargins(11, 11, 11, 11); + damageScrollAreaLayout->setObjectName(QStringLiteral("damageScrollAreaLayout")); + damageScrollAreaLayout->setContentsMargins(2, 2, 2, 2); + verticalSpacerDamage = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + damageScrollAreaLayout->addItem(verticalSpacerDamage); + + damageScrollArea->setWidget(damageScrollAreaContents); + + gridLayoutDamage->addWidget(damageScrollArea, 0, 0, 1, 1); + + sideBarTab->addTab(tabDamage, QString()); + + sideBarTab->setTabText(sideBarTab->indexOf(tabDamage), QApplication::translate("AppMainWindowClass", "Damage", 0)); + + ExpandablePanel* panel = 0; + int pannelCnt = 0; + + panel = new ExpandablePanel(damageScrollAreaContents); + _defaultDamagePanel = new DefaultDamagePanel(panel); + panel->AddContent(_defaultDamagePanel); + damageScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Default Damage"); + } + + return true; +} + +bool BlastPlugin::AppMainWindow_InitUI() +{ + AppMainWindow* mainWindow = &AppMainWindow::Inst(); + _mainToolbar = new BlastToolbar(mainWindow); + _mainToolbar->setAllowedAreas(Qt::TopDockWidgetArea); + _mainToolbar->setFeatures(_mainToolbar->features()&~QDockWidget::DockWidgetClosable); + mainWindow->addDockWidget(Qt::TopDockWidgetArea, _mainToolbar); + + _filtersDockWidget = new FiltersDockWidget(mainWindow); + _filtersDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea); + _filtersDockWidget->setFeatures(_filtersDockWidget->features()&~QDockWidget::DockWidgetClosable); + mainWindow->addDockWidget(Qt::LeftDockWidgetArea, _filtersDockWidget); + + _blastSceneTree = new BlastSceneTree(mainWindow); + _blastSceneTree->setAllowedAreas(Qt::LeftDockWidgetArea); + _blastSceneTree->setFeatures(_blastSceneTree->features()&~QDockWidget::DockWidgetClosable); + _blastSceneTree->addObserver(_defaultDamagePanel); + mainWindow->addDockWidget(Qt::LeftDockWidgetArea, _blastSceneTree); + return true; +} + +bool BlastPlugin::AppMainWindow_updateUI() +{ + if (_mainToolbar) + _mainToolbar->updateValues(); + + if (_filtersDockWidget) + _filtersDockWidget->updateValues(); + + if (_blastSceneTree) + _blastSceneTree->updateValues(); + + if (_materialLibraryPanel) + _materialLibraryPanel->updateValues(); + + if (_materialAssignmentsPanel) + _materialAssignmentsPanel->updateValues(); + + if (_fileReferencesPanel) + _fileReferencesPanel->updateValues(); + + if (_generalPanel) + _generalPanel->updateValues(); + + if (_blastCompositePanel) + _blastCompositePanel->updateValues(); + + if (_fractureCutoutSettingsPanel) + _fractureCutoutSettingsPanel->updateValues(); + + if (_fractureGeneralPanel) + _fractureGeneralPanel->updateValues(); + + if (_fractureShellCutSettingPanel) + _fractureShellCutSettingPanel->updateValues(); + + if (_fractureSliceSettingsPanel) + _fractureSliceSettingsPanel->updateValues(); + + if (_fractureVisualizersPanel) + _fractureVisualizersPanel->updateValues(); + + if (_fractureVoronoiSettingsPanel) + _fractureVoronoiSettingsPanel->updateValues(); + + if (_supportPanel) + _supportPanel->updateValues(); + + if (_defaultDamagePanel) + _defaultDamagePanel->updateValues(); + return true; +} + +bool BlastPlugin::AppMainWindow_updatePluginUI() +{ + return true; +} + +bool BlastPlugin::AppMainWindow_processDragAndDrop(QString fname) +{ + return true; +} + +bool BlastPlugin::AppMainWindow_closeEvent(QCloseEvent *event) +{ + if (!menu_saveProject()) + { + return false; + } + + return true; +} + + +bool BlastPlugin::AppMainWindow_InitToolbar(QWidget *pQWidget, QVBoxLayout* pLayout) +{ + //_mainToolbar = new BlastToolbar(pQWidget); + //pLayout->insertWidget(0, _mainToolbar); +// connect(_mainToolbar->getUI().btnFileOpen, SIGNAL(clicked()), this, SLOT(menu_openProject())); + + return true; +} + +bool BlastPlugin::AppMainWindow_shortcut_expert(bool mode) +{ + if (_mainToolbar) + _mainToolbar->setVisible(mode); + + return true; +} + +bool BlastPlugin::AppMainWindow_updateMainToolbar() +{ + if (_mainToolbar) + _mainToolbar->updateValues(); + + return true; +} + +bool BlastPlugin::AppMainWindow_menu_about() +{ + return true; +} + +bool BlastPlugin::AppMainWindow_menu_opendoc() +{ + QString appDir = QApplication::applicationDirPath(); + QString docsFile = QFileInfo(appDir + "/../../docs/User_Guide/Nvidia Blast.chm").absoluteFilePath(); + + QUrl docsUrl = QUrl::fromLocalFile(docsFile); + QUrl url = QUrl::fromUserInput(QString("http://docs.nvidia.com/gameworks/content/artisttools/blast/index.html")); + QDesktopServices::openUrl(url); + + return true; +} + +#if USE_CURVE_EDITOR +#include "CurveEditorMainWindow.h" + +bool BlastPlugin::AppMainWindow_UpdateCurveEditor() +{ + return true; +} +bool BlastPlugin::AppMainWindow_ShowCurveEditor(int paramId) +{ + return true; +} +bool BlastPlugin::AppMainWindow_onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute) +{ + return true; +} +bool BlastPlugin::AppMainWindow_onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute) +{ + return true; +} +bool BlastPlugin::AppMainWindow_onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex) +{ + return true; +} +#endif + +bool BlastPlugin::menu_openProject() +{ + AppMainWindow& window = AppMainWindow::Inst(); + QString lastDir = window._lastFilePath; + QString fileName = QFileDialog::getOpenFileName(&window, "Open Blast Project File", lastDir, "Blast Project File (*.blastProj)"); + + return window.openProject(fileName); +} + +bool BlastPlugin::menu_saveProject() +{ + char message[1024]; + + std::string projectFilePath = GlobalSettings::Inst().getAbsoluteFilePath(); + std::string projectFileName = GlobalSettings::Inst().m_projectFileName; + if (projectFileName != "") + { + if (SimpleScene::Inst()->SaveProject( + GlobalSettings::Inst().m_projectFileDir.c_str(), + GlobalSettings::Inst().m_projectFileName.c_str() + ) == false) + { + QMessageBox messageBox; + + sprintf(message, "Project file %s could not be saved!", (const char*)projectFilePath.c_str()); + messageBox.critical(0, "Error", message); + messageBox.setFixedSize(500, 200); + char message[1024]; + sprintf(message, "Failed to save project file(\"%s\")", (const char*)projectFilePath.c_str()); + viewer_err(message); + return false; + } + + sprintf(message, "Project file %s was saved.", (const char*)projectFilePath.c_str()); + + /* + QMessageBox messageBox; + messageBox.information(0, "Info", message); + messageBox.setFixedSize(500,200); + */ + viewer_msg(message); + return true; + } + else + { + return menu_saveProjectAs(); + } + return false; +} + +bool BlastPlugin::menu_saveProjectAs() +{ + AppMainWindow& window = AppMainWindow::Inst(); + + char message[1024]; + + QString lastDir = window._lastFilePath; + QString fileName = QFileDialog::getSaveFileName(&window, "Save Blast Project File", lastDir, "Blast Project File (*.blastProj)"); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file = fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->SaveProject(dir, file) == false) + { + QMessageBox messageBox; + sprintf(message, "Project file %s could not be saved!", (const char*)file); + messageBox.critical(0, "Error", message); + messageBox.setFixedSize(500, 200); + return false; + } + + sprintf(message, "Project file %s was saved.", (const char*)file); + + /* + QMessageBox messageBox; + messageBox.information(0, "Info", message); + messageBox.setFixedSize(500,200); + */ + + viewer_msg(message); + + window._lastFilePath = fileInfo.absoluteDir().absolutePath(); + return true; + } + return false; +} + +bool BlastPlugin::shortcut_damagetool() +{ + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + sampleManager.setBlastToolType(BTT_Damage); + return true; +} + +bool BlastPlugin::shortcut_selecttool() +{ + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + sampleManager.setBlastToolType(BTT_Select); + return true; +} + +bool BlastPlugin::shortcut_Translate() +{ + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + sampleManager.setBlastToolType(BTT_Translate); + return true; +} + +bool BlastPlugin::shortcut_Rotation() +{ + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + sampleManager.setBlastToolType(BTT_Rotation); + return true; +} + +bool BlastPlugin::shortcut_Scale() +{ + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + sampleManager.setBlastToolType(BTT_Scale); + return true; +} + +bool BlastPlugin::shortcut_edittool() +{ + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + sampleManager.setBlastToolType(BTT_Edit); + return true; +} + +bool BlastPlugin::slot_Make_Support() +{ + BlastSceneTree::ins()->makeSupport(); + return true; +} + +bool BlastPlugin::slot_Make_Static_Support() +{ + BlastSceneTree::ins()->makeStaticSupport(); + return true; +} + +bool BlastPlugin::slot_Remove_Support() +{ + BlastSceneTree::ins()->removeSupport(); + return true; +} + +bool BlastPlugin::slot_Bond_Chunks() +{ + BlastSceneTree::ins()->bondChunks(); + return true; +} + +bool BlastPlugin::slot_Bond_Chunks_with_Joints() +{ + BlastSceneTree::ins()->bondChunksWithJoints(); + return true; +} + +bool BlastPlugin::slot_Remove_all_Bonds() +{ + BlastSceneTree::ins()->removeAllBonds(); + return true; +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/BlastPlugin.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/BlastPlugin.h new file mode 100644 index 0000000..21a5499 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/BlastPlugin.h @@ -0,0 +1,192 @@ +#ifndef BLASTPLUGIN_H +#define BLASTPLUGIN_H + +#include <QtCore/QObject> +#include <QtCore/QtPlugin> +#include "PluginInterface.h" +#include "UIGlobal.h" + +class QMenu; +class QAction; +class QDoubleSpinBox; +class QComboBox; +class QCheckBox; +class QVBoxLayout; +class BlastToolbar; +class FileReferencesPanel; +class GeneralPanel; +class BlastCompositePanel; +class DefaultDamagePanel; +class MaterialLibraryPanel; +class MaterialAssignmentsPanel; +class FractureCutoutSettingsPanel; +class FractureGeneralPanel; +class FractureShellCutSettingsPanel; +class FractureSliceSettingsPanel; +class FractureVisualizersPanel; +class FractureVoronoiSettingsPanel; +class SupportPanel; +class BlastSceneTree; +class FiltersDockWidget; + +class Camera; +class Light; +namespace NvParameterized +{ + class Interface; + class Handle; +} +class D3D11RenderShader; + +#define BlastPluginName "BlastPlugin" + +class BlastPlugin : public QObject, public PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID PluginInterface_iid FILE "blastplugin.json") + Q_INTERFACES(PluginInterface) + +public: + virtual QString GetPluginName(); + + virtual bool CoreLib_RunApp(); + + virtual bool LoadRenderPlugin(std::string api); + + virtual bool GetBoneNames(std::vector<std::string>& BoneNames); + + virtual bool MainToolbar_updateValues(); + + virtual bool CurveEditor_updateValues(int _paramId, float* _values); + virtual bool CurveEditor_onUpdateValues(int _paramId, float* _values); + + virtual bool DisplayMeshesPanel_updateValues(); + virtual bool DisplayMeshesPanel_EmitToggleSignal(unsigned int id, bool visible); + + virtual bool Camera_LoadParameters(void* ptr, Camera* pCamera); + virtual bool Camera_SaveParameters(void * ptr, Camera* pCamera); + + virtual bool Gamepad_ToggleSimulation(); + virtual bool Gamepad_LoadSamples(QString fn); + virtual bool Gamepad_ResetScene(); + virtual bool Gamepad_StartAnimation(); + virtual bool GamepadHandler_ShowHair(); + virtual bool GamepadHandler_SpinWindStrength(float windStrength); + virtual bool Gamepad_ResetAnimation(); + virtual bool Gamepad_PlayPauseAnimation(); + + virtual bool Light_loadParameters(NvParameterized::Handle& handle, Light* pLight); + virtual bool Light_saveParameters(NvParameterized::Handle& handle, Light* pLight); + + virtual bool SimpleScene_SimpleScene(); + virtual bool SimpleScene_Initialize(int backdoor); + virtual bool SimpleScene_Shutdown(); + virtual bool SimpleScene_Clear(); + virtual bool SimpleScene_Draw_DX12(); + virtual bool SimpleScene_Draw_DX11(); + virtual bool SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents); + virtual bool SimpleScene_DrawGround(); + virtual bool SimpleScene_DrawWind(); + virtual bool SimpleScene_DrawAxis(); + virtual bool SimpleScene_LoadSceneFromFbx(const char* dir, const char* fbxName); + virtual bool SimpleScene_LoadProject(const char* dir, const char* file); + virtual bool SimpleScene_SaveProject(const char* dir, const char* file); + virtual bool SimpleScene_LoadParameters(NvParameterized::Interface* iface); + virtual bool SimpleScene_SaveParameters(NvParameterized::Interface* iface); + virtual bool SimpleScene_LoadCameraBookmarks(NvParameterized::Interface* iface); + virtual bool SimpleScene_SaveCameraBookmarks(NvParameterized::Interface* iface); + + virtual bool D3DWidget_resizeEvent(QResizeEvent* e); + virtual bool D3DWidget_paintEvent(QPaintEvent* e); + virtual bool D3DWidget_mousePressEvent(QMouseEvent* e); + virtual bool D3DWidget_mouseReleaseEvent(QMouseEvent* e); + virtual bool D3DWidget_mouseMoveEvent(QMouseEvent* e); + virtual bool D3DWidget_wheelEvent(QWheelEvent * e); + virtual bool D3DWidget_keyPressEvent(QKeyEvent* e); + virtual bool D3DWidget_keyReleaseEvent(QKeyEvent* e); + virtual bool D3DWidget_dragEnterEvent(QDragEnterEvent *e); + virtual bool D3DWidget_dragMoveEvent(QDragMoveEvent *e); + virtual bool D3DWidget_dragLeaveEvent(QDragLeaveEvent *e); + virtual bool D3DWidget_dropEvent(QDropEvent *e); + virtual bool D3DWidget_contextMenuEvent(QContextMenuEvent *e); + + virtual bool D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap); + + virtual bool AppMainWindow_AppMainWindow(); + virtual bool AppMainWindow_InitMenuItems(QMenuBar* pMenuBar); + virtual bool AppMainWindow_InitMainTab(QWidget *displayScrollAreaContents, QVBoxLayout *displayScrollAreaLayout, int idx); + virtual bool AppMainWindow_InitPluginTab(QTabWidget* pTabWidget); + virtual bool AppMainWindow_InitUI(); + virtual bool AppMainWindow_updateUI(); + virtual bool AppMainWindow_updatePluginUI(); + virtual bool AppMainWindow_processDragAndDrop(QString fname); + virtual bool AppMainWindow_closeEvent(QCloseEvent *event); + virtual bool AppMainWindow_InitToolbar(QWidget *pQWidget, QVBoxLayout* pLayout); + virtual bool AppMainWindow_shortcut_expert(bool mode); + virtual bool AppMainWindow_updateMainToolbar(); + + virtual bool AppMainWindow_menu_about(); + virtual bool AppMainWindow_menu_opendoc(); +#if USE_CURVE_EDITOR + virtual bool AppMainWindow_UpdateCurveEditor(); + virtual bool AppMainWindow_ShowCurveEditor(int paramId); + virtual bool AppMainWindow_onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute); + virtual bool AppMainWindow_onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute); + virtual bool AppMainWindow_onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex); +#endif + BlastToolbar* GetMainToolbar() { return _mainToolbar; } + +public: + static void DrawHUD(); + + ///////////////////////////////////////////////////////////////////// + // profiler and timer + static void ResetFrameTimer(); + +public slots: + bool menu_openProject(); + bool menu_saveProject(); + bool menu_saveProjectAs(); + bool shortcut_damagetool(); + bool shortcut_selecttool(); + bool shortcut_Translate(); + bool shortcut_Rotation(); + bool shortcut_Scale(); + bool shortcut_edittool(); + + bool slot_Make_Support(); + bool slot_Make_Static_Support(); + bool slot_Remove_Support(); + bool slot_Bond_Chunks(); + bool slot_Bond_Chunks_with_Joints(); + bool slot_Remove_all_Bonds(); + +private: + BlastToolbar* _mainToolbar; + MaterialLibraryPanel* _materialLibraryPanel; + MaterialAssignmentsPanel* _materialAssignmentsPanel; + FileReferencesPanel* _fileReferencesPanel; + GeneralPanel* _generalPanel; + BlastCompositePanel* _blastCompositePanel; + DefaultDamagePanel* _defaultDamagePanel; + FractureCutoutSettingsPanel* _fractureCutoutSettingsPanel; + FractureGeneralPanel* _fractureGeneralPanel; + FractureShellCutSettingsPanel* _fractureShellCutSettingPanel; + FractureSliceSettingsPanel* _fractureSliceSettingsPanel; + FractureVisualizersPanel* _fractureVisualizersPanel; + FractureVoronoiSettingsPanel* _fractureVoronoiSettingsPanel; + SupportPanel* _supportPanel; + BlastSceneTree* _blastSceneTree; + FiltersDockWidget* _filtersDockWidget; + + QMenu* _chunkContextMenu; + QMenu* _bondContextMenu; + QAction* action_Make_Support; + QAction* action_Make_Static_Support; + QAction* action_Remove_Support; + QAction* action_Bond_Chunks; + QAction* action_Bond_Chunks_with_Joints; + QAction* action_Remove_all_Bonds; +}; + +#endif // HAIRWORKSPLUGIN_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Parameters/FoundationHolder.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Parameters/FoundationHolder.h new file mode 100644 index 0000000..5ec7868 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Parameters/FoundationHolder.h @@ -0,0 +1,138 @@ +// 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. +// + +#pragma once + +#include "NvErrorCallback.h" +#include "NsGlobals.h" +#include "NsVersionNumber.h" + +class DefaultErrorCallback : public nvidia::NvErrorCallback +{ +public: + DefaultErrorCallback(void) + { + } + + virtual void reportError(nvidia::NvErrorCode::Enum code, const char* message, const char* file, int line) + { + NV_UNUSED(code); + printf("PhysX: %s : %s : %d\r\n", message, file, line); + } +private: +}; + +class DefaultAllocator : public nvidia::NvAllocatorCallback +{ +public: + DefaultAllocator(void) + { + } + + ~DefaultAllocator(void) + { + } + + virtual void* allocate(size_t size, const char* typeName, const char* filename, int line) + { + NV_UNUSED(typeName); + NV_UNUSED(filename); + NV_UNUSED(line); + void *ret = ::_aligned_malloc(size, 16); + return ret; + } + + virtual void deallocate(void* ptr) + { + ::_aligned_free(ptr); + } +private: +}; + + +#if 0 +class FoundationHolder +{ + NvFoundation* mFoundation; + FoundationHolder() + :mFoundation(nullptr) + { + } + + ~FoundationHolder() + { + if (mFoundation) + { + // to-do + // we should release foundation. but Hair SDK could release it first. + //mFoundation->release(); + mFoundation = nullptr; + } + } + +public: + + static NvFoundation* GetFoundation() + { + static FoundationHolder fh; + if (fh.mFoundation == nullptr) + { + static DefaultAllocator sDefaultAllocator; + static DefaultErrorCallback sDefaultErrorCallback; + fh.mFoundation = NvCreateFoundation(NV_FOUNDATION_VERSION, sDefaultAllocator, sDefaultErrorCallback); + assert(fh.mFoundation != nullptr); + } + return fh.mFoundation; + } +}; + +#else + +class FoundationHolder +{ + bool m_isInitialized; + public: + static void GetFoundation() + { + static FoundationHolder s_holder; + if (!s_holder.m_isInitialized) + { + static DefaultAllocator sDefaultAllocator; + static DefaultErrorCallback sDefaultErrorCallback; + nvidia::shdfnd::initializeSharedFoundation(NV_FOUNDATION_VERSION, sDefaultAllocator, sDefaultErrorCallback); + + s_holder.m_isInitialized = true; + } + } + ~FoundationHolder() + { + //nvidia::terminateSharedFoundation(); + } +}; + +#endif diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.cpp new file mode 100644 index 0000000..36d78cc --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.cpp @@ -0,0 +1,2162 @@ +// 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-2013 NVIDIA Corporation. All rights reserved. + +#include "NvParameterized.h" +#include "XmlSerializer.h" +#include "NsFileBuffer.h" +#include "NvTraits.h" +#include "NsMemoryBuffer.h" + +#include "BlastProjectParameters.h" +#include "SimpleScene.h" +#include "ProjectParams.h" + +#include "NvErrorCallback.h" +#include "NsGlobals.h" +#include "NsVersionNumber.h" +#include <QtXml\QtXml> +#include <QtWidgets/QMessageBox> +#include "AppMainWindow.h" +#include "FoundationHolder.h" + +using namespace nvidia; +using namespace nvidia::parameterized; + + +struct ProjectParamsContext* g_projectParamsContext = nullptr; +const char* USER_PRESET_PATH = ".\\BlastUserPreset.userPreset"; + +struct ProjectParamsContext +{ + //NvFoundation* mFoundation; + NvParameterized::Traits* mTraits; + BlastProjectParametersFactory* mBlastProjectParametersFactory; +}; + +void freeString(NvParameterized::DummyStringStruct& str) +{ + delete[] str.buf; + str.buf = nullptr; +} + +void freeBlast(BPPGraphicsMesh& data) +{ + freeString(data.name); +} + +void freeBlast(BPPChunk& data) +{ + freeString(data.name); + freeString(data.asset); +} + +void freeBlast(BPPBond& data) +{ + freeString(data.name); + freeString(data.asset); +} + +void freeBlast(BPPAsset& data) +{ + freeString(data.path); +} + +void freeBlast(BPPAssetInstance& data) +{ + freeString(data.name); + freeString(data.source); +} + +void freeBlast(BPPComposite& data) +{ + freeString(data.composite); + + freeBlast(data.blastAssetInstances); + freeBlast(data.landmarks); +} + +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.chunks); + freeBlast(data.bonds); +} + +void freeBlast(BPPLandmark& data) +{ + freeString(data.name); +} + +void freeBlast(BPPStringArray& data) +{ + for (int i = 0; i < data.arraySizes[0]; ++i) + { + freeString(data.buf[i]); + } + + delete[] data.buf; + data.buf = nullptr; + data.arraySizes[0] = 0; +} + +void freeBlast(BPPGraphicsMeshArray& data) +{ + for (int i = 0; i < data.arraySizes[0]; ++i) + { + freeBlast(data.buf[i]); + } + + delete[] data.buf; + data.buf = nullptr; + data.arraySizes[0] = 0; +} + +void freeBlast(BPPChunkArray& data) +{ + for (int i = 0; i < data.arraySizes[0]; ++i) + { + freeBlast(data.buf[i]); + } + + delete[] data.buf; + data.buf = nullptr; + data.arraySizes[0] = 0; +} + +void freeBlast(BPPBondArray& data) +{ + for (int i = 0; i < data.arraySizes[0]; ++i) + { + freeBlast(data.buf[i]); + } + + delete[] data.buf; + data.buf = nullptr; + data.arraySizes[0] = 0; +} + +void freeBlast(BPPAssetArray& data) +{ + for (int i = 0; i < data.arraySizes[0]; ++i) + { + freeBlast(data.buf[i]); + } + + delete[] data.buf; + data.buf = nullptr; + data.arraySizes[0] = 0; +} + +void freeBlast(BPPAssetInstanceArray& data) +{ + for (int i = 0; i < data.arraySizes[0]; ++i) + { + freeBlast(data.buf[i]); + } + + delete[] data.buf; + data.buf = nullptr; + data.arraySizes[0] = 0; +} + +void freeBlast(BPPLandmarkArray& data) +{ + for (int i = 0; i < data.arraySizes[0]; ++i) + { + freeBlast(data.buf[i]); + } + + delete[] data.buf; + data.buf = nullptr; + data.arraySizes[0] = 0; +} + +void copy(NvParameterized::DummyStringStruct& dest, const char* source) +{ + delete[] dest.buf; + dest.buf = nullptr; + //dest.isAllocated = false; + + if (source != nullptr) + { + dest.buf = new char[strlen(source) + 1]; + strcpy(const_cast<char*>(dest.buf), source); + //dest.isAllocated = true; + } +} + +void copy(NvParameterized::DummyStringStruct& dest, NvParameterized::DummyStringStruct& source) +{ + copy(dest, source.buf); +} + +void copy(BPPStringArray& dest, BPPStringArray& source) +{ + { + for (int i = 0; i < dest.arraySizes[0]; ++i) + { + delete[] dest.buf[i].buf; + } + delete[] dest.buf; + dest.buf = nullptr; + dest.arraySizes[0] = 0; + } + + + if (source.arraySizes[0] > 0) + { + dest.buf = new NvParameterized::DummyStringStruct[source.arraySizes[0]]; + + for (int i = 0; i < source.arraySizes[0]; ++i) + { + NvParameterized::DummyStringStruct& destItem = dest.buf[i]; + NvParameterized::DummyStringStruct& sourceItem = source.buf[i]; + + destItem.buf = nullptr; + + copy(destItem, sourceItem); + } + dest.arraySizes[0] = source.arraySizes[0]; + } +} + +void copy(BPPGraphicsMaterialArray& dest, BPPGraphicsMaterialArray& source) +{ + delete[] dest.buf; + dest.buf = nullptr; + dest.arraySizes[0] = 0; + + if (source.arraySizes[0] > 0) + { + dest.buf = new BPPGraphicsMaterial[source.arraySizes[0]]; + for (int i = 0; i < source.arraySizes[0]; ++i) + { + BPPGraphicsMaterial& destItem = dest.buf[i]; + BPPGraphicsMaterial& sourceItem = source.buf[i]; + + init(destItem); + + copy(destItem, sourceItem); + } + dest.arraySizes[0] = source.arraySizes[0]; + } +} + +void copy(BPPGraphicsMeshArray& dest, BPPGraphicsMeshArray& source) +{ + delete[] dest.buf; + dest.buf = nullptr; + dest.arraySizes[0] = 0; + + if (source.arraySizes[0] > 0) + { + dest.buf = new BPPGraphicsMesh[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; + + copy(destItem.name, sourceItem.name); + destItem.visible = sourceItem.visible; + copy(destItem.materialAssignments, sourceItem.materialAssignments); + } + dest.arraySizes[0] = source.arraySizes[0]; + } +} + +void copy(BPPBookmarkArray& dest, BPPBookmarkArray& source) +{ + { + int count = dest.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + delete[] dest.buf[i].name.buf; + } + delete[] dest.buf; + dest.buf = nullptr; + dest.arraySizes[0] = 0; + } + + { + int count = source.arraySizes[0]; + dest.arraySizes[0] = count; + if (count > 0) + { + dest.buf = new BPPCameraBookmark[count]; + for (int i = 0; i < count; ++i) + { + BPPCameraBookmark& destItem = dest.buf[i]; + BPPCameraBookmark& sourceItem = source.buf[i]; + + destItem.name.buf = nullptr; + + copy(destItem.name, sourceItem.name); + destItem.camera = sourceItem.camera; + } + } + } +} + +void copy(BPPLightArray& dest, BPPLightArray& source) +{ + delete[] dest.buf; + dest.buf = nullptr; + dest.arraySizes[0] = 0; + + if (source.arraySizes[0] > 0) + { + dest.buf = new BPPLight[source.arraySizes[0]]; + for (int i = 0; i < source.arraySizes[0]; ++i) + { + BPPLight& destItem = dest.buf[i]; + BPPLight& sourceItem = source.buf[i]; + + destItem.name.buf = nullptr; + + copy(destItem.name, sourceItem.name); + copy(destItem, sourceItem); + } + dest.arraySizes[0] = source.arraySizes[0]; + } +} + +void copy(BPPChunkArray& dest, BPPChunkArray& source) +{ + freeBlast(dest); + + if (source.arraySizes[0] > 0) + { + dest.buf = new BPPChunk[source.arraySizes[0]]; + for (int i = 0; i < source.arraySizes[0]; ++i) + { + BPPChunk& destItem = dest.buf[i]; + BPPChunk& sourceItem = source.buf[i]; + + destItem.name.buf = nullptr; + destItem.asset.buf = nullptr; + + copy(destItem, sourceItem); + } + dest.arraySizes[0] = source.arraySizes[0]; + } +} + +void copy(BPPBondArray& dest, BPPBondArray& source) +{ + freeBlast(dest); + + if (source.arraySizes[0] > 0) + { + dest.buf = new BPPBond[source.arraySizes[0]]; + for (int i = 0; i < source.arraySizes[0]; ++i) + { + 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; + + copy(destItem, sourceItem); + } + dest.arraySizes[0] = source.arraySizes[0]; + } +} + +void copy(BPPAssetArray& dest, BPPAssetArray& source) +{ + delete[] dest.buf; + dest.buf = nullptr; + dest.arraySizes[0] = 0; + + if (source.arraySizes[0] > 0) + { + dest.buf = new BPPAsset[source.arraySizes[0]]; + for (int i = 0; i < source.arraySizes[0]; ++i) + { + BPPAsset& destItem = dest.buf[i]; + BPPAsset& sourceItem = source.buf[i]; + + destItem.path.buf = nullptr; + destItem.activePreset.buf = nullptr; + + copy(destItem, sourceItem); + } + dest.arraySizes[0] = source.arraySizes[0]; + } +} + +void copy(BPPAssetInstanceArray& dest, BPPAssetInstanceArray& source) +{ + delete[] dest.buf; + dest.buf = nullptr; + dest.arraySizes[0] = 0; + + if (source.arraySizes[0] > 0) + { + dest.buf = new BPPAssetInstance[source.arraySizes[0]]; + for (int i = 0; i < source.arraySizes[0]; ++i) + { + BPPAssetInstance& destItem = dest.buf[i]; + BPPAssetInstance& sourceItem = source.buf[i]; + + destItem.name.buf = nullptr; + destItem.source.buf = nullptr; + + copy(destItem, sourceItem); + } + dest.arraySizes[0] = source.arraySizes[0]; + } +} + +void copy(BPPLandmarkArray& dest, BPPLandmarkArray& source) +{ + delete[] dest.buf; + dest.buf = nullptr; + dest.arraySizes[0] = 0; + + if (source.arraySizes[0] > 0) + { + dest.buf = new BPPLandmark[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; + + copy(destItem, sourceItem); + } + dest.arraySizes[0] = source.arraySizes[0]; + } +} + +void copy(BPPU32Array& dest, BPPU32Array& source) +{ + delete[] dest.buf; + dest.buf = nullptr; + dest.arraySizes[0] = 0; + + if (source.arraySizes[0] > 0) + { + dest.buf = new uint32_t[source.arraySizes[0]]; + for (int i = 0; i < source.arraySizes[0]; ++i) + { + uint32_t& destItem = dest.buf[i]; + uint32_t& sourceItem = source.buf[i]; + + destItem = sourceItem; + } + dest.arraySizes[0] = source.arraySizes[0]; + } +} + +void copy(BPPFilterPresetArray& dest, BPPFilterPresetArray& source) +{ + delete[] dest.buf; + dest.buf = nullptr; + dest.arraySizes[0] = 0; + + if (source.arraySizes[0] > 0) + { + dest.buf = new BPPFilterPreset[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; + + copy(destItem, sourceItem); + } + dest.arraySizes[0] = source.arraySizes[0]; + } +} + +void copy(BPPLight& dest, BPPLight& source) +{ + copy(dest.name, source.name); + dest.enable = source.enable; + dest.useShadows = source.useShadows; + dest.lockToRoot = source.lockToRoot; + dest.visualize = source.visualize; + dest.type = source.type; + dest.shadowMapResolution = source.shadowMapResolution; + dest.color = source.color; + dest.diffuseColor = source.diffuseColor; + dest.ambientColor = source.ambientColor; + dest.specularColor = source.specularColor; + dest.intensity = source.intensity; + dest.distance = source.distance; + dest.spotFalloffStart = source.spotFalloffStart; + dest.spotFalloffEnd = source.spotFalloffEnd; + dest.lightAxisX = source.lightAxisX; + dest.lightAxisY = source.lightAxisY; + dest.lightAxisZ = source.lightAxisZ; + dest.lightPos = source.lightPos; +} + +void copy(BPPGraphicsMaterial& dest, BPPGraphicsMaterial& source) +{ + copy(dest.name, source.name); + dest.useTextures = source.useTextures; + copy(dest.diffuseTextureFilePath, source.diffuseTextureFilePath); + copy(dest.specularTextureFilePath, source.specularTextureFilePath); + copy(dest.normalTextureFilePath, source.normalTextureFilePath); + dest.diffuseColor = source.diffuseColor; + dest.specularColor = source.specularColor; + dest.specularShininess = source.specularShininess; +} + +void copy(BPPGraphicsMesh& dest, BPPGraphicsMesh& source) +{ + copy(dest.name, source.name); + dest.visible = source.visible; + copy(dest.materialAssignments, source.materialAssignments); +} + +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; +} + +void copy(BPPSupportStructure& dest, BPPSupportStructure& source) +{ + copy(dest.healthMask, source.healthMask); + dest.bondStrength = source.bondStrength; + dest.enableJoint = source.enableJoint; +} + +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.visible = source.visible; + dest.support = source.support; + dest.staticFlag = source.staticFlag; +} + +void copy(BPPBond& dest, BPPBond& source) +{ + copy(dest.name, source.name); + copy(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; + dest.frameStartTime = source.frameStartTime; + dest.frameEndTime = source.frameEndTime; + dest.animationFps = source.animationFps; + dest.animate = source.animate; + dest.simulate = source.simulate; + dest.resetSimulationOnLoop = source.resetSimulationOnLoop; + dest.simulationFps = source.simulationFps; + dest.showGraphicsMesh = source.showGraphicsMesh; + dest.visualizeGrowthMesh = source.visualizeGrowthMesh; + dest.visualizeLight = source.visualizeLight; + dest.visualizeWind = source.visualizeWind; + dest.showStatistics = source.showStatistics; + dest.renderStyle = source.renderStyle; + dest.colorizeOption = source.colorizeOption; + dest.showWireframe = source.showWireframe; + dest.lockRootBone = source.lockRootBone; + dest.controlTextureOption = source.controlTextureOption; + dest.useLighting = source.useLighting; + dest.showSkinnedMeshOnly = source.showSkinnedMeshOnly; + dest.lightDir = source.lightDir; + dest.ambientColor = source.ambientColor; + dest.windDir = source.windDir; + dest.windStrength = source.windStrength; + dest.lightIntensity = source.lightIntensity; + dest.gravityDir = source.gravityDir; + dest.gravityScale = source.gravityScale; + + copy(dest.textureFilePath, source.textureFilePath); + copy(dest.lights, source.lights); +} + +void copy(BPPStressSolver& dest, BPPStressSolver& source) +{ + dest.solverMode = source.solverMode; + dest.linearFactor = source.linearFactor; + dest.angularFactor = source.angularFactor; + dest.meanError = source.meanError; + dest.varianceError = source.varianceError; + dest.bondsPerFrame = source.bondsPerFrame; + dest.bondsIterations = source.bondsIterations; +} + +void copy(BPPAsset& dest, BPPAsset& source) +{ + copy(dest.path, source.path); + dest.visible = source.visible; + dest.stressSolver = source.stressSolver; + copy(dest.activePreset, source.activePreset); + dest.defaultDamage = source.defaultDamage; +} + +void copy(BPPAssetInstance& dest, BPPAssetInstance& source) +{ + copy(dest.name, source.name); + dest.visible = source.visible; + copy(dest.source, source.source); + 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); +} + +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.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) +{ + dest.activeFilter = source.activeFilter; + copy(dest.filters, source.filters); +} + +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; +} + +void copy(BPPFracture& dest, BPPFracture& source) +{ + dest.activeFractureMethod = source.activeFractureMethod; + 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) +{ + copy(dest.name, source.name); + copy(dest.depthFilters, source.depthFilters); +} + +void copy(BPParams& dest, BPParams& source) +{ + dest.camera = source.camera; + copy(dest.cameraBookmarks, source.cameraBookmarks); + dest.lightCamera = source.camera; + dest.windCamera = source.camera; + copy(dest.graphicsMaterials, source.graphicsMaterials); + 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.blast.userPreset, USER_PRESET_PATH); +} + +void merge(BPPChunkArray& dest, BPPChunkArray& source) +{ + if (source.arraySizes[0] > 0) + { + BPPChunk* oriDestArray = dest.buf; + int oriCount = dest.arraySizes[0]; + int srcCount = source.arraySizes[0]; + dest.buf = new BPPChunk[oriCount + srcCount]; + int i = 0; + for (; i < oriCount; ++i) + { + BPPChunk& destItem = dest.buf[i]; + BPPChunk& oriItem = oriDestArray[i]; + + destItem.name.buf = nullptr; + destItem.asset.buf = nullptr; + copy(destItem, oriItem); + } + for (int j = 0; j < srcCount; ++j, ++i) + { + BPPChunk& destItem = dest.buf[i]; + BPPChunk& sourceItem = source.buf[j]; + + destItem.name.buf = nullptr; + destItem.asset.buf = nullptr; + copy(destItem, sourceItem); + } + for (int m = 0; m < oriCount; ++m) + { + freeBlast(oriDestArray[m]); + } + delete[] oriDestArray; + dest.arraySizes[0] = oriCount + srcCount; + } +} + +void merge(BPPBondArray& dest, BPPBondArray& source) +{ + if (source.arraySizes[0] > 0) + { + BPPBond* oriDestArray = dest.buf; + int oriCount = dest.arraySizes[0]; + int srcCount = source.arraySizes[0]; + dest.buf = new BPPBond[oriCount + srcCount]; + int i = 0; + for (; i < oriCount; ++i) + { + BPPBond& destItem = dest.buf[i]; + BPPBond& oriItem = oriDestArray[i]; + + destItem.name.buf = nullptr; + destItem.asset.buf = nullptr; + destItem.support.healthMask.buf = nullptr; + copy(destItem, oriItem); + } + for (int j = 0; j < srcCount; ++j, ++i) + { + BPPBond& destItem = dest.buf[i]; + BPPBond& sourceItem = source.buf[j]; + + destItem.name.buf = nullptr; + destItem.asset.buf = nullptr; + destItem.support.healthMask.buf = nullptr; + copy(destItem, sourceItem); + } + for (int m = 0; m < oriCount; ++m) + { + freeBlast(oriDestArray[m]); + } + delete[] oriDestArray; + dest.arraySizes[0] = oriCount + srcCount; + } +} + +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; +} + +void init(BPPGraphicsMaterial& param) +{ + param.name.buf = nullptr; + param.useTextures = false; + param.diffuseTextureFilePath.buf = nullptr; + param.specularTextureFilePath.buf = nullptr; + param.normalTextureFilePath.buf = nullptr; + param.specularShininess = 0.0; +} + +void init(BPParams& params) +{ + //memset(¶ms, sizeof(BPParams), 0); + + //params.cameraBookmarks.buf = nullptr; + //for (int i = 0; i < 4; ++i) + // params.renderer.lights.buf[i].name.buf = +} + +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; +} + +BlastProject& BlastProject::ins() +{ + static BlastProject _ins; + return _ins; +} + +BlastProject::~BlastProject() +{ + delete[] _projectParams.cameraBookmarks.buf; +} + +void BlastProject::clear() +{ + freeBlast(_projectParams.blast); +} + +bool BlastProject::isGraphicsMaterialNameExist(const char* name) +{ + if (name == nullptr || strlen(name) == 0) + return false; + + BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials; + + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + BPPGraphicsMaterial& item = theArray.buf[i]; + if (nvidia::shdfnd::strcmp(item.name.buf, name) == 0) + return true; + } + return false; +} + +BPPGraphicsMaterial* BlastProject::addGraphicsMaterial(const char* name, const char* diffuseTexture) +{ + if (name == nullptr || strlen(name) == 0) + return nullptr; + + BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials; + BPPGraphicsMaterial* oldBuf = theArray.buf; + theArray.buf = new BPPGraphicsMaterial[theArray.arraySizes[0] + 1]; + + int i = 0; + for (; i < theArray.arraySizes[0]; ++i) + { + 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; + 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; + copy(newItem.name, name); + if (diffuseTexture != nullptr) + { + copy(newItem.diffuseTextureFilePath, diffuseTexture); + } + theArray.arraySizes[0] += 1; + + delete[] oldBuf; + + return &newItem; +} + +void BlastProject::removeGraphicsMaterial(const char* name) +{ + if (name == nullptr || strlen(name) == 0 || !isGraphicsMaterialNameExist(name)) + return; + + BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials; + BPPGraphicsMaterial* oldBuf = theArray.buf; + + theArray.buf = new BPPGraphicsMaterial[theArray.arraySizes[0] - 1]; + int index = 0; + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + if (nvidia::shdfnd::strcmp(oldBuf[i].name.buf, name) != 0) + { + 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; + copy(newItem, oldItem); + } + } + theArray.arraySizes[0] -= 1; + delete[] oldBuf; +} + +void BlastProject::renameGraphicsMaterial(const char* oldName, const char* newName) +{ + if (oldName == nullptr || newName == nullptr) + return; + + BPPGraphicsMaterialArray& theArray = _projectParams.graphicsMaterials; + + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, oldName) == 0) + { + copy(theArray.buf[i].name, newName); + return; + } + } +} + +std::vector<BPPAsset*> BlastProject::getSelectedBlastAssets(void) +{ + std::vector<BPPAsset*> assets; + return assets; +} + +bool BlastProject::isAssetInstanceNameExist(const char* name) +{ + if (name == nullptr || strlen(name) == 0) + return false; + + BPPAssetInstanceArray& theArray = _projectParams.blast.composite.blastAssetInstances; + + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + BPPAssetInstance& item = theArray.buf[i]; + if (nvidia::shdfnd::strcmp(item.name.buf, name) == 0) + return true; + } + return false; +} + +BPPAssetInstance* BlastProject::getAssetInstance(const char* assetPath, int instanceIndex) +{ + if (assetPath == nullptr || strlen(assetPath) == 0 || instanceIndex < 0) + { + return nullptr; + } + + BPPAssetInstanceArray& instanceArray = _projectParams.blast.composite.blastAssetInstances; + if (instanceIndex < instanceArray.arraySizes[0]) + { + BPPAssetInstance& assetInstance = instanceArray.buf[instanceIndex]; + if (nvidia::shdfnd::strcmp(assetPath, assetInstance.source.buf) == 0) + return &assetInstance; + } + + return nullptr; +} + +BPPAssetInstance* BlastProject::addAssetInstance(int blastAssetIndex, const char* instanceName) +{ + if (instanceName == nullptr) + return nullptr; + + BPPAssetArray& assetArray = _projectParams.blast.blastAssets; + if (blastAssetIndex < 0 && blastAssetIndex > assetArray.arraySizes[0]) + return nullptr; + + BPPComposite& composite = _projectParams.blast.composite; + BPPAssetInstanceArray& theArray = composite.blastAssetInstances; + + BPPAssetInstance* oldBuf = theArray.buf; + theArray.buf = new BPPAssetInstance[theArray.arraySizes[0] + 1]; + + int i = 0; + for (; i < theArray.arraySizes[0]; ++i) + { + BPPAssetInstance& newItem = theArray.buf[i]; + BPPAssetInstance& oldItem = oldBuf[i]; + + newItem.name.buf = nullptr; + newItem.source.buf = nullptr; + copy(newItem, oldItem); + } + + BPPAssetInstance& newItem = theArray.buf[i]; + newItem.name.buf = nullptr; + newItem.source.buf = nullptr; + copy(newItem.name, instanceName); + copy(newItem.source, assetArray.buf[blastAssetIndex].path); + newItem.visible = true; + + delete[] oldBuf; + + return &newItem; +} + +void BlastProject::removeAssetInstance(const char* name) +{ + if (name == nullptr || strlen(name) == 0 || !isAssetInstanceNameExist(name)) + return; + + BPPAssetInstanceArray& theArray = _projectParams.blast.composite.blastAssetInstances; + BPPAssetInstance* oldBuf = theArray.buf; + + theArray.buf = new BPPAssetInstance[theArray.arraySizes[0] - 1]; + int index = 0; + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + if (nvidia::shdfnd::strcmp(oldBuf[i].name.buf, name) != 0) + { + BPPAssetInstance& newItem = theArray.buf[index++]; + BPPAssetInstance& oldItem = oldBuf[i]; + newItem.name.buf = nullptr; + newItem.source.buf = nullptr; + copy(newItem, oldItem); + } + } + theArray.arraySizes[0] -= 1; + delete[] oldBuf; +} + +BPPChunk* BlastProject::getChunk(BPPAsset& asset, int id) +{ + BPPChunkArray& chunkArray = _projectParams.blast.chunks; + + int count = chunkArray.arraySizes[0]; + 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)) + return &chunk; + } + + return nullptr; +} + +std::vector<BPPChunk*> BlastProject::getChildrenChunks(BPPAsset& asset, int parentID) +{ + std::vector<BPPChunk*> chunks; + + BPPChunkArray& chunkArray = _projectParams.blast.chunks; + + int count = chunkArray.arraySizes[0]; + 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)) + chunks.push_back(&chunk); + } + + return chunks; +} + +std::vector<BPPChunk*> BlastProject::getChildrenChunks(BPPAsset& asset) +{ + std::vector<BPPChunk*> chunks; + + BPPChunkArray& chunkArray = _projectParams.blast.chunks; + + int count = chunkArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + BPPChunk& chunk = chunkArray.buf[i]; + if (nvidia::shdfnd::strcmp(chunk.asset.buf, asset.path.buf) == 0) + chunks.push_back(&chunk); + } + + return chunks; +} + +std::vector<BPPBond*> BlastProject::getBondsByChunk(BPPAsset& asset, int chunkID) +{ + std::vector<BPPBond*> bonds; + BPPBondArray& bondArray = _projectParams.blast.bonds; + int count = bondArray.arraySizes[0]; + 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.fromChunk == chunkID) + bonds.push_back(&bond); + else if (bond.toChunk == chunkID) + bonds.push_back(&bond); + } + } + + return bonds; +} + +bool BlastProject::isLandmarkNameExist(const char* name) +{ + if (name == nullptr || strlen(name) == 0) + return false; + + BPPLandmarkArray& theArray = _projectParams.blast.composite.landmarks; + + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + BPPLandmark& item = theArray.buf[i]; + if (nvidia::shdfnd::strcmp(item.name.buf, name) == 0) + return true; + } + return false; +} + +BPPLandmark* BlastProject::addLandmark(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]; + + int i = 0; + for (; i < theArray.arraySizes[0]; ++i) + { + BPPLandmark& newItem = theArray.buf[i]; + BPPLandmark& oldItem = oldBuf[i]; + + newItem.name.buf = nullptr; + copy(newItem, oldItem); + } + + 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; + + delete[] oldBuf; + + return &newItem; +} + +void BlastProject::removeLandmark(const char* name) +{ + if (name == nullptr || strlen(name) == 0 || !isLandmarkNameExist(name)) + return ; + + 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) + { + 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); + } + } + theArray.arraySizes[0] -= 1; + delete[] oldBuf; +} + +BPPLandmark* BlastProject::getLandmark(const char* name) +{ + if (name == nullptr) + return nullptr; + + BPPLandmarkArray& theArray = _projectParams.blast.composite.landmarks; + + 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; +} + +void BlastProject::renameLandmark(const char* oldName, const char* newName) +{ + if (oldName == nullptr || newName == nullptr) + return ; + + BPPLandmarkArray& theArray = _projectParams.blast.composite.landmarks; + + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, oldName) == 0) + { + copy(theArray.buf[i].name, newName); + return; + } + } +} + +bool BlastProject::isUserPresetNameExist(const char* name) +{ + if (name == nullptr || strlen(name) == 0) + return false; + + for (size_t i = 0; i < _userPresets.size(); ++i) + { + StressSolverUserPreset& item = _userPresets[i]; + if (item.name == name) + return true; + } + + return false; +} + +std::vector<StressSolverUserPreset>& BlastProject::getUserPresets() +{ + return _userPresets; +} + +void BlastProject::addUserPreset(const char* name) +{ + _userPresets.push_back(StressSolverUserPreset(name)); +} + +void BlastProject::saveUserPreset() +{ + QFile file(_projectParams.blast.userPreset.buf); + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + return; + } + QTextStream out(&file); + + QDomDocument xmlDoc; + QDomElement rootElm = xmlDoc.createElement(QObject::tr("UserPreSet")); + xmlDoc.appendChild(rootElm); + + for (size_t i = 0; i < _userPresets.size(); ++i) + { + _saveStressSolverPreset(rootElm, _userPresets[i]); + } + + // 4 is count of indent + xmlDoc.save(out, 4); +} + +void BlastProject::loadUserPreset() +{ + QFile file(_projectParams.blast.userPreset.buf); + + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + + QDomDocument xmlDoc; + if (!xmlDoc.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + 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; + } + + 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]); + } + +} + +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) + { + BPPFilterPreset& item = theArray.buf[i]; + if (nvidia::shdfnd::strcmp(item.name.buf, name) == 0) + return true; + } + return false; +} + +std::vector<BPPFilterPreset*> BlastProject::getFilterPresets() +{ + std::vector<BPPFilterPreset*> presets; + return presets; +} + +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; +} + +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) + { + if (nvidia::shdfnd::strcmp(oldBuf[i].name.buf, name) != 0) + { + 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); + } + } + theArray.arraySizes[0] -= 1; + delete[] oldBuf; +} + +BPPFilterPreset* BlastProject::getFilterPreset(const char* name) +{ + if (name == nullptr) + return nullptr; + + BPPFilterPresetArray& theArray = _projectParams.filter.filters; + + 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; +} + +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) + { + if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, oldName) == 0) + { + copy(theArray.buf[i].name, newName); + return; + } + } +} + +void BlastProject::addFilterDepth(const char* filterName, int depth) +{ + if (filterName == nullptr || depth < 0) + return; + + BPPFilterPresetArray& theArray = _projectParams.filter.filters; + + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, filterName) == 0) + { + 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; + return; + } + } +} + +void BlastProject::removeFilterDepth(const char* filterName, int depth) +{ + if (filterName == nullptr || depth < 0) + return; + + BPPFilterPresetArray& theArray = _projectParams.filter.filters; + + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + if (nvidia::shdfnd::strcmp(theArray.buf[i].name.buf, filterName) == 0) + { + 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; + return; + } + } +} + +bool BlastProject::isCutoutTextureNameExist(const char* name) +{ + 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) + { + NvParameterized::DummyStringStruct& item = theArray.buf[i]; + if (nvidia::shdfnd::strcmp(item.buf, name) == 0) + return true; + } + 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)) + return; + + 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; + + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + NvParameterized::DummyStringStruct& item = theArray.buf[i]; + if (nvidia::shdfnd::strcmp(item.buf, name) == 0) + return true; + } + 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); +} + +bool BlastProject::isMeshCutterNameExist(const char* name) +{ + if (name == nullptr || strlen(name) == 0) + return false; + + BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.meshCutters; + + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + 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) + { + NvParameterized::DummyStringStruct& item = theArray.buf[i]; + if (nvidia::shdfnd::strcmp(item.buf, name) == 0) + return true; + } + return false; +} + +void BlastProject::addVoronoiTexture(const char* name) +{ + BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.textureSites; + _addStringItem(theArray, name); +} + +void BlastProject::removeVoronoiTexture(const char* name) +{ + if (name == nullptr || strlen(name) == 0 || !isVoronoiTextureNameExist(name)) + return; + + BPPStringArray& theArray = BlastProject::ins().getParams().fracture.voronoi.textureSites; + _removeStringItem(theArray, name); +} + +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]; + _projectParams.renderer.lights.arraySizes[0] = 4; + + for (int i = 0; i < 4; ++i) + { + _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.voronoi.meshCutters.buf = nullptr; + _projectParams.fracture.voronoi.meshCutters.arraySizes[0] = 0; + + _projectParams.fracture.voronoi.textureSites.buf = nullptr; + _projectParams.fracture.voronoi.textureSites.arraySizes[0] = 0; + + _projectParams.fracture.cutoutProjection.textures.buf = nullptr; + _projectParams.fracture.cutoutProjection.textures.arraySizes[0] = 0; +} + +void BlastProject::_saveStressSolverPreset(QDomElement& parentElm, StressSolverUserPreset& stressSolverUserPreset) +{ + QDomElement newElm = parentElm.ownerDocument().createElement(QObject::tr("StressSolverPreset")); + parentElm.appendChild(newElm); + newElm.setAttribute(QObject::tr("Name"), stressSolverUserPreset.name.c_str()); + _saveStressSolver(newElm, stressSolverUserPreset.stressSolver); +} + +void BlastProject::_saveStressSolver(QDomElement& parentElm, BPPStressSolver& stressSolver) +{ + QDomElement newElm = parentElm.ownerDocument().createElement(QObject::tr("StressSolver")); + parentElm.appendChild(newElm); + newElm.setAttribute(QObject::tr("SolverMode"), stressSolver.solverMode); + 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); +} + +void BlastProject::_loadStressSolverPreset(QDomElement& parentElm, StressSolverUserPreset& stressSolverUserPreset) +{ + stressSolverUserPreset.name = parentElm.attribute(QObject::tr("Name")).toUtf8().data(); + + QDomElement stressSolverElm = parentElm.firstChildElement(QObject::tr("StressSolver")); + _loadStressSolver(stressSolverElm, stressSolverUserPreset.stressSolver); +} + +void BlastProject::_loadStressSolver(QDomElement& parentElm, BPPStressSolver& stressSolver) +{ + stressSolver.solverMode = parentElm.attribute(QObject::tr("SolverMode")).toInt(); + 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(); +} + +void BlastProject::_addStringItem(BPPStringArray& theArray, const char* name) +{ + if (name == nullptr) + return; + + NvParameterized::DummyStringStruct* oldBuf = theArray.buf; + theArray.buf = new NvParameterized::DummyStringStruct[theArray.arraySizes[0] + 1]; + + int i = 0; + for (; i < theArray.arraySizes[0]; ++i) + { + NvParameterized::DummyStringStruct& newItem = theArray.buf[i]; + NvParameterized::DummyStringStruct& oldItem = oldBuf[i]; + newItem.buf = nullptr; + copy(newItem, oldItem); + } + + NvParameterized::DummyStringStruct& newItem = theArray.buf[i]; + newItem.buf = nullptr; + copy(newItem, name); + theArray.arraySizes[0] += 1; + + delete[] oldBuf; +} + +void BlastProject::_removeStringItem(BPPStringArray& theArray, const char* name) +{ + if (name == nullptr || strlen(name) == 0) + return; + + bool nameExist = false; + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + NvParameterized::DummyStringStruct& item = theArray.buf[i]; + if (nvidia::shdfnd::strcmp(item.buf, name) == 0) + { + nameExist = true; + break; + } + } + + if (!nameExist) + return; + + NvParameterized::DummyStringStruct* oldBuf = theArray.buf; + + theArray.buf = new NvParameterized::DummyStringStruct[theArray.arraySizes[0] - 1]; + int index = 0; + for (int i = 0; i < theArray.arraySizes[0]; ++i) + { + if (nvidia::shdfnd::strcmp(oldBuf[i].buf, name) != 0) + { + NvParameterized::DummyStringStruct& newItem = theArray.buf[index++]; + NvParameterized::DummyStringStruct& oldItem = oldBuf[i]; + newItem.buf = nullptr; + copy(newItem, oldItem); + } + } + theArray.arraySizes[0] -= 1; + delete[] oldBuf; +} + +static bool LoadParamVec2Array(NvParameterized::Interface* iface, + const char* paramName, + nvidia::NvVec2** outValue) +{ + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + int arraySize; + handle.getArraySize(arraySize); + *outValue = new nvidia::NvVec2[arraySize]; + handle.getParamVec2Array((nvidia::NvVec2*)*outValue, arraySize); + return true; + } + return false; +} + +static bool LoadParamVec3Array(NvParameterized::Interface* iface, + const char* paramName, + nvidia::NvVec3** outValue) +{ + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + int arraySize; + handle.getArraySize(arraySize); + *outValue = new nvidia::NvVec3[arraySize]; + handle.getParamVec3Array((nvidia::NvVec3*)*outValue, arraySize); + return true; + } + return false; +} + +static bool LoadParamVec4Array(NvParameterized::Interface* iface, + const char* paramName, + nvidia::NvVec4** outValue) +{ + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + int arraySize; + handle.getArraySize(arraySize); + *outValue = new nvidia::NvVec4[arraySize]; + handle.getParamVec4Array((nvidia::NvVec4*)*outValue, arraySize); + return true; + } + return false; +} + +static bool LoadParamU8Array(NvParameterized::Interface* iface, + const char* paramName, + NvUInt8** outValue) +{ + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + int arraySize; + handle.getArraySize(arraySize); + *outValue = new NvUInt8[arraySize]; + handle.getParamU8Array((NvUInt8*)*outValue, arraySize); + return true; + } + return false; +} + +static bool LoadParamU32Array(NvParameterized::Interface* iface, + const char* paramName, + NvUInt32** outValue) +{ + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + int arraySize; + handle.getArraySize(arraySize); + *outValue = new NvUInt32[arraySize]; + handle.getParamU32Array((NvUInt32*)*outValue, arraySize); + return true; + } + return false; +} + +static bool LoadParamString(NvParameterized::Interface* iface, + const char* paramName, + char* outString) +{ + if (outString == NV_NULL) + { + return false; + } + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + const char* var; + handle.getParamString(var); + if (var) + { + strcpy(outString, var); + } + else + { + outString[0] = '\0'; + } + return true; + } + return false; +} + +static bool SaveParamVec2Array(NvParameterized::Interface* iface, + const char* paramName, + const nvidia::NvVec2* value, + int arraySize) +{ + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + handle.resizeArray(arraySize); + handle.setParamVec2Array((nvidia::NvVec2*)value, arraySize); + return true; + } + return false; +} + +static bool SaveParamVec3Array(NvParameterized::Interface* iface, + const char* paramName, + const nvidia::NvVec3* value, + int arraySize) +{ + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + handle.resizeArray(arraySize); + handle.setParamVec3Array((nvidia::NvVec3*)value, arraySize); + return true; + } + return false; +} + +static bool SaveParamVec4Array(NvParameterized::Interface* iface, + const char* paramName, + const nvidia::NvVec4* value, + int arraySize) +{ + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + handle.resizeArray(arraySize); + handle.setParamVec4Array((nvidia::NvVec4*)value, arraySize); + return true; + } + return false; +} + +static bool SaveParamU8Array(NvParameterized::Interface* iface, + const char* paramName, + const NvUInt8* value, + int arraySize) +{ + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + handle.resizeArray(arraySize); + handle.setParamU8Array((NvUInt8*)value, arraySize); + return true; + } + return false; +} + +static bool SaveParamU32Array(NvParameterized::Interface* iface, + const char* paramName, + const NvUInt32* value, + int arraySize) +{ + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + handle.resizeArray(arraySize); + handle.setParamU32Array((NvUInt32*)value, arraySize); + return true; + } + return false; +} + +static bool SaveParamString(NvParameterized::Interface* iface, + const char* paramName, + const char* inString) +{ + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle(paramName, handle) == NvParameterized::ERROR_NONE) + { + handle.setParamString(inString); + return true; + } + return false; +} + +bool CreateProjectParamsContext() +{ + FoundationHolder::GetFoundation(); + + ProjectParamsContext* context = new ProjectParamsContext; + g_projectParamsContext = context; + if (context == nullptr) + return false; + + //context->mFoundation = FoundationHolder::GetFoundation(); + //assert(context->mFoundation != NV_NULL); + context->mTraits = NvParameterized::createTraits(); + context->mBlastProjectParametersFactory = new BlastProjectParametersFactory; + context->mTraits->registerFactory(*context->mBlastProjectParametersFactory); + return true; +} + +void ReleaseProjectParamsContext() +{ + g_projectParamsContext->mTraits->release(); + delete g_projectParamsContext->mBlastProjectParametersFactory; + delete g_projectParamsContext; +} + +bool ProjectParamsLoad(const char* filePath, + SimpleScene* scene) +{ + if (g_projectParamsContext == NV_NULL) return false; + NvFileBuf* stream = new NvFileBufferBase(filePath, NvFileBuf::OPEN_READ_ONLY); + if (!stream || !stream->isOpen()) + { + // file open error + if (stream) stream->release(); + return false; + } + NvParameterized::Serializer::DeserializedData data; + NvParameterized::Serializer::ErrorType serError = NvParameterized::Serializer::ERROR_NONE; + NvParameterized::XmlSerializer serializer(g_projectParamsContext->mTraits); + bool isUpdated; + serError = serializer.deserialize(*stream, data, isUpdated); + if (data.size() < 1) + { + if (stream) stream->release(); + return false; + } + + scene->Clear(); + + for (int idx = 0; idx < (int)data.size(); ++idx) { + NvParameterized::Interface* iface = data[idx]; + if (::strcmp(iface->className(), BlastProjectParameters::staticClassName()) == 0) + { + scene->LoadParameters(iface); + } + } + stream->release(); + return true; +} + +bool ProjectParamsSave(const char* filePath, + SimpleScene* scene) +{ + if (g_projectParamsContext == NV_NULL) return false; + NvParameterized::XmlSerializer serializer(g_projectParamsContext->mTraits); + NvFileBuf* stream = new NvFileBufferBase(filePath, NvFileBuf::OPEN_WRITE_ONLY); + if (!stream || !stream->isOpen()) + { + // file open error + if (stream) stream->release(); + return false; + } + NvParameterized::Traits* traits = g_projectParamsContext->mTraits; + int numObjects = 0; + const int kMaxObjects = 1; + NvParameterized::Interface* objects[kMaxObjects]; + + if (1) + { + BlastProjectParameters* params = new BlastProjectParameters(traits); + objects[numObjects++] = params; + NvParameterized::Interface* iface = static_cast<NvParameterized::Interface*>(params); + scene->SaveParameters(iface); + } + + NV_ASSERT(numObjects <= kMaxObjects); + NvParameterized::Serializer::ErrorType serError = NvParameterized::Serializer::ERROR_NONE; + bool isUpdate = false; + serError = serializer.serialize(*stream, (const NvParameterized::Interface**)&objects[0], numObjects, isUpdate); + //for (int idx = 0; idx < numObjects; ++idx) + //{ + // delete objects[idx]; + //} + stream->release(); + return true; +} + +// Utility function to get the child parameter handle from the parent handle. +bool ParamGetChild(NvParameterized::Handle& parentHandle, NvParameterized::Handle& outChildHandle, const char* childName) +{ + if (parentHandle.getChildHandle(parentHandle.getInterface(), childName, outChildHandle) == NvParameterized::ERROR_NONE) + { + return true; + } + return false; +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.h new file mode 100644 index 0000000..fa7adf7 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Parameters/ProjectParams.h @@ -0,0 +1,210 @@ +#pragma once + +#include "BlastProjectParameters.h" +#include <QtCore/QVector> + +class QDomElement; + +typedef nvidia::parameterized::BlastProjectParametersNS::ParametersStruct BPParams; +typedef nvidia::parameterized::BlastProjectParametersNS::GraphicsMaterial_Type BPPGraphicsMaterial; +typedef nvidia::parameterized::BlastProjectParametersNS::MaterialAssignments_Type BPPMaterialAssignments; +typedef nvidia::parameterized::BlastProjectParametersNS::GraphicsMesh_Type BPPGraphicsMesh; +typedef nvidia::parameterized::BlastProjectParametersNS::Light_Type BPPLight; +typedef nvidia::parameterized::BlastProjectParametersNS::Camera_Type BPPCamera; +typedef nvidia::parameterized::BlastProjectParametersNS::CameraBookmark_Type BPPCameraBookmark; +typedef nvidia::parameterized::BlastProjectParametersNS::Scene_Type BPPScene; +typedef nvidia::parameterized::BlastProjectParametersNS::Renderer_Type BPPRenderer; +typedef nvidia::parameterized::BlastProjectParametersNS::BlastFileReferences_Type BPPFileReferences; +typedef nvidia::parameterized::BlastProjectParametersNS::StressSolver_Type BPPStressSolver; +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::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::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; + +void freeString(NvParameterized::DummyStringStruct& str); +void freeBlast(BPPGraphicsMesh& data); +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(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 copy(NvParameterized::DummyStringStruct& dest, const char* source); +void copy(NvParameterized::DummyStringStruct& dest, NvParameterized::DummyStringStruct& source); +void copy(BPPStringArray& dest, BPPStringArray& source); +void copy(BPPGraphicsMaterialArray& dest, BPPGraphicsMaterialArray& source); +void copy(BPPGraphicsMeshArray& dest, BPPGraphicsMeshArray& 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(BPPLight& dest, BPPLight& source); +void copy(BPPRenderer& dest, BPPRenderer& source); +void copy(BPPGraphicsMaterial& dest, BPPGraphicsMaterial& source); +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(BPPVoronoi& dest, BPPVoronoi& source); +void copy(BPPCutoutProjection& dest, BPPCutoutProjection& source); +void copy(BPPFracture& dest, BPPFracture& source); +void copy(BPPFilterPreset& dest, BPPFilterPreset& source); +void copy(BPParams& dest, BPParams& source); + +void merge(BPPChunkArray& dest, BPPChunkArray& source); +void merge(BPPBondArray& dest, BPPBondArray& source); + +void init(BPPStressSolver& param); +void init(BPPGraphicsMaterial& param); +void init(BPParams& params); + +struct StressSolverUserPreset +{ + StressSolverUserPreset(const char* inName); + std::string name; + BPPStressSolver stressSolver; +}; + +class BlastProject +{ +public: + + static BlastProject& ins(); + ~BlastProject(); + + BPParams& getParams() { return _projectParams; } + + void clear(); + + bool isGraphicsMaterialNameExist(const char* name); + BPPGraphicsMaterial* addGraphicsMaterial(const char* name, const char* diffuseTexture); + void removeGraphicsMaterial(const char* name); + void renameGraphicsMaterial(const char* oldName, const char* newName); + + std::vector<BPPAsset*> getSelectedBlastAssets(void); + + bool isAssetInstanceNameExist(const char* name); + BPPAssetInstance* getAssetInstance(const char* assetPath, int instanceIndex); + BPPAssetInstance* addAssetInstance(int blastAssetIndex, const char* instanceName); + void removeAssetInstance(const char* name); + + BPPChunk* getChunk(BPPAsset& asset, int id); + std::vector<BPPChunk*> getChildrenChunks(BPPAsset& asset, int parentID); + std::vector<BPPChunk*> getChildrenChunks(BPPAsset& asset); + 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); + + bool isUserPresetNameExist(const char* name); + std::vector<StressSolverUserPreset>& getUserPresets(); + void addUserPreset(const char* name); + void saveUserPreset(); + void loadUserPreset(); + + bool isFilterPresetNameExist(const char* name); + std::vector<BPPFilterPreset*> getFilterPresets(); + void addFilterPreset(const char* name); + void removeFilterPreset(const char* name); + BPPFilterPreset* 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); + +private: + BlastProject(); + void _saveStressSolverPreset(QDomElement& parentElm, StressSolverUserPreset& stressSolverUserPreset); + void _saveStressSolver(QDomElement& parentElm, BPPStressSolver& stressSolver); + void _loadStressSolverPreset(QDomElement& parentElm, StressSolverUserPreset& stressSolverUserPreset); + void _loadStressSolver(QDomElement& parentElm, BPPStressSolver& stressSolver); + + void _addStringItem(BPPStringArray& theArray, const char* name); + void _removeStringItem(BPPStringArray& theArray, const char* name); + +private: + BPParams _projectParams; + std::vector<StressSolverUserPreset> _userPresets; +}; + +bool CreateProjectParamsContext(); +void ReleaseProjectParamsContext(); +bool ProjectParamsLoad(const char* filePath, + class SimpleScene* scene); +bool ProjectParamsSave(const char* filePath, + class SimpleScene* scene); + +bool ParamGetChild(NvParameterized::Handle& parentHandle, NvParameterized::Handle& outChildHandle, const char* childName); diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D11/PluginBlastDx11.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D11/PluginBlastDx11.cpp new file mode 100644 index 0000000..1c37502 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D11/PluginBlastDx11.cpp @@ -0,0 +1,23 @@ +#include "PluginBlastDx11.h" +#include "D3D11RenderShader.h" +#include "D3D11RenderInterface.h" +#include "LightShaderParam.h" + +PluginBlast* CreateRenderBlast(void) +{ + return new PluginBlastDx11; +} + +PluginBlastDx11::PluginBlastDx11() +{ +} + +PluginBlastDx11::~PluginBlastDx11() +{ +} + +// D3D11Shaders +bool PluginBlastDx11::D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap) +{ + return true; +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D11/PluginBlastDx11.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D11/PluginBlastDx11.h new file mode 100644 index 0000000..ed9dbe1 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D11/PluginBlastDx11.h @@ -0,0 +1,16 @@ +#pragma once + +#include "PluginBlast.h" + +extern "C" PLUGINBTRENDER_EXPORT PluginBlast* CreateRenderBlast(void); + +class PluginBlastDx11 : public PluginBlast +{ +public: + PluginBlastDx11(); + ~PluginBlastDx11(); + + // D3D11Shaders + virtual bool D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap); +}; + diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D12/PluginBlastDx12.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D12/PluginBlastDx12.cpp new file mode 100644 index 0000000..670f17b --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D12/PluginBlastDx12.cpp @@ -0,0 +1,20 @@ +#include "PluginBlastDx12.h" + +PluginBlast* CreateRenderBlast(void) +{ + return new PluginBlastDx12; +} + +PluginBlastDx12::PluginBlastDx12() +{ +} + +PluginBlastDx12::~PluginBlastDx12() +{ +} + +// D3D11Shaders +bool PluginBlastDx12::D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap) +{ + return true; +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D12/PluginBlastDx12.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D12/PluginBlastDx12.h new file mode 100644 index 0000000..fab6b4e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/D3D12/PluginBlastDx12.h @@ -0,0 +1,16 @@ +#pragma once + +#include "PluginBlast.h" + +extern "C" PLUGINBTRENDER_EXPORT PluginBlast* CreateRenderBlast(void); + +class PluginBlastDx12 : public PluginBlast +{ +public: + PluginBlastDx12(); + ~PluginBlastDx12(); + + // D3D11Shaders + virtual bool D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap); +}; + diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/Interface/PluginBlast.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/Interface/PluginBlast.cpp new file mode 100644 index 0000000..3a9c9c9 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/Interface/PluginBlast.cpp @@ -0,0 +1,69 @@ +#include "PluginBlast.h" + +PluginBlast* g_Plugin = nullptr; + +PluginBlast::PluginBlast() +{ +} + +PluginBlast::~PluginBlast() +{ +} + +typedef PluginBlast*(*Func)(void); + +bool PluginBlast::Create(std::string strApi) +{ + if ("" == strApi) + return false; + + std::string pluginDll = ""; + HMODULE module = NULL; + Func CreateFunc = NULL; + +#ifdef NV_ARTISTTOOLS + pluginDll = "RenderBlast"; +#else + pluginDll = "FurRender"; +#endif + + pluginDll.append(strApi); + +#ifdef _WIN64 + pluginDll.append(".win64"); +#else + pluginDll.append(".win32"); +#endif + +#ifdef _DEBUG + pluginDll.append(".d"); +#else +#endif + + pluginDll.append(".dll"); + + module = LoadLibraryA(pluginDll.c_str()); + if (NULL == module) + return false; + + CreateFunc = (Func)GetProcAddress(module, "CreateRenderBlast"); + if (NULL == CreateFunc) + return false; + + g_Plugin = CreateFunc(); + return (NULL != g_Plugin); +} + +PluginBlast* PluginBlast::Instance() +{ + return g_Plugin; +} + +void PluginBlast::Destroy() +{ + if (nullptr == g_Plugin) + return; + + delete g_Plugin; + g_Plugin = nullptr; +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/Interface/PluginBlast.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/Interface/PluginBlast.h new file mode 100644 index 0000000..a67fd89 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Render/Interface/PluginBlast.h @@ -0,0 +1,21 @@ +#pragma once + +#include "RenderPlugin.h" +#include "blastplugin_global.h" + +class PLUGINBT_EXPORT PluginBlast +{ +public: + static bool Create(std::string api); + static PluginBlast* Instance(); + static void Destroy(); + + ~PluginBlast(); + + // D3D11Shaders + virtual bool D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap) = 0; + +protected: + PluginBlast(); +}; + diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/Sample.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/Sample.h new file mode 100644 index 0000000..c9fa503 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/Sample.h @@ -0,0 +1,95 @@ +/* +* 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. +*/ + +#ifndef SAMPLE_H +#define SAMPLE_H + +#include "PxTransform.h" +#include <string> +#include <vector> + + +struct AssetList +{ + struct BoxAsset + { + BoxAsset() : staticHeight(-std::numeric_limits<float>().infinity()), + jointAllBonds(false), extents(20, 20, 20) + {} + + struct Level + { + Level() :x(0), y(0), z(0), isSupport(0) {}; + + int x, y, z; + bool isSupport; + }; + + std::string id; + std::string name; + physx::PxVec3 extents; + float staticHeight; + bool jointAllBonds; + std::vector<Level> levels; + }; + + struct ModelAsset + { + ModelAsset() : isSkinned(false), transform(physx::PxIdentity) + {} + + std::string id; + std::string file; + std::string name; + physx::PxTransform transform; + bool isSkinned; + }; + + struct CompositeAsset + { + CompositeAsset() : transform(physx::PxIdentity) + {} + + struct AssetRef + { + std::string id; + physx::PxTransform transform; + }; + + struct Joint + { + int32_t assetIndices[2]; + uint32_t chunkIndices[2]; + physx::PxVec3 attachPositions[2]; + }; + + std::string id; + std::string name; + physx::PxTransform transform; + std::vector<AssetRef> assetRefs; + std::vector<Joint> joints; + }; + + std::vector<ModelAsset> models; + std::vector<CompositeAsset> composites; + std::vector<BoxAsset> boxes; +}; + +struct SampleConfig +{ + std::wstring sampleName; + std::string assetsFile; + std::vector<std::string> additionalResourcesDir; + AssetList additionalAssetList; +}; + +int runSample(const SampleConfig& config); + +#endif //SAMPLE_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.cpp new file mode 100644 index 0000000..01f8fd6 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.cpp @@ -0,0 +1,60 @@ +/* +* 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. +*/ + +#include "BlastAsset.h" +#include "NvBlastExtPxAsset.h" +#include "NvBlastTkAsset.h" +#include <map> + +BlastAsset::BlastAsset(Renderer& renderer) + : m_renderer(renderer) +{ +} + +void BlastAsset::validate() +{ +} + +size_t BlastAsset::getBlastAssetSize() const +{ + return m_pxAsset->getTkAsset().getDataSize(); +} + +std::vector<uint32_t> BlastAsset::getChunkIndexesByDepth(uint32_t depth) const +{ + const TkAsset& tkAsset = m_pxAsset->getTkAsset(); + const NvBlastChunk* pNvBlastChunk = tkAsset.getChunks(); + uint32_t chunkCount = tkAsset.getChunkCount(); + + std::map<uint32_t, uint32_t> indexDepthMap; + indexDepthMap.insert(std::make_pair(0, 0)); + for (size_t i = 1; i < chunkCount; ++i) + { + int depth = 0; + const NvBlastChunk* curChunk = pNvBlastChunk + i; + while (-1 != curChunk->parentChunkIndex) + { + ++depth; + curChunk = pNvBlastChunk + curChunk->parentChunkIndex; + } + indexDepthMap.insert(std::make_pair(i, depth)); + } + + std::vector<uint32_t> indexes; + for (std::map<uint32_t, uint32_t>::iterator itr = indexDepthMap.begin(); itr != indexDepthMap.end(); ++itr) + { + if (itr->second == depth) + { + indexes.push_back(itr->first); + } + } + + return indexes; +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.h new file mode 100644 index 0000000..b2e2f38 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAsset.h @@ -0,0 +1,99 @@ +/* +* 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. +*/ + +#ifndef BLAST_ASSET_H +#define BLAST_ASSET_H + +#include <memory> +#include <vector> +#include "PxTransform.h" +#include "NvBlastTypes.h" + +using namespace physx; + +class Renderer; +class BlastFamily; +class PhysXController; + +namespace Nv +{ +namespace Blast +{ +class ExtPxFamily; +class ExtPxAsset; +class ExtPxManager; +class TkGroup; +} +} + +using namespace Nv::Blast; + +// Add By Lixu Begin +typedef BlastFamily* BlastFamilyPtr; +// Add By Lixu End + + +class BlastAsset +{ +public: + //////// ctor //////// + + BlastAsset(Renderer& renderer); + virtual ~BlastAsset() {} + + + //////// desc //////// + + /** + Descriptor with actor initial settings. + */ + struct ActorDesc + { + NvBlastID id; + PxTransform transform; + TkGroup* group; + }; + + + //////// abstract //////// + + virtual BlastFamilyPtr createFamily(PhysXController& physXConroller, ExtPxManager& pxManager, const ActorDesc& desc) = 0; + + + //////// data getters //////// + + const ExtPxAsset* getPxAsset() const + { + return m_pxAsset; + } + + size_t getBlastAssetSize() const; + + std::vector<uint32_t> getChunkIndexesByDepth(uint32_t depth) const; + +protected: + //////// internal operations //////// + + void validate(); + + + //////// input data //////// + + Renderer& m_renderer; + + + //////// internal data //////// + + ExtPxAsset* m_pxAsset; +}; + + + +#endif //BLAST_ASSET_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.cpp new file mode 100644 index 0000000..dfa0138 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.cpp @@ -0,0 +1,84 @@ +/* +* 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. +*/ + +#include "BlastAssetBoxes.h" +#include "BlastFamilyBoxes.h" +#include "NvBlastExtPxAsset.h" +#include "PxPhysics.h" +#include "cooking/PxCooking.h" + + +BlastAssetBoxes::BlastAssetBoxes(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const Desc& desc) + : BlastAsset(renderer) +{ + // generate boxes slices procedurally + CubeAssetGenerator::generate(m_generatorAsset, desc.generatorSettings); + + // asset desc / tk asset + ExtPxAssetDesc assetDesc; + assetDesc.chunkDescs = &m_generatorAsset.solverChunks[0]; + assetDesc.chunkCount = (uint32_t)m_generatorAsset.solverChunks.size(); + assetDesc.bondDescs = m_generatorAsset.solverBonds.size() > 0 ? &m_generatorAsset.solverBonds[0] : nullptr; + 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); + assetDesc.bondFlags = bondFlags.data(); + + // box convex + PxVec3 vertices[8] = { { -1, -1, -1 }, { -1, -1, 1 }, { -1, 1, -1 }, { -1, 1, 1 }, { 1, -1, -1 }, { 1, -1, 1 }, { 1, 1, -1 }, { 1, 1, 1 } }; + PxConvexMeshDesc convexMeshDesc; + convexMeshDesc.points.count = 8; + convexMeshDesc.points.data = vertices; + convexMeshDesc.points.stride = sizeof(PxVec3); + convexMeshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX; + m_boxMesh = cooking.createConvexMesh(convexMeshDesc, physics.getPhysicsInsertionCallback()); + + // prepare chunks + const uint32_t chunkCount = (uint32_t)m_generatorAsset.solverChunks.size(); + std::vector<ExtPxAssetDesc::ChunkDesc> pxChunks(chunkCount); + std::vector<ExtPxAssetDesc::SubchunkDesc> pxSubchunks; + pxSubchunks.reserve(chunkCount); + for (uint32_t i = 0; i < m_generatorAsset.solverChunks.size(); i++) + { + uint32_t chunkID = m_generatorAsset.solverChunks[i].userData; + GeneratorAsset::BlastChunkCube& cube = m_generatorAsset.chunks[chunkID]; + PxVec3 position = *reinterpret_cast<PxVec3*>(&cube.position); + PxVec3 extents = *reinterpret_cast<PxVec3*>(&cube.extents); + ExtPxAssetDesc::ChunkDesc& chunk = pxChunks[chunkID]; + ExtPxAssetDesc::SubchunkDesc subchunk = + { + PxTransform(position), + PxConvexMeshGeometry(m_boxMesh, PxMeshScale(extents / 2)) + }; + pxSubchunks.push_back(subchunk); + chunk.subchunks = &pxSubchunks.back(); + chunk.subchunkCount = 1; + chunk.isStatic = (position.y - (extents.y - desc.generatorSettings.extents.y) / 2) <= desc.staticHeight; + } + + // create asset + assetDesc.pxChunks = pxChunks.data(); + m_pxAsset = ExtPxAsset::create(assetDesc, framework); + + validate(); +} + + +BlastAssetBoxes::~BlastAssetBoxes() +{ + m_boxMesh->release(); + m_pxAsset->release(); +} + + +BlastFamilyPtr BlastAssetBoxes::createFamily(PhysXController& physXConroller, ExtPxManager& pxManager, const ActorDesc& desc) +{ + return BlastFamilyPtr(new BlastFamilyBoxes(physXConroller, pxManager, m_renderer, *this, desc)); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.h new file mode 100644 index 0000000..518e93d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetBoxes.h @@ -0,0 +1,56 @@ +/* +* 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. +*/ + +#ifndef BLAST_ASSET_BOXES_H +#define BLAST_ASSET_BOXES_H + +#include "BlastAsset.h" +#include "AssetGenerator.h" +#include "PxConvexMesh.h" + + +namespace physx +{ +class PxPhysics; +class PxCooking; +} + +namespace Nv +{ +namespace Blast +{ +class TkFramework; +} +} + + +class BlastAssetBoxes : public BlastAsset +{ +public: + struct Desc + { + CubeAssetGenerator::Settings generatorSettings; + float staticHeight; + bool jointAllBonds; + }; + + BlastAssetBoxes(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const Desc& desc); + virtual ~BlastAssetBoxes(); + + BlastFamilyPtr createFamily(PhysXController& physXConroller, ExtPxManager& pxManager, const ActorDesc& desc); + +private: + PxConvexMesh* m_boxMesh; + GeneratorAsset m_generatorAsset; +}; + + + +#endif //BLAST_ASSET_BOXES_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.cpp new file mode 100644 index 0000000..c42215e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.cpp @@ -0,0 +1,64 @@ +/* +* 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. +*/ + +#include "BlastAssetModel.h" +#include "Renderer.h" +#include "BlastController.h" +#include "Utils.h" +#include "ResourceManager.h" +#include "PsFileBuffer.h" +#include "NvBlastExtPxAsset.h" +#include <sstream> + + +BlastAssetModel::BlastAssetModel(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName) + : BlastAsset(renderer) +{ + ResourceManager& resourceManager = m_renderer.getResourceManager(); + + // Physics Asset + std::ostringstream blastFileName; + blastFileName << modelName << ".bpxa"; + std::string path; + if (resourceManager.findFile(blastFileName.str(), path)) + { + 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"); + } + + // load obj file + std::ostringstream objFileName; + objFileName << modelName << ".obj"; + if (resourceManager.findFile(objFileName.str(), path)) + { + m_model = BlastModel::loadFromFileTinyLoader(path.c_str()); + if (!m_model) + { + ASSERT_PRINT(false, "obj load failed"); + } + } + else + { + ASSERT_PRINT(false, "wrong objFileName"); + } + + validate(); +} + + +BlastAssetModel::~BlastAssetModel() +{ + m_pxAsset->release(); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.h new file mode 100644 index 0000000..8132911 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModel.h @@ -0,0 +1,57 @@ +/* +* 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. +*/ + +#ifndef BLAST_ASSET_MODEL_H +#define BLAST_ASSET_MODEL_H + +#include "BlastAsset.h" +#include "BlastModel.h" + + +namespace physx +{ +class PxPhysics; +class PxCooking; +} + +namespace Nv +{ +namespace Blast +{ +class TkFramework; +} +} + + +class BlastAssetModel : public BlastAsset +{ +public: + //////// ctor //////// + + BlastAssetModel(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName); + virtual ~BlastAssetModel(); + + + //////// data getters //////// + + const BlastModel& getModel() const + { +// Add By Lixu Begin + return *m_model; +// Add By Lixu End + } + +private: + //////// private internal data //////// + + BlastModelPtr m_model; +}; + +#endif //BLAST_ASSET_MODEL_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.cpp new file mode 100644 index 0000000..56c7441 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.cpp @@ -0,0 +1,56 @@ +/* +* 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. +*/ + + +#include "BlastAssetModelSimple.h" +#include "BlastFamilyModelSimple.h" +#include "CustomRenderMesh.h" +#include "Renderer.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BlastAssetModelSimple +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +BlastAssetModelSimple::BlastAssetModelSimple(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName) + : BlastAssetModel(framework, physics, cooking, 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(); +} + + +BlastAssetModelSimple::~BlastAssetModelSimple() +{ + // release materials + for (RenderMaterial* r : m_renderMaterials) + { + if (r == RenderMaterial::getDefaultRenderMaterial()) + { + continue; + } + SAFE_DELETE(r); + } +} + + +BlastFamilyPtr BlastAssetModelSimple::createFamily(PhysXController& physXConroller, ExtPxManager& pxManager, const ActorDesc& desc) +{ + return BlastFamilyPtr(new BlastFamilyModelSimple(physXConroller, pxManager, m_renderer, *this, desc)); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.h new file mode 100644 index 0000000..7e61616 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSimple.h @@ -0,0 +1,47 @@ +/* +* 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. +*/ + +#ifndef BLAST_ASSET_MODEL_SIMPLE_H +#define BLAST_ASSET_MODEL_SIMPLE_H + +#include "BlastAssetModel.h" + + +class RenderMaterial; + +class BlastAssetModelSimple : public BlastAssetModel +{ +public: + //////// ctor //////// + + BlastAssetModelSimple(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName); + virtual ~BlastAssetModelSimple(); + + + //////// interface implementation //////// + + virtual BlastFamilyPtr createFamily(PhysXController& physXConroller, ExtPxManager& pxManager, const ActorDesc& desc); + + + //////// data getters //////// + + const std::vector<RenderMaterial*>& getRenderMaterials() const + { + return m_renderMaterials; + } + + +private: + //////// private internal data //////// + + std::vector<RenderMaterial*> m_renderMaterials; +}; + +#endif //BLAST_ASSET_MODEL_SIMPLE_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.cpp new file mode 100644 index 0000000..5cf3a0d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.cpp @@ -0,0 +1,47 @@ +/* +* 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. +*/ + +#include "BlastAssetModelSkinned.h" +#include "BlastFamilyModelSkinned.h" +#include "RenderMaterial.h" +#include "Renderer.h" + + +BlastAssetModelSkinned::BlastAssetModelSkinned(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName) + : BlastAssetModel(framework, physics, cooking, renderer, modelName) +{ +// Add By Lixu Begin + int index = 0; + char materialName[50]; + for (const BlastModel::Material& material : getModel().materials) + { + sprintf(materialName, "%s_Material%d", modelName, index++); + + if (material.diffuseTexture.empty()) + m_renderMaterials.push_back(new RenderMaterial(modelName, renderer.getResourceManager(), "model_skinned")); + else + m_renderMaterials.push_back(new RenderMaterial(modelName, renderer.getResourceManager(), "model_skinned_textured", material.diffuseTexture.c_str())); + } +// Add By Lixu End + validate(); +} + +BlastAssetModelSkinned::~BlastAssetModelSkinned() +{ + for (RenderMaterial* r : m_renderMaterials) + { + SAFE_DELETE(r); + } +} + +BlastFamilyPtr BlastAssetModelSkinned::createFamily(PhysXController& physXConroller, ExtPxManager& pxManager, const ActorDesc& desc) +{ + return BlastFamilyPtr(new BlastFamilyModelSkinned(physXConroller, pxManager, m_renderer, *this, desc)); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.h new file mode 100644 index 0000000..149c8e8 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastAssetModelSkinned.h @@ -0,0 +1,46 @@ +/* +* 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. +*/ + +#ifndef BLAST_ASSET_MODEL_SKINNED_H +#define BLAST_ASSET_MODEL_SKINNED_H + +#include "BlastAssetModel.h" + +class RenderMaterial; + +class BlastAssetModelSkinned : public BlastAssetModel +{ +public: + //////// ctor //////// + + BlastAssetModelSkinned(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName); + virtual ~BlastAssetModelSkinned(); + + + //////// interface implementation //////// + + BlastFamilyPtr createFamily(PhysXController& physXConroller, ExtPxManager& pxManager, const ActorDesc& desc); + + + //////// public getter //////// + + const std::vector<RenderMaterial*>& getRenderMaterials() const + { + return m_renderMaterials; + } + + +private: + //////// internal data //////// + + std::vector<RenderMaterial*> m_renderMaterials; +}; + +#endif //BLAST_ASSET_MODEL_SKINNED_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.cpp new file mode 100644 index 0000000..4061931 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.cpp @@ -0,0 +1,555 @@ +/* +* 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. +*/ + +#include "BlastController.h" +#include "BlastFamily.h" +#include "BlastAsset.h" +#include "BlastReplay.h" +#include "PhysXController.h" +#include "SampleTime.h" +#include "SampleProfiler.h" +#include "Utils.h" +#include "Renderer.h" + +#include "NvBlast.h" +#include "NvBlastExtPxManager.h" +#include "NvBlastExtPxFamily.h" +#include "NvBlastExtPxActor.h" + +#include "NvBlastTkFramework.h" + +#include "PsString.h" +#include "PxTaskManager.h" +#include "PxDefaultCpuDispatcher.h" +#include "PxRigidBody.h" +#include "PxScene.h" +#include "PxRigidDynamic.h" +#include "PxDistanceJoint.h" + +#include <sstream> +#include <numeric> +#include <cstdlib> + +#include "imgui.h" + +// Add By Lixu Begin +#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 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static physx::PxJoint* createPxJointCallback(ExtPxActor* actor0, const physx::PxTransform& localFrame0, ExtPxActor* actor1, const physx::PxTransform& localFrame1, physx::PxPhysics& physics, TkJoint& joint) +{ + PxDistanceJoint* pxJoint = PxDistanceJointCreate(physics, actor0 ? &actor0->getPhysXActor() : nullptr, localFrame0, actor1 ? &actor1->getPhysXActor() : nullptr, localFrame1); + pxJoint->setMaxDistance(1.0f); + return pxJoint; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Controller +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +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_extImpactDamageManagerSettings.fragility = 500.0f; + + m_impactDamageToStressFactor = 0.01f; + m_draggingToStressFactor = 100.0f; +} + + +BlastController::~BlastController() +{ +} + +void BlastController::reinitialize() +{ + onSampleStop(); + onSampleStart(); +} + +void BlastController::onSampleStart() +{ + TkFrameworkDesc desc; + desc.allocatorCallback = &g_allocatorCallback; + desc.errorCallback = &g_errorCallback; + m_tkFramework = NvBlastTkFrameworkCreate(desc); + + m_replay = new BlastReplay(); + + m_taskManager = PxTaskManager::createTaskManager(g_errorCallback, getPhysXController().getCPUDispatcher(), 0); + + TkGroupDesc gdesc; + gdesc.pxTaskManager = m_taskManager; + m_tkGroup = m_tkFramework->createGroup(gdesc); + + m_extPxManager = ExtPxManager::create(getPhysXController().getPhysics(), *m_tkFramework, createPxJointCallback); + m_extPxManager->setActorCountLimit(m_rigidBodyLimitEnabled ? m_rigidBodyLimit : 0); + m_extImpactDamageManager = ExtImpactDamageManager::create(m_extPxManager, m_extImpactDamageManagerSettings); + m_eventCallback = new EventCallback(m_extImpactDamageManager); + + setImpactDamageEnabled(m_impactDamageEnabled, true); +} + + +void BlastController::onSampleStop() +{ + removeAllFamilies(); + + m_extImpactDamageManager->release(); + m_extPxManager->release(); + SAFE_DELETE(m_eventCallback); + + m_tkGroup->release(); + + delete m_replay; + + m_tkFramework->release(); + + m_taskManager->release(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Impact damage +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void BlastController::setImpactDamageEnabled(bool enabled, bool forceUpdate) +{ + if (m_impactDamageEnabled != enabled || forceUpdate) + { + m_impactDamageEnabled = enabled; + getPhysXController().getPhysXScene().setSimulationEventCallback(m_impactDamageEnabled ? m_eventCallback : nullptr); + refreshImpactDamageSettings(); + } +} + +bool BlastController::customImpactDamageFunction(void* data, ExtPxActor* actor, physx::PxShape* shape, physx::PxVec3 position, physx::PxVec3 force) +{ + return reinterpret_cast<BlastController*>(data)->stressDamage(actor, position, force); +} + +bool BlastController::stressDamage(ExtPxActor *actor, physx::PxVec3 position, physx::PxVec3 force) +{ + if (actor->getTkActor().getGraphNodeCount() > 1) + { + void* userData = actor->getFamily().userData; + if (userData) + { + ExtStressSolver* solver = reinterpret_cast<ExtStressSolver*>(userData); + solver->applyImpulse(*actor, position, force * m_impactDamageToStressFactor); + return true; + } + } + + return false; +} + +void BlastController::refreshImpactDamageSettings() +{ + m_extImpactDamageManagerSettings.damageFunction = m_impactDamageToStressEnabled ? customImpactDamageFunction : nullptr; + m_extImpactDamageManagerSettings.damageFunctionData = this; + m_extImpactDamageManager->setSettings(m_extImpactDamageManagerSettings); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Stress +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void BlastController::updateDraggingStress() +{ + auto physxController = getPhysXController(); + auto actor = physxController.getDraggingActor(); + if (actor) + { + ExtPxActor* pxActor = m_extPxManager->getActorFromPhysXActor(*actor); + if (pxActor && pxActor->getTkActor().getGraphNodeCount() > 1 && pxActor->getPhysXActor().getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC) + { + void* userData = pxActor->getFamily().userData; + if (userData) + { + ExtStressSolver* solver = reinterpret_cast<ExtStressSolver*>(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); + } + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Stats +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +uint32_t BlastController::getActorCount() const +{ + return std::accumulate(m_families.begin(), m_families.end(), (uint32_t)0, [](uint32_t sum, const BlastFamilyPtr& a) + { + return sum += a->getActorCount(); + }); +} + +uint32_t BlastController::getTotalVisibleChunkCount() const +{ + return std::accumulate(m_families.begin(), m_families.end(), (uint32_t)0, [](uint32_t sum, const BlastFamilyPtr& a) + { + return sum += a->getTotalVisibleChunkCount(); + }); +} + +size_t BlastController::getFamilySize() const +{ + return std::accumulate(m_families.begin(), m_families.end(), (size_t)0, [](size_t sum, const BlastFamilyPtr& a) + { + return sum += a->getFamilySize(); + }); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Time +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +const double Time::s_secondsPerTick = Time::getTickDuration(); + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Controller events +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void BlastController::Animate(double dt) +{ + PROFILER_SCOPED_FUNCTION(); + + PROFILER_BEGIN("Apply Impact Damage"); + m_extImpactDamageManager->applyDamage(); + PROFILER_END(); + + updateDraggingStress(); + + m_replay->update(); + + Time blastTime; + for (uint32_t i = 0; i < m_families.size(); ++i) + { + if (m_families[i]) + { + m_families[i]->updatePreSplit(dt); + } + } + + fillDebugRender(); + + PROFILER_BEGIN("Tk Group Process/Sync"); + m_tkGroup->process(); + m_tkGroup->sync(true); + PROFILER_END(); + + TkGroupStats gstats; + m_tkGroup->getStats(gstats); + + this->m_lastBlastTimers.blastDamageMaterial = NvBlastTicksToSeconds(gstats.timers.material); + this->m_lastBlastTimers.blastDamageFracture = NvBlastTicksToSeconds(gstats.timers.fracture); + this->m_lastBlastTimers.blastSplitIsland = NvBlastTicksToSeconds(gstats.timers.island); + this->m_lastBlastTimers.blastSplitPartition = NvBlastTicksToSeconds(gstats.timers.partition); + this->m_lastBlastTimers.blastSplitVisibility = NvBlastTicksToSeconds(gstats.timers.visibility); + + for (uint32_t i = 0; i < m_families.size(); ++i) + { + if (m_families[i]) + { + m_families[i]->updateAfterSplit(dt); + } + } + +// Add By Lixu Begin + BlastSceneTree* pBlastSceneTree = BlastSceneTree::ins(); + bool needUpdateUI = false; + + std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = getManager()->getAssetFamiliesMap(); + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAsset; + std::vector<BlastFamily*>::iterator itFamily; + uint32_t assetIndex = 0; + for (itAsset = AssetFamiliesMap.begin(); itAsset != AssetFamiliesMap.end(); itAsset++) + { + std::vector<BlastFamily*>& BlastFamilies = itAsset->second; + for (itFamily = BlastFamilies.begin(); itFamily != BlastFamilies.end(); itFamily++) + { + BlastFamily* pFamily = *itFamily; + + std::map<uint32_t, bool>& VisibleChangedChunks = pFamily->getVisibleChangedChunks(); + std::map<uint32_t, bool>::iterator itChunk; + for (itChunk = VisibleChangedChunks.begin(); itChunk != VisibleChangedChunks.end(); itChunk++) + { + pBlastSceneTree->updateVisible(assetIndex, itChunk->first, itChunk->second); + } + pFamily->clearVisibleChangedChunks(); + + needUpdateUI = needUpdateUI || VisibleChangedChunks.size() > 0; + } + + assetIndex++; + } + + if (needUpdateUI) + { + pBlastSceneTree->updateValues(false); + } +// Add By Lixu End +} + + +void BlastController::drawUI() +{ + // impact damage + bool impactEnabled = getImpactDamageEnabled(); + if (ImGui::Checkbox("Impact Damage", &impactEnabled)) + { + setImpactDamageEnabled(impactEnabled); + } + + if (ImGui::DragFloat("Fragility", &m_extImpactDamageManagerSettings.fragility)) + { + refreshImpactDamageSettings(); + } + + if (ImGui::Checkbox("Impact Damage To Stress Solver", &m_impactDamageToStressEnabled)) + { + refreshImpactDamageSettings(); + } + + ImGui::DragFloat("Impact Damage To Stress Factor", &m_impactDamageToStressFactor, 0.001f, 0.0f, 1000.0f, "%.4f"); + ImGui::DragFloat("Dragging To Stress Factor", &m_draggingToStressFactor, 0.1f, 0.0f, 1000.0f, "%.3f"); + + ImGui::Checkbox("Limit Rigid Body Count", &m_rigidBodyLimitEnabled); + if (m_rigidBodyLimitEnabled) + { + ImGui::DragInt("Rigid Body Limit", (int*)&m_rigidBodyLimit, 100, 1000, 100000); + } + m_extPxManager->setActorCountLimit(m_rigidBodyLimitEnabled ? m_rigidBodyLimit : 0); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// actor management +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +BlastFamilyPtr BlastController::spawnFamily(BlastAsset* blastAsset, const BlastAsset::ActorDesc& desc) +{ + BlastFamilyPtr actor = blastAsset->createFamily(getPhysXController(), *m_extPxManager, desc); + m_families.push_back(actor); + recalculateAssetsSize(); + m_replay->addFamily(&actor->getFamily()->getTkFamily()); + return actor; +} + +void BlastController::removeFamily(BlastFamilyPtr actor) +{ + m_replay->removeFamily(&actor->getFamily()->getTkFamily()); + m_families.erase(std::remove(m_families.begin(), m_families.end(), actor), m_families.end()); + recalculateAssetsSize(); + getPhysXController().resetDragging(); +// Add By Lixu Begin + delete actor; +// Add By Lixu End +} + +void BlastController::removeAllFamilies() +{ + while (!m_families.empty()) + { + removeFamily(m_families.back()); + } + 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) + { + if (uniquedAssets.find(&m_families[i]->getBlastAsset()) == uniquedAssets.end()) + { + m_blastAssetsSize += m_families[i]->getBlastAsset().getBlastAssetSize(); + uniquedAssets.insert(&m_families[i]->getBlastAsset()); + } + } +} + +void BlastController::blast(PxVec3 worldPos, float damageRadius, float explosiveImpulse, std::function<void(ExtPxActor*)> damageFunction) +{ + PROFILER_SCOPED_FUNCTION(); + + for (uint32_t i = 0; i < m_families.size(); ++i) + { + if (m_families[i]) + { + m_families[i]->blast(worldPos, damageRadius, explosiveImpulse, damageFunction); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// 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()); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// debug render +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void BlastController::fillDebugRender() +{ + PROFILER_SCOPED_FUNCTION(); + + m_debugRenderBuffer.clear(); + + if (debugRenderMode != BlastFamily::DEBUG_RENDER_DISABLED) + { + getPhysXController().getPhysXScene().setVisualizationParameter(PxVisualizationParameter::eSCALE, 1); + for (uint32_t i = 0; i < m_families.size(); ++i) + { + m_families[i]->fillDebugRender(m_debugRenderBuffer, debugRenderMode, debugRenderScale); + } + } + else + { + getPhysXController().getPhysXScene().setVisualizationParameter(PxVisualizationParameter::eSCALE, 0); + } + + getRenderer().queueRenderBuffer(&m_debugRenderBuffer); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.h new file mode 100644 index 0000000..98f5c24 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastController.h @@ -0,0 +1,246 @@ +/* +* 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. +*/ + +#ifndef BLAST_CONTROLLER_H +#define BLAST_CONTROLLER_H + +#include "SampleManager.h" +#include "BlastFamily.h" +#include "DebugRenderBuffer.h" +#include "PxSimulationEventCallback.h" +#include "NvBlastExtImpactDamageManager.h" + +using namespace physx; + +class BlastAsset; +class BlastReplay; + +namespace physx +{ +class PxTaskManager; +} +namespace Nv +{ +namespace Blast +{ +class TkFramework; +} +} + + +struct BlastTimers +{ + double blastDamageMaterial; + double blastDamageFracture; + double blastSplitIsland; + double blastSplitPartition; + double blastSplitVisibility; +}; + +/** +Blast Controller. Entry point for all blast related code, keeps blast actors and controls them. +*/ +class BlastController : public ISampleController +{ +public: + //////// ctor //////// + + BlastController(); + virtual ~BlastController(); + + void reinitialize(); + + //////// controller callbacks //////// + + virtual void onSampleStart(); + virtual void onSampleStop(); + + virtual void Animate(double dt); + void drawUI(); + + + //////// public API //////// + + void blast(PxVec3 worldPos, float damageRadius, float explosiveImpulse, std::function<void(ExtPxActor*)> damageFunction); + + bool stressDamage(ExtPxActor *actor, PxVec3 position, PxVec3 force); + + BlastFamilyPtr spawnFamily(BlastAsset* blastAsset, const BlastAsset::ActorDesc& desc); + void removeFamily(BlastFamilyPtr actor); + void removeAllFamilies(); + + + //////// public static //////// + + static void blastLog(int type, const char* msg, const char* file, int line); + + + //////// public getters/setters //////// + + TkFramework& getTkFramework() const + { + return *m_tkFramework; + } + + TkGroup* getTkGroup() const + { + return m_tkGroup; + } + + ExtPxManager& getExtPxManager() const + { + return *m_extPxManager; + } + + ExtImpactDamageManager* getExtImpactDamageManager() const + { + return m_extImpactDamageManager; + } + + BlastReplay* getReplay() const + { + return m_replay; + } + + uint32_t getActorCount() const; + + uint32_t getTotalVisibleChunkCount() const; + + size_t getFamilySize() const; + + size_t getBlastAssetsSize() const + { + return m_blastAssetsSize; + } + + const BlastTimers& getLastBlastTimers() const + { + return m_lastBlastTimers; + } + + bool getImpactDamageEnabled() const + { + return m_impactDamageEnabled; + } + + void setImpactDamageEnabled(bool enabled, bool forceUpdate = false); + + ExtStressSolverSettings& getStressSolverSettings() + { + return m_extStressSolverSettings; + } + +// Add By Lixu Begin + std::vector<BlastFamilyPtr>& getFamilies() + { + return m_families; + } +// Add By Lixu End + + float getLastStressDelta() const; + + //////// public variables for UI //////// + + BlastFamily::DebugRenderMode debugRenderMode; + float debugRenderScale; + + + //////// Filter shader enum //////// + + enum FilterDataAttributes + { + SUPPRESS_CONTACT_NOTIFY = 1, + }; + +private: + //////// impact damage event callback //////// + + class EventCallback : public PxSimulationEventCallback + { + public: + EventCallback(ExtImpactDamageManager* manager) : m_manager(manager) {} + + // implemented + virtual void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, uint32_t nbPairs) + { + m_manager->onContact(pairHeader, pairs, nbPairs); + } + + private: + // unused + void onConstraintBreak(PxConstraintInfo*, PxU32) {} + void onWake(PxActor**, PxU32) {} + void onSleep(PxActor**, PxU32) {} + void onTrigger(PxTriggerPair*, PxU32) {} + void onAdvance(const PxRigidBody*const*, const PxTransform*, const PxU32) {} + + // data + ExtImpactDamageManager* m_manager; + }; + + + //////// private methods //////// + + void updateDraggingStress(); + + void refreshImpactDamageSettings(); + + void fillDebugRender(); + + void recalculateAssetsSize(); + + static bool customImpactDamageFunction(void* data, ExtPxActor* actor, PxShape* shape, PxVec3 position, PxVec3 force); + + + //////// used controllers //////// + + Renderer& getRenderer() const + { + return getManager()->getRenderer(); + } + + PhysXController& getPhysXController() const + { + return getManager()->getPhysXController(); + } + + + //////// internal data //////// + + PxTaskManager* m_taskManager; + TkFramework* m_tkFramework; + TkGroup* m_tkGroup; + ExtPxManager* m_extPxManager; + ExtImpactDamageManager* m_extImpactDamageManager; + ExtImpactSettings m_extImpactDamageManagerSettings; + EventCallback* m_eventCallback; + ExtStressSolverSettings m_extStressSolverSettings; + + std::vector<BlastFamilyPtr> m_families; + DebugRenderBuffer m_debugRenderBuffer; + + bool m_impactDamageEnabled; + bool m_impactDamageToStressEnabled; + + float m_impactDamageToStressFactor; + float m_draggingToStressFactor; + + bool m_rigidBodyLimitEnabled; + uint32_t m_rigidBodyLimit; + + BlastReplay* m_replay; + + BlastTimers m_lastBlastTimers; + + size_t m_blastAssetsSize; +}; + + +#endif diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.cpp new file mode 100644 index 0000000..f947cbd --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.cpp @@ -0,0 +1,588 @@ +/* +* 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. +*/ + +#include "BlastFamily.h" +#include "SampleProfiler.h" +#include "PhysXController.h" +#include "RenderUtils.h" +#include "SampleTime.h" +#include "UIHelpers.h" + +#include "NvBlast.h" +#include "NvBlastTkFamily.h" +#include "NvBlastTkActor.h" +#include "NvBlastTkAsset.h" +#include "NvBlastTkJoint.h" +#include "NvBlastExtPxAsset.h" +#include "NvBlastExtPxActor.h" +#include "NvBlastExtPxFamily.h" +#include "NvBlastExtPxManager.h" + +#include "PxRigidDynamic.h" +#include "PxScene.h" +#include "PxJoint.h" + + +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) + , m_blastAsset(blastAsset) + , m_listener(this) + , m_totalVisibleChunkCount(0) + , m_stressSolver(nullptr) +{ + 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() +{ + if (m_stressSolver) + { + m_stressSolver->release(); + } + + m_pxFamily->unsubscribe(m_listener); + + m_pxFamily->release(); +} + +void BlastFamily::initialize(const BlastAsset::ActorDesc& desc) +{ + ExtPxFamilyDesc familyDesc; + familyDesc.actorDesc.initialBondHealths = nullptr; + familyDesc.actorDesc.initialSupportChunkHealths = nullptr; + familyDesc.actorDesc.uniformInitialBondHealth = BOND_HEALTH_MAX; + familyDesc.actorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; + familyDesc.group = desc.group; + familyDesc.pxAsset = m_blastAsset.getPxAsset(); + m_pxFamily = m_pxManager.createFamily(familyDesc); + + m_tkFamily = &m_pxFamily->getTkFamily(); + m_tkFamily->setID(desc.id); + m_tkFamily->setMaterial(&m_settings.material); + + m_familySize = NvBlastFamilyGetSize(m_tkFamily->getFamilyLL(), nullptr); + + m_pxFamily->subscribe(m_listener); + + ExtPxSpawnSettings spawnSettings = { + &m_physXController.getPhysXScene(), + m_physXController.getDefaultMaterial(), + RIGIDBODY_DENSITY + }; + m_pxFamily->spawn(desc.transform, PxVec3(1.0f), spawnSettings); + + reloadStressSolver(); +} + +void BlastFamily::updatePreSplit(float dt) +{ + 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(); + + // collect potential actors to health update + m_actorsToUpdateHealth.clear(); + for (const ExtPxActor* actor : m_actors) + { + if (actor->getTkActor().isPending()) + { + m_actorsToUpdateHealth.emplace(actor); + } + } +} + +void BlastFamily::updateAfterSplit(float dt) +{ + PROFILER_BEGIN("Actor Health Update"); + for (const ExtPxActor* actor : m_actors) + { + onActorUpdate(*actor); + + // update health if neccessary + if (m_actorsToUpdateHealth.find(actor) != m_actorsToUpdateHealth.end()) + { + onActorHealthUpdate(*actor); + } + } + PROFILER_END(); + + PROFILER_BEGIN("Actor Misc Update"); + onUpdate(); + PROFILER_END(); + + m_pxFamily->postSplitUpdate(); +} + +void BlastFamily::processActorCreated(ExtPxFamily&, ExtPxActor& actor) +{ + m_totalVisibleChunkCount += actor.getChunkCount(); + m_actors.emplace(&actor); + + onActorCreated(actor); + onActorHealthUpdate(actor); +} + +void BlastFamily::processActorDestroyed(ExtPxFamily&, ExtPxActor& actor) +{ + m_totalVisibleChunkCount -= actor.getChunkCount(); + m_physXController.notifyRigidDynamicDestroyed(&actor.getPhysXActor()); + + onActorDestroyed(actor); + + m_actors.erase(m_actors.find(&actor)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Data Helpers +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +uint32_t BlastFamily::getActorCount() const +{ + return (uint32_t)m_tkFamily->getActorCount(); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// UI +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +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::Spacing(); + + // Stress Solver Settings + if (ImGui::Checkbox("Stress Solver Enabled", &m_settings.stressSolverEnabled)) + { + reloadStressSolver(); + } + + if (m_settings.stressSolverEnabled) + { + // Settings + 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::SliderInt("Graph Reduction Level", (int*)&m_settings.stressSolverSettings.graphReductionLevel, 0, 32); + if (changed) + { + refreshStressSolverSettings(); + } + + ImGui::Checkbox("Stress Damage Enabled", &m_settings.stressDamageEnabled); + + if (ImGui::Button("Recalculate Stress")) + { + resetStress(); + } + } +} + +void BlastFamily::drawStatsUI() +{ + ImGui::PushStyleColor(ImGuiCol_Text, ImColor(10, 255, 10, 255)); + const ExtStressSolver* stressSolver = m_stressSolver; + if (stressSolver) + { + 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 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 = std::max<float>(scale, errorLinear); + scale = std::max<float>(scale, errorAngular); + + static PlotLinesInstance<> linearErrorPlot; + linearErrorPlot.plot("Stress Linear Error", errorLinear, "error/frame", 0.0f, 1.0f * scale); + static PlotLinesInstance<> angularErrorPlot; + angularErrorPlot.plot("Stress Angular Error", errorAngular, "error/frame", 0.0f, 1.0f * scale); + } + } + else + { + ImGui::Text("No Stress Solver"); + } + ImGui::PopStyleColor(); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Stress Solver +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void BlastFamily::setSettings(const Settings& settings) +{ + bool reloadStressSolverNeeded = (m_settings.stressSolverEnabled != settings.stressSolverEnabled); + + m_settings = settings; + refreshStressSolverSettings(); + + if (reloadStressSolverNeeded) + { + reloadStressSolver(); + } + + m_tkFamily->setMaterial(&m_settings.material); +} + +void BlastFamily::refreshStressSolverSettings() +{ + if (m_stressSolver) + { + m_stressSolver->setSettings(m_settings.stressSolverSettings); + } +} + +void BlastFamily::resetStress() +{ + m_stressSolver->reset(); +} + +void BlastFamily::reloadStressSolver() +{ + if (m_stressSolver) + { + m_stressSolver->release(); + m_stressSolver = nullptr; + } + + if (m_settings.stressSolverEnabled) + { + m_stressSolver = ExtStressSolver::create(*m_pxFamily, m_settings.stressSolverSettings); + m_pxFamily->userData = m_stressSolver; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// debug render +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +const DirectX::XMFLOAT4 BOND_NORMAL_COLOR(0.0f, 0.8f, 1.0f, 1.0f); +const DirectX::XMFLOAT4 BOND_INVISIBLE_COLOR(0.65f, 0.16f, 0.16f, 1.0f); +const DirectX::XMFLOAT4 BOND_IMPULSE_LINEAR_COLOR(0.0f, 1.0f, 0.0f, 1.0f); +const DirectX::XMFLOAT4 BOND_IMPULSE_ANGULAR_COLOR(1.0f, 0.0f, 0.0f, 1.0f); +const DirectX::XMFLOAT4 JOINT_COLOR(0.5f, 0.6f, 7.0f, 1.0f); + + +inline void pushCentroid(std::vector<PxDebugLine>& lines, PxVec3 pos, PxU32 color, const float& area, const PxVec3& normal) +{ + // draw square of area 'area' rotated by normal + { + // build world rotation + PxVec3 n0(0, 0, 1); + PxVec3 n1 = normal; + PxVec3 axis = n0.cross(n1); + float d = n0.dot(n1); + PxQuat q(axis.x, axis.y, axis.z, 1.f + d); + q.normalize(); + float e = PxSqrt(1.0f / 2.0f); + float r = PxSqrt(area); + + // transform all 4 square points + PxTransform t(pos, q); + PxVec3 p0 = t.transform(PxVec3(-e, e, 0) * r); + PxVec3 p1 = t.transform(PxVec3( e, e, 0) * r); + PxVec3 p2 = t.transform(PxVec3( e, -e, 0) * r); + PxVec3 p3 = t.transform(PxVec3(-e, -e, 0) * r); + + // push square edges + lines.push_back(PxDebugLine(p0, p1, color)); + lines.push_back(PxDebugLine(p3, p2, color)); + lines.push_back(PxDebugLine(p1, p2, color)); + lines.push_back(PxDebugLine(p0, p3, color)); + } + + // draw normal + lines.push_back(PxDebugLine(pos, pos + normal * 0.5f, XMFLOAT4ToU32Color(BOND_NORMAL_COLOR))); +} + +inline DirectX::XMFLOAT4 bondHealthColor(float healthFraction) +{ + const DirectX::XMFLOAT4 BOND_HEALTHY_COLOR(0.0f, 1.0f, 0.0f, 1.0f); + const DirectX::XMFLOAT4 BOND_MID_COLOR(1.0f, 1.0f, 0.0f, 1.0f); + const DirectX::XMFLOAT4 BOND_BROKEN_COLOR(1.0f, 0.0f, 0.0f, 1.0f); + + return healthFraction < 0.5 ? XMFLOAT4Lerp(BOND_BROKEN_COLOR, BOND_MID_COLOR, 2.0f * healthFraction) : XMFLOAT4Lerp(BOND_MID_COLOR, BOND_HEALTHY_COLOR, 2.0f * healthFraction - 1.0f); +} + +void BlastFamily::fillDebugRender(DebugRenderBuffer& debugRenderBuffer, DebugRenderMode mode, float renderScale) +{ + const NvBlastChunk* chunks = m_tkFamily->getAsset()->getChunks(); + const NvBlastBond* bonds = m_tkFamily->getAsset()->getBonds(); + const NvBlastSupportGraph graph = m_tkFamily->getAsset()->getGraph(); + + for (const ExtPxActor* pxActor : m_actors) + { + TkActor& actor = pxActor->getTkActor(); + uint32_t lineStartIndex = (uint32_t)debugRenderBuffer.m_lines.size(); + + uint32_t nodeCount = actor.getGraphNodeCount(); + if (nodeCount == 0) // subsupport chunks don't have graph nodes + continue; + + std::vector<uint32_t> nodes(actor.getGraphNodeCount()); + actor.getGraphNodeIndices(nodes.data(), static_cast<uint32_t>(nodes.size())); + + if (DEBUG_RENDER_HEALTH_GRAPH <= mode && mode <= DEBUG_RENDER_HEALTH_GRAPH_CENTROIDS) + { + const float* bondHealths = actor.getBondHealths(); + + const ExtPxChunk* pxChunks = m_blastAsset.getPxAsset()->getChunks(); + + for (uint32_t node0 : nodes) + { + const uint32_t chunkIndex0 = graph.chunkIndices[node0]; + const NvBlastChunk& blastChunk0 = chunks[chunkIndex0]; + const ExtPxChunk& assetChunk0 = pxChunks[chunkIndex0]; + + for (uint32_t adjacencyIndex = graph.adjacencyPartition[node0]; adjacencyIndex < graph.adjacencyPartition[node0 + 1]; adjacencyIndex++) + { + uint32_t node1 = graph.adjacentNodeIndices[adjacencyIndex]; + const uint32_t chunkIndex1 = graph.chunkIndices[node1]; + const NvBlastChunk& blastChunk1 = chunks[chunkIndex1]; + const ExtPxChunk& assetChunk1 = pxChunks[chunkIndex1]; + if (node0 > node1) + continue; + + bool invisibleBond = 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); + + DirectX::XMFLOAT4 color = bondHealthColor(healthVal); + + const NvBlastBond& solverBond = bonds[bondIndex]; + const PxVec3& centroid = reinterpret_cast<const PxVec3&>(solverBond.centroid); + + // centroid + if (mode == DEBUG_RENDER_HEALTH_GRAPH_CENTROIDS || mode == DEBUG_RENDER_CENTROIDS) + { + const PxVec3& normal = reinterpret_cast<const PxVec3&>(solverBond.normal); + pushCentroid(debugRenderBuffer.m_lines, centroid, XMFLOAT4ToU32Color(invisibleBond ? BOND_INVISIBLE_COLOR : color), solverBond.area, normal.getNormalized()); + } + + // chunk connection (bond) + if ((mode == DEBUG_RENDER_HEALTH_GRAPH || mode == DEBUG_RENDER_HEALTH_GRAPH_CENTROIDS) && !invisibleBond) + { + const PxVec3& c0 = reinterpret_cast<const PxVec3&>(blastChunk0.centroid); + const PxVec3& c1 = reinterpret_cast<const PxVec3&>(blastChunk1.centroid); + debugRenderBuffer.m_lines.push_back(PxDebugLine(c0, c1, XMFLOAT4ToU32Color(color))); + } + } + } + } + + // stress + if (DEBUG_RENDER_STRESS_GRAPH <= mode && mode <= DEBUG_RENDER_STRESS_GRAPH_BONDS_IMPULSES) + { + if (m_stressSolver) + { + m_stressSolver->fillDebugRender(nodes, debugRenderBuffer.m_lines, (ExtStressSolver::DebugRenderMode)(mode - DEBUG_RENDER_STRESS_GRAPH), renderScale); + } + } + + // transform all added lines from local to global + PxTransform localToGlobal = pxActor->getPhysXActor().getGlobalPose(); + for (uint32_t i = lineStartIndex; i < debugRenderBuffer.m_lines.size(); i++) + { + PxDebugLine& line = debugRenderBuffer.m_lines[i]; + line.pos0 = localToGlobal.transform(line.pos0); + line.pos1 = localToGlobal.transform(line.pos1); + } + } + + // joints debug render + if (mode == DEBUG_RENDER_JOINTS) + { + for (const ExtPxActor* pxActor : m_actors) + { + TkActor& actor = pxActor->getTkActor(); + const uint32_t jointCount = actor.getJointCount(); + if (jointCount > 0) + { + std::vector<TkJoint*> joints(jointCount); + actor.getJoints(joints.data(), jointCount); + for (auto joint : joints) + { + PxJoint* pxJoint = reinterpret_cast<PxJoint*>(joint->userData); + if (pxJoint) + { + PxRigidActor *actor0, *actor1; + pxJoint->getActors(actor0, actor1); + auto lp0 = pxJoint->getLocalPose(PxJointActorIndex::eACTOR0); + auto lp1 = pxJoint->getLocalPose(PxJointActorIndex::eACTOR1); + PxVec3 p0 = actor0 ? actor0->getGlobalPose().transform(lp0).p : lp0.p; + PxVec3 p1 = actor1 ? actor1->getGlobalPose().transform(lp1).p : lp1.p; + debugRenderBuffer.m_lines.push_back(PxDebugLine(p0, p1, XMFLOAT4ToU32Color(JOINT_COLOR))); + } + } + } + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// action!!! +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class BlastOverlapCallback : public PxOverlapCallback +{ +public: + BlastOverlapCallback(ExtPxManager& pxManager, std::set<ExtPxActor*>& actorBuffer) + : m_pxManager(pxManager), m_actorBuffer(actorBuffer), PxOverlapCallback(m_hitBuffer, sizeof(m_hitBuffer) / sizeof(m_hitBuffer[0])) {} + + PxAgain processTouches(const PxOverlapHit* buffer, PxU32 nbHits) + { + for (PxU32 i = 0; i < nbHits; ++i) + { + PxRigidDynamic* rigidDynamic = buffer[i].actor->is<PxRigidDynamic>(); + if (rigidDynamic) + { + ExtPxActor* actor = m_pxManager.getActorFromPhysXActor(*rigidDynamic); + if (actor != nullptr) + { + m_actorBuffer.insert(actor); + } + } + } + return true; + } + +private: + ExtPxManager& m_pxManager; + std::set<ExtPxActor*>& m_actorBuffer; + PxOverlapHit m_hitBuffer[1000]; +}; + +void BlastFamily::blast(PxVec3 worldPos, float damageRadius, float explosiveImpulse, std::function<void(ExtPxActor*)> damageFunction) +{ +// Add By Lixu Begin + const ExtPxAsset* pExtPxAsset = m_blastAsset.getPxAsset(); + const TkAsset& tkAsset = pExtPxAsset->getTkAsset(); + uint32_t bondCount = tkAsset.getBondCount(); + if (bondCount == 0) + { + return; + } +// Add By Lixu End + + std::set<ExtPxActor*> actorsToDamage; +#if 1 + BlastOverlapCallback overlapCallback(m_pxManager, actorsToDamage); + m_physXController.getPhysXScene().overlap(PxSphereGeometry(damageRadius), PxTransform(worldPos), overlapCallback); +#else + for (std::map<NvBlastActor*, PhysXController::Actor*>::iterator it = m_actorsMap.begin(); it != m_actorsMap.end(); it++) + { + actorsToDamage.insert(it->first); + } +#endif + + 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; + } + +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); + +} + +// 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/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.h new file mode 100644 index 0000000..b4611a9 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamily.h @@ -0,0 +1,224 @@ +/* +* 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. +*/ + +#ifndef BLAST_FAMILY_H +#define BLAST_FAMILY_H + +#include "BlastAsset.h" +#include "NvBlastExtPxListener.h" +#include "NvBlastExtStressSolver.h" +#include "NvBlastExtDamageShaders.h" +#include <functional> +#include <set> +#include <map> + + +class DebugRenderBuffer; +// Add By Lixu Begin +class RenderMaterial; +// Add By Lixu End + +namespace Nv +{ +namespace Blast +{ +class TkFamily; +class ExtPxManager; +} +} + + +/** +BlastFamily class represents 1 spawned BlastAsset, contains and manipulates all physx/blast actors spawned by fracturing it. +Abstract class, internal actor management functions are implementation dependent and so pure virtual. +*/ +class BlastFamily +{ +public: + + //////// public API //////// + + void blast(PxVec3 worldPos, float damageRadius, float explosiveImpulse, std::function<void(ExtPxActor*)> damageFunction); + void explode(PxVec3 worldPos, float damageRadius, float explosiveImpulse); + + void updatePreSplit(float dt); + void updateAfterSplit(float dt); + + void drawUI(); + void drawStatsUI(); + +// Add By Lixu Begin + bool find(ExtPxActor* actor); + virtual void setActorSelected(const ExtPxActor& actor, bool selected) {} + 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 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) {} + 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) {} +// Add By Lixu End + + enum DebugRenderMode + { + DEBUG_RENDER_DISABLED, + DEBUG_RENDER_HEALTH_GRAPH, + DEBUG_RENDER_CENTROIDS, + DEBUG_RENDER_HEALTH_GRAPH_CENTROIDS, + DEBUG_RENDER_JOINTS, + DEBUG_RENDER_STRESS_GRAPH, + DEBUG_RENDER_STRESS_GRAPH_NODES_IMPULSES, + DEBUG_RENDER_STRESS_GRAPH_BONDS_IMPULSES, + + // count + DEBUG_RENDER_MODES_COUNT + }; + + void fillDebugRender(DebugRenderBuffer& debugRenderBuffer, DebugRenderMode mode, float renderScale); + + + //////// public getters //////// + + const ExtPxFamily* getFamily() const + { + return m_pxFamily; + } + + uint32_t getActorCount() const; + + uint32_t getTotalVisibleChunkCount() const + { + return m_totalVisibleChunkCount; + } + + size_t getFamilySize() const + { + return m_familySize; + } + + const BlastAsset& getBlastAsset() + { + return m_blastAsset; + } + + void resetStress(); + + void refreshStressSolverSettings(); + + void reloadStressSolver(); + + + //////// consts //////// + + static const float BOND_HEALTH_MAX; + + + //////// settings //////// + + struct Settings + { + bool stressSolverEnabled; + ExtStressSolverSettings stressSolverSettings; + bool stressDamageEnabled; + NvBlastExtMaterial material; + }; + + void setSettings(const Settings& settings); + + const Settings& getSettings() const + { + return m_settings; + } + + + //////// dtor //////// + + virtual ~BlastFamily(); + +protected: + + //////// ctor //////// + + BlastFamily(PhysXController& physXController, ExtPxManager& pxManager, const BlastAsset& blastAsset); + + void initialize(const BlastAsset::ActorDesc& desc); + + + //////// internal virtual callbacks //////// + + virtual void onActorCreated(const ExtPxActor& actor) = 0; + virtual void onActorUpdate(const ExtPxActor& actor) = 0; + virtual void onActorDestroyed(const ExtPxActor& actor) = 0; + virtual void onActorHealthUpdate(const ExtPxActor& pxActor) {}; + + virtual void onUpdate() {} + + + //////// protected data //////// + + PhysXController& m_physXController; + ExtPxManager& m_pxManager; + const BlastAsset& m_blastAsset; + std::map<uint32_t, bool> m_VisibleChangedChunks; + +private: + + //////// physics listener //////// + + class PxManagerListener : public ExtPxListener + { + public: + PxManagerListener(BlastFamily* family) : m_family(family) {} + + virtual void onActorCreated(ExtPxFamily& family, ExtPxActor& actor) + { + m_family->processActorCreated(family, actor); + + } + + virtual void onActorDestroyed(ExtPxFamily& family, ExtPxActor& actor) + { + m_family->processActorDestroyed(family, actor); + } + private: + BlastFamily* m_family; + }; + + friend class PxManagerListener; + + //////// private methods //////// + + void processActorCreated(ExtPxFamily&, ExtPxActor& actor); + void processActorDestroyed(ExtPxFamily&, ExtPxActor& actor); + + + //////// private data //////// + + TkFamily* m_tkFamily; + ExtPxFamily* m_pxFamily; + PxManagerListener m_listener; + Settings m_settings; + size_t m_familySize; + uint32_t m_totalVisibleChunkCount; + ExtStressSolver* m_stressSolver; + double m_stressSolveTime; + std::set<ExtPxActor*> m_actors; + std::set<const ExtPxActor*> m_actorsToUpdateHealth; +}; + + +#endif //BLAST_FAMILY_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.cpp new file mode 100644 index 0000000..e8b7b27 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.cpp @@ -0,0 +1,92 @@ +/* +* 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. +*/ + + +#include "BlastFamilyBoxes.h" +#include "NvBlastExtPxAsset.h" +#include "NvBlastExtPxActor.h" +#include "BlastAssetBoxes.h" +#include "Renderer.h" +#include "PhysXController.h" +#include "RenderUtils.h" +#include "PxRigidDynamic.h" + +using namespace physx; + + +BlastFamilyBoxes::BlastFamilyBoxes(PhysXController& physXController, ExtPxManager& pxManager, Renderer& renderer, const BlastAssetBoxes& blastAsset, const BlastAsset::ActorDesc& desc) + : BlastFamily(physXController, pxManager, blastAsset), m_renderer(renderer) +{ + // prepare renderables + IRenderMesh* boxRenderMesh = renderer.getPrimitiveRenderMesh(PrimitiveRenderMeshType::Box); + RenderMaterial* primitiveRenderMaterial = physXController.getPrimitiveRenderMaterial(); + + const ExtPxAsset* pxAsset = m_blastAsset.getPxAsset(); + const uint32_t chunkCount = pxAsset->getChunkCount(); + const ExtPxChunk* chunks = pxAsset->getChunks(); + const ExtPxSubchunk* subChunks = pxAsset->getSubchunks(); + m_chunkRenderables.resize(chunkCount); + for (uint32_t i = 0; i < chunkCount; i++) + { + Renderable* renderable = renderer.createRenderable(*boxRenderMesh, *primitiveRenderMaterial); + renderable->setHidden(true); + renderable->setScale(subChunks[chunks[i].firstSubchunkIndex].geometry.scale.scale); + m_chunkRenderables[i] = renderable; + } + + // initialize in position + initialize(desc); +} + +BlastFamilyBoxes::~BlastFamilyBoxes() +{ + for (uint32_t i = 0; i < m_chunkRenderables.size(); i++) + { + m_renderer.removeRenderable(m_chunkRenderables[i]); + } +} + +void BlastFamilyBoxes::onActorCreated(const ExtPxActor& actor) +{ + DirectX::XMFLOAT4 color = getRandomPastelColor(); + + const uint32_t* chunkIndices = actor.getChunkIndices(); + uint32_t chunkCount = actor.getChunkCount(); + for (uint32_t i = 0; i < chunkCount; i++) + { + const uint32_t chunkIndex = chunkIndices[i]; + m_chunkRenderables[chunkIndex]->setHidden(false); + m_chunkRenderables[chunkIndex]->setColor(color); + } +} + +void BlastFamilyBoxes::onActorUpdate(const ExtPxActor& actor) +{ + const ExtPxChunk* chunks = m_blastAsset.getPxAsset()->getChunks(); + const ExtPxSubchunk* subChunks = m_blastAsset.getPxAsset()->getSubchunks(); + const uint32_t* chunkIndices = actor.getChunkIndices(); + uint32_t chunkCount = actor.getChunkCount(); + for (uint32_t i = 0; i < chunkCount; i++) + { + const uint32_t chunkIndex = chunkIndices[i]; + m_chunkRenderables[chunkIndex]->setTransform(actor.getPhysXActor().getGlobalPose() * subChunks[chunks[chunkIndex].firstSubchunkIndex].transform); + } +} + +void BlastFamilyBoxes::onActorDestroyed(const ExtPxActor& actor) +{ + const uint32_t* chunkIndices = actor.getChunkIndices(); + uint32_t chunkCount = actor.getChunkCount(); + for (uint32_t i = 0; i < chunkCount; i++) + { + m_chunkRenderables[chunkIndices[i]]->setHidden(true); + } + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.h new file mode 100644 index 0000000..1f70451 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyBoxes.h @@ -0,0 +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. +*/ + +#ifndef BLAST_FAMILY_BOXES +#define BLAST_FAMILY_BOXES + +#include "BlastFamily.h" + +class BlastAssetBoxes; +class Renderable; + + +class BlastFamilyBoxes : public BlastFamily +{ +public: + BlastFamilyBoxes(PhysXController& physXController, ExtPxManager& pxManager, Renderer& renderer, const BlastAssetBoxes& blastAsset, const BlastAsset::ActorDesc& desc); + virtual ~BlastFamilyBoxes(); + +protected: + virtual void onActorCreated(const ExtPxActor& actor); + virtual void onActorUpdate(const ExtPxActor& actor); + virtual void onActorDestroyed(const ExtPxActor& actor); + +private: + Renderer& m_renderer; + std::vector<Renderable*> m_chunkRenderables; +}; + + +#endif //BLAST_FAMILY_BOXES
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.cpp new file mode 100644 index 0000000..54df3cd --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.cpp @@ -0,0 +1,638 @@ +/* +* 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. +*/ + +#include "BlastFamilyModelSimple.h" +#include "RenderUtils.h" +#include "DeviceManager.h" +#include "Renderer.h" +#include "NvBlastExtPxAsset.h" +#include "NvBlastExtPxActor.h" +#include "NvBlastTkActor.h" +#include "NvBlastTkAsset.h" +#include "PxRigidDynamic.h" + +using namespace physx; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SimpleRenderMesh +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SimpleRenderMesh : public IRenderMesh +{ +public: + SimpleRenderMesh(const SimpleMesh* mesh) : m_mesh(mesh) + { + m_device = GetDeviceManager()->GetDevice(); + + 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({ "TEXCOORD", 1, DXGI_FORMAT_R32_FLOAT, 1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + + m_numVertices = static_cast<uint32_t>(mesh->vertices.size()); + m_numFaces = static_cast<uint32_t>(mesh->indices.size()); + + // VB + { + D3D11_SUBRESOURCE_DATA vertexBufferData; + ZeroMemory(&vertexBufferData, sizeof(vertexBufferData)); + vertexBufferData.pSysMem = mesh->vertices.data(); + + D3D11_BUFFER_DESC bufferDesc; + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = sizeof(SimpleMesh::Vertex) * m_numVertices; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + + V(m_device->CreateBuffer(&bufferDesc, &vertexBufferData, &m_vertexBuffer)); + } + + // Health Buffer + { + // fill with 1.0f initially + std::vector<float> healths(mesh->vertices.size()); + std::fill(healths.begin(), healths.end(), 1.0f); + + D3D11_SUBRESOURCE_DATA vertexBufferData; + ZeroMemory(&vertexBufferData, sizeof(vertexBufferData)); + vertexBufferData.pSysMem = healths.data(); + + D3D11_BUFFER_DESC bufferDesc; + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = (uint32_t)(sizeof(float) * m_numVertices); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(m_device->CreateBuffer(&bufferDesc, &vertexBufferData, &m_healthBuffer)); + } + + // IB + if (m_numFaces) + { + D3D11_SUBRESOURCE_DATA indexBufferData; + + ZeroMemory(&indexBufferData, sizeof(indexBufferData)); + indexBufferData.pSysMem = mesh->indices.data(); + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc.ByteWidth = sizeof(uint16_t) * m_numFaces; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + + V(m_device->CreateBuffer(&bufferDesc, &indexBufferData, &m_indexBuffer)); + } + } + + ~SimpleRenderMesh() + { + SAFE_RELEASE(m_healthBuffer); + SAFE_RELEASE(m_vertexBuffer); + SAFE_RELEASE(m_indexBuffer); + } + + + void render(ID3D11DeviceContext& context) const + { + context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + UINT strides[2] = { sizeof(SimpleMesh::Vertex), sizeof(uint32_t) }; + UINT offsets[2] = { 0 }; + ID3D11Buffer* buffers[2] = { m_vertexBuffer, m_healthBuffer }; + context.IASetVertexBuffers(0, 2, buffers, strides, offsets); + + + context.IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0); + + if (m_indexBuffer) + context.DrawIndexed(m_numFaces, 0, 0); + else + context.Draw(m_numVertices, 0); + } + + const std::vector<D3D11_INPUT_ELEMENT_DESC>& getInputElementDesc() const { return m_inputDesc; } + + const SimpleMesh* getMesh() { return m_mesh; } + + void updateHealths(const std::vector<float>& healths) + { + ID3D11DeviceContext* context; + m_device->GetImmediateContext(&context); + + // update buffer + { + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(m_healthBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + memcpy(mappedRead.pData, healths.data(), sizeof(float) * healths.size()); + context->Unmap(m_healthBuffer, 0); + } + + } + +// Add By Lixu Begin + void setScale(PxMat44 scale, bool replace) + { + std::vector<SimpleMesh::Vertex> newVertex(m_numVertices); + for (int v = 0; v < m_numVertices; v++) + { + newVertex[v] = m_mesh->vertices[v]; + newVertex[v].position = scale.transform(newVertex[v].position); + } + + D3D11_SUBRESOURCE_DATA vertexBufferData; + ZeroMemory(&vertexBufferData, sizeof(vertexBufferData)); + vertexBufferData.pSysMem = newVertex.data(); + + D3D11_BUFFER_DESC bufferDesc; + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = sizeof(SimpleMesh::Vertex) * m_numVertices; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + + ID3D11Buffer* pBuffer = m_vertexBuffer; + V(m_device->CreateBuffer(&bufferDesc, &vertexBufferData, &m_vertexBuffer)); + if (NULL != pBuffer) + { + pBuffer->Release(); + pBuffer = NULL; + } + + if (replace) + { + memcpy((void*)m_mesh->vertices.data(), newVertex.data(), bufferDesc.ByteWidth); + } + } +// Add By Lixu End + +private: + + ID3D11Device* m_device; + + ID3D11Buffer* m_vertexBuffer; + ID3D11Buffer* m_healthBuffer; + ID3D11Buffer* m_indexBuffer; + uint32_t m_numFaces; + uint32_t m_numVertices; + + std::vector<D3D11_INPUT_ELEMENT_DESC> m_inputDesc; + + const SimpleMesh* m_mesh; +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BlastFamilyModelSimple +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +BlastFamilyModelSimple::BlastFamilyModelSimple(PhysXController& physXController, ExtPxManager& pxManager, Renderer& renderer, const BlastAssetModelSimple& blastAsset, const BlastAsset::ActorDesc& desc) + : BlastFamily(physXController, pxManager, blastAsset), m_renderer(renderer) +{ + // materials + auto materials = blastAsset.getRenderMaterials(); + + // model + const BlastModel& model = blastAsset.getModel(); + + // create render mesh for every BlastModel::Chunk::Mesh and renderable with it + const std::vector<BlastModel::Chunk>& modelChunks = model.chunks; + m_chunks.resize(modelChunks.size()); + for (uint32_t chunkIndex = 0; chunkIndex < modelChunks.size(); chunkIndex++) + { + const std::vector<BlastModel::Chunk::Mesh>& meshes = modelChunks[chunkIndex].meshes; + std::vector<SimpleRenderMesh*>& renderMeshes = m_chunks[chunkIndex].renderMeshes; + std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables; +// Add By Lixu Begin + std::vector<Renderable*>& ex_Renderables = m_chunks[chunkIndex].ex_Renderables; + ex_Renderables.clear(); + std::vector<Renderable*>& in_Renderables = m_chunks[chunkIndex].in_Renderables; + in_Renderables.clear(); +// Add By Lixu End + renderMeshes.resize(meshes.size()); + renderables.resize(meshes.size()); + for (uint32_t i = 0; i < meshes.size(); i++) + { + 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); + renderables[i] = renderable; +// Add By Lixu Begin + if (materialIndex == 0) + { + ex_Renderables.push_back(renderable); + } + else if (materialIndex == 1) + { + in_Renderables.push_back(renderable); + } +// Add By Lixu End + } + } + + // initialize in position + initialize(desc); +} + +BlastFamilyModelSimple::~BlastFamilyModelSimple() +{ + // release all chunks + for (uint32_t chunkIndex = 0; chunkIndex < m_chunks.size(); chunkIndex++) + { + std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables; + for (uint32_t i = 0; i < m_chunks[chunkIndex].renderables.size(); i++) + { + m_renderer.removeRenderable(m_chunks[chunkIndex].renderables[i]); + SAFE_DELETE(m_chunks[chunkIndex].renderMeshes[i]); + } + } +} + +void BlastFamilyModelSimple::onActorCreated(const ExtPxActor& actor) +{ + // separate color for every material + std::vector<DirectX::XMFLOAT4> colors; + + const uint32_t* chunkIndices = actor.getChunkIndices(); + uint32_t chunkCount = actor.getChunkCount(); + for (uint32_t i = 0; i < chunkCount; i++) + { + uint32_t chunkIndex = chunkIndices[i]; + std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables; + for (uint32_t r = 0; r < renderables.size(); r++) + { + if (colors.size() <= r) + colors.push_back(getRandomPastelColor()); + + renderables[r]->setHidden(false); + renderables[r]->setColor(colors[r]); + + m_VisibleChangedChunks[chunkIndex] = true; + } + } +} + +void BlastFamilyModelSimple::onActorUpdate(const ExtPxActor& actor) +{ +// Add By Lixu Begin + uint32_t shapesCount = actor.getPhysXActor().getNbShapes(); + PxTransform lp; + if (shapesCount > 0) + { + std::vector<PxShape*> shapes(shapesCount); + actor.getPhysXActor().getShapes(&shapes[0], shapesCount); + PxShape* shape = shapes[0]; + lp = shape->getLocalPose(); + } +// Add By Lixu End + + const ExtPxChunk* chunks = m_blastAsset.getPxAsset()->getChunks(); + const ExtPxSubchunk* subChunks = m_blastAsset.getPxAsset()->getSubchunks(); + const uint32_t* chunkIndices = actor.getChunkIndices(); + uint32_t chunkCount = actor.getChunkCount(); + for (uint32_t i = 0; i < chunkCount; i++) + { + uint32_t chunkIndex = chunkIndices[i]; + std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables; + for (Renderable* r : renderables) + { +// Add By Lixu Begin + r->setTransform(actor.getPhysXActor().getGlobalPose() * lp * subChunks[chunks[chunkIndex].firstSubchunkIndex].transform); +// Add By Lixu End + } + } +} + +void BlastFamilyModelSimple::onActorDestroyed(const ExtPxActor& actor) +{ + const uint32_t* chunkIndices = actor.getChunkIndices(); + uint32_t chunkCount = actor.getChunkCount(); + for (uint32_t i = 0; i < chunkCount; i++) + { + uint32_t chunkIndex = chunkIndices[i]; + std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables; + for (Renderable* r : renderables) + { + r->setHidden(true); + + m_VisibleChangedChunks[chunkIndex] = false; + } + } +} + +void BlastFamilyModelSimple::onActorHealthUpdate(const ExtPxActor& actor) +{ + TkActor& tkActor = actor.getTkActor(); + const TkAsset* tkAsset = tkActor.getAsset(); + + const float* bondHealths = tkActor.getBondHealths(); + uint32_t nodeCount = tkActor.getGraphNodeCount(); + if (nodeCount == 0) // subsupport chunks don't have graph nodes + return; + + std::vector<uint32_t> nodes(tkActor.getGraphNodeCount()); + tkActor.getGraphNodeIndices(nodes.data(), static_cast<uint32_t>(nodes.size())); + + const NvBlastChunk* chunks = tkAsset->getChunks(); + const NvBlastBond* bonds = tkAsset->getBonds(); + + const NvBlastSupportGraph graph = tkAsset->getGraph(); + + std::vector<float> healthBuffer; + + for (uint32_t node0 : nodes) + { + uint32_t chunkIndex = graph.chunkIndices[node0]; + + if (chunkIndex >= m_chunks.size()) + continue; + + std::vector<SimpleRenderMesh*>& meshes = m_chunks[chunkIndex].renderMeshes; + const auto& renderables = m_chunks[chunkIndex].renderables; + for (uint32_t i = 0; i < meshes.size(); ++i) + { + if(renderables[i]->isHidden()) + continue; + + SimpleRenderMesh* renderMesh = meshes[i]; + + const SimpleMesh* mesh = renderMesh->getMesh(); + healthBuffer.resize(mesh->vertices.size()); + + for (uint32_t vertexIndex = 0; vertexIndex < mesh->vertices.size(); vertexIndex++) + { + PxVec3 position = mesh->vertices[vertexIndex].position; + float health = 0.0f; + float healthDenom = 0.0f; + + for (uint32_t adjacencyIndex = graph.adjacencyPartition[node0]; adjacencyIndex < graph.adjacencyPartition[node0 + 1]; adjacencyIndex++) + { + uint32_t node1 = graph.adjacentNodeIndices[adjacencyIndex]; + uint32_t bondIndex = graph.adjacentBondIndices[adjacencyIndex]; + float bondHealth = PxClamp(bondHealths[bondIndex] / BOND_HEALTH_MAX, 0.0f, 1.0f); + const NvBlastBond& solverBond = bonds[bondIndex]; + const PxVec3& centroid = reinterpret_cast<const PxVec3&>(solverBond.centroid); + + float factor = 1.0f / (centroid - position).magnitudeSquared(); + + health += bondHealth * factor; + healthDenom += factor; + } + + healthBuffer[vertexIndex] = healthDenom > 0.0f ? health / healthDenom : 1.0f; + } + + renderMesh->updateHealths(healthBuffer); + } + } +} + +// Add By Lixu Begin +void BlastFamilyModelSimple::setActorSelected(const ExtPxActor& actor, bool selected) +{ + const uint32_t* chunkIndices = actor.getChunkIndices(); + uint32_t chunkCount = actor.getChunkCount(); + for (uint32_t i = 0; i < chunkCount; i++) + { + uint32_t chunkIndex = chunkIndices[i]; + std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables; + for (Renderable* r : renderables) + { + r->setSelected(selected); + } + } +} + +void BlastFamilyModelSimple::setChunkSelected(uint32_t chunk, bool selected) +{ + if (chunk > m_chunks.size()) + return; + + std::vector<Renderable*>& renderables = m_chunks[chunk].renderables; + for (Renderable* r : renderables) + { + r->setSelected(select); + } +} + +void BlastFamilyModelSimple::setChunkSelected(std::vector<uint32_t> depths, bool selected) +{ + for (size_t i = 0; i < depths.size(); ++i) + { + const std::vector<uint32_t> indexes = m_blastAsset.getChunkIndexesByDepth(depths[i]); + for (size_t j = 0; j < indexes.size(); ++j) + { + setChunkSelected(indexes[j], selected); + } + } +} + +void BlastFamilyModelSimple::clearChunksSelected() +{ + size_t count = m_chunks.size(); + for (size_t chunkIndex = 0; chunkIndex < count; ++chunkIndex) + { + std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables; + for (Renderable* r : renderables) + { + r->setSelected(false); + } + } +} + +bool BlastFamilyModelSimple::getChunkSelected(uint32_t chunk) +{ + if (chunk > m_chunks.size()) + return false; + + std::vector<Renderable*>& renderables = m_chunks[chunk].renderables; + for (Renderable* r : renderables) + { + for (Renderable* r : renderables) + { + if (r->isSelected()) + { + return true; + } + } + } + + return false; +} + +std::vector<uint32_t> BlastFamilyModelSimple::getSelectedChunks() +{ + std::vector<uint32_t> selectedChunks; + size_t count = m_chunks.size(); + for (size_t chunkIndex = 0; chunkIndex < count; ++chunkIndex) + { + std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables; + for (Renderable* r : renderables) + { + if (r->isSelected()) + { + selectedChunks.push_back(chunkIndex); + break; + } + } + } + return selectedChunks; +} + +void BlastFamilyModelSimple::setActorScale(const ExtPxActor& 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 = chunkIndices[i]; + std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables; + for (Renderable* r : renderables) + { + r->setMeshScale(scale, replace); + } + } +} + +bool BlastFamilyModelSimple::isChunkVisible(uint32_t chunkIndex) +{ + if (chunkIndex < 0 || chunkIndex >= m_chunks.size()) + { + return false; + } + + bool bVisible = false; + std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables; + if (renderables.size() > 0) + { + bVisible = !renderables[0]->isHidden(); + } + return bVisible; +} + +void BlastFamilyModelSimple::setChunkVisible(uint32_t chunkIndex, bool bVisible) +{ + if (chunkIndex < 0 || chunkIndex >= m_chunks.size()) + { + return; + } + + std::vector<Renderable*>& renderables = m_chunks[chunkIndex].renderables; + for (Renderable* r : renderables) + { + r->setHidden(!bVisible); + } +} + +void BlastFamilyModelSimple::setChunkVisible(std::vector<uint32_t> depths, bool bVisible) +{ + for (size_t i = 0; i < depths.size(); ++i) + { + const std::vector<uint32_t> indexes = m_blastAsset.getChunkIndexesByDepth(depths[i]); + for (size_t j = 0; j < indexes.size(); ++j) + { + setChunkVisible(indexes[j], bVisible); + } + } +} + +void BlastFamilyModelSimple::initTransform(physx::PxTransform t) +{ + int chunkSize = m_chunks.size(); + for (int i = 0; i < chunkSize; i++) + { + std::vector<Renderable*>& renderables = m_chunks[i].renderables; + for (Renderable* r : renderables) + { + r->setTransform(t); + } + } +} + +void BlastFamilyModelSimple::getMaterial(RenderMaterial** ppRenderMaterial, bool externalSurface) +{ + *ppRenderMaterial = nullptr; + + int chunkSize = m_chunks.size(); + if (chunkSize == 0) + { + return; + } + + if (externalSurface) + { + for (int i = 0; i < chunkSize; i++) + { + std::vector<Renderable*>& renderables = m_chunks[i].ex_Renderables; + if (renderables.size() > 0) + { + RenderMaterial& m = renderables[0]->getMaterial(); + *ppRenderMaterial = &m; + return; + } + } + } + else + { + for (int i = 0; i < chunkSize; i++) + { + std::vector<Renderable*>& renderables = m_chunks[i].in_Renderables; + if (renderables.size() > 0) + { + RenderMaterial& m = renderables[0]->getMaterial(); + *ppRenderMaterial = &m; + return; + } + } + } +} + +void BlastFamilyModelSimple::setMaterial(RenderMaterial* pRenderMaterial, bool externalSurface) +{ + RenderMaterial* p = pRenderMaterial; + if (p == nullptr) + { + p = RenderMaterial::getDefaultRenderMaterial(); + } + + int chunkSize = m_chunks.size(); + if (externalSurface) + { + for (int i = 0; i < chunkSize; i++) + { + std::vector<Renderable*>& renderables = m_chunks[i].ex_Renderables; + for (Renderable* r : renderables) + { + r->setMaterial(*p); + } + } + } + else + { + for (int i = 0; i < chunkSize; i++) + { + std::vector<Renderable*>& renderables = m_chunks[i].in_Renderables; + for (Renderable* r : renderables) + { + r->setMaterial(*p); + } + } + } +} +// Add By Lixu End
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.h new file mode 100644 index 0000000..ed51133 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSimple.h @@ -0,0 +1,72 @@ +/* +* 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. +*/ + +#ifndef BLAST_FAMILY_MODEL_SIMPLE_H +#define BLAST_FAMILY_MODEL_SIMPLE_H + +#include "BlastFamily.h" +#include "BlastAssetModelSimple.h" + +class SimpleRenderMesh; +class Renderable; +class Renderer; + +class BlastFamilyModelSimple : public BlastFamily +{ +public: + //////// ctor //////// + + BlastFamilyModelSimple(PhysXController& physXController, ExtPxManager& pxManager, Renderer& renderer, const BlastAssetModelSimple& blastAsset, const BlastAsset::ActorDesc& desc); + virtual ~BlastFamilyModelSimple(); + +// Add By Lixu Begin + virtual void setActorSelected(const ExtPxActor& actor, bool selected); + 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 std::vector<uint32_t> getSelectedChunks(); + virtual void setActorScale(const ExtPxActor& 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); +// Add By Lixu End + +protected: + //////// abstract implementation //////// + + virtual void onActorCreated(const ExtPxActor& actor); + virtual void onActorUpdate(const ExtPxActor& actor); + virtual void onActorDestroyed(const ExtPxActor& actor); + virtual void onActorHealthUpdate(const ExtPxActor& pxActor); + +private: + //////// internal data //////// + + Renderer& m_renderer; + + struct Chunk + { + std::vector<SimpleRenderMesh*> renderMeshes; + std::vector<Renderable*> renderables; +// Add By Lixu Begin + std::vector<Renderable*> ex_Renderables; + std::vector<Renderable*> in_Renderables; +// Add By Lixu End + }; + + std::vector<Chunk> m_chunks; +}; + + +#endif //BLAST_FAMILY_MODEL_SIMPLE_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.cpp new file mode 100644 index 0000000..c0731d5 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.cpp @@ -0,0 +1,167 @@ +/* +* 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. +*/ + +#include "BlastFamilyModelSkinned.h" +#include "RenderUtils.h" +#include "Renderer.h" +#include "SkinnedRenderMesh.h" +#include "NvBlastExtPxAsset.h" +#include "NvBlastExtPxActor.h" +#include "NvBlastTkActor.h" +#include "PxRigidDynamic.h" + +using namespace physx; + +BlastFamilyModelSkinned::BlastFamilyModelSkinned(PhysXController& physXController, ExtPxManager& pxManager, Renderer& renderer, const BlastAssetModelSkinned& blastAsset, const BlastAsset::ActorDesc& desc) + : BlastFamily(physXController, pxManager, blastAsset), m_renderer(renderer), m_visibleActorsDirty(true) +{ + // materials + auto materials = blastAsset.getRenderMaterials(); + + const BlastModel& model = blastAsset.getModel(); + + // finalize (create) sub model + auto finalizeSubModelFunction = [&](SubModel* subModel, std::vector<const SimpleMesh*>& subModelMeshes, RenderMaterial& renderMaterial) + { + subModel->skinnedRenderMesh = new SkinnedRenderMesh(subModelMeshes); + subModel->renderable = renderer.createRenderable(*subModel->skinnedRenderMesh, renderMaterial); + subModel->renderable->setColor(getRandomPastelColor()); + }; + + // create at least one submodel per every material (if mesh count is too high, more then one sub model per material to be created) + SubModel* subModel = nullptr; + std::vector<const SimpleMesh*> subModelMeshes; + subModelMeshes.reserve(model.chunks.size()); + for (uint32_t materialIndex = 0; materialIndex < model.materials.size(); materialIndex++) + { + for (uint32_t chunkIndex = 0; chunkIndex < model.chunks.size(); chunkIndex++) + { + const BlastModel::Chunk& chunk = model.chunks[chunkIndex]; + for (const BlastModel::Chunk::Mesh& mesh : chunk.meshes) + { + if (mesh.materialIndex == materialIndex) + { + // init new submodel? + if (subModel == nullptr) + { + m_subModels.push_back(SubModel()); + subModel = &m_subModels.back(); + subModel->chunkIdToBoneMap.resize(model.chunks.size()); + std::fill(subModel->chunkIdToBoneMap.begin(), subModel->chunkIdToBoneMap.end(), SubModel::INVALID_BONE_ID); + subModelMeshes.clear(); + } + + // add mesh to map and list + subModel->chunkIdToBoneMap[chunkIndex] = (uint32_t)subModelMeshes.size(); + subModelMeshes.push_back(&(mesh.mesh)); + + // mesh reached limit? + if (subModelMeshes.size() == SkinnedRenderMesh::MeshesCountMax) + { + finalizeSubModelFunction(subModel, subModelMeshes, *materials[materialIndex]); + subModel = nullptr; + } + } + } + } + + // finalize subModel for this material + if (subModel && subModelMeshes.size() > 0) + { + finalizeSubModelFunction(subModel, subModelMeshes, *materials[materialIndex]); + subModel = nullptr; + } + } + + // reserve for scratch + m_visibleBones.reserve(model.chunks.size()); + m_visibleBoneTransforms.reserve(model.chunks.size()); + + // initialize in position + initialize(desc); +} + +BlastFamilyModelSkinned::~BlastFamilyModelSkinned() +{ + for (uint32_t subModelIndex = 0; subModelIndex < m_subModels.size(); subModelIndex++) + { + m_renderer.removeRenderable(m_subModels[subModelIndex].renderable); + SAFE_DELETE(m_subModels[subModelIndex].skinnedRenderMesh); + } +} + +void BlastFamilyModelSkinned::onActorCreated(const ExtPxActor& actor) +{ + m_visibleActors.insert(&actor); + m_visibleActorsDirty = true; +} + +void BlastFamilyModelSkinned::onActorUpdate(const ExtPxActor& actor) +{ +} + +void BlastFamilyModelSkinned::onActorDestroyed(const ExtPxActor& actor) +{ + m_visibleActors.erase(&actor); + m_visibleActorsDirty = true; +} + +void BlastFamilyModelSkinned::onUpdate() +{ + // visible actors changed this frame? + if (m_visibleActorsDirty) + { + for (const SubModel& model : m_subModels) + { + // pass visible chunks list to render mesh + m_visibleBones.clear(); + for (const ExtPxActor* actor : m_visibleActors) + { + const uint32_t* chunkIndices = actor->getChunkIndices(); + uint32_t chunkCount = actor->getChunkCount(); + for (uint32_t i = 0; i < chunkCount; ++i) + { + uint32_t chunkIndex = chunkIndices[i]; + uint32_t boneIndex = model.chunkIdToBoneMap[chunkIndex]; + if (boneIndex != SubModel::INVALID_BONE_ID) + { + m_visibleBones.push_back(boneIndex); + } + } + } + model.skinnedRenderMesh->updateVisibleMeshes(m_visibleBones); + } + + m_visibleActorsDirty = false; + } + + // update and pass chunk transforms + const ExtPxChunk* chunks = m_blastAsset.getPxAsset()->getChunks(); + const ExtPxSubchunk* subChunks = m_blastAsset.getPxAsset()->getSubchunks(); + for (const SubModel& model : m_subModels) + { + m_visibleBoneTransforms.clear(); + for (const ExtPxActor* actor : m_visibleActors) + { + const uint32_t* chunkIndices = actor->getChunkIndices(); + uint32_t chunkCount = actor->getChunkCount(); + for (uint32_t i = 0; i < chunkCount; ++i) + { + uint32_t chunkIndex = chunkIndices[i]; + uint32_t boneIndex = model.chunkIdToBoneMap[chunkIndex]; + if (boneIndex != SubModel::INVALID_BONE_ID) + { + m_visibleBoneTransforms.push_back(PxMat44(actor->getPhysXActor().getGlobalPose() * subChunks[chunks[chunkIndex].firstSubchunkIndex].transform)); + } + } + } + model.skinnedRenderMesh->updateVisibleMeshTransforms(m_visibleBoneTransforms); + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.h new file mode 100644 index 0000000..aeb9353 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFamilyModelSkinned.h @@ -0,0 +1,63 @@ +/* +* 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. +*/ + +#ifndef BLAST_FAMILY_MODEL_SKINNED_H +#define BLAST_FAMILY_MODEL_SKINNED_H + +#include "BlastFamily.h" +#include "BlastAssetModelSkinned.h" + +class SkinnedRenderMesh; +class Renderable; + +class BlastFamilyModelSkinned : public BlastFamily +{ +public: + //////// ctor //////// + + BlastFamilyModelSkinned(PhysXController& physXController, ExtPxManager& pxManager, Renderer& renderer, const BlastAssetModelSkinned& blastAsset, const BlastAsset::ActorDesc& desc); + virtual ~BlastFamilyModelSkinned(); + +protected: + //////// abstract implementation //////// + + virtual void onActorCreated(const ExtPxActor& actor); + virtual void onActorUpdate(const ExtPxActor& actor); + virtual void onActorDestroyed(const ExtPxActor& actor); + + virtual void onUpdate(); + +private: + //////// internal data //////// + + Renderer& m_renderer; + + struct SubModel + { + static const uint32_t INVALID_BONE_ID = ~(uint32_t)0; + + Renderable* renderable = nullptr; + SkinnedRenderMesh* skinnedRenderMesh = nullptr; + std::vector<uint32_t> chunkIdToBoneMap; + }; + std::vector<SubModel> m_subModels; + + std::set<const ExtPxActor*> m_visibleActors; + bool m_visibleActorsDirty; + + //////// scratch buffers //////// + + std::vector<uint32_t> m_visibleBones; + std::vector<PxMat44> m_visibleBoneTransforms; + +}; + + +#endif //BLAST_FAMILY_MODEL_SKINNED_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.cpp new file mode 100644 index 0000000..aa738b9 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.cpp @@ -0,0 +1,171 @@ +/* +* 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. +*/ + +#include "BlastFractureTool.h" +#include <BlastAssetModel.h> +#include <BlastAsset.h> +#include <NvBlastExtPxAsset.h> +#include <NvBlastTkAsset.h> + +void BlastFractureTool::free() +{ + std::vector<Nv::Blast::Mesh*>::iterator it; + for (it = chunkMeshes.begin(); it != chunkMeshes.end(); it++) + { + delete (*it); + (*it) = nullptr; + } + chunkMeshes.clear(); +} + +void BlastFractureTool::setSourceAsset(const BlastAsset* pBlastAsset) +{ + free(); + + BlastAssetModel* pBlastAssetModel = (BlastAssetModel*)pBlastAsset; + const BlastModel& blastModel = pBlastAssetModel->getModel(); + const std::vector<BlastModel::Chunk>& chunks = blastModel.chunks; + int chunkSize = chunks.size(); + if (chunkSize == 0) + { + return; + } + + chunkMeshes.resize(chunkSize, nullptr); + for (int cs = 0; cs < chunkSize; cs++) + { + const BlastModel::Chunk& chunk = chunks[cs]; + 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); + } + + PxVec3* nr = (!normals.empty()) ? normals.data() : 0; + 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()), + ind.data(), static_cast<uint32_t>(ind.size())); + + int curFaceIndex = 0; + int curFaceBreakPoint = faceBreakPoint[curFaceIndex]; + uint32_t curMaterialIndex = materialIndexes[curFaceIndex]; + for (int fc = 0; fc < pMesh->getFacetCount(); fc++) + { + if (fc >= curFaceBreakPoint) + { + curFaceIndex++; + curFaceBreakPoint += faceBreakPoint[curFaceIndex]; + curMaterialIndex = materialIndexes[curFaceIndex]; + } + + pMesh->getFacet(fc)->userData = curMaterialIndex; + } + + chunkMeshes[cs] = pMesh; + } + + const ExtPxAsset* pExtPxAsset = pBlastAsset->getPxAsset(); + const TkAsset& tkAsset = pExtPxAsset->getTkAsset(); + + std::vector<int32_t> parentIds; + parentIds.resize(chunkSize); + parentIds.assign(chunkSize, -1); + { + const NvBlastChunk* pNvBlastChunk = tkAsset.getChunks(); + for (uint32_t i = 0; i < chunkSize; ++i) + { + parentIds[i] = pNvBlastChunk[i].parentChunkIndex; + } + } + std::vector<bool> isLeafs; + isLeafs.resize(chunkSize); + isLeafs.assign(chunkSize, false); + { + const NvBlastSupportGraph supportGraph = tkAsset.getGraph(); + for (uint32_t i = 0; i < supportGraph.nodeCount; ++i) + { + const uint32_t chunkIndex = supportGraph.chunkIndices[i]; + 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 = cs; + 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; + } + } +} + +Nv::Blast::Mesh* BlastFractureTool::getSourceMesh(int32_t chunkId) +{ + if (chunkId < 0 || chunkId >= chunkMeshes.size()) + { + return nullptr; + } + return chunkMeshes[chunkId]; +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.h new file mode 100644 index 0000000..b50ccf3 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastFractureTool.h @@ -0,0 +1,41 @@ +/* +* 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. +*/ + +#ifndef BLAST_FRACTURETOOL_H +#define BLAST_FRACTURETOOL_H + +#include "NvBlastExtAuthoringFractureTool.h" + +class BlastAsset; +namespace Nv +{ + namespace Blast + { + class Mesh; + } +} + +class BlastFractureTool : public Nv::Blast::FractureTool +{ +public: + BlastFractureTool(NvBlastLog logCallback = nullptr) : FractureTool(logCallback) {} + ~BlastFractureTool() { free(); } + + void setSourceAsset(const BlastAsset* pBlastAsset); + + Nv::Blast::Mesh* getSourceMesh(int32_t chunkId); + +private: + void free(); + + std::vector<Nv::Blast::Mesh*> chunkMeshes; +}; + +#endif //BLAST_FRACTURETOOL_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.cpp new file mode 100644 index 0000000..d231a6c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.cpp @@ -0,0 +1,167 @@ +/* +* 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. +*/ + +#include "BlastModel.h" + +// Add By Lixu Begin +//#define TINYOBJLOADER_IMPLEMENTATION +// Add By Lixu End +#include "tiny_obj_loader.h" + + +using namespace physx; + +BlastModelPtr BlastModel::loadFromFileTinyLoader(const char* path) +{ +// Add By Lixu Begin + BlastModel* model = new BlastModel(); +// Add By Lixu End + + std::vector<tinyobj::shape_t> shapes; + std::vector<tinyobj::material_t> mats; + std::string err; + std::string mtlPath; + for (size_t i = strnlen(path, 255) - 1; i >= 0; --i) + { + if (path[i] == '\\') + { + mtlPath.resize(i + 2, 0); + strncpy(&mtlPath[0], path, i + 1); + break; + } + } + + + bool ret = tinyobj::LoadObj(shapes, mats, err, path, mtlPath.data()); + + // can't load? + if (!ret) + return false; + + // one submodel per material + uint32_t materialsCount = (uint32_t)mats.size(); + model->materials.resize(materialsCount); + + // fill submodel materials + for (uint32_t i = 0; i < materialsCount; i++) + { + tinyobj::material_t *pMaterial = &mats[i]; + + if (!pMaterial->diffuse_texname.empty()) + { +// Add By Lixu Begin + model->materials[i].name = pMaterial->name; +// Add By Lixu End + model->materials[i].diffuseTexture = pMaterial->diffuse_texname; + } + } + + // estimate + model->chunks.reserve(shapes.size() / materialsCount + 1); + + if (shapes.size() > 0) + { + uint32_t meshIndex = 0; + for (uint32_t m = 0; m < shapes.size(); m++) + { + tinyobj::shape_t& pMesh = shapes[m]; + uint32_t materialIndex; + uint32_t chunkIndex; + sscanf(pMesh.name.data(), "%d_%d", &chunkIndex, &materialIndex); + if (model->chunks.size() <= chunkIndex) + { + model->chunks.resize(chunkIndex + 1); + } + model->chunks[chunkIndex].meshes.push_back(Chunk::Mesh()); + Chunk::Mesh& mesh = model->chunks[chunkIndex].meshes.back(); + + mesh.materialIndex = materialIndex; + SimpleMesh& chunkMesh = mesh.mesh; + + PxVec3 emin(FLT_MAX, FLT_MAX, FLT_MAX); + PxVec3 emax(FLT_MIN, FLT_MIN, FLT_MIN); + + + + // create an index buffer + chunkMesh.indices.resize(pMesh.mesh.indices.size()); + + // Check if all faces are triangles + bool allTriangles = true; + for (uint32_t i = 0; i < pMesh.mesh.num_vertices.size(); ++i) + { + if (pMesh.mesh.num_vertices[i] != 3) + { + allTriangles = false; + break; + } + } + + if (pMesh.mesh.indices.size() > 0 && allTriangles) + { + for (uint32_t i = 0; i < pMesh.mesh.indices.size(); i += 3) + { + chunkMesh.indices[i] = (uint16_t)pMesh.mesh.indices[i + 2]; + chunkMesh.indices[i + 1] = (uint16_t)pMesh.mesh.indices[i + 1]; + chunkMesh.indices[i + 2] = (uint16_t)pMesh.mesh.indices[i]; + } + } + // create vertex buffer + chunkMesh.vertices.resize(pMesh.mesh.positions.size() / 3); + // copy positions + uint32_t indexer = 0; + for (uint32_t i = 0; i < pMesh.mesh.positions.size() / 3; i++) + { + chunkMesh.vertices[i].position.x = pMesh.mesh.positions[indexer]; + chunkMesh.vertices[i].position.y = pMesh.mesh.positions[indexer + 1]; + chunkMesh.vertices[i].position.z = pMesh.mesh.positions[indexer + 2]; + indexer += 3; + // calc min/max + emin = emin.minimum(chunkMesh.vertices[i].position); + emax = emax.maximum(chunkMesh.vertices[i].position); + } + + // copy normals + if (pMesh.mesh.normals.size() > 0) + { + indexer = 0; + for (uint32_t i = 0; i < pMesh.mesh.normals.size() / 3; i++) + { + chunkMesh.vertices[i].normal.x = pMesh.mesh.normals[indexer]; + chunkMesh.vertices[i].normal.y = pMesh.mesh.normals[indexer + 1]; + chunkMesh.vertices[i].normal.z = pMesh.mesh.normals[indexer + 2]; + + indexer += 3; + } + } + + // copy uv + if (pMesh.mesh.texcoords.size() > 0) + { + indexer = 0; + for (uint32_t i = 0; i < pMesh.mesh.texcoords.size() / 2; i++) + { + chunkMesh.vertices[i].uv.x = pMesh.mesh.texcoords[indexer]; + chunkMesh.vertices[i].uv.y = pMesh.mesh.texcoords[indexer + 1]; + indexer += 2; + } + } + + // assign extents + chunkMesh.extents = (emax - emin) * 0.5f; + + // get the center + chunkMesh.center = emin + chunkMesh.extents; + + } + } + + return model; +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.h new file mode 100644 index 0000000..683a343 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastModel.h @@ -0,0 +1,60 @@ +/* +* 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. +*/ + +#ifndef BLAST_MODEL_H +#define BLAST_MODEL_H + +#include "Mesh.h" +#include <vector> +#include <memory> + + +class BlastModel; +// Add By Lixu Begin +typedef BlastModel* BlastModelPtr; +// Add By Lixu End + +/** +BlastModel struct represents graphic model. +Now only loading from .obj file is supported. +Can have >=0 materials +Every chunk can have multiple meshes (1 for every material) +*/ +class BlastModel +{ +public: + struct Material + { +// Add By Lixu Begin + std::string name; +// Add By Lixu End + std::string diffuseTexture; + }; + + struct Chunk + { + struct Mesh + { + uint32_t materialIndex; + SimpleMesh mesh; + }; + + std::vector<Mesh> meshes; + }; + + std::vector<Material> materials; + std::vector<Chunk> chunks; + + static BlastModelPtr loadFromFileTinyLoader(const char* path); +private: + BlastModel() {} +}; + +#endif // ifndef BLAST_MODEL_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.cpp new file mode 100644 index 0000000..13d2b33 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.cpp @@ -0,0 +1,160 @@ +/* +* 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. +*/ + +#include "BlastReplay.h" +#include "NvBlastTk.h" +#include "NvBlastExtPxManager.h" +#include "NvBlastExtPxFamily.h" +#include "SampleProfiler.h" + + +using namespace std::chrono; + +BlastReplay::BlastReplay() : m_sync(nullptr) +{ + m_sync = ExtSync::create(); + reset(); +} + +BlastReplay::~BlastReplay() +{ + m_sync->release(); + clearBuffer(); +} + +void BlastReplay::addFamily(TkFamily* family) +{ + family->addListener(*m_sync); +} + +void BlastReplay::removeFamily(TkFamily* family) +{ + family->removeListener(*m_sync); +} + +void BlastReplay::startRecording(ExtPxManager& manager, bool syncFamily, bool syncPhysics) +{ + if (isRecording()) + return; + + m_sync->releaseSyncBuffer(); + + if (syncFamily || syncPhysics) + { + std::vector<ExtPxFamily*> families(manager.getFamilyCount()); + manager.getFamilies(families.data(), (uint32_t)families.size()); + for (ExtPxFamily* family : families) + { + if (syncPhysics) + { + m_sync->syncFamily(*family); + } + else if (syncFamily) + { + m_sync->syncFamily(family->getTkFamily()); + } + } + } + + m_isRecording = true; +} + +void BlastReplay::stopRecording() +{ + if (!isRecording()) + return; + + const ExtSyncEvent*const* buffer; + uint32_t size; + m_sync->acquireSyncBuffer(buffer, size); + + clearBuffer(); + m_buffer.resize(size); + for (uint32_t i = 0; i < size; ++i) + { + m_buffer[i] = buffer[i]->clone(); + } + + // TODO: sort by ts ? make sure? + //m_buffer.sort + + m_sync->releaseSyncBuffer(); + + m_isRecording = false; +} + +void BlastReplay::startPlayback(ExtPxManager& manager, TkGroup* group) +{ + if (isPlaying() || !hasRecord()) + return; + + m_isPlaying = true; + m_startTime = steady_clock::now(); + m_nextEventIndex = 0; + m_firstEventTs = m_buffer[0]->timestamp; + m_pxManager = &manager; + m_group = group; +} + +void BlastReplay::stopPlayback() +{ + if (!isPlaying()) + return; + + m_isPlaying = false; + m_pxManager = nullptr; + m_group = nullptr; +} + +void BlastReplay::update() +{ + if (isPlaying()) + { + PROFILER_SCOPED_FUNCTION(); + + auto now = steady_clock::now(); + auto mil = duration_cast<milliseconds>((now - m_startTime)); + bool stop = true; + while (m_nextEventIndex < m_buffer.size()) + { + const ExtSyncEvent* e = m_buffer[m_nextEventIndex]; + auto t = e->timestamp - m_firstEventTs; + if (t < (uint64_t)mil.count()) + { + m_sync->applySyncBuffer(m_pxManager->getFramework(), &e, 1, m_group, m_pxManager); + m_nextEventIndex++; + } + else + { + stop = false; + break; + } + } + + if (stop) + stopPlayback(); + } +} + +void BlastReplay::reset() +{ + m_isPlaying = false; + m_isRecording = false; + m_sync->releaseSyncBuffer(); +} + +void BlastReplay::clearBuffer() +{ + for (auto e : m_buffer) + { + e->release(); + } + m_buffer.clear(); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.h new file mode 100644 index 0000000..a85c996 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/blast/BlastReplay.h @@ -0,0 +1,75 @@ +/* +* 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. +*/ + +#ifndef BLAST_REPLAY_H +#define BLAST_REPLAY_H + +#include "NvBlastExtSync.h" +#include <chrono> + +using namespace Nv::Blast; + +class BlastReplay +{ +public: + BlastReplay(); + ~BlastReplay(); + + bool isRecording() const + { + return m_isRecording; + } + + bool isPlaying() const + { + return m_isPlaying; + } + + bool hasRecord() const + { + return m_buffer.size() > 0; + } + + size_t getEventCount() const + { + return isRecording() ? m_sync->getSyncBufferSize() : m_buffer.size(); + } + + uint32_t getCurrentEventIndex() const + { + return m_nextEventIndex; + } + + void addFamily(TkFamily* family); + void removeFamily(TkFamily* family); + + void startRecording(ExtPxManager& manager, bool syncFamily, bool syncPhysics); + void stopRecording(); + void startPlayback(ExtPxManager& manager, TkGroup* group); + void stopPlayback(); + void update(); + void reset(); + +private: + void clearBuffer(); + + ExtPxManager* m_pxManager; + TkGroup* m_group; + std::chrono::steady_clock::time_point m_startTime; + uint64_t m_firstEventTs; + uint32_t m_nextEventIndex; + bool m_isRecording; + bool m_isPlaying; + ExtSync* m_sync; + std::vector<ExtSyncEvent*> m_buffer; +}; + + +#endif // ifndef BLAST_REPLAY_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.cpp new file mode 100644 index 0000000..955d841 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.cpp @@ -0,0 +1,66 @@ +/* +* 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. +*/ + +#include "Application.h" +#include <DirectXMath.h> +#include "XInput.h" +#include "DXUTMisc.h" + + +Application::Application(DeviceManager* pDeviceManager) +{ + m_deviceManager = pDeviceManager; +} + +void Application::addControllerToFront(IApplicationController* controller) +{ + m_controllers.push_back(controller); + m_deviceManager->AddControllerToFront(controller); +} + +int Application::init() +{ + // FirstPersonCamera uses this timer, without it it will be FPS-dependent + DXUTGetGlobalTimer()->Start(); + + m_deviceManager->DeviceCreated(); + m_deviceManager->BackBufferResized(); + + for (auto it = m_controllers.begin(); it != m_controllers.end(); it++) + (*it)->onInitialize(); + + for (auto it = m_controllers.begin(); it != m_controllers.end(); it++) + (*it)->onSampleStart(); + + m_deviceManager->SetVsyncEnabled(false); + + return 0; +} + +int Application::run() +{ + m_deviceManager->MessageLoop(); + + return 0; +} + +int Application::free() +{ + for (auto it = m_controllers.rbegin(); it != m_controllers.rend(); it++) + (*it)->onSampleStop(); + + for (auto it = m_controllers.rbegin(); it != m_controllers.rend(); it++) + (*it)->onTerminate(); + + //m_deviceManager->Shutdown(); // destructor will call this function + delete m_deviceManager; + + return 0; +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.h new file mode 100644 index 0000000..f0e0601 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/Application.h @@ -0,0 +1,57 @@ +/* +* 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. +*/ + +#ifndef APPLICATION_H +#define APPLICATION_H + +#include <DeviceManager.h> +#include <vector> +#include <string> + +/** +ISampleController adds more onstart and onstop callbacks to IVisualController +*/ +class IApplicationController : public IVisualController +{ + public: + virtual void onInitialize() {} + virtual void onSampleStart() {} + virtual void onSampleStop() {} + virtual void onTerminate() {} +}; + + +/** +Main manager which runs sample. +You have to add controllers to it which will receive all the start, animate, render etc. callbacks. +*/ +class Application +{ +public: + Application(DeviceManager* pDeviceManager); + void addControllerToFront(IApplicationController* controller); + + const std::vector<IApplicationController*>& getControllers() const + { + return m_controllers; + } + + int init(); + int run(); + int free(); + +private: + DeviceManager* m_deviceManager; + std::vector<IApplicationController*> m_controllers; +// std::wstring m_sampleName; +}; + + +#endif //APPLICATION_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/DeviceManager.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/DeviceManager.cpp new file mode 100644 index 0000000..b29fb86 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/DeviceManager.cpp @@ -0,0 +1,801 @@ +// TAGRELEASE: PUBLIC + +#include "DeviceManager.h" +#include <WinUser.h> +#include <Windows.h> +#include <assert.h> +#include <sstream> +#include <algorithm> +#include <vector> + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } } +#endif + +#undef min +#undef max + +namespace +{ + bool IsNvDeviceID(UINT id) + { + return id == 0x10DE; + } + + // Find an adapter whose name contains the given string. + IDXGIAdapter* FindAdapter(const WCHAR* targetName, bool& isNv) + { + IDXGIAdapter* targetAdapter = NULL; + IDXGIFactory* IDXGIFactory_0001 = NULL; + HRESULT hres = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&IDXGIFactory_0001); + if (hres != S_OK) + { + printf("ERROR in CreateDXGIFactory, %s@%d.\nFor more info, get log from debug D3D runtime: (1) Install DX SDK, and enable Debug D3D from DX Control Panel Utility. (2) Install and start DbgView. (3) Try running the program again.\n",__FILE__,__LINE__); + return targetAdapter; + } + + // changed by Junma Lixu + std::vector<IDXGIAdapter*> adapters; + // check current adapter first. EnumAdapters could fail on some device + IDXGIAdapter* pAdapter = nullptr; + ID3D11Device* pD3dDevice = nullptr; + ID3D11DeviceContext* pD3dDeviceContext = nullptr; + DWORD createDeviceFlags = D3D11_CREATE_DEVICE_DEBUG; + D3D_FEATURE_LEVEL fl; + // This following code is the robust way to get all possible feature levels while handling DirectX 11.0 systems: + // please read https://blogs.msdn.microsoft.com/chuckw/2014/02/05/anatomy-of-direct3d-11-create-device/ + D3D_FEATURE_LEVEL lvl[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; + HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, + createDeviceFlags, lvl, _countof(lvl), + D3D11_SDK_VERSION, &pD3dDevice, &fl, &pD3dDeviceContext); + if (pD3dDevice) + { + IDXGIDevice* dxgiDevice = nullptr; + hr = pD3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice)); + if (SUCCEEDED(hr)) + { + hr = dxgiDevice->GetAdapter(&pAdapter); + if (pAdapter) + { + adapters.push_back(pAdapter); + } + SAFE_RELEASE(dxgiDevice); + } + SAFE_RELEASE(pD3dDeviceContext); + SAFE_RELEASE(pD3dDevice); + } + + // Enum Adapters + unsigned int adapterNo = 0; + while (SUCCEEDED(hres = IDXGIFactory_0001->EnumAdapters(adapterNo, (IDXGIAdapter**)&pAdapter))) + { + adapters.push_back(pAdapter); + adapterNo++; + } + if (wcslen(targetName) != 0) + { + // find the adapter with specified name + for (int i = 0; i < adapters.size(); ++i) + { + IDXGIAdapter* pAdapter = adapters[i]; + DXGI_ADAPTER_DESC aDesc; + pAdapter->GetDesc(&aDesc); + std::wstring aName = aDesc.Description; + if (aName.find(targetName) != std::string::npos) + { + targetAdapter = pAdapter; + isNv = IsNvDeviceID(aDesc.VendorId); + } + } + } + else + { + // no name specified, find one NV adapter + for (int i = 0; i < adapters.size(); ++i) + { + IDXGIAdapter* pAdapter = adapters[i]; + DXGI_ADAPTER_DESC aDesc; + pAdapter->GetDesc(&aDesc); + std::wstring aName = aDesc.Description; + if (IsNvDeviceID(aDesc.VendorId)) + { + targetAdapter = pAdapter; + isNv = true; + } + } + } + if (targetAdapter == nullptr) + targetAdapter = adapters[0]; + for (int i = 0; i < adapters.size(); ++i) + { + IDXGIAdapter* pAdapter = adapters[i]; + if (pAdapter != targetAdapter) + { + pAdapter->Release(); + } + } + + if (IDXGIFactory_0001) + IDXGIFactory_0001->Release(); + + return targetAdapter; + } + + // Adjust window rect so that it is centred on the given adapter. Clamps to fit if it's too big. + RECT MoveWindowOntoAdapter(IDXGIAdapter* targetAdapter, const RECT& rect) + { + assert(targetAdapter != NULL); + + RECT result = rect; + HRESULT hres = S_OK; + unsigned int outputNo = 0; + while (SUCCEEDED(hres)) + { + IDXGIOutput* pOutput = NULL; + hres = targetAdapter->EnumOutputs(outputNo++, &pOutput); + + if (SUCCEEDED(hres) && pOutput) + { + DXGI_OUTPUT_DESC OutputDesc; + pOutput->GetDesc( &OutputDesc ); + const RECT desktop = OutputDesc.DesktopCoordinates; + const int centreX = (int) desktop.left + (int)(desktop.right - desktop.left) / 2; + const int centreY = (int) desktop.top + (int)(desktop.bottom - desktop.top) / 2; + const int winW = rect.right - rect.left; + const int winH = rect.bottom - rect.top; + int left = centreX - winW/2; + int right = left + winW; + int top = centreY - winH/2; + int bottom = top + winH; + result.left = std::max(left, (int) desktop.left); + result.right = std::min(right, (int) desktop.right); + result.bottom = std::min(bottom, (int) desktop.bottom); + result.top = std::max(top, (int) desktop.top); + pOutput->Release(); + + // If there is more than one output, go with the first found. Multi-monitor support could go here. + break; + } + } + return result; + } +} + +HRESULT +DeviceManager::CreateWindowDeviceAndSwapChain(const DeviceCreationParameters& params) +{ + IDXGIAdapter* targetAdapter = FindAdapter(params.adapterNameSubstring, m_IsNvidia); + if (targetAdapter) + { + RECT rect = { 0, 0, params.backBufferWidth, params.backBufferHeight }; + rect = MoveWindowOntoAdapter(targetAdapter, rect); + } + else + { + return E_FAIL; + } + + HRESULT hr = E_FAIL; + + m_hWnd = params.hWnd; + + RECT clientRect; + GetClientRect(m_hWnd, &clientRect); + UINT width = clientRect.right - clientRect.left; + UINT height = clientRect.bottom - clientRect.top; + + ZeroMemory(&m_SwapChainDesc, sizeof(m_SwapChainDesc)); + m_SwapChainDesc.BufferCount = params.swapChainBufferCount; + m_SwapChainDesc.BufferDesc.Width = width; + m_SwapChainDesc.BufferDesc.Height = height; + m_SwapChainDesc.BufferDesc.Format = params.swapChainFormat; + m_SwapChainDesc.BufferDesc.RefreshRate.Numerator = params.refreshRate; + m_SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; + m_SwapChainDesc.BufferUsage = params.swapChainUsage; + m_SwapChainDesc.OutputWindow = m_hWnd; + m_SwapChainDesc.SampleDesc.Count = params.swapChainSampleCount; + m_SwapChainDesc.SampleDesc.Quality = params.swapChainSampleQuality; + m_SwapChainDesc.Windowed = !params.startFullscreen; + m_SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + // The D3D documentation says that if adapter is non-null, driver type must be unknown. Why not put + // this logic in the CreateDevice fns then?!? + const D3D_DRIVER_TYPE dType = (targetAdapter)? D3D_DRIVER_TYPE_UNKNOWN: params.driverType; + + hr = D3D11CreateDeviceAndSwapChain( + targetAdapter, // pAdapter + dType, // DriverType + NULL, // Software + params.createDeviceFlags, // Flags + ¶ms.featureLevel, // pFeatureLevels + 1, // FeatureLevels + D3D11_SDK_VERSION, // SDKVersion + &m_SwapChainDesc, // pSwapChainDesc + &m_SwapChain, // ppSwapChain + &m_Device, // ppDevice + NULL, // pFeatureLevel + &m_ImmediateContext // ppImmediateContext + ); + + if (targetAdapter) + targetAdapter->Release(); + + if(FAILED(hr)) + return hr; + + m_DepthStencilDesc.ArraySize = 1; + m_DepthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + m_DepthStencilDesc.CPUAccessFlags = 0; + m_DepthStencilDesc.Format = params.depthStencilFormat; + m_DepthStencilDesc.Width = width; + m_DepthStencilDesc.Height = height; + m_DepthStencilDesc.MipLevels = 1; + m_DepthStencilDesc.MiscFlags = 0; + m_DepthStencilDesc.SampleDesc.Count = params.swapChainSampleCount; + m_DepthStencilDesc.SampleDesc.Quality = 0; + m_DepthStencilDesc.Usage = D3D11_USAGE_DEFAULT; + + hr = CreateRenderTargetAndDepthStencil(); + + return hr; +} + +void +DeviceManager::Shutdown() +{ + if(m_SwapChain && GetWindowState() == kWindowFullscreen) + m_SwapChain->SetFullscreenState(false, NULL); + + DeviceDestroyed(); + + // changed by Junma Lixu + //SAFE_RELEASE(m_BackBufferRTV); + //SAFE_RELEASE(m_DepthStencilDSV); + //SAFE_RELEASE(m_DepthStencilBuffer); + +// g_DeviceManagerInstance = NULL; + + // changed by Junma Lixu + //SAFE_RELEASE(m_ImmediateContext); + //SAFE_RELEASE(m_SwapChain); + +#if defined(DEBUG) || defined(_DEBUG) + ID3D11Debug * d3dDebug = nullptr; + if (nullptr != m_Device) + { + ID3D11DeviceContext* pCtx; + m_Device->GetImmediateContext(&pCtx); + pCtx->ClearState(); + pCtx->Flush(); + pCtx->Release(); + if (SUCCEEDED(m_Device->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(&d3dDebug)))) + { + d3dDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL); + d3dDebug->Release(); + } + } +#endif + + // changed by Junma Lixu + //SAFE_RELEASE(m_Device); + + if(m_hWnd) + { + DestroyWindow(m_hWnd); + m_hWnd = NULL; + } +} + +HRESULT +DeviceManager::CreateRenderTargetAndDepthStencil() +{ + HRESULT hr; + + ID3D11Texture2D *backBuffer = NULL; + hr = m_SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer); + if (FAILED(hr)) + return hr; + + hr = m_Device->CreateRenderTargetView(backBuffer, NULL, &m_BackBufferRTV); + backBuffer->Release(); + if (FAILED(hr)) + return hr; + + if(m_DepthStencilDesc.Format != DXGI_FORMAT_UNKNOWN) + { + hr = m_Device->CreateTexture2D(&m_DepthStencilDesc, NULL, &m_DepthStencilBuffer); + if (FAILED(hr)) + return hr; + + hr = m_Device->CreateDepthStencilView(m_DepthStencilBuffer, NULL, &m_DepthStencilDSV); + if (FAILED(hr)) + return hr; + } + + return S_OK; +} + +#include "SimpleScene.h" +#include "RenderInterface.h" + +void +DeviceManager::MessageLoop() +{ + LARGE_INTEGER newTime; + QueryPerformanceCounter(&newTime); + + double elapsedSeconds = (m_FixedFrameInterval >= 0) + ? m_FixedFrameInterval + : (double)(newTime.QuadPart - previousTime.QuadPart) / (double)perfFreq.QuadPart; + + 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 + { + // Release CPU resources when idle + Sleep(1); + } + + { + m_vFrameTimes.push_back(elapsedSeconds); + double timeSum = 0; + for (auto it = m_vFrameTimes.begin(); it != m_vFrameTimes.end(); it++) + timeSum += *it; + + if (timeSum > m_AverageTimeUpdateInterval) + { + m_AverageFrameTime = timeSum / (double)m_vFrameTimes.size(); + m_vFrameTimes.clear(); + } + } + + previousTime = newTime; +} + +LRESULT +DeviceManager::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_DESTROY: + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SYSKEYDOWN: + if(wParam == VK_F4) + { + PostQuitMessage(0); + return 0; + } + break; + + case WM_ENTERSIZEMOVE: + m_InSizingModalLoop = true; + m_NewWindowSize.cx = m_SwapChainDesc.BufferDesc.Width; + m_NewWindowSize.cy = m_SwapChainDesc.BufferDesc.Height; + break; + + case WM_EXITSIZEMOVE: + m_InSizingModalLoop = false; + ResizeSwapChain(); + break; + + case WM_SIZE: + // Ignore the WM_SIZE event if there is no device, + // or if the window has been minimized (size == 0), + // or if it has been restored to the previous size (this part is tested inside ResizeSwapChain) + if (m_Device && (lParam != 0)) + { + m_NewWindowSize.cx = LOWORD(lParam); + m_NewWindowSize.cy = HIWORD(lParam); + + if(!m_InSizingModalLoop) + ResizeSwapChain(); + } + } + + if( uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST ) + { + // processing messages front-to-back + for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++) + { + if((*it)->IsEnabled()) + { + // for kb/mouse messages, 0 means the message has been handled + if(0 == (*it)->MsgProc(hWnd, uMsg, wParam, lParam)) + return 0; + } + } + } + + if (uMsg >= WM_KEYFIRST && uMsg <= WM_KEYLAST) + { + return 0; + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +void +DeviceManager::ResizeSwapChain() +{ + // changed by Junma Lixu + RenderPlugin* pPlugin = RenderPlugin::Instance(); + D3DHandles handles; + SetWindowDeviceAndSwapChain(pPlugin->GetDeviceHandles(handles)); + BackBufferResized(); + return; + + if (m_NewWindowSize.cx == (LONG)m_SwapChainDesc.BufferDesc.Width && + m_NewWindowSize.cy == (LONG)m_SwapChainDesc.BufferDesc.Height) + return; + + m_SwapChainDesc.BufferDesc.Width = m_NewWindowSize.cx; + m_SwapChainDesc.BufferDesc.Height = m_NewWindowSize.cy; + + ID3D11RenderTargetView *nullRTV = NULL; + m_ImmediateContext->OMSetRenderTargets(1, &nullRTV, NULL); + SAFE_RELEASE(m_BackBufferRTV); + SAFE_RELEASE(m_DepthStencilDSV); + SAFE_RELEASE(m_DepthStencilBuffer); + + if (m_SwapChain) + { + // Resize the swap chain + m_SwapChain->ResizeBuffers(m_SwapChainDesc.BufferCount, m_SwapChainDesc.BufferDesc.Width, + m_SwapChainDesc.BufferDesc.Height, m_SwapChainDesc.BufferDesc.Format, + m_SwapChainDesc.Flags); + + m_DepthStencilDesc.Width = m_NewWindowSize.cx; + m_DepthStencilDesc.Height = m_NewWindowSize.cy; + + CreateRenderTargetAndDepthStencil(); + + BackBufferResized(); + } +} + +void +DeviceManager::Render() +{ + D3D11_VIEWPORT viewport = { 0.0f, 0.0f, (float)m_SwapChainDesc.BufferDesc.Width, (float)m_SwapChainDesc.BufferDesc.Height, 0.0f, 1.0f }; + + // rendering back-to-front + for(auto it = m_vControllers.rbegin(); it != m_vControllers.rend(); it++) + { + if((*it)->IsEnabled()) + { + m_ImmediateContext->OMSetRenderTargets(1, &m_BackBufferRTV, m_DepthStencilDSV); + m_ImmediateContext->RSSetViewports(1, &viewport); + + (*it)->Render(m_Device, m_ImmediateContext, m_BackBufferRTV, m_DepthStencilDSV); + } + } + + m_ImmediateContext->OMSetRenderTargets(0, NULL, NULL); +} + +void +DeviceManager::Animate(double fElapsedTimeSeconds) +{ + // front-to-back, but the order shouldn't matter + for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++) + { + if((*it)->IsEnabled()) + { + (*it)->Animate(fElapsedTimeSeconds); + } + } +} + +void +DeviceManager::DeviceCreated() +{ + // creating resources front-to-back + for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++) + { + (*it)->DeviceCreated(m_Device); + } +} + +void +DeviceManager::DeviceDestroyed() +{ + // releasing resources back-to-front + for(auto it = m_vControllers.rbegin(); it != m_vControllers.rend(); it++) + { + (*it)->DeviceDestroyed(); + } +} + +void +DeviceManager::BackBufferResized() +{ + if(m_SwapChain == NULL) + return; + + DXGI_SURFACE_DESC backSD; + backSD.Format = m_SwapChainDesc.BufferDesc.Format; + backSD.Width = m_SwapChainDesc.BufferDesc.Width; + backSD.Height = m_SwapChainDesc.BufferDesc.Height; + backSD.SampleDesc = m_SwapChainDesc.SampleDesc; + + for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++) + { + (*it)->BackBufferResized(m_Device, &backSD); + } +} + +HRESULT +DeviceManager::ChangeBackBufferFormat(DXGI_FORMAT format, UINT sampleCount) +{ + HRESULT hr = E_FAIL; + + if((format == DXGI_FORMAT_UNKNOWN || format == m_SwapChainDesc.BufferDesc.Format) && + (sampleCount == 0 || sampleCount == m_SwapChainDesc.SampleDesc.Count)) + return S_FALSE; + + if(m_Device) + { + bool fullscreen = (GetWindowState() == kWindowFullscreen); + if(fullscreen) + m_SwapChain->SetFullscreenState(false, NULL); + + IDXGISwapChain* newSwapChain = NULL; + DXGI_SWAP_CHAIN_DESC newSwapChainDesc = m_SwapChainDesc; + + if(format != DXGI_FORMAT_UNKNOWN) + newSwapChainDesc.BufferDesc.Format = format; + if(sampleCount != 0) + newSwapChainDesc.SampleDesc.Count = sampleCount; + + IDXGIAdapter* pDXGIAdapter = GetDXGIAdapter(); + + IDXGIFactory* pDXGIFactory = NULL; + pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&pDXGIFactory)); + + hr = pDXGIFactory->CreateSwapChain(m_Device, &newSwapChainDesc, &newSwapChain); + + pDXGIFactory->Release(); + pDXGIAdapter->Release(); + + if (FAILED(hr)) + { + if(fullscreen) + m_SwapChain->SetFullscreenState(true, NULL); + + return hr; + } + + SAFE_RELEASE(m_BackBufferRTV); + SAFE_RELEASE(m_SwapChain); + SAFE_RELEASE(m_DepthStencilBuffer); + SAFE_RELEASE(m_DepthStencilDSV); + + m_SwapChain = newSwapChain; + m_SwapChainDesc = newSwapChainDesc; + + m_DepthStencilDesc.SampleDesc.Count = sampleCount; + + if(fullscreen) + m_SwapChain->SetFullscreenState(true, NULL); + + CreateRenderTargetAndDepthStencil(); + BackBufferResized(); + } + + return S_OK; +} + +void +DeviceManager::AddControllerToFront(IVisualController* pController) +{ + m_vControllers.remove(pController); + m_vControllers.push_front(pController); +} + +void +DeviceManager::AddControllerToBack(IVisualController* pController) +{ + m_vControllers.remove(pController); + m_vControllers.push_back(pController); +} + +void +DeviceManager::RemoveController(IVisualController* pController) +{ + m_vControllers.remove(pController); +} + +HRESULT +DeviceManager::ResizeWindow(int width, int height) +{ + if(m_SwapChain == NULL) + return E_FAIL; + + RECT rect; + GetWindowRect(m_hWnd, &rect); + + ShowWindow(m_hWnd, SW_RESTORE); + + if(!MoveWindow(m_hWnd, rect.left, rect.top, width, height, true)) + return E_FAIL; + + // No need to call m_SwapChain->ResizeBackBuffer because MoveWindow will send WM_SIZE, which calls that function. + + return S_OK; +} + +#define WINDOW_STYLE_NORMAL (WS_OVERLAPPEDWINDOW | WS_VISIBLE) +#define WINDOW_STYLE_FULLSCREEN (WS_POPUP | WS_SYSMENU | WS_VISIBLE) + +HRESULT +DeviceManager::EnterFullscreenMode(int width, int height) +{ + if(m_SwapChain == NULL) + return E_FAIL; + + if(GetWindowState() == kWindowFullscreen) + return S_FALSE; + + if(width <= 0 || height <= 0) + { + width = m_SwapChainDesc.BufferDesc.Width; + height = m_SwapChainDesc.BufferDesc.Height; + } + + SetWindowLong(m_hWnd, GWL_STYLE, WINDOW_STYLE_FULLSCREEN); + MoveWindow(m_hWnd, 0, 0, width, height, true); + + HRESULT hr = m_SwapChain->SetFullscreenState(true, NULL); + + if(FAILED(hr)) + { + SetWindowLong(m_hWnd, GWL_STYLE, WINDOW_STYLE_NORMAL); + return hr; + } + + UpdateWindow(m_hWnd); + m_SwapChain->GetDesc(&m_SwapChainDesc); + + return S_OK; +} + +HRESULT +DeviceManager::LeaveFullscreenMode(int windowWidth, int windowHeight) +{ + if(m_SwapChain == NULL) + return E_FAIL; + + if(GetWindowState() != kWindowFullscreen) + return S_FALSE; + + HRESULT hr = m_SwapChain->SetFullscreenState(false, NULL); + if(FAILED(hr)) return hr; + + SetWindowLong(m_hWnd, GWL_STYLE, WINDOW_STYLE_NORMAL); + + if(windowWidth <= 0 || windowHeight <= 0) + { + windowWidth = m_SwapChainDesc.BufferDesc.Width; + windowHeight = m_SwapChainDesc.BufferDesc.Height; + } + + RECT rect = { 0, 0, windowWidth, windowHeight }; + AdjustWindowRect(&rect, WINDOW_STYLE_NORMAL, FALSE); + MoveWindow(m_hWnd, 0, 0, rect.right - rect.left, rect.bottom - rect.top, true); + UpdateWindow(m_hWnd); + + m_SwapChain->GetDesc(&m_SwapChainDesc); + + return S_OK; +} + +HRESULT +DeviceManager::ToggleFullscreen() +{ + if(GetWindowState() == kWindowFullscreen) + return LeaveFullscreenMode(); + else + return EnterFullscreenMode(); +} + +DeviceManager::WindowState +DeviceManager::GetWindowState() +{ + if(m_SwapChain && !m_SwapChainDesc.Windowed) + return kWindowFullscreen; + + if(m_hWnd == INVALID_HANDLE_VALUE) + return kWindowNone; + + if(IsZoomed(m_hWnd)) + return kWindowMaximized; + + if(IsIconic(m_hWnd)) + return kWindowMinimized; + + return kWindowNormal; +} + +HRESULT +DeviceManager::GetDisplayResolution(int& width, int& height) +{ + if(m_hWnd != INVALID_HANDLE_VALUE) + { + HMONITOR monitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTOPRIMARY); + MONITORINFO info; + info.cbSize = sizeof(MONITORINFO); + + if(GetMonitorInfo(monitor, &info)) + { + width = info.rcMonitor.right - info.rcMonitor.left; + height = info.rcMonitor.bottom - info.rcMonitor.top; + return S_OK; + } + } + + return E_FAIL; +} + +IDXGIAdapter* +DeviceManager::GetDXGIAdapter() +{ + if(!m_Device) + return NULL; + + IDXGIDevice* pDXGIDevice = NULL; + m_Device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&pDXGIDevice)); + + IDXGIAdapter* pDXGIAdapter = NULL; + pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&pDXGIAdapter)); + + pDXGIDevice->Release(); + + return pDXGIAdapter; +} + +// added by Junma Lixu +void +DeviceManager::SetWindowHandle(HWND hWnd) +{ + m_hWnd = hWnd; +} + +HRESULT +DeviceManager::SetWindowDeviceAndSwapChain(D3DHandles& deviceHandles) +{ + ID3D11Device* pDevice = (ID3D11Device*)(deviceHandles.pDevice); + ID3D11DeviceContext* pImmediateContext = (ID3D11DeviceContext*)(deviceHandles.pDeviceContext); + if (pDevice == nullptr || pImmediateContext == nullptr) + { + return E_FAIL; + } + + m_Device = pDevice; + m_ImmediateContext = pImmediateContext; + m_SwapChain = deviceHandles.pDXGISwapChain; + HRESULT res0 = m_SwapChain->GetDesc(&m_SwapChainDesc); + assert(m_SwapChainDesc.OutputWindow == m_hWnd); + + m_BackBufferRTV = (ID3D11RenderTargetView*)deviceHandles.pD3D11RenderTargetView; + m_DepthStencilBuffer = (ID3D11Texture2D*)deviceHandles.pD3D11DepthBuffer; + m_DepthStencilDSV = (ID3D11DepthStencilView*)deviceHandles.pD3D11DepthStencilView; + m_DepthStencilBuffer->GetDesc(&m_DepthStencilDesc); + //m_DepthStencilDSV->GetDesc(&); + return S_OK; +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/DeviceManager.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/DeviceManager.h new file mode 100644 index 0000000..bd6f7e2 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/DeviceManager.h @@ -0,0 +1,179 @@ +// TAGRELEASE: PUBLIC + +#pragma once +#include <Windows.h> +#include <DXGI.h> +#include <D3D11.h> +#include <list> +// added by Junma Lixu +#include "RenderPlugin.h" + +struct DeviceCreationParameters +{ + bool startMaximized; + bool startFullscreen; + int backBufferWidth; + int backBufferHeight; + int refreshRate; + int swapChainBufferCount; + DXGI_FORMAT swapChainFormat; + DXGI_FORMAT depthStencilFormat; + DXGI_USAGE swapChainUsage; + int swapChainSampleCount; + int swapChainSampleQuality; + UINT createDeviceFlags; + D3D_DRIVER_TYPE driverType; + D3D_FEATURE_LEVEL featureLevel; + HWND hWnd; + + // For use in the case of multiple adapters. If this is non-null, device creation will try to match + // the given string against an adapter name. If the specified string exists as a sub-string of the + // adapter name, the device and window will be created on that adapter. Case sensitive. + const WCHAR* adapterNameSubstring; + + DeviceCreationParameters() + : startMaximized(false) + , startFullscreen(false) + , backBufferWidth(1280) + , backBufferHeight(720) + , refreshRate(0) + , swapChainBufferCount(1) + , swapChainFormat(DXGI_FORMAT_R8G8B8A8_UNORM) + , depthStencilFormat(DXGI_FORMAT_D24_UNORM_S8_UINT) + , swapChainUsage(DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT) + , swapChainSampleCount(1) + , swapChainSampleQuality(0) + , createDeviceFlags(0) + , driverType(D3D_DRIVER_TYPE_HARDWARE) + , featureLevel(D3D_FEATURE_LEVEL_11_0) + , adapterNameSubstring(L"") + , hWnd(0) + { } +}; + +#pragma warning(push) +#pragma warning(disable: 4100) // unreferenced formal parameter +class IVisualController +{ +private: + bool m_Enabled; +public: + IVisualController() : m_Enabled(true) { } + + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return 1; } + virtual void Render(ID3D11Device* pDevice, ID3D11DeviceContext* pDeviceContext, ID3D11RenderTargetView* pRTV, ID3D11DepthStencilView* pDSV) { } + virtual void Animate(double fElapsedTimeSeconds) { } + virtual HRESULT DeviceCreated(ID3D11Device* pDevice) { return S_OK; } + virtual void DeviceDestroyed() { } + virtual void BackBufferResized(ID3D11Device* pDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc) { } + + virtual void EnableController() { m_Enabled = true; } + virtual void DisableController() { m_Enabled = false; } + virtual bool IsEnabled() { return m_Enabled; } +}; +#pragma warning(pop) + +struct D3DHandles; + +class DeviceManager +{ +public: + enum WindowState + { + kWindowNone, + kWindowNormal, + kWindowMinimized, + kWindowMaximized, + kWindowFullscreen + }; + +protected: + ID3D11Device* m_Device; + ID3D11DeviceContext* m_ImmediateContext; + IDXGISwapChain* m_SwapChain; + ID3D11RenderTargetView* m_BackBufferRTV; + ID3D11Texture2D* m_DepthStencilBuffer; + ID3D11DepthStencilView* m_DepthStencilDSV; + DXGI_SWAP_CHAIN_DESC m_SwapChainDesc; + D3D11_TEXTURE2D_DESC m_DepthStencilDesc; + bool m_IsNvidia; + HWND m_hWnd; + std::list<IVisualController*> m_vControllers; + std::wstring m_WindowTitle; + double m_FixedFrameInterval; + UINT m_SyncInterval; + std::list<double> m_vFrameTimes; + double m_AverageFrameTime; + double m_AverageTimeUpdateInterval; + bool m_InSizingModalLoop; + SIZE m_NewWindowSize; + LARGE_INTEGER perfFreq, previousTime; +private: + HRESULT CreateRenderTargetAndDepthStencil(); + void ResizeSwapChain(); +public: + + DeviceManager() + : m_Device(NULL) + , m_ImmediateContext(NULL) + , m_SwapChain(NULL) + , m_BackBufferRTV(NULL) + , m_DepthStencilBuffer(NULL) + , m_DepthStencilDSV(NULL) + , m_IsNvidia(false) + , m_hWnd(NULL) + , m_WindowTitle(L"") + , m_FixedFrameInterval(-1) + , m_SyncInterval(0) + , m_AverageFrameTime(0) + , m_AverageTimeUpdateInterval(0.5) + , m_InSizingModalLoop(false) + { + QueryPerformanceFrequency(&perfFreq); + QueryPerformanceCounter(&previousTime); + } + + virtual ~DeviceManager() + { Shutdown(); } + + virtual HRESULT CreateWindowDeviceAndSwapChain(const DeviceCreationParameters& params); + virtual HRESULT ChangeBackBufferFormat(DXGI_FORMAT format, UINT sampleCount); + virtual HRESULT ResizeWindow(int width, int height); + virtual HRESULT EnterFullscreenMode(int width = 0, int height = 0); + virtual HRESULT LeaveFullscreenMode(int windowWidth = 0, int windowHeight = 0); + virtual HRESULT ToggleFullscreen(); + + virtual void Shutdown(); + virtual void MessageLoop(); + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual void Render(); + virtual void Animate(double fElapsedTimeSeconds); + virtual void DeviceCreated(); + virtual void DeviceDestroyed(); + virtual void BackBufferResized(); + + void AddControllerToFront(IVisualController* pController); + void AddControllerToBack(IVisualController* pController); + void RemoveController(IVisualController* pController); + + void SetFixedFrameInterval(double seconds) { m_FixedFrameInterval = seconds; } + void DisableFixedFrameInterval() { m_FixedFrameInterval = -1; } + + bool IsNvidia() const { return m_IsNvidia; } + HWND GetHWND() { return m_hWnd; } + ID3D11Device* GetDevice() { return m_Device; } + WindowState GetWindowState(); + bool GetVsyncEnabled() { return m_SyncInterval > 0; } + void SetVsyncEnabled(bool enabled) { m_SyncInterval = enabled ? 1 : 0; } + HRESULT GetDisplayResolution(int& width, int& height); + IDXGIAdapter* GetDXGIAdapter(); + double GetAverageFrameTime() { return m_AverageFrameTime; } + void SetAverageTimeUpdateInterval(double value) { m_AverageTimeUpdateInterval = value; } + + // added by Junma Lixu + void SetWindowHandle(HWND hWnd); + virtual HRESULT SetWindowDeviceAndSwapChain(D3DHandles& pDeviceHandles); +}; + + +DeviceManager* GetDeviceManager(); diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.cpp new file mode 100644 index 0000000..163b3b4 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.cpp @@ -0,0 +1,63 @@ +/* +* 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. +*/ + +#include "SampleController.h" +#include "SceneController.h" +#include "CommonUIController.h" +#include "BlastController.h" +#include "PhysXController.h" + +#include "imgui.h" + +SampleController::SampleController() +{ +} + +SampleController::~SampleController() +{ +} + +void SampleController::onSampleStart() +{ + // start with GPU physics by default + setUseGPUPhysics(true); +} + + +void SampleController::setUseGPUPhysics(bool useGPUPhysics) +{ + if (!getPhysXController().getGPUPhysicsAvailable()) + { + useGPUPhysics = false; + } + + if (getPhysXController().getUseGPUPhysics() == useGPUPhysics) + { + return; + } + + int assetNum = getSceneController().releaseAll(); + + getPhysXController().setUseGPUPhysics(useGPUPhysics); + getBlastController().reinitialize(); + + getSceneController().spawnAsset(assetNum); +} + + +void SampleController::drawPhysXGpuUI() +{ + // GPU Physics + bool useGPU = getPhysXController().getUseGPUPhysics(); + if (ImGui::Checkbox("Use GPU Physics", &useGPU)) + { + getCommonUIController().addDelayedCall([=]() { setUseGPUPhysics(useGPU); }, "Loading..."); + } +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.h new file mode 100644 index 0000000..a52c2fe --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleController.h @@ -0,0 +1,57 @@ +/* +* 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. +*/ + +#ifndef SAMPLE_CONTROLLER_H +#define SAMPLE_CONTROLLER_H + +#include "SampleManager.h" + +class SampleController : public ISampleController +{ +public: + SampleController(); + virtual ~SampleController(); + + virtual void onSampleStart(); + void drawPhysXGpuUI(); + +private: + SampleController& operator= (SampleController&); + + + //////// used controllers //////// + + PhysXController& getPhysXController() const + { + return getManager()->getPhysXController(); + } + + BlastController& getBlastController() const + { + return getManager()->getBlastController(); + } + + SceneController& getSceneController() const + { + return getManager()->getSceneController(); + } + + CommonUIController& getCommonUIController() const + { + return getManager()->getCommonUIController(); + } + + + //////// private methods //////// + + void setUseGPUPhysics(bool useGPUPhysics); +}; + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.cpp new file mode 100644 index 0000000..2e13687 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.cpp @@ -0,0 +1,1267 @@ +/* +* 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. +*/ +#include "NvBlastExtAuthoringTypes.h" +#include "NvBlastExtAuthoringFractureTool.h" +#include "NvBlastExtAuthoringBondGenerator.h" +#include "NvBlastIndexFns.h" + +#include "SampleManager.h" + +#include "Utils.h" + +#include "Renderer.h" +#include "PhysXController.h" +#include "BlastController.h" +#include "CommonUIController.h" +#include "DamageToolController.h" +#include "SelectionToolController.h" +#include "GizmoToolController.h" +#include "EditionToolController.h" +#include "SceneController.h" +#include "SampleController.h" + +#include "tclap/CmdLine.h" +#include "PxPhysics.h" +#include "PsFileBuffer.h" +#include "NvBlast.h" +#include "NvBlastExtAuthoringCollisionBuilder.h" +#include "NvBlastExtPxAsset.h" +#include "BlastFractureTool.h" +#include <set> +#include "MaterialLibraryPanel.h" +#include "MaterialAssignmentsPanel.h" + +using namespace physx; + +physx::PxFoundation* foundation = nullptr; +physx::PxPhysics* physics = nullptr; +physx::PxCooking* cooking = nullptr; +Nv::Blast::ExtPxManager* physicsManager = nullptr; +SampleManager* sSampleManager = nullptr; + +class SimpleRandomGenerator : public RandomGeneratorBase +{ +public: + SimpleRandomGenerator() { + remember = false; + }; + + virtual float getRandomValue() + { + float r = (float)rand(); + r = r / RAND_MAX; + return r; + } + + virtual float getExponential(float lambda) + { + return -1.0f / lambda * log(1 - getRandomValue()); + } + + virtual void seed(int32_t seed) + { + srand(seed); + } + + virtual ~SimpleRandomGenerator() {}; + +private: + bool remember; +}; +static SimpleRandomGenerator sRandomGenerator; + +void loggingCallback(int type, const char* msg, const char* file, int line) +{ + (void)type; + + std::cout << msg << " FILE:" << file << " Line: " << line << "\n"; +} + +void buildPxChunks(const std::vector<std::vector<Triangle>>& chunkGeometry, std::vector<ExtPxAssetDesc::ChunkDesc>& pxChunks, + std::vector<ExtPxAssetDesc::SubchunkDesc>& pxSubchunks) +{ + ConvexMeshBuilder collisionBuilder(cooking, &physics->getPhysicsInsertionCallback()); + + pxChunks.resize(chunkGeometry.size()); + pxSubchunks.resize(chunkGeometry.size()); + + for (uint32_t i = 0; i < chunkGeometry.size(); ++i) + { + std::vector<physx::PxVec3> vertices; + for (uint32_t p = 0; p < chunkGeometry[i].size(); ++p) + { + vertices.push_back(chunkGeometry[i][p].a.p); + vertices.push_back(chunkGeometry[i][p].b.p); + vertices.push_back(chunkGeometry[i][p].c.p); + } + pxSubchunks[i].transform = physx::PxTransform(physx::PxIdentity); + pxSubchunks[i].geometry = physx::PxConvexMeshGeometry(collisionBuilder.buildConvexMesh(vertices)); + pxChunks[i].isStatic = false; + pxChunks[i].subchunkCount = 1; + pxChunks[i].subchunks = &pxSubchunks[i]; + } + + // only effect when chunk is support + pxChunks[0].isStatic = true; +} + +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); + + uint32_t submeshCount = 2; + // export materials (mtl file) + { + std::ostringstream mtlFilePath; + mtlFilePath << path << name << ".mtl"; + FILE* f = fopen(mtlFilePath.str().c_str(), "w"); + if (!f) + return; + + for (uint32_t submeshIndex = 0; submeshIndex < submeshCount; ++submeshIndex) + { + fprintf(f, "newmtl %s\n", materialNames[submeshIndex].c_str()); + fprintf(f, "\tmap_Kd %s\n", materialPaths[submeshIndex].c_str()); + fprintf(f, "\n"); + } + + fclose(f); + } + + { + std::ostringstream objFilePath; + objFilePath << path << name << ".obj"; + FILE* outStream = fopen(objFilePath.str().c_str(), "w"); + + fprintf(outStream, "mtllib %s.mtl\n", name.c_str()); + fprintf(outStream, "o frac \n"); + + + for (uint32_t vc = 0; vc < chunksGeometry.size(); ++vc) + { + std::vector<Triangle>& chunk = chunksGeometry[vc]; + for (uint32_t i = 0; i < chunk.size(); ++i) + { + fprintf(outStream, "v %lf %lf %lf\n", chunk[i].a.p.x, chunk[i].a.p.y, chunk[i].a.p.z); + fprintf(outStream, "v %lf %lf %lf\n", chunk[i].b.p.x, chunk[i].b.p.y, chunk[i].b.p.z); + fprintf(outStream, "v %lf %lf %lf\n", chunk[i].c.p.x, chunk[i].c.p.y, chunk[i].c.p.z); + } + + for (uint32_t i = 0; i < chunk.size(); ++i) + { + fprintf(outStream, "vt %lf %lf \n", chunk[i].a.uv[0].x, chunk[i].a.uv[0].y); + fprintf(outStream, "vt %lf %lf \n", chunk[i].b.uv[0].x, chunk[i].b.uv[0].y); + fprintf(outStream, "vt %lf %lf \n", chunk[i].c.uv[0].x, chunk[i].c.uv[0].y); + } + + for (uint32_t i = 0; i < chunk.size(); ++i) + { + fprintf(outStream, "vn %lf %lf %lf\n", chunk[i].a.n.x, chunk[i].a.n.y, chunk[i].a.n.z); + fprintf(outStream, "vn %lf %lf %lf\n", chunk[i].b.n.x, chunk[i].b.n.y, chunk[i].b.n.z); + fprintf(outStream, "vn %lf %lf %lf\n", chunk[i].c.n.x, chunk[i].c.n.y, chunk[i].c.n.z); + } + } + int indx = 1; + for (uint32_t vc = 0; vc < chunksGeometry.size(); ++vc) + { + fprintf(outStream, "g %d_%d \n", vc, 0); + fprintf(outStream, "usemtl %s\n", materialNames[0].c_str()); + int totalSize = chunksGeometry[vc].size(); + std::vector<int> internalSurfaces; + for (uint32_t i = 0; i < totalSize; ++i) + { + if (chunksGeometry[vc][i].userInfo != 0) + { + internalSurfaces.push_back(indx++); + internalSurfaces.push_back(indx++); + internalSurfaces.push_back(indx++); + continue; + } + fprintf(outStream, "f %d/%d/%d ", indx, indx, indx); + indx++; + fprintf(outStream, "%d/%d/%d ", indx, indx, indx); + indx++; + fprintf(outStream, "%d/%d/%d \n", indx, indx, indx); + indx++; + } + int internalSize = internalSurfaces.size(); + if (internalSize > 0) + { + fprintf(outStream, "g %d_%d \n", vc, 1); + fprintf(outStream, "usemtl %s\n", materialNames[1].c_str()); + int isIndex; + for (uint32_t is = 0; is < internalSize;) + { + isIndex = internalSurfaces[is++]; + fprintf(outStream, "f %d/%d/%d ", isIndex, isIndex, isIndex); + isIndex = internalSurfaces[is++]; + fprintf(outStream, "%d/%d/%d ", isIndex, isIndex, isIndex); + isIndex = internalSurfaces[is++]; + fprintf(outStream, "%d/%d/%d \n", isIndex, isIndex, isIndex); + } + } + } + fclose(outStream); + } +} + +void FractureExecutor::setSourceMesh(Nv::Blast::Mesh* mesh) +{ + assert(m_fractureTool); + m_sourMesh = mesh; + m_fractureTool->setSourceMesh(mesh); +} + +void FractureExecutor::setSourceAsset(const BlastAsset* blastAsset) +{ + assert(m_fractureTool); + m_fractureTool->setSourceAsset(blastAsset); + m_sourMesh = nullptr; +} + +VoronoiFractureExecutor::VoronoiFractureExecutor() +: m_cellsCount(5) +{ + 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) + { + mesh = m_sourMesh; + } + else + { + 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(); + + return sSampleManager->postProcessCurrentAsset(); +} + +SliceFractureExecutor::SliceFractureExecutor() +: m_config(new Nv::Blast::SlicingConfiguration()) +{ + 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) +{ + m_fractureTool->applyNoise(amplitude, frequency, octaves, falloff, relaxIterations, relaxFactor, seed); +} + +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; +} + +bool SliceFractureExecutor::execute() +{ + m_fractureTool->slicing(m_chunkId, *m_config, false, (m_randomGenerator == nullptr ? &sRandomGenerator : m_randomGenerator)); + m_fractureTool->finalizeFracturing(); + return sSampleManager->postProcessCurrentAsset(); +} + +static VoronoiFractureExecutor sVoronoiFracture; + +SampleManager* SampleManager::ins() +{ + return sSampleManager; +} + +SampleManager::SampleManager(DeviceManager* pDeviceManager) +{ + sSampleManager = this; + m_bNeedConfig = false; + m_bNeedRefreshTree = false; + + m_renderer = new Renderer(); + m_physXController = new PhysXController(ExtImpactDamageManager::FilterShader); + m_blastController = new BlastController(); + m_sceneController = new SceneController(); + m_damageToolController = new DamageToolController(); + m_selectionToolController = new SelectionToolController(); + m_gizmoToolController = new GizmoToolController(); + m_editionToolController = new EditionToolController(); + m_sampleController = new SampleController(); +// m_commonUIController = new CommonUIController(); + + m_pApplication = new Application(pDeviceManager); + + Application& app = *m_pApplication; + + app.addControllerToFront(m_renderer); + app.addControllerToFront(m_physXController); + app.addControllerToFront(m_blastController); + app.addControllerToFront(m_sceneController); + app.addControllerToFront(m_damageToolController); + app.addControllerToFront(m_selectionToolController); + app.addControllerToFront(m_gizmoToolController); + app.addControllerToFront(m_editionToolController); + app.addControllerToFront(m_sampleController); +// app.addControllerToFront(m_commonUIController); + + for (IApplicationController* c : app.getControllers()) + { + (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_fractureExecutor = nullptr; + + setFractureExecutor(&sVoronoiFracture); + + m_pCurBlastAsset = nullptr; + m_nCurFamilyIndex = -1; +} + +SampleManager::~SampleManager() +{ + delete m_renderer; + delete m_physXController; + delete m_blastController; + delete m_sceneController; + delete m_damageToolController; + delete m_selectionToolController; + delete m_gizmoToolController; + delete m_editionToolController; + delete m_sampleController; + delete m_fTool; +// delete m_commonUIController; +} + +int SampleManager::init() +{ + Application& app = *m_pApplication; + app.init(); + + m_ToolType = BTT_Num; + setBlastToolType(BTT_Edit); + + return 0; +} + +int SampleManager::run() +{ + if (m_bNeedConfig) + { + getSceneController().onSampleStop(); + getSceneController().onSampleStart(); + + _setSourceAsset(); + + m_bNeedConfig = false; + m_bNeedRefreshTree = true; + } + + Application& app = *m_pApplication; + app.run(); + + 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()); + } + + removeRenderMaterial(materialName); + } + m_NeedDeleteRenderMaterials.clear(); + + MaterialLibraryPanel::ins()->deleteMaterials(); + + return 0; +} + +int SampleManager::free() +{ + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator it; + for (it = m_AssetFamiliesMap.begin(); it != m_AssetFamiliesMap.end(); it++) + { + std::vector<BlastFamily*>& fs = it->second; + fs.clear(); + } + m_AssetFamiliesMap.clear(); + m_AssetDescMap.clear(); + + 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++) + { + AssetList::ModelAsset& m = *it; + + sprintf(filename, "../../../../bin/resources/models/%s.bpxa", m.id.c_str()); + DeleteFileA(filename); + + sprintf(filename, "../../../../bin/resources/models/%s.mtl", m.id.c_str()); + DeleteFileA(filename); + + sprintf(filename, "../../../../bin/resources/models/%s.obj", m.id.c_str()); + DeleteFileA(filename); + } + */ + + return 0; +} + +void SampleManager::addModelAsset(std::string file, bool isSkinned, physx::PxTransform transform, bool clear) +{ + if (clear) + { + m_config.additionalAssetList.models.clear(); + } + else + { + 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; + } + } + } + + AssetList::ModelAsset modelAsset; + modelAsset.name = file; + modelAsset.id = file; + modelAsset.file = file; + modelAsset.isSkinned = isSkinned; + modelAsset.transform = transform; + + m_config.additionalAssetList.models.push_back(modelAsset); + + m_bNeedConfig = true; +} + +bool SampleManager::createAsset( + 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) +{ + PhysXController& pc = getPhysXController(); + BlastController& bc = getBlastController(); + + physics = &pc.getPhysics(); + foundation = &physics->getFoundation(); + cooking = &pc.getCooking(); + physicsManager = &bc.getExtPxManager(); + + 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); + + m_fractureExecutor->setSourceMesh(sourceMesh); + if (fracture) + { + m_fractureExecutor->execute(); + m_fractureExecutor = &sVoronoiFracture; + } + else + { + m_fTool->finalizeFracturing(); + } + + std::string outDir = "../../../../bin/resources/models/"; + _createAsset(assetName, outDir, meshes); + + delete sourceMesh; + sourceMesh = 0; + + m_bNeedConfig = true; + + return true; +} + +bool SampleManager::createAsset( + const std::string& assetName, + const std::vector<Nv::Blast::Mesh* >& meshes, + bool fracture) +{ + PhysXController& pc = getPhysXController(); + BlastController& bc = getBlastController(); + + physics = &pc.getPhysics(); + foundation = &physics->getFoundation(); + cooking = &pc.getCooking(); + physicsManager = &bc.getExtPxManager(); + + if (meshes.size() == 1) + { + Nv::Blast::Mesh* sourceMesh = meshes[0]; + m_fractureExecutor->setSourceMesh(sourceMesh); + if (fracture) + { + m_fractureExecutor->execute(); + m_fractureExecutor = &sVoronoiFracture; + } + else + { + m_fTool->finalizeFracturing(); + } + } + + std::string outDir = "../../../../bin/resources/models/"; + _createAsset(assetName, outDir, meshes); + + m_bNeedConfig = true; + + return true; +} + +bool SampleManager::saveAsset() +{ + if (m_pCurBlastAsset == nullptr) + { + return false; + } + + AssetList::ModelAsset& desc = m_AssetDescMap[m_pCurBlastAsset]; + + PhysXController& pc = getPhysXController(); + BlastController& bc = getBlastController(); + physics = &pc.getPhysics(); + foundation = &physics->getFoundation(); + cooking = &pc.getCooking(); + physicsManager = &bc.getExtPxManager(); + + std::string outDir = "../../../../bin/resources/models/"; + + std::ostringstream outBlastFilePathStream; + outBlastFilePathStream << outDir << desc.name << ".bpxa"; + std::string outBlastFilePath = outBlastFilePathStream.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); + 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; + } + + 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; + } + + std::vector<uint32_t> chunkReorderInvMap; + { + 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())); + } + + std::vector<std::vector<Triangle>> resultGeometry(chunkMeshes.size()); + for (uint32_t i = 0; i < chunkMeshes.size(); ++i) + { + uint32_t chunkIndex = chunkReorderInvMap[i]; + resultGeometry[chunkIndex] = chunkMeshes[i]; + } + + saveFractureToObj(resultGeometry, desc.name, outDir); + + std::string saveInfo = outBlastFilePath + " saved successfully\n"; + output(saveInfo.c_str()); + + return true; +} + +bool SampleManager::fractureAsset(std::string& assetName, const BlastAsset* pBlastAsset, int32_t chunkId) +{ + PhysXController& pc = getPhysXController(); + BlastController& bc = getBlastController(); + + physics = &pc.getPhysics(); + 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 = "../../../../bin/resources/models/"; + + std::ostringstream outBlastFilePathStream; + outBlastFilePathStream << outDir << assetName << ".bpxa"; + std::string outBlastFilePath = outBlastFilePathStream.str(); + + std::vector<NvBlastChunkDesc> chunkDesc; + std::vector<NvBlastBondDesc> bondDescs; + std::vector<std::vector<Triangle> > chunkMeshes; + std::vector<bool> isSupport; + + size_t nChunkListSize = m_fTool->getChunkList().size(); + 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; + } + + BlastBondGenerator bondGenerator(cooking, &physics->getPhysicsInsertionCallback()); + + BondGenerationConfig cnf; + cnf.bondMode = BondGenerationConfig::AVERAGE; + 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; + } + + // order chunks, build map + std::vector<uint32_t> chunkReorderInvMap; + { + 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())); + } + + // get result geometry + std::vector<std::vector<Triangle>> resultGeometry(chunkMeshes.size()); + for (uint32_t i = 0; i < chunkMeshes.size(); ++i) + { + uint32_t chunkIndex = chunkReorderInvMap[i]; + resultGeometry[chunkIndex] = chunkMeshes[i]; + } + + // prepare physics data (convexes) + std::vector<ExtPxAssetDesc::ChunkDesc> pxChunks(chunkCount); + std::vector<ExtPxAssetDesc::SubchunkDesc> pxSubchunks; + buildPxChunks(resultGeometry, pxChunks, pxSubchunks); + + // 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, bc.getTkFramework()); + 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(); + asset->release(); + + saveFractureToObj(resultGeometry, assetName, outDir); + + m_bNeedConfig = true; + + return true; +} + +bool SampleManager::postProcessCurrentAsset() +{ + std::vector<AssetList::ModelAsset>& models = m_config.additionalAssetList.models; + if (models.size() < 0) + { + return true; + } + + std::string assetName = models.at(models.size() - 1).file; + std::string outDir = "../../../../bin/resources/models/"; + std::vector<Nv::Blast::Mesh* > meshes; + _createAsset(assetName, outDir, meshes); + + m_bNeedConfig = true; + + return true; +} + +std::vector<uint32_t> SampleManager::getCurrentSelectedChunks() +{ + std::vector<uint32_t> selectedChunks; + std::vector<BlastFamilyPtr>& spFamilies = m_blastController->getFamilies(); + if (spFamilies.size() > 0) + { + return spFamilies.back()->getSelectedChunks(); + } + return selectedChunks; +} + +std::map<BlastAsset*, std::vector<uint32_t>> SampleManager::getSelectedChunks() +{ + std::map<BlastAsset*, std::vector<uint32_t>> selectedChunks; + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itrBlast = m_AssetFamiliesMap.begin(); + for (; itrBlast != m_AssetFamiliesMap.end(); ++itrBlast) + { + std::set<uint32_t> assetChunks; + std::vector<BlastFamily*>& families = itrBlast->second; + std::vector<BlastFamily*>::iterator itrFamily = families.begin(); + for (; itrFamily != families.end(); ++itrFamily) + { + std::vector<uint32_t> familyChunks = (*itrFamily)->getSelectedChunks(); + for (std::vector<uint32_t>::iterator itrChunk = familyChunks.begin(); itrChunk != familyChunks.end(); ++itrChunk) + { + assetChunks.insert(*itrChunk); + } + } + + if (assetChunks.size() == 0) + continue; + + std::vector<uint32_t> vecAssetChunks; + for (std::set<uint32_t>::iterator itrChunk = assetChunks.begin(); itrChunk != assetChunks.end(); ++itrChunk) + { + vecAssetChunks.push_back(*itrChunk); + } + + selectedChunks.insert(std::make_pair(itrBlast->first, vecAssetChunks)); + } + + return selectedChunks; +} + +void SampleManager::clearChunksSelected() +{ + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itr = m_AssetFamiliesMap.begin(); + for (; itr != m_AssetFamiliesMap.end(); ++itr) + { + BlastAsset* pBlastAsset = itr->first; + std::vector<BlastFamily*>& fs = itr->second; + + for (BlastFamily* f : fs) + { + f->clearChunksSelected(); + } + } +} + +void SampleManager::setChunkSelected(std::vector<uint32_t> depths, bool selected) +{ + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itrBlast = m_AssetFamiliesMap.begin(); + for (; itrBlast != m_AssetFamiliesMap.end(); ++itrBlast) + { + std::vector<BlastFamily*>& families = itrBlast->second; + std::vector<BlastFamily*>::iterator itrFamily = families.begin(); + for (; itrFamily != families.end(); ++itrFamily) + { + (*itrFamily)->setChunkSelected(depths, selected); + } + } +} + +void SampleManager::setChunkVisible(std::vector<uint32_t> depths, bool bVisible) +{ + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itrBlast = m_AssetFamiliesMap.begin(); + for (; itrBlast != m_AssetFamiliesMap.end(); ++itrBlast) + { + std::vector<BlastFamily*>& families = itrBlast->second; + std::vector<BlastFamily*>::iterator itrFamily = families.begin(); + for (; itrFamily != families.end(); ++itrFamily) + { + (*itrFamily)->setChunkVisible(depths, bVisible); + } + } +} + +void SampleManager::setFractureExecutor(FractureExecutor* executor) +{ + m_fractureExecutor = executor; + if (executor) + { + executor->m_fractureTool = m_fTool; + if (executor->m_randomGenerator == nullptr) + executor->m_randomGenerator = &sRandomGenerator; + } +} + +void SampleManager::setBlastToolType(BlastToolType type) +{ + if (m_ToolType == type) + { + getPhysXController().setPaused(type != BTT_Damage); + return; + } + + // 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) + { + needClear = false; + } + if (needClear) + { + getSelectionToolController().clearSelect(); + getGizmoToolController().resetPos(); + } + + getDamageToolController().getPickPointer()->setHidden(type != BTT_Damage); + getGizmoToolController().showAxisRenderables(switchToGizmo); + getPhysXController().setPaused(type != BTT_Damage); + + getDamageToolController().DisableController(); + getSelectionToolController().DisableController(); + getGizmoToolController().DisableController(); + getEditionToolController().DisableController(); + + switch (type) + { + case BTT_Damage: + { + getDamageToolController().EnableController(); + } + break; + case BTT_Drag: + { + getDamageToolController().EnableController(); + } + break; + case BTT_Select: + { + getSelectionToolController().EnableController(); + } + break; + case BTT_Translate: + { + getGizmoToolController().EnableController(); + getGizmoToolController().setGizmoToolMode(GTM_Translate); + } + break; + case BTT_Scale: + { + getGizmoToolController().EnableController(); + getGizmoToolController().setGizmoToolMode(GTM_Scale); + } + break; + case BTT_Rotation: + { + getGizmoToolController().EnableController(); + getGizmoToolController().setGizmoToolMode(GTM_Rotation); + } + break; + case BTT_Edit: + { + getEditionToolController().EnableController(); + } + break; + default: + break; + } + + m_ToolType = type; +} + +#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() +{ + getSceneController().ClearScene(); + m_config.sampleName.clear(); + m_config.assetsFile.clear(); + //m_config.additionalResourcesDir.clear(); + m_config.additionalAssetList.models.clear(); + m_config.additionalAssetList.composites.clear(); + m_config.additionalAssetList.boxes.clear(); + + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator it; + for (it = m_AssetFamiliesMap.begin(); it != m_AssetFamiliesMap.end(); it++) + { + std::vector<BlastFamily*>& fs = it->second; + fs.clear(); + } + m_AssetFamiliesMap.clear(); + m_AssetDescMap.clear(); +} + +bool SampleManager::_createAsset( + const std::string& assetName, + const std::string& outDir, + const std::vector<Nv::Blast::Mesh* >& meshes) +{ + PhysXController& pc = getPhysXController(); + BlastController& bc = getBlastController(); + + physics = &pc.getPhysics(); + foundation = &physics->getFoundation(); + cooking = &pc.getCooking(); + physicsManager = &bc.getExtPxManager(); + TkFramework& tk = bc.getTkFramework(); + + std::ostringstream outBlastFilePathStream; + outBlastFilePathStream << outDir << assetName << ".bpxa"; + std::string outBlastFilePath = outBlastFilePathStream.str(); + + std::vector<NvBlastChunkDesc> chunkDesc; + std::vector<NvBlastBondDesc> bondDescs; + std::vector<std::vector<Triangle> > chunkMeshes; + std::vector<bool> isSupport; + + if (meshes.size() <= 1) + { + size_t nChunkListSize = m_fTool->getChunkList().size(); + 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; + } + } + // 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. + else + { + chunkMeshes.resize(meshes.size()); + std::vector<PxVec3> chunkCentroids(meshes.size(), PxVec3(0, 0, 0)); + + for (uint32_t i = 0; i < meshes.size(); ++i) + { + std::vector<Triangle>& chunk = chunkMeshes[i]; + + Vertex* vbf = meshes[i]->getVertices(); + Edge* ebf = meshes[i]->getEdges(); + + for (uint32_t fc = 0; fc < meshes[i]->getFacetCount(); ++fc) + { + 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; + } + + chunkCentroids[i] *= 1.0f / (3 * meshes[i]->getFacetCount()); + } + + isSupport.resize(chunkMeshes.size()); + chunkDesc.resize(chunkMeshes.size()); + isSupport[0] = false; + + 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; + + for (uint32_t i = 1; i < chunkDesc.size(); ++i) + { + 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; + } + } + + BlastBondGenerator bondGenerator(cooking, &physics->getPhysicsInsertionCallback()); + + BondGenerationConfig cnf; + cnf.bondMode = BondGenerationConfig::AVERAGE; + + if (meshes.size() > 1) + { + bondGenerator.bondsFromPrefractured(chunkMeshes, isSupport, bondDescs, cnf); + } + else + { + 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; + } + + // order chunks, build map + std::vector<uint32_t> chunkReorderInvMap; + { + 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())); + } + + // get result geometry + std::vector<std::vector<Triangle>> resultGeometry(chunkMeshes.size()); + for (uint32_t i = 0; i < chunkMeshes.size(); ++i) + { + uint32_t chunkIndex = chunkReorderInvMap[i]; + resultGeometry[chunkIndex] = chunkMeshes[i]; + } + + // prepare physics data (convexes) + std::vector<ExtPxAssetDesc::ChunkDesc> pxChunks(chunkCount); + std::vector<ExtPxAssetDesc::SubchunkDesc> pxSubchunks; + buildPxChunks(resultGeometry, pxChunks, pxSubchunks); + + // 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) + { + return false; + } + + physx::PsFileBuffer fileBuf(outBlastFilePath.c_str(), physx::PxFileBuf::OPEN_WRITE_ONLY); + if (!asset->serialize(fileBuf, *cooking)) + { + return false; + } + fileBuf.close(); + asset->release(); + + saveFractureToObj(resultGeometry, assetName, outDir); + + m_bNeedConfig = true; + + return true; +} + +void SampleManager::_setSourceAsset() +{ + std::vector<BlastFamilyPtr>& families = m_blastController->getFamilies(); + if (families.size() > 0) + { + BlastFamilyPtr spLastFamily = families.back(); + + m_fTool->setSourceAsset(&(spLastFamily->getBlastAsset())); + } +} + +void SampleManager::addRenderMaterial(RenderMaterial* pRenderMaterial) +{ + if (pRenderMaterial == nullptr) + { + return; + } + + std::string materialName = pRenderMaterial->getMaterialName(); + if (materialName.empty()) + { + return; + } + + m_RenderMaterialMap[materialName] = pRenderMaterial; + + std::string textureFileName = pRenderMaterial->getTextureFileName(); + MaterialLibraryPanel::ins()->addMaterial(materialName, textureFileName); +} + +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_RenderMaterialMap.erase(it); + MaterialLibraryPanel::ins()->removeMaterial(name); + } +} + +void SampleManager::deleteRenderMaterial(std::string name) +{ + if (name.empty()) + { + return; + } + + m_NeedDeleteRenderMaterials.push_back(name); +} + +void SampleManager::renameRenderMaterial(std::string oldName, std::string newName) +{ + 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::getCurrentSelectedInstance(BlastAsset** ppBlastAsset, int& index) +{ + *ppBlastAsset = m_pCurBlastAsset; + index = m_nCurFamilyIndex; +} + +void SampleManager::setCurrentSelectedInstance(BlastAsset* pBlastAsset, int index) +{ + m_pCurBlastAsset = pBlastAsset; + m_nCurFamilyIndex = index; + + MaterialAssignmentsPanel::ins()->updateValues(); +} + +void SampleManager::getMaterialForCurrentFamily(RenderMaterial** ppRenderMaterial, bool externalSurface) +{ + if (m_pCurBlastAsset == nullptr || m_nCurFamilyIndex < 0) + { + return; + } + + std::vector<BlastFamily*>& fs = m_AssetFamiliesMap[m_pCurBlastAsset]; + int fsSize = fs.size(); + if (fsSize == 0 || fsSize < m_nCurFamilyIndex) + { + return; + } + + BlastFamily* pBlastFamily = fs[m_nCurFamilyIndex]; + pBlastFamily->getMaterial(ppRenderMaterial, externalSurface); +} + +void SampleManager::setMaterialForCurrentFamily(RenderMaterial* pRenderMaterial, bool externalSurface) +{ + if (m_pCurBlastAsset == nullptr || m_nCurFamilyIndex < 0) + { + return; + } + + std::vector<BlastFamily*>& fs = m_AssetFamiliesMap[m_pCurBlastAsset]; + int fsSize = fs.size(); + if (fsSize == 0 || fsSize < m_nCurFamilyIndex) + { + return; + } + + BlastFamily* pBlastFamily = fs[m_nCurFamilyIndex]; + pBlastFamily->setMaterial(pRenderMaterial, externalSurface); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.h new file mode 100644 index 0000000..e0b0ac9 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/core/SampleManager.h @@ -0,0 +1,302 @@ +/* +* 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. +*/ + +#ifndef SAMPLE_MANAGER_H +#define SAMPLE_MANAGER_H + +#include "Application.h" +#include "Sample.h" +#include <map> + +class SampleManager; +class BlastFractureTool; +class BlastAsset; +class BlastFamily; +class RenderMaterial; +namespace Nv +{ +namespace Blast +{ + class Mesh; + class RandomGeneratorBase; + class VoronoiSitesGenerator; + struct SlicingConfiguration; +} +} + +class ISampleController : public IApplicationController +{ +public: + + void setManager(SampleManager* manager) + { + m_manager = manager; + } +protected: + + SampleManager* getManager() const + { + return m_manager; + } + +private: + SampleManager* m_manager; +}; + +class FractureExecutor +{ + friend class SampleManager; +public: + FractureExecutor() + : m_fractureTool(0) + , m_chunkId(-1) + , m_randomGenerator(nullptr) + , m_sourMesh(nullptr) + { + } + + virtual bool execute() = 0; + void setSourceMesh(Nv::Blast::Mesh* mesh); + void setSourceAsset(const BlastAsset* blastAsset); + void setTargetChunk(uint32_t chunkId) { m_chunkId = chunkId; } + void setRandomGenerator(Nv::Blast::RandomGeneratorBase* randomGenerator) { m_randomGenerator = randomGenerator; } +protected: + BlastFractureTool* m_fractureTool; + uint32_t m_chunkId; + Nv::Blast::RandomGeneratorBase* m_randomGenerator; + Nv::Blast::Mesh* m_sourMesh; +}; + +class VoronoiFractureExecutor : public FractureExecutor +{ +public: + VoronoiFractureExecutor(); + void setCellsCount(uint32_t cellsCount); + + virtual bool execute(); + +private: + uint32_t m_cellsCount; +}; + +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); + + 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 +}; + +enum SelectMode +{ + SM_RESET = 0, + SM_ADD, + SM_SUB, + SM_REMAIN, +}; + +class Renderer; +class PhysXController; +class BlastController; +class SceneController; +class DamageToolController; +class SelectionToolController; +class GizmoToolController; +class EditionToolController; +class SampleController; +class CommonUIController; +class SimpleRandomGenerator; + +/** +*/ +class SampleManager +{ + friend class VoronoiFractureExecutor; + friend class SliceFractureExecutor; + public: + static SampleManager* ins(); + SampleManager(DeviceManager* pDeviceManager); + ~SampleManager(); + + int init(); + int run(); + int free(); + + void addModelAsset(std::string file, bool isSkinned, physx::PxTransform transform, bool clear = true); + + bool createAsset( + 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); + + bool createAsset( + const std::string& assetName, + const std::vector<Nv::Blast::Mesh* >& meshes, + bool fracture = false); + + bool saveAsset(); + bool fractureAsset(std::string& assetName, const BlastAsset* blastAsset, int32_t chunkId); + + bool postProcessCurrentAsset(); + + Renderer& getRenderer() + { + return *m_renderer; + } + + PhysXController& getPhysXController() const + { + return *m_physXController; + } + + BlastController& getBlastController() const + { + return *m_blastController; + } + + SceneController& getSceneController() const + { + return *m_sceneController; + } + + DamageToolController& getDamageToolController() const + { + return *m_damageToolController; + } + + SelectionToolController& getSelectionToolController() const + { + return *m_selectionToolController; + } + + GizmoToolController& getGizmoToolController() const + { + return *m_gizmoToolController; + } + + EditionToolController& getEditionToolController() const + { + return *m_editionToolController; + } + + SampleController& getSampleController() const + { + return *m_sampleController; + } + + CommonUIController& getCommonUIController() const + { + 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(); + void setChunkSelected(std::vector<uint32_t> depths, bool selected); + void setChunkVisible(std::vector<uint32_t> depths, bool bVisible); + + void setFractureExecutor(FractureExecutor* executor); + + void setBlastToolType(BlastToolType type); + + void output(const char* str); + void output(float value); + void output(physx::PxVec3& vec); + + void clearScene(); + + std::map<BlastAsset*, std::vector<BlastFamily*>>& getAssetFamiliesMap() + { + return m_AssetFamiliesMap; + } + std::map<BlastAsset*, AssetList::ModelAsset>& getAssetDescMap() + { + return m_AssetDescMap; + } + + 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); + + 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); + +private: + bool _createAsset( + const std::string& assetName, + const std::string& outDir, + const std::vector<Nv::Blast::Mesh* >& meshes); + + void _setSourceAsset(); + +private: + Renderer* m_renderer; + PhysXController* m_physXController; + BlastController* m_blastController; + SceneController* m_sceneController; + DamageToolController* m_damageToolController; + SelectionToolController* m_selectionToolController; + 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; + + std::map<BlastAsset*, std::vector<BlastFamily*>> m_AssetFamiliesMap; + std::map<BlastAsset*, AssetList::ModelAsset> m_AssetDescMap; + std::map<std::string, RenderMaterial*> m_RenderMaterialMap; + std::vector<std::string> m_NeedDeleteRenderMaterials; + + BlastAsset* m_pCurBlastAsset; + int m_nCurFamilyIndex; + + bool m_bNeedConfig; +}; + + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.cpp new file mode 100644 index 0000000..5146914 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.cpp @@ -0,0 +1,825 @@ +/* + * 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. + */ + +#include "PhysXController.h" +#include "RenderMaterial.h" +#include "ResourceManager.h" +#include "Renderer.h" + +#include "XInput.h" +#include "DXUTMisc.h" +#include "DXUTCamera.h" +#include "ConvexRenderMesh.h" +#include "RenderUtils.h" +#include "SampleProfiler.h" +#include "NvBlastProfiler.h" + +#include "PxPhysicsVersion.h" +#include "PxPvdTransport.h" +#include "PxDefaultCpuDispatcher.h" +#include "PxPhysics.h" +#include "PxScene.h" +#include "PxCooking.h" +#include "PxGpu.h" +#include "PxSimpleFactory.h" +#include "PxRigidBodyExt.h" +#include "PxRigidDynamic.h" +#include "PxRigidStatic.h" +#include "PxMaterial.h" +#include "PxFoundationVersion.h" +#include "PxMath.h" + +#include <imgui.h> +#include <chrono> + +using namespace std::chrono; + +#define PVD_TO_FILE 0 + +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; + +PhysXController::PhysXController(PxSimulationFilterShader filterShader) +: m_filterShader(filterShader) +, m_gpuPhysicsAvailable(true) +, m_useGPUPhysics(true) +, m_lastSimulationTime(0) +, m_paused(false) +, m_draggingActor(nullptr) +, m_draggingEnabled(true) +, m_draggingTryReconnect(false) +, m_perfWriter(NULL) +, m_fixedTimeStep(DEFAULT_FIXED_TIMESTEP) +, m_timeAccumulator(0) +, m_useFixedTimeStep(true) +, m_maxSubstepCount(1) +{ + QueryPerformanceFrequency(&m_performanceFreq); + +// Add By Lixu Begin + m_bForce = true; +// Add By Lixu End +} + +PhysXController::~PhysXController() +{ +} + +void PhysXController::onInitialize() +{ + initPhysX(); + initPhysXPrimitives(); +} + +void PhysXController::onTerminate() +{ + releasePhysXPrimitives(); + releasePhysX(); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PhysX init/release +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void PhysXController::initPhysX() +{ + m_foundation = PxCreateFoundation(PX_FOUNDATION_VERSION, m_allocator, m_errorCallback); + + m_pvd = PxCreatePvd(*m_foundation); + + NvBlastProfilerSetCallback(m_pvd); + NvBlastProfilerEnablePlatform(false); + NvBlastProfilerSetDetail(NvBlastProfilerDetail::LOW); + + PxTolerancesScale scale; + + m_physics = PxCreatePhysics(PX_PHYSICS_VERSION, *m_foundation, scale, true, m_pvd); + + PxCookingParams cookingParams(scale); + cookingParams.buildGPUData = true; + m_cooking = PxCreateCooking(PX_PHYSICS_VERSION, m_physics->getFoundation(), cookingParams); + + PxCudaContextManagerDesc ctxMgrDesc; + m_cudaContext = PxCreateCudaContextManager(m_physics->getFoundation(), ctxMgrDesc); + if (m_cudaContext && !m_cudaContext->contextIsValid()) + { + m_cudaContext->release(); + m_cudaContext = NULL; + } + + PxSceneDesc sceneDesc(m_physics->getTolerancesScale()); + sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f); + m_dispatcher = PxDefaultCpuDispatcherCreate(4); + sceneDesc.cpuDispatcher = m_dispatcher; + sceneDesc.gpuDispatcher = m_cudaContext != NULL ? m_cudaContext->getGpuDispatcher() : NULL; + sceneDesc.filterShader = m_filterShader; + sceneDesc.flags |= PxSceneFlag::eENABLE_STABILIZATION; + sceneDesc.flags |= PxSceneFlag::eENABLE_PCM; + if (sceneDesc.gpuDispatcher == nullptr) + { + m_gpuPhysicsAvailable = false; + m_useGPUPhysics = false; + } + if (m_useGPUPhysics) + { + sceneDesc.flags |= PxSceneFlag::eENABLE_GPU_DYNAMICS; + sceneDesc.broadPhaseType = PxBroadPhaseType::eGPU; + + sceneDesc.gpuDynamicsConfig.constraintBufferCapacity *= 4; + sceneDesc.gpuDynamicsConfig.contactBufferCapacity *= 4; + sceneDesc.gpuDynamicsConfig.contactStreamSize *= 4; + sceneDesc.gpuDynamicsConfig.forceStreamCapacity *= 4; + sceneDesc.gpuDynamicsConfig.foundLostPairsCapacity *= 4; + sceneDesc.gpuDynamicsConfig.patchStreamSize *= 4; + sceneDesc.gpuDynamicsConfig.tempBufferCapacity *= 4; + + } + m_physicsScene = m_physics->createScene(sceneDesc); + + m_defaultMaterial = m_physics->createMaterial(0.8f, 0.7f, 0.1f); + + PxPvdSceneClient* pvdClient = m_physicsScene->getScenePvdClient(); + if(pvdClient) + { + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true); + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true); + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true); + } + + m_physicsScene->setVisualizationParameter(PxVisualizationParameter::eSCALE, 0); + +#if NV_DEBUG || NV_CHECKED || NV_PROFILE + PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate("localhost", 5425, 10); + if (transport) + { + m_pvd->connect(*transport, +#if NV_DEBUG || NV_CHECKED + PxPvdInstrumentationFlag::eALL +#else + PxPvdInstrumentationFlag::ePROFILE +#endif + ); + } +#endif +} + +void PhysXController::releasePhysX() +{ + m_defaultMaterial->release(); + m_physicsScene->release(); + if (m_cudaContext) + m_cudaContext->release(); + m_dispatcher->release(); + m_physics->release(); + if (m_pvd) + { + PxPvdTransport* transport = m_pvd->getTransport(); + m_pvd->release(); + if (transport) + transport->release(); + } + m_cooking->release(); + m_foundation->release(); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// GPU toggle +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void PhysXController::setUseGPUPhysics(bool useGPUPhysics) +{ + if (!m_gpuPhysicsAvailable) + { + useGPUPhysics = false; + } + + if (m_useGPUPhysics == useGPUPhysics) + { + return; + } + + onTerminate(); + + m_useGPUPhysics = useGPUPhysics; + + onInitialize(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PhysX wrappers +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +PxRigidDynamic* PhysXController::createRigidDynamic(const PxTransform& transform) +{ + return m_physics->createRigidDynamic(transform); +} + +void PhysXController::releaseRigidDynamic(PxRigidDynamic* rigidDynamic) +{ + notifyRigidDynamicDestroyed(rigidDynamic); + + m_physXActorsToRemove.push_back(rigidDynamic); +} + +void PhysXController::notifyRigidDynamicDestroyed(PxRigidDynamic* rigidDynamic) +{ + if (m_draggingActor == rigidDynamic) + { + m_draggingActor = nullptr; + m_draggingTryReconnect = true; + } +} + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Controller events +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void PhysXController::Animate(double dt) +{ + PROFILER_SCOPED_FUNCTION(); + +// Add By Lixu Begin + if (m_paused && !m_bForce) + return; + if (m_bForce) + { + m_paused = true; + m_bForce = false; + } +// Add By Lixu End + + // slower physics if fps is too low + dt = PxClamp(dt, 0.0, 0.033333); + + updateDragging(dt); + + { + PROFILER_SCOPED("PhysX simulate"); + steady_clock::time_point start = steady_clock::now(); + 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) + { + PROFILER_SCOPED("PhysX simulate (substep)"); + m_physicsScene->simulate(m_fixedTimeStep); + m_physicsScene->fetchResults(true); + } + } + else + { + m_substepCount = 1; + m_physicsScene->simulate(dt); + m_physicsScene->fetchResults(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(); + + updateActorTransforms(); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Dragging +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void PhysXController::setDraggingEnabled(bool enabled) +{ + m_draggingEnabled = enabled; + + if (!m_draggingEnabled) + { + m_draggingActor = nullptr; + } +} + +void PhysXController::updateDragging(double dt) +{ + PROFILER_SCOPED_FUNCTION(); + + // If dragging actor was recently removed we try to reconnect to new one once, using previous hook world point. + // Often it is removed because it was split into smaller chunks (actors), so we wont to stay connected for nicer user experience. + if (m_draggingActor == nullptr && m_draggingTryReconnect) + { + class OverlapCallback : public PxOverlapBufferN<32> + { + public: + OverlapCallback() : hitActor(nullptr) {} + + PxAgain processTouches(const PxOverlapHit* buffer, PxU32 nbHits) + { + for (PxU32 i = 0; i < nbHits; ++i) + { + PxRigidDynamic* rigidDynamic = buffer[i].actor->is<PxRigidDynamic>(); + if (rigidDynamic) + { + hitActor = rigidDynamic; + break; + } + } + return true; + } + + PxRigidDynamic* hitActor; + }; + + OverlapCallback overlapCallback; + PxSphereGeometry sphere(0.15f); + bool isHit = getPhysXScene().overlap(sphere, PxTransform(m_draggingActorLastHookWorldPoint), overlapCallback, PxQueryFilterData(PxQueryFlag::eDYNAMIC)); + if (isHit && overlapCallback.hitActor) + { + m_draggingActor = overlapCallback.hitActor; + } + + m_draggingTryReconnect = false; + } + + // Update dragging force and debug render (line) + if (m_draggingEnabled && m_draggingActor != NULL) + { + const float DRAGGING_FORCE_FACTOR = 10.0f; + const float DRAGGING_VELOCITY_FACTOR = 2.0f; + PxVec3 attractionPoint = m_dragAttractionPoint; + 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); + + // debug render line + m_dragDebugRenderBuffer.clear(); + m_dragDebugRenderBuffer.m_lines.push_back(PxDebugLine(attractionPoint, hookPoint, XMFLOAT4ToU32Color(HOOK_LINE_COLOR))); + getRenderer().queueRenderBuffer(&m_dragDebugRenderBuffer); + } +} + +void PhysXController::resetDragging() +{ + m_draggingActor = nullptr; +} + + +LRESULT PhysXController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PROFILER_SCOPED_FUNCTION(); + + if (m_draggingEnabled && (uMsg == WM_LBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP)) + { + float mouseX = (short)LOWORD(lParam) / getRenderer().getScreenWidth(); + float mouseY = (short)HIWORD(lParam) / getRenderer().getScreenHeight(); + + PxVec3 eyePos, pickDir; + getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); + pickDir = pickDir.getNormalized(); + + if (uMsg == WM_LBUTTONDOWN) + { + if (pickDir.magnitude() > 0) + { + PxRaycastHit hit; + PxRaycastBuffer rcBuffer(&hit, 1); + bool isHit = getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, rcBuffer, PxHitFlag::ePOSITION, PxQueryFilterData(PxQueryFlag::eDYNAMIC)); + if (isHit) + { + 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; + } + } + } + else if (uMsg == WM_MOUSEMOVE) + { + PxRaycastHit hit; + PxRaycastBuffer rcBuffer(&hit, 1); + bool isHit = getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, rcBuffer, PxHitFlag::ePOSITION, PxQueryFilterData(PxQueryFlag::eSTATIC)); + if (isHit) + { + m_dragDistance = PxMin(m_dragDistance, (eyePos - hit.position).magnitude()); + } + + m_dragAttractionPoint = eyePos + pickDir * m_dragDistance; + } + else if (uMsg == WM_LBUTTONUP) + { + m_draggingActor = NULL; + } + } + + return 1; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// UI +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void PhysXController::drawUI() +{ + ImGui::Checkbox("Use Fixed Timestep", &m_useFixedTimeStep); + if (m_useFixedTimeStep) + { + ImGui::InputFloat("Fixed Timestep", &m_fixedTimeStep); + ImGui::InputInt("Max Substep Count", &m_maxSubstepCount); + } + + 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); +} + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PhysX Primitive +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void PhysXController::initPhysXPrimitives() +{ + // physx primitive render materials + { +// Add By Lixu Begin + m_physXPrimitiveRenderMaterial = new RenderMaterial("", getRenderer().getResourceManager(), "physx_primitive", ""); + m_physXPlaneRenderMaterial = new RenderMaterial("", getRenderer().getResourceManager(), "physx_primitive_plane", ""); + m_physXPrimitiveTransparentRenderMaterial = new RenderMaterial("", getRenderer().getResourceManager(), "physx_primitive_transparent", "", RenderMaterial::BLEND_ALPHA_BLENDING); +// Add By Lixu End + } + + // create plane + Actor* plane = spawnPhysXPrimitivePlane(PxPlane(PxVec3(0, 1, 0).getNormalized(), 0)); + plane->setColor(PLANE_COLOR); +} + +void PhysXController::releasePhysXPrimitives() +{ + // remove all actors + for (std::set<Actor*>::iterator it = m_actors.begin(); it != m_actors.end(); it++) + { + delete (*it); + } + m_actors.clear(); + + // remove all materials + SAFE_DELETE(m_physXPrimitiveRenderMaterial); + SAFE_DELETE(m_physXPlaneRenderMaterial); + SAFE_DELETE(m_physXPrimitiveTransparentRenderMaterial); + + // remove all convex render meshes + for (auto it = m_convexRenderMeshes.begin(); it != m_convexRenderMeshes.end(); it++) + { + SAFE_DELETE((*it).second); + } + m_convexRenderMeshes.clear(); +} + +void PhysXController::updateActorTransforms() +{ + PROFILER_SCOPED_FUNCTION(); + + for (std::set<Actor*>::iterator it = m_actors.begin(); it != m_actors.end(); it++) + { + (*it)->update(); + } +} + +PhysXController::Actor* PhysXController::spawnPhysXPrimitiveBox(const PxTransform& position, PxVec3 extents, float density) +{ + PxBoxGeometry geom = PxBoxGeometry(extents); + PxRigidDynamic* actor = PxCreateDynamic(*m_physics, position, geom, *m_defaultMaterial, density); + + return spawnPhysXPrimitive(actor); +} + +PhysXController::Actor* PhysXController::spawnPhysXPrimitivePlane(const PxPlane& plane) +{ + PxRigidStatic* actor = PxCreatePlane(*m_physics, plane, *m_defaultMaterial); + PhysXController::Actor* p = spawnPhysXPrimitive(actor, true, true); + return p; +} + +PhysXController::Actor* PhysXController::spawnPhysXPrimitive(PxRigidActor* actor, bool addToScene, bool ownPxActor) +{ + if (addToScene) + { + m_physicsScene->addActor(*actor); + } + + Actor* a = new Actor(this, actor, ownPxActor); + + m_actors.emplace(a); + + return a; +} + +void PhysXController::removePhysXPrimitive(Actor* actor) +{ + if (m_actors.find(actor) == m_actors.end()) + return; + + m_actors.erase(actor); + + if (!actor->ownsPxActor()) + { + m_physXActorsToRemove.push_back(actor->getActor()); + } + + if (m_draggingActor == actor->getActor()) + { + m_draggingActor = nullptr; + } + + delete actor; +} + +void PhysXController::removeUnownedPhysXActors() +{ + if (m_physXActorsToRemove.size()) + { + m_physicsScene->removeActors(&m_physXActorsToRemove[0], (PxU32)m_physXActorsToRemove.size()); + for (size_t i = 0; i < m_physXActorsToRemove.size(); ++i) + { + m_physXActorsToRemove[i]->release(); + } + m_physXActorsToRemove.resize(0); + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Actor +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +PhysXController::Actor::Actor(PhysXController* controller, PxRigidActor* actor, bool ownPxActor) : + m_controller(controller), + m_ownPxActor(ownPxActor), + m_hidden(false) +{ + m_actor = actor; + + uint32_t shapesCount = actor->getNbShapes(); + m_shapes.resize(shapesCount); + actor->getShapes(&m_shapes[0], shapesCount); + + m_renderables.resize(m_shapes.size()); + for (uint32_t i = 0; i < m_shapes.size(); i++) + { + PxShape* shape = m_shapes[i]; + IRenderMesh* mesh = m_controller->getRenderMeshForShape(shape); + RenderMaterial* material = shape->getGeometryType() == PxGeometryType::ePLANE ? m_controller->m_physXPlaneRenderMaterial : m_controller->m_physXPrimitiveRenderMaterial; + m_renderables[i] = m_controller->getRenderer().createRenderable(*mesh, *material); + m_renderables[i]->setScale(m_controller->getMeshScaleForShape(shape)); + } +} + +PhysXController::Actor::~Actor() +{ + for (uint32_t i = 0; i < m_renderables.size(); i++) + { + m_controller->getRenderer().removeRenderable(m_renderables[i]); + } + if (m_ownPxActor) + { + m_actor->release(); + } +} + +void PhysXController::Actor::setColor(DirectX::XMFLOAT4 color) +{ + m_color = color; + + for (uint32_t i = 0; i < m_renderables.size(); i++) + { + m_renderables[i]->setColor(color); + } +} + +void PhysXController::Actor::setHidden(bool hidden) +{ + m_hidden = hidden; + + for (uint32_t i = 0; i < m_renderables.size(); i++) + { + m_renderables[i]->setHidden(hidden); + } +} + +void PhysXController::Actor::update() +{ + for (uint32_t i = 0; i < m_renderables.size(); i++) + { + m_renderables[i]->setTransform(m_actor->getGlobalPose() * m_shapes[i]->getLocalPose()); + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PhysX Shapes Renderer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +IRenderMesh* PhysXController::getConvexRenderMesh(const PxConvexMesh* mesh) +{ + auto it = m_convexRenderMeshes.find(mesh); + if (it != m_convexRenderMeshes.end()) + { + return (*it).second; + } + else + { + ConvexRenderMesh* renderMesh = new ConvexRenderMesh(mesh); + m_convexRenderMeshes[mesh] = renderMesh; + return renderMesh; + } +} + +IRenderMesh* PhysXController::getRenderMeshForShape(const PxShape* shape) +{ + switch (shape->getGeometryType()) + { + case PxGeometryType::eBOX: + return getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Box); + case PxGeometryType::ePLANE: + return getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Plane); + case PxGeometryType::eSPHERE: + return getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Sphere); + case PxGeometryType::eCONVEXMESH: + { + PxConvexMeshGeometry geom; + shape->getConvexMeshGeometry(geom); + return getConvexRenderMesh(geom.convexMesh); + } + default: + PX_ALWAYS_ASSERT_MESSAGE("Unsupported PxGeometryType"); + return NULL; + } +} + +PxVec3 PhysXController::getMeshScaleForShape(const PxShape* shape) +{ + switch (shape->getGeometryType()) + { + case PxGeometryType::eBOX: + { + PxBoxGeometry boxGeom; + shape->getBoxGeometry(boxGeom); + return boxGeom.halfExtents; + } + case PxGeometryType::ePLANE: + { + return PxVec3(1, 2000, 2000); + } + case PxGeometryType::eSPHERE: + { + PxSphereGeometry sphereGeom; + shape->getSphereGeometry(sphereGeom); + return PxVec3(sphereGeom.radius, sphereGeom.radius, sphereGeom.radius); + } + case PxGeometryType::eCONVEXMESH: + { + PxConvexMeshGeometry convexGeom; + shape->getConvexMeshGeometry(convexGeom); + return convexGeom.scale.scale; // maybe incorrect because of rotation not used + } + default: + return PxVec3(1, 1, 1); + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Utils +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +PxVec3 unproject(PxMat44& proj, PxMat44& view, float x, float y) +{ + PxVec4 screenPoint(x, y, 0, 1); + PxVec4 viewPoint = PxVec4(x / proj[0][0], y / proj[1][1], 1, 1); + PxVec4 nearPoint = view.inverseRT().transform(viewPoint); + if (nearPoint.w) + nearPoint *= 1.0f / nearPoint.w; + return PxVec3(nearPoint.x, nearPoint.y, nearPoint.z); +} + + +void PhysXController::getEyePoseAndPickDir(float mouseX, float mouseY, PxVec3& eyePos, PxVec3& pickDir) +{ + PxMat44 view = XMMATRIXToPxMat44(getRenderer().getCamera().GetViewMatrix()); + PxMat44 proj = XMMATRIXToPxMat44(getRenderer().getCamera().GetProjMatrix()); + + PxMat44 eyeTransform = view.inverseRT(); + eyePos = eyeTransform.getPosition(); + PxVec3 nearPos = unproject(proj, view, mouseX * 2 - 1, 1 - mouseY * 2); + pickDir = nearPos - eyePos; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Add By Lixu Begin +#include "PxExtensionsAPI.h" +#include "PxDefaultStreams.h" +#include "PxCollectionExt.h" +// export collision as RepX. In exported file, it includes collisions as convexMesh. But for Rigidbodies, it will only export those exists. +// if export as file A before damaging, it exports all of the chunks as convexMeshes. And Chunk 0 as Dynamic rigid body. +// if export as file B after damaging and fracturing in the middle of simulation, it exports all of the chunks as convexMeshes. And the existing chunks as dynamic rigid bodies. +bool PhysXController::ExportCollisionRepX(const char* fname, physx::PxPhysics* pSDK, physx::PxScene* pScene, bool asBinary) +{ + if ((pSDK == NULL) || (pScene == NULL) || (fname == NULL)) + return false; + + int count = pSDK->getNbScenes(); + assert(count == 1); + + physx::PxSerializationRegistry* psr = physx::PxSerialization::createSerializationRegistry(*pSDK); + + physx::PxCollection* collectionSdk = physx::PxCollectionExt::createCollection(*pSDK); + PX_ASSERT(collectionSdk); + + physx::PxCollection* collectionScene = physx::PxCollectionExt::createCollection(*pScene); + PX_ASSERT(collectionScene); + + collectionSdk->add(*collectionScene); + physx::PxSerialization::complete(*collectionSdk, *psr, NULL, true); + + physx::PxDefaultFileOutputStream theStream(fname); + bool exportNames = true; + bool bExportOk = false; + if (asBinary) + bExportOk = physx::PxSerialization::serializeCollectionToBinary(theStream, *collectionSdk, *psr, NULL, exportNames); + else + bExportOk = physx::PxSerialization::serializeCollectionToXml(theStream, *collectionSdk, *psr); + + if (!bExportOk) + { + std::string warning = "Fail to save scene: "; + warning += fname; + warning += "!"; + MessageBoxA(NULL, warning.c_str(), "", MB_OK | MB_ICONWARNING); + bExportOk = false; + } + + collectionScene->release(); + collectionSdk->release(); + + psr->release(); + + return bExportOk; +} + +// we have to clear those convexMeshes when init scene. if not, they increase. +void PhysXController::ClearOldCOllisions() +{ + physx::PxU32 size = m_physics->getNbShapes(); + if (size > 0) + { + physx::PxShape** pShapes = new physx::PxShape*[size]; + memset(pShapes, 0, size); // clear + physx::PxU32 count = m_physics->getShapes(pShapes, size); + for (physx::PxU32 i = 0; i < count; i++) + { + physx::PxShape& shape = *pShapes[i]; + PxGeometryType::Enum type = shape.getGeometryType(); + if (type == PxGeometryType::eCONVEXMESH) + shape.release(); + } + delete[] pShapes; + size = m_physics->getNbShapes(); + } + // release convexMesh + size = m_physics->getNbConvexMeshes(); + if (size > 0) + { + physx::PxConvexMesh** pConvex = new physx::PxConvexMesh*[size]; + memset(pConvex, 0, size); // clear + physx::PxU32 count = m_physics->getConvexMeshes(pConvex, size); + for (physx::PxU32 i = 0; i < count; i++) + { + pConvex[i]->release(); + } + delete[] pConvex; + size = m_physics->getNbConvexMeshes(); + } +} +// Add By Lixu Begin diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.h new file mode 100644 index 0000000..2473526 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/physx/PhysXController.h @@ -0,0 +1,296 @@ +/* +* 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. +*/ + +#ifndef PHYSX_CONTROLLER_H +#define PHYSX_CONTROLLER_H + +#include "SampleManager.h" +#include <DirectXMath.h> +#include "DebugRenderBuffer.h" +#include "PxFiltering.h" +#include "PxDefaultAllocator.h" +#include "PxDefaultErrorCallback.h" +#include <set> +#include <map> + + +using namespace physx; + +class PerformanceDataWriter; +class RenderMaterial; +class Renderable; +class IRenderMesh; + +namespace physx +{ +class PxCpuDispatcher; +class PxFoundation; +class PxDefaultAllocator; +class PxDefaultErrorCallback; +class PxPhysics; +class PxCooking; +class PxPvd; +class PxCudaContextManager; +class PxDefaultCpuDispatcher; +} + + +/** +SampleController which manages all the PhysX related work: +1. initialization, scene updates, release. +2. it can create update and render physx primitives. They are represented by PhysXController::Actor, see public API. +3. provides ability to drag actors by mouse or other similar input + +NOTE: this class does too much, probably should be split in a few smaller ones. +*/ +class PhysXController : public ISampleController +{ + public: + + //////// Actor //////// + + class Actor + { + public: + + Actor(PhysXController* controller, PxRigidActor* actor, bool ownPxActor = true); + ~Actor(); + + void setColor(DirectX::XMFLOAT4 color); + DirectX::XMFLOAT4 getColor() const { return m_color; } + + bool isHidden() { return m_hidden; } + void setHidden(bool hidden); + + void update(); + PxRigidActor* getActor() const { return m_actor; } + + bool ownsPxActor() const { return m_ownPxActor; } + + private: + PhysXController* m_controller; + PxRigidActor* m_actor; + std::vector<PxShape*> m_shapes; + + std::vector<Renderable*> m_renderables; + DirectX::XMFLOAT4 m_color; + + bool m_hidden; + bool m_ownPxActor; + }; + + + //////// ctor //////// + + PhysXController(PxSimulationFilterShader filterShader); + virtual ~PhysXController(); + + + //////// virtual callbacks //////// + + virtual void onInitialize(); + virtual void onTerminate(); + + virtual void Animate(double dt); + + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + + //////// public API //////// + + void getEyePoseAndPickDir(float mouseX, float mouseY, PxVec3& eyePos, PxVec3& pickDir); + + // wrappers to physx calls + PxRigidDynamic* createRigidDynamic(const PxTransform& transform); + void releaseRigidDynamic(PxRigidDynamic*); + + Actor* spawnPhysXPrimitiveBox(const PxTransform& position, PxVec3 extents = PxVec3(1, 1, 1), float density = 2000.0f); + Actor* spawnPhysXPrimitivePlane(const PxPlane& plane); + Actor* spawnPhysXPrimitive(PxRigidActor* actor, bool addToScene = true, bool ownPxActor = true); + void removePhysXPrimitive(Actor*); + + IRenderMesh* getConvexRenderMesh(const PxConvexMesh* mesh); + IRenderMesh* getRenderMeshForShape(const PxShape* shape); + PxVec3 getMeshScaleForShape(const PxShape* shape); + + void removeUnownedPhysXActors(); + + bool isPaused() const + { + return m_paused; + } + + void setPaused(bool paused) + { + m_paused = paused; + } + + void setDraggingEnabled(bool enabled); + bool getDraggingEnabled() const { return m_draggingEnabled; } + void resetDragging(); + + void notifyRigidDynamicDestroyed(PxRigidDynamic*); + + void drawUI(); + + //////// public getters //////// + + double getLastSimulationTime() const + { + return m_lastSimulationTime; + } + + RenderMaterial* getPrimitiveRenderMaterial() + { + return m_physXPrimitiveRenderMaterial; + } + +// Add By Lixu Begin + bool ExportCollisionRepX(const char* fname, physx::PxPhysics* pSDK, physx::PxScene* pScene, bool asBinary); + void ClearOldCOllisions(); + RenderMaterial* getFBXRenderMaterial() + { + return m_physXPlaneRenderMaterial; + } + bool m_bForce; +// Add By Lixu End + + PxPhysics& getPhysics() const + { + return *m_physics; + } + + PxScene& getPhysXScene() const + { + return *m_physicsScene; + } + + PxMaterial* getDefaultMaterial() const + { + return m_defaultMaterial; + } + + PxCooking& getCooking() const + { + return *m_cooking; + } + + PxDefaultCpuDispatcher* getCPUDispatcher() const + { + return m_dispatcher; + } + + void setPerformanceWriter(PerformanceDataWriter* perfWriter) + { + m_perfWriter = perfWriter; + } + + bool getGPUPhysicsAvailable() const + { + return m_gpuPhysicsAvailable; + } + + void setUseGPUPhysics(bool useGPUPhysics); + + bool getUseGPUPhysics() const + { + return m_useGPUPhysics; + } + + const PxVec3& getDragActorHookLocalPoint() const + { + return m_draggingActorHookLocalPoint; + } + + const PxVec3& getDragVector() const + { + return m_dragVector; + } + + PxRigidDynamic* getDraggingActor() const + { + return m_draggingActor; + } + + private: + //////// internal methods //////// + + void initPhysX(); + void releasePhysX(); + + void initPhysXPrimitives(); + void releasePhysXPrimitives(); + void updateActorTransforms(); + void updateDragging(double dt); + + + //////// used controllers //////// + + Renderer& getRenderer() const + { + return getManager()->getRenderer(); + } + + + //////// internal data //////// + + // PhysX + PxFoundation* m_foundation; + PxDefaultAllocator m_allocator; + PxDefaultErrorCallback m_errorCallback; + PxPhysics* m_physics; + PxCooking* m_cooking; + PxPvd* m_pvd; + PxCudaContextManager* m_cudaContext; + PxDefaultCpuDispatcher* m_dispatcher; + PxMaterial* m_defaultMaterial; + PxSimulationFilterShader m_filterShader; + PxScene* m_physicsScene; + + // PhysX API related + std::vector<PxActor*> m_physXActorsToRemove; + + // primitives/actors + std::set<Actor*> m_actors; + std::map<const PxConvexMesh*, IRenderMesh*> m_convexRenderMeshes; + RenderMaterial* m_physXPrimitiveRenderMaterial; + RenderMaterial* m_physXPlaneRenderMaterial; + RenderMaterial* m_physXPrimitiveTransparentRenderMaterial; + + // simulation + bool m_gpuPhysicsAvailable; + bool m_useGPUPhysics; + double m_lastSimulationTime; + LARGE_INTEGER m_performanceFreq; + bool m_paused; + bool m_useFixedTimeStep; + float m_fixedTimeStep; + float m_timeAccumulator; + uint32_t m_substepCount; + int32_t m_maxSubstepCount; + + // dragging + bool m_draggingEnabled; + PxRigidDynamic* m_draggingActor; + PxVec3 m_draggingActorHookLocalPoint; + PxVec3 m_dragAttractionPoint; + PxVec3 m_dragVector; + float m_dragDistance; + DebugRenderBuffer m_dragDebugRenderBuffer; + PxVec3 m_draggingActorLastHookWorldPoint; + bool m_draggingTryReconnect; + + // Performance writer + PerformanceDataWriter* m_perfWriter; + + +}; + +#endif diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.cpp new file mode 100644 index 0000000..074cc2d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.cpp @@ -0,0 +1,82 @@ +/* +* 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. +*/ + +#include "ConvexRenderMesh.h" +#include "Renderer.h" +#include "PxConvexMesh.h" + + +struct Vertex +{ + PxVec3 position; + PxVec3 normal; +}; + +ConvexRenderMesh::ConvexRenderMesh(const PxConvexMesh* mesh) +{ + const uint32_t nbPolygons = mesh->getNbPolygons(); + const uint8_t* indexBuffer = mesh->getIndexBuffer(); + const PxVec3* meshVertices = mesh->getVertices(); + + uint32_t nbVerts = 0; + uint32_t nbFaces = 0; + + for (uint32_t i = 0; i < nbPolygons; i++) + { + PxHullPolygon data; + mesh->getPolygonData(i, data); + uint32_t nbPolyVerts = data.mNbVerts; + nbVerts += nbPolyVerts; + nbFaces += (nbPolyVerts - 2) * 3; + } + + std::vector<Vertex> vertices; + std::vector<uint16_t> faces; + + vertices.resize(nbVerts); + faces.resize(nbFaces); + + uint32_t vertCounter = 0; + uint32_t facesCounter = 0; + for (uint32_t i = 0; i < nbPolygons; i++) + { + PxHullPolygon data; + mesh->getPolygonData(i, data); + + PxVec3 normal(data.mPlane[0], data.mPlane[1], data.mPlane[2]); + + uint32_t vI0 = vertCounter; + for (uint32_t vI = 0; vI < data.mNbVerts; vI++) + { + vertices[vertCounter].position = meshVertices[indexBuffer[data.mIndexBase + vI]]; + vertices[vertCounter].normal = normal; + vertCounter++; + } + + for (uint32_t vI = 1; vI < uint32_t(data.mNbVerts) - 1; vI++) + { + faces[facesCounter++] = uint16_t(vI0); + faces[facesCounter++] = uint16_t(vI0 + vI + 1); + faces[facesCounter++] = uint16_t(vI0 + vI); + } + } + + std::vector<D3D11_INPUT_ELEMENT_DESC> layout; + layout.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + layout.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + + initialize(vertices.data(), (uint32_t)vertices.size(), sizeof(Vertex), layout, faces.data(), nbFaces); +} + + +ConvexRenderMesh::~ConvexRenderMesh() +{ +} + diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.h new file mode 100644 index 0000000..dfe8d8f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ConvexRenderMesh.h @@ -0,0 +1,34 @@ +/* +* 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. +*/ + +#ifndef CONVEX_RENDER_MESH_H +#define CONVEX_RENDER_MESH_H + +#include "CustomRenderMesh.h" + +namespace physx +{ +class PxConvexMesh; +} + + +/** +PxConvexMesh render mesh +(this class relates to PhysX more then to Renderer) +*/ +class ConvexRenderMesh : public CustomRenderMesh +{ +public: + ConvexRenderMesh(const PxConvexMesh* mesh); + virtual ~ConvexRenderMesh(); +}; + + +#endif //CONVEX_RENDER_MESH_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.cpp new file mode 100644 index 0000000..61ae9e0 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.cpp @@ -0,0 +1,96 @@ +/* +* 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. +*/ + +#include "CustomRenderMesh.h" + + +CustomRenderMesh::CustomRenderMesh() + : m_indexBuffer(nullptr) +{ +} + +CustomRenderMesh::CustomRenderMesh(const void* vertices, uint32_t numVertices, uint32_t vertexSize, std::vector<D3D11_INPUT_ELEMENT_DESC>& inputDesc, const uint16_t* faces, uint32_t numFaces) + : m_indexBuffer(nullptr) +{ + initialize(vertices, numVertices, vertexSize, inputDesc, faces, numFaces); +} + +void CustomRenderMesh::initialize(const void* vertices, uint32_t numVertices, uint32_t vertexSize, std::vector<D3D11_INPUT_ELEMENT_DESC>& inputDesc, const uint16_t* faces, uint32_t numFaces) +{ + ID3D11Device* device = GetDeviceManager()->GetDevice(); + + m_inputDesc = inputDesc; + m_numVertices = numVertices; + m_vertexSize = vertexSize; + m_numFaces = numFaces; + + // VB + { + D3D11_SUBRESOURCE_DATA vertexBufferData; + + ZeroMemory(&vertexBufferData, sizeof(vertexBufferData)); + vertexBufferData.pSysMem = vertices; + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = vertexSize * numVertices; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + + V(device->CreateBuffer(&bufferDesc, &vertexBufferData, &m_vertexBuffer)); + } + + // IB + if (faces != nullptr) + { + D3D11_SUBRESOURCE_DATA indexBufferData; + + ZeroMemory(&indexBufferData, sizeof(indexBufferData)); + indexBufferData.pSysMem = faces; + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc.ByteWidth = sizeof(uint16_t) * numFaces; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + + V(device->CreateBuffer(&bufferDesc, &indexBufferData, &m_indexBuffer)); + } +} + +CustomRenderMesh::~CustomRenderMesh() +{ + SAFE_RELEASE(m_vertexBuffer); + SAFE_RELEASE(m_indexBuffer); +} + + +void CustomRenderMesh::render(ID3D11DeviceContext& context) const +{ + context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + UINT strides[1] = { m_vertexSize }; + UINT offsets[1] = { 0 }; + context.IASetVertexBuffers(0, 1, &m_vertexBuffer, strides, offsets); + + context.IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R16_UINT, 0); + + if (m_indexBuffer) + context.DrawIndexed(m_numFaces, 0, 0); + else + context.Draw(m_numVertices, 0); +} + diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.h new file mode 100644 index 0000000..b0ddea1 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/CustomRenderMesh.h @@ -0,0 +1,41 @@ +/* +* 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. +*/ + +#ifndef CUSTOM_RENDER_MESH_H +#define CUSTOM_RENDER_MESH_H + +#include "Renderable.h" + + +class CustomRenderMesh : public IRenderMesh +{ +public: + const std::vector<D3D11_INPUT_ELEMENT_DESC>& getInputElementDesc() const { return m_inputDesc; } + void render(ID3D11DeviceContext& context) const; + + CustomRenderMesh(const void* vertices, uint32_t numVertices, uint32_t vertexSize, std::vector<D3D11_INPUT_ELEMENT_DESC>& inputDesc, const uint16_t* faces = nullptr, uint32_t numFaces = 0); + virtual ~CustomRenderMesh(); + +protected: + CustomRenderMesh(); + void initialize(const void* vertices, uint32_t numVertices, uint32_t vertexSize, std::vector<D3D11_INPUT_ELEMENT_DESC>& inputDesc, const uint16_t* faces, uint32_t numFaces); + +private: + ID3D11Buffer* m_vertexBuffer; + ID3D11Buffer* m_indexBuffer; + uint32_t m_numFaces; + uint32_t m_numVertices; + uint32_t m_vertexSize; + + std::vector<D3D11_INPUT_ELEMENT_DESC> m_inputDesc; +}; + + +#endif //CUSTOM_RENDER_MESH_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/DebugRenderBuffer.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/DebugRenderBuffer.h new file mode 100644 index 0000000..7810733 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/DebugRenderBuffer.h @@ -0,0 +1,50 @@ +/* +* 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. +*/ + +#ifndef DEBUGRENDERBUFFER_H +#define DEBUGRENDERBUFFER_H + +#include "PxRenderBuffer.h" +#include <vector> + +using namespace physx; + + +/** +Simple PxRenderBuffer implementation for easy debug primitives adding +*/ +class DebugRenderBuffer : public PxRenderBuffer +{ +public: + ~DebugRenderBuffer() {} + + virtual PxU32 getNbPoints() const { return 0; } + virtual const PxDebugPoint* getPoints() const { return nullptr; } + + virtual PxU32 getNbLines() const { return static_cast<PxU32>(m_lines.size()); } + virtual const PxDebugLine* getLines() const { return m_lines.data(); } + + virtual PxU32 getNbTriangles() const { return 0; } + virtual const PxDebugTriangle* getTriangles() const { return nullptr; } + + virtual PxU32 getNbTexts() const { return 0; } + virtual const PxDebugText* getTexts() const { return nullptr; } + + virtual void append(const PxRenderBuffer& other) {} + virtual void clear() + { + m_lines.clear(); + } + + std::vector<PxDebugLine> m_lines; +}; + + +#endif //DEBUGRENDERBUFFER_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.cpp new file mode 100644 index 0000000..cdf63f2 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.cpp @@ -0,0 +1,13 @@ +/* +* 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. +*/ + + +#include "Mesh.h" + diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.h new file mode 100644 index 0000000..b10f0d6 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Mesh.h @@ -0,0 +1,54 @@ +/* +* 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. +*/ + +#ifndef MESH_H +#define MESH_H + +#include <vector> +#include "PxVec2.h" +#include "PxVec3.h" + +// Add By Lixu Begin +class MeshBase +// Add By Lixu End +{ + virtual uint32_t getVertexStride() = 0; + // ... TBD +}; + +/** +SimpleMesh: position + normal + uv +We use only this type everywhere, once other versions will be required we should generalize Mesh and refactor code. +*/ +// Add By Lixu Begin +class SimpleMesh : public MeshBase +// Add By Lixu End +{ +public: + + class Vertex + { + public: + physx::PxVec3 position; + physx::PxVec3 normal; + physx::PxVec2 uv; + }; + + virtual uint32_t getVertexStride() { return sizeof(Vertex); } + + std::vector<Vertex> vertices; + std::vector<uint16_t> indices; + + physx::PxVec3 extents; + physx::PxVec3 center; +}; + + +#endif //MESH_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.cpp new file mode 100644 index 0000000..06c7616 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.cpp @@ -0,0 +1,284 @@ +/* +* 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. +*/ + + +#include "PrimitiveRenderMesh.h" +#include "Renderer.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Base Mesh internal class +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +PrimitiveRenderMesh::PrimitiveRenderMesh(const float v[], UINT numVertices) +{ + std::vector<D3D11_INPUT_ELEMENT_DESC> layout; + layout.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + layout.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + + initialize(v, numVertices, sizeof(float) * 6, layout, nullptr, 0); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Box Mesh +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +const float boxVertices[] = +{ + -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + + -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + + -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, + -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, + -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, + -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, + -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, + -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, + + 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, + + -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, + 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, + -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, + -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, + + -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f +}; + +BoxRenderMesh::BoxRenderMesh() : PrimitiveRenderMesh(boxVertices, sizeof(boxVertices) / (6 * sizeof(boxVertices[0]))) {} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Plane Mesh +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +const float planeSize = 1.0f; // we use scaling instead +const float planeTilesCount = 1000.0f; + +const float planeVertices[] = +{ + 0, planeSize, planeSize, 1.0f, 0.0f, 0.0f, planeTilesCount, planeTilesCount, + 0, planeSize, -planeSize, 1.0f, 0.0f, 0.0f, planeTilesCount, -planeTilesCount, + 0, -planeSize, -planeSize, 1.0f, 0.0f, 0.0f, -planeTilesCount, -planeTilesCount, + 0, -planeSize, -planeSize, 1.0f, 0.0f, 0.0f, -planeTilesCount, -planeTilesCount, + 0, -planeSize, planeSize, 1.0f, 0.0f, 0.0f, -planeTilesCount, planeTilesCount, + 0, planeSize, planeSize, 1.0f, 0.0f, 0.0f, planeTilesCount, planeTilesCount +}; + +PlaneRenderMesh::PlaneRenderMesh() +{ + std::vector<D3D11_INPUT_ELEMENT_DESC> layout; + layout.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + layout.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + layout.push_back({ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + + initialize(planeVertices, sizeof(planeVertices) / (8 * sizeof(planeVertices[0])), sizeof(float) * 8, layout, nullptr, 0); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Sphere Mesh +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +const uint32_t g_numSlices = 8; // along lines of longitude +const uint32_t g_numStacks = 16; // along lines of latitude + +const uint32_t g_numSphereVertices = (g_numSlices * 2 + 1)*(g_numStacks + 1); +const uint32_t g_numSphereIndices = g_numSlices * 2 * g_numStacks * 6; + +const uint32_t g_numConeVertices = (g_numSlices * 2 + 1) * 2; +const uint32_t g_numConeIndices = g_numSlices * 2 * 6; + +PxVec3 g_spherePositions[g_numSphereVertices]; +uint16_t g_sphereIndices[g_numSphereIndices]; + +void generateSphereMesh(uint16_t slices, uint16_t stacks, PxVec3* positions, uint16_t* indices) +{ + const PxF32 thetaStep = PxPi / stacks; + const PxF32 phiStep = PxTwoPi / (slices * 2); + + PxF32 theta = 0.0f; + + // generate vertices + for (uint16_t y = 0; y <= stacks; ++y) + { + PxF32 phi = 0.0f; + + PxF32 cosTheta = PxCos(theta); + PxF32 sinTheta = PxSin(theta); + + for (uint16_t x = 0; x <= slices * 2; ++x) + { + PxF32 cosPhi = PxCos(phi); + PxF32 sinPhi = PxSin(phi); + + PxVec3 p(cosPhi*sinTheta, cosTheta, sinPhi*sinTheta); + + // write vertex + *(positions++) = p; + + phi += phiStep; + } + + theta += thetaStep; + } + + const uint16_t numRingQuads = 2 * slices; + const uint16_t numRingVerts = 2 * slices + 1; + + // add faces + for (uint16_t y = 0; y < stacks; ++y) + { + for (uint16_t i = 0; i < numRingQuads; ++i) + { + // add a quad + *(indices++) = (y + 0)*numRingVerts + i; + *(indices++) = (y + 1)*numRingVerts + i; + *(indices++) = (y + 1)*numRingVerts + i + 1; + + *(indices++) = (y + 1)*numRingVerts + i + 1; + *(indices++) = (y + 0)*numRingVerts + i + 1; + *(indices++) = (y + 0)*numRingVerts + i; + } + } +} + + +struct SphereVertex +{ + PxVec3 position; + PxVec3 normal; +}; + +SphereRenderMesh::SphereRenderMesh() +{ + generateSphereMesh(g_numSlices, g_numStacks, g_spherePositions, g_sphereIndices); + + std::vector<SphereVertex> vertices; + for (uint32_t i = 0; i < g_numSphereVertices; i++) + { + vertices.push_back({ g_spherePositions[i], g_spherePositions[i] }); + } + + std::vector<D3D11_INPUT_ELEMENT_DESC> layout; + layout.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + layout.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + + initialize(vertices.data(), (uint32_t)vertices.size(), sizeof(SphereVertex), layout, g_sphereIndices, g_numSphereIndices); +} + + +SphereRenderMesh::~SphereRenderMesh() +{ +} + +// Add By Lixu Begin +const float coneVertices[] = +{ + 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f,//top + -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f,//left bottom + -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f,//left top + + 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,//top + 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f,//right top + 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f,//right bottom + + 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f,//top + -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f,//left top + 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f,//right top + + 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,//top + 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,//right bottom + -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,//left bottom + + -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f,//left top + 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f,//right bottom + 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f,//right top + + 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f,//right bottom + -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f,//left top + -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f,//left bottom +}; + +ConeRenderMesh::ConeRenderMesh() : PrimitiveRenderMesh(coneVertices, sizeof(coneVertices) / (6 * sizeof(coneVertices[0]))) {} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// FBX Mesh class +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#include <AnimUtil.h> +#include <PxVec2.h> +#include <vector> + +struct FBXVertex +{ + PxVec3 position; + PxVec3 normal; + PxVec2 uv; +}; + +FBXRenderMesh::FBXRenderMesh(MeshDesc* pMeshData) +{ + std::vector<D3D11_INPUT_ELEMENT_DESC> layout; + layout.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + layout.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + layout.push_back({ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + + std::vector<FBXVertex> vertices; + std::vector<uint16_t> indices; + + for (uint32_t i = 0; i < pMeshData->m_NumVertices; ++i) + { + atcore_float3 pos = pMeshData->m_pVertices[i]; + atcore_float3 vertexNormal = pMeshData->m_pVertexNormals[i]; + atcore_float2 texcoord = pMeshData->m_pTexCoords[i]; + + FBXVertex newVertex; + newVertex.position = physx::PxVec3(pos.x, pos.y, pos.z); + newVertex.normal = physx::PxVec3(vertexNormal.x, vertexNormal.y, vertexNormal.z); + newVertex.uv = physx::PxVec2(texcoord.x, texcoord.y); + + vertices.push_back(newVertex); + } + + for (uint32_t i = 0; i < pMeshData->m_NumTriangles; ++i) + { + indices.push_back(pMeshData->m_pIndices[i * 3 + 0]); + indices.push_back(pMeshData->m_pIndices[i * 3 + 1]); + indices.push_back(pMeshData->m_pIndices[i * 3 + 2]); + } + + initialize(vertices.data(), (uint32_t)vertices.size(), sizeof(FBXVertex), layout, indices.data(), (uint32_t)indices.size()); +} +// Add By Lixu End
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.h new file mode 100644 index 0000000..0f3f345 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/PrimitiveRenderMesh.h @@ -0,0 +1,81 @@ +/* +* 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. +*/ + +#ifndef PRIMITIVE_RENDER_MESH_H +#define PRIMITIVE_RENDER_MESH_H + +#include "Utils.h" +#include <DirectXMath.h> + +#include <vector> +#include "Renderable.h" +#include "CustomRenderMesh.h" + + +class PrimitiveRenderMesh : public CustomRenderMesh +{ +protected: + PrimitiveRenderMesh(const float v[], UINT numVertices); +}; + +class BoxRenderMesh : public PrimitiveRenderMesh +{ +public: + BoxRenderMesh(); +}; + + +class PlaneRenderMesh : public CustomRenderMesh +{ +public: + PlaneRenderMesh(); +}; + + +class SphereRenderMesh : public CustomRenderMesh +{ +public: + SphereRenderMesh(); + virtual ~SphereRenderMesh(); +}; + + +// Add By Lixu Begin +class ConeRenderMesh : public PrimitiveRenderMesh +{ +public: + ConeRenderMesh(); +}; + +class MeshDesc; + +class FBXRenderMesh : public CustomRenderMesh +{ +public: + FBXRenderMesh(MeshDesc* pMeshData); +}; +// Add By Lixu End + + +struct PrimitiveRenderMeshType +{ + enum Enum + { + Box, + Plane, + Sphere, +// Add By Lixu Begin + Cone, +// Add By Lixu End + Count + }; +}; + +#endif //PRIMITIVE_RENDER_MESH_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.cpp new file mode 100644 index 0000000..1b90f8f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.cpp @@ -0,0 +1,277 @@ +/* +* 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. +*/ + +#include "RenderMaterial.h" +#include <DirectXMath.h> +#include "ShaderUtils.h" +#include "Renderer.h" +#include "SampleManager.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// RenderMaterial +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +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 + + this->initialize(resourceCallback, shaderFileName, textureFileName, blendMode); +} + +void RenderMaterial::initialize(ResourceManager& resourceCallback, const char* shaderFileName, const char* textureFileName, BlendMode blendMode) +{ + std::vector<std::string> v; + v.push_back(shaderFileName); + initialize(resourceCallback, v, textureFileName, blendMode); +} + +void RenderMaterial::initialize(ResourceManager& resourceCallback, std::vector<std::string> shaderFileNames, const char* textureFileName, BlendMode blendMode) +{ + mTextureSRV = nullptr; + mTexture = nullptr; + mBlendState = nullptr; + + for (uint32_t i = 0; i < shaderFileNames.size(); i++) + { + const ShaderFileResource* resource = resourceCallback.requestShaderFile(shaderFileNames[i].c_str()); + if (resource) + { + std::string shaderFilePath = resource->path; + mShaderFilePathes.push_back(shaderFilePath); + } + } + mShaderGroups.reserve(mShaderFilePathes.size()); + + if (!mTextureFileName.empty()) + { + mTexture = resourceCallback.requestTexture(mTextureFileName.c_str()); + } + + setBlending(blendMode); + + reload(); +} + +void RenderMaterial::releaseReloadableResources() +{ + for (std::vector<ShaderGroup*>::iterator it = mShaderGroups.begin(); it != mShaderGroups.end(); it++) + { + delete *it; + } + mShaderGroups.clear(); + +// Add By Lixu Begin + for (std::map<const IRenderMesh*, Instance*>::iterator it = mRenderMeshToInstanceMap.begin(); + it != mRenderMeshToInstanceMap.end(); it++) + { + delete it->second; + } + mRenderMeshToInstanceMap.clear(); +// Add By Lixu End + + SAFE_RELEASE(mTextureSRV); +} + +RenderMaterial::~RenderMaterial() +{ +// Add By Lixu Begin + SampleManager::ins()->removeRenderMaterial(mMaterialName); +// Add By Lixu End + + releaseReloadableResources(); + SAFE_RELEASE(mBlendState); +} + +void RenderMaterial::setBlending(BlendMode blendMode) +{ + mBlendMode = blendMode; + + SAFE_RELEASE(mBlendState); + + D3D11_BLEND_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + + switch (blendMode) + { + case BLEND_NONE: + desc.RenderTarget[0].BlendEnable = FALSE; + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + break; + case BLEND_ALPHA_BLENDING: + desc.AlphaToCoverageEnable = FALSE; + desc.IndependentBlendEnable = TRUE; + desc.RenderTarget[0].BlendEnable = TRUE; + desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + break; + case BLEND_ADDITIVE: // actually, is's additive by alpha + desc.AlphaToCoverageEnable = FALSE; + desc.IndependentBlendEnable = TRUE; + desc.RenderTarget[0].BlendEnable = TRUE; + desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; + desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; + desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + break; + default: + PX_ALWAYS_ASSERT_MESSAGE("Unknown blend mode"); + } + + ID3D11Device* device = GetDeviceManager()->GetDevice(); + V(device->CreateBlendState(&desc, &mBlendState)); +} + +void RenderMaterial::reload() +{ + releaseReloadableResources(); + + // load shaders + ID3D11Device* device = GetDeviceManager()->GetDevice(); + + for (std::vector<std::string>::iterator it = mShaderFilePathes.begin(); it != mShaderFilePathes.end(); it++) + { + const char* shaderFilePath = (*it).c_str(); + ShaderGroup* shaderGroup = new ShaderGroup(); + V(createShaderFromFile(device, shaderFilePath, "VS", &(shaderGroup->vs), shaderGroup->buffer)); + createShaderFromFile(device, shaderFilePath, "PS", &shaderGroup->ps); + createShaderFromFile(device, shaderFilePath, "GS", &shaderGroup->gs); + mShaderGroups.push_back(shaderGroup); + } + + // load texture + if (mTexture) + { + V(DirectX::CreateShaderResourceView(device, mTexture->image.GetImages(), mTexture->image.GetImageCount(), + mTexture->metaData, &mTextureSRV)); + } +} + + + +RenderMaterial::InstancePtr RenderMaterial::getMaterialInstance(const IRenderMesh* mesh) +{ + // look in cache + auto it = mRenderMeshToInstanceMap.find(mesh); + if (it != mRenderMeshToInstanceMap.end()) + { +// Add By Lixu Begin + /* + if (!(*it).second.expired()) + { + return (*it).second.lock(); + } + */ + return it->second; +// Add By Lixu End + } + + // create new + const std::vector<D3D11_INPUT_ELEMENT_DESC>& descs = mesh->getInputElementDesc(); + RenderMaterial::InstancePtr instance = getMaterialInstance(&descs[0], (uint32_t)descs.size()); + mRenderMeshToInstanceMap[mesh] = instance; + return instance; +} + +RenderMaterial::InstancePtr RenderMaterial::getMaterialInstance(const D3D11_INPUT_ELEMENT_DESC* elementDescs, uint32_t numElements) +{ + ID3D11Device* device = GetDeviceManager()->GetDevice(); + + for (uint32_t i = 0; i < mShaderGroups.size(); i++) + { + if (mShaderGroups[i]->buffer == NULL) + continue; + + ID3D11InputLayout* inputLayout = NULL; + device->CreateInputLayout(elementDescs, numElements, mShaderGroups[i]->buffer->GetBufferPointer(), mShaderGroups[i]->buffer->GetBufferSize(), &inputLayout); + + if (inputLayout) + { + RenderMaterial::InstancePtr materialInstance(new Instance(*this, inputLayout, i)); + return materialInstance; + } + } + PX_ALWAYS_ASSERT(); + return NULL; +} + +void RenderMaterial::Instance::bind(ID3D11DeviceContext& context, uint32_t slot, bool depthStencilOnly) +{ + mMaterial.mShaderGroups[mShaderNum]->Set(&context, !depthStencilOnly); + + context.OMSetBlendState(mMaterial.mBlendState, nullptr, 0xFFFFFFFF); + context.PSSetShaderResources(slot, 1, &(mMaterial.mTextureSRV)); + context.IASetInputLayout(mInputLayout); +} + +bool RenderMaterial::Instance::isValid() +{ + return mMaterial.mShaderGroups.size() > 0 && mMaterial.mShaderGroups[mShaderNum]->IsValid(); +} + +// Add By Lixu Begin +void RenderMaterial::setTextureFileName(std::string textureFileName) +{ + if (mTextureFileName == textureFileName) + { + return; + } + + mTextureFileName = textureFileName; + mTexture = nullptr; + SAFE_RELEASE(mTextureSRV); + + if (mTextureFileName.empty()) + { + return; + } + + std::string searchDir = mTextureFileName; + 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) + { + return; + } + + ID3D11Device* device = GetDeviceManager()->GetDevice(); + DirectX::CreateShaderResourceView(device, mTexture->image.GetImages(), mTexture->image.GetImageCount(), + mTexture->metaData, &mTextureSRV); +} + +RenderMaterial* g_DefaultRenderMaterial = nullptr; +RenderMaterial* RenderMaterial::getDefaultRenderMaterial() +{ + if (g_DefaultRenderMaterial == nullptr) + { + ResourceManager* pResourceManager = ResourceManager::ins(); + g_DefaultRenderMaterial = new RenderMaterial("", *pResourceManager, "model_simple_ex"); + } + return g_DefaultRenderMaterial; +} +// Add By Lixu End
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.h new file mode 100644 index 0000000..912a81a --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderMaterial.h @@ -0,0 +1,132 @@ +/* +* 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. +*/ + +#ifndef RENDER_MATERIAL_H +#define RENDER_MATERIAL_H + +#include "Utils.h" +#include "DirectXTex.h" + +#include <string> +#include <vector> +#include <list> +#include <map> +#include <memory> + + +class IRenderMesh; +class ResourceManager; +struct TextureResource; +class Renderable; + + +class RenderMaterial +{ + public: + + enum BlendMode + { + BLEND_NONE, + BLEND_ALPHA_BLENDING, + BLEND_ADDITIVE + }; + + RenderMaterial(const char* materialName, ResourceManager& resourceProvider, const char* shaderFileName, const char* textureFileName = "", BlendMode blendMode = BLEND_NONE); + ~RenderMaterial(); + + void setBlending(BlendMode blendMode); + BlendMode getBlending() const { return mBlendMode; } + + void reload(); + + class Instance + { + public: + Instance(RenderMaterial& material, ID3D11InputLayout* inputLayout, uint32_t shaderNum = 0) : mMaterial(material), mInputLayout(inputLayout), mShaderNum(shaderNum) {} + ~Instance() { SAFE_RELEASE(mInputLayout); } + + bool isValid(); + void bind(ID3D11DeviceContext& context, uint32_t slot, bool depthStencilOnly = false); + RenderMaterial& getMaterial() const { return mMaterial; } + private: + RenderMaterial& mMaterial; + ID3D11InputLayout* mInputLayout; + uint32_t mShaderNum; + }; + +// Add By Lixu Begin + 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); + void addRelatedRenderable(Renderable* pRenderable){ mRelatedRenderables.push_back(pRenderable); } + std::vector<Renderable*>& getRelatedRenderables(){ return mRelatedRenderables; } + static RenderMaterial* getDefaultRenderMaterial(); +// Add By Lixu End + + InstancePtr getMaterialInstance(const IRenderMesh* mesh); + InstancePtr getMaterialInstance(const D3D11_INPUT_ELEMENT_DESC* elementDescs, uint32_t numElements); + + private: + void initialize(ResourceManager& resourceCallback, const char* shaderFileName, const char* textureFileName, BlendMode blendMode); + void initialize(ResourceManager&resourceProvider, std::vector<std::string> shaderFileNames, const char* textureFileName, BlendMode blendMode); + + void releaseReloadableResources(); + + std::string mMaterialName; + std::string mShaderFileName; + std::string mTextureFileName; + + struct ShaderGroup + { + ShaderGroup() : vs(nullptr), gs(nullptr), ps(nullptr), buffer(nullptr) + { + } + ~ShaderGroup() + { + Release(); + } + void Release() + { + SAFE_RELEASE(vs); + SAFE_RELEASE(gs); + SAFE_RELEASE(ps); + SAFE_RELEASE(buffer); + } + void Set(ID3D11DeviceContext* c, bool setPixelShader = true) + { + c->VSSetShader(vs, nullptr, 0); + c->GSSetShader(gs, nullptr, 0); + c->PSSetShader(setPixelShader ? ps : nullptr, nullptr, 0); + } + bool IsValid() + { + return vs != nullptr; + } + ID3D11VertexShader* vs; + ID3D11GeometryShader* gs; + ID3D11PixelShader* ps; + ID3DBlob* buffer; + }; + +// Add By Lixu Begin + std::map<const IRenderMesh*, Instance*> mRenderMeshToInstanceMap; + std::vector<Renderable*> mRelatedRenderables; +// Add By Lixu End + const TextureResource* mTexture; + ID3D11ShaderResourceView* mTextureSRV; + std::vector<std::string> mShaderFilePathes; + std::vector<ShaderGroup*> mShaderGroups; + ID3D11BlendState* mBlendState; + BlendMode mBlendMode; +}; + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderUtils.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderUtils.h new file mode 100644 index 0000000..12df9f2 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RenderUtils.h @@ -0,0 +1,78 @@ +/* +* 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. +*/ + +#ifndef RENDER_UTILS_H +#define RENDER_UTILS_H + +#include "DirectXTex.h" +#include <DirectXMath.h> +#include "PxMat44.h" +#include "PxVec3.h" +#include "PxVec4.h" + +static DirectX::XMFLOAT4 getRandomPastelColor() +{ + float r = ((double)rand() / (RAND_MAX)) * 0.5f + 0.5f; + float g = ((double)rand() / (RAND_MAX)) * 0.5f + 0.5f; + float b = ((double)rand() / (RAND_MAX)) * 0.5f + 0.5f; + return DirectX::XMFLOAT4(r, g, b, 1.0f); +} + +static physx::PxMat44 XMMATRIXToPxMat44(const DirectX::XMMATRIX& mat) +{ + physx::PxMat44 m; + memcpy(const_cast<float*>(m.front()), &mat.r[0], 4 * 4 * sizeof(float)); + return m; +} + +static DirectX::XMMATRIX PxMat44ToXMMATRIX(const physx::PxMat44& mat) +{ + return DirectX::XMMATRIX(mat.front()); +} + +static physx::PxVec4 XMVECTORToPxVec4(const DirectX::XMVECTOR& vec) +{ + DirectX::XMFLOAT4 f; + DirectX::XMStoreFloat4(&f, vec); + return physx::PxVec4(f.x, f.y, f.z, f.w); +} + +static physx::PxVec3 XMFLOAT3ToPxVec3(const DirectX::XMFLOAT3& vec) +{ + return physx::PxVec3(vec.x, vec.y, vec.z); +} + +static physx::PxVec4 XMFLOAT4ToPxVec4(const DirectX::XMFLOAT4& vec) +{ + return physx::PxVec4(vec.x, vec.y, vec.z, vec.w); +} + +static uint32_t XMFLOAT4ToU32Color(const DirectX::XMFLOAT4& color) +{ + uint32_t c = 0; + c |= (int)(color.w * 255); c <<= 8; + c |= (int)(color.z * 255); c <<= 8; + c |= (int)(color.y * 255); c <<= 8; + c |= (int)(color.x * 255); + return c; +} + +static DirectX::XMFLOAT4 XMFLOAT4Lerp(const DirectX::XMFLOAT4 v0, const DirectX::XMFLOAT4 v1, float val) +{ + DirectX::XMFLOAT4 v( + v0.x * (1 - val) + v1.x * val, + v0.y * (1 - val) + v1.y * val, + v0.z * (1 - val) + v1.z * val, + v0.w * (1 - val) + v1.w * val + ); + return v; +} + +#endif //RENDER_UTILS_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.cpp new file mode 100644 index 0000000..51569b7 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.cpp @@ -0,0 +1,55 @@ +/* +* 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. +*/ + +#include "Renderable.h" +#include "Renderer.h" +#include "RenderUtils.h" + +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) +// Add By Lixu End +{ + setMaterial(material); +} + +void Renderable::setMaterial(RenderMaterial& material) +{ + material.addRelatedRenderable(this); + m_materialInstance = material.getMaterialInstance(&m_mesh); +} + +void Renderable::render(Renderer& renderer, bool depthStencilOnly) const +{ + if (!m_materialInstance->isValid()) + { + PX_ALWAYS_ASSERT(); + return; + } + + m_materialInstance->bind(*renderer.m_context, 0, depthStencilOnly); + + // 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 + renderer.m_context->Unmap(renderer.m_objectCB, 0); + } + + m_mesh.render(*renderer.m_context); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.h new file mode 100644 index 0000000..9e38e4f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderable.h @@ -0,0 +1,151 @@ +/* +* 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. +*/ + +#ifndef RENDERABLE_H +#define RENDERABLE_H + +#include "RenderMaterial.h" +#include <DirectXMath.h> +#include "PxMat44.h" +#include "PxVec3.h" +#include "PxVec4.h" + +using namespace physx; + +class Renderer; + +/** +RenderMesh interface, used by Renderable +*/ +class IRenderMesh +{ +public: + virtual ~IRenderMesh() {} + virtual const std::vector<D3D11_INPUT_ELEMENT_DESC>& getInputElementDesc() const = 0; + virtual void render(ID3D11DeviceContext& context) const = 0; +// Add By Lixu Begin + virtual void setScale(PxMat44 scale, bool replace) {}; +// Add By Lixu End +}; + +/** +Renderable, represents single object renderer by Renderer. +Basically Renderable = RenderMaterial + RenderMesh +*/ +class Renderable +{ +public: + //////// public API //////// + + void setMaterial(RenderMaterial& material); + + PxMat44 getModelMatrix() const + { + return PxMat44(m_transform) * PxMat44(PxVec4(m_scale, 1)); + } + + void setTransform(PxTransform& transform) + { + m_transform = transform; + } + + const PxTransform& getTransform() const + { + return m_transform; + } + + void setScale(PxVec3 scale) + { + m_scale = scale; + } + + const PxVec3& getScale() const + { + return m_scale; + } + + void setColor(DirectX::XMFLOAT4 color) + { + m_color = color; + } + DirectX::XMFLOAT4 getColor() const + { + return m_color; + } + + void setHidden(bool hidden) + { + m_hidden = hidden; + } + + bool isHidden() const + { + return m_hidden; + } + +// Add By Lixu Begin + void setSelected(bool selected) + { + m_selected = selected; + } + + bool isSelected() const + { + return m_selected; + } + + void setMeshScale(PxMat44 scale, bool replace) + { + m_mesh.setScale(scale, replace); + } +// Add By Lixu End + + bool isTransparent() const + { + return !(m_materialInstance->getMaterial().getBlending() == RenderMaterial::BLEND_NONE); + } + + RenderMaterial& getMaterial() const { return m_materialInstance->getMaterial(); } + +private: + //////// methods used by Renderer //////// + + friend class Renderer; + + void render(Renderer& renderer) const + { + render(renderer, false); + } + + void renderDepthStencilOnly(Renderer& renderer) const + { + render(renderer, true); + } + + Renderable(IRenderMesh& mesh, RenderMaterial& material); + + void render(Renderer& renderer, bool depthStencilOnly) const; + + + //////// internal data //////// + + DirectX::XMFLOAT4 m_color; + PxTransform m_transform; + PxVec3 m_scale; + + RenderMaterial::InstancePtr m_materialInstance; + IRenderMesh& m_mesh; + bool m_hidden; +// Add By Lixu Begin + bool m_selected; +// Add By Lixu End +}; + +#endif //RENDERABLE_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.cpp new file mode 100644 index 0000000..49b1669 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.cpp @@ -0,0 +1,736 @@ +/* +* 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. +*/ + +#include "Renderer.h" +#include "RenderUtils.h" +#include "UIHelpers.h" +#include "SampleProfiler.h" + +#include "PxRenderBuffer.h" + +#include <set> + + +const float CAMERA_CLIP_NEAR = 1.0f; +const float CAMERA_CLIP_FAR = 1000.00f; + +const float CLEAR_SCENE_COLOR[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Renderer +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +Renderer::Renderer() +: m_cameraCB(nullptr) +, m_worldCB(nullptr) +, m_objectCB(nullptr) +, m_RSState(nullptr) +, m_opaqueRenderDSState(nullptr) +, m_transparencyRenderDSState(nullptr) +, m_DSTexture(nullptr) +, m_DSView(nullptr) +, m_DSTextureSRV(nullptr) +, m_pointSampler(nullptr) +, m_linearSampler(nullptr) +, m_wireframeMode(false) +, m_debugPrimitiveVB(nullptr) +, m_debugPrimitiveVBVerticesCount(0) +, m_shadowEnabled(true) +, m_HBAOEnabled(true) +, m_visibleOpaqueRenderablesCount(0) +, m_visibleTransparentRenderablesCount(0) +{ + m_worldCBData.ambientColor = DirectX::XMFLOAT3(0.21f, 0.21f, 0.22f); + m_worldCBData.pointLightColor = DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f); + m_worldCBData.pointLightPos = DirectX::XMFLOAT3(0.0f, 30.0f, 12.0f); + m_worldCBData.dirLightColor = DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f); + m_worldCBData.dirLightDir = DirectX::XMFLOAT3(-0.08f, -0.34f, -0.91f); + m_worldCBData.specularPower = 140.0f; + m_worldCBData.specularIntensity = 0.4f; + + toggleCameraSpeed(false); +} + +Renderer::~Renderer() +{ +} + +void Renderer::initializeDefaultRSState() +{ + SAFE_RELEASE(m_RSState); + D3D11_RASTERIZER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); +// Add By Lixu Begin + desc.CullMode = D3D11_CULL_NONE; +// Add By Lixu End + desc.FillMode = m_wireframeMode ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID; + desc.AntialiasedLineEnable = FALSE; + desc.DepthBias = 0; + desc.DepthBiasClamp = 0; + desc.DepthClipEnable = TRUE; + desc.FrontCounterClockwise = FALSE; + desc.MultisampleEnable = TRUE; + desc.ScissorEnable = FALSE; + desc.SlopeScaledDepthBias = 0; + + V(m_device->CreateRasterizerState(&desc, &m_RSState)); +} + +HRESULT Renderer::DeviceCreated(ID3D11Device* device) +{ + m_device = device; + + // Camera constant buffer + { + D3D11_BUFFER_DESC buffer_desc; + ZeroMemory(&buffer_desc, sizeof(buffer_desc)); + buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + buffer_desc.ByteWidth = sizeof(CBCamera); + _ASSERT((buffer_desc.ByteWidth % 16) == 0); + + V(device->CreateBuffer(&buffer_desc, nullptr, &m_cameraCB)); + } + + // World constant buffer + { + D3D11_BUFFER_DESC buffer_desc; + ZeroMemory(&buffer_desc, sizeof(buffer_desc)); + buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + buffer_desc.ByteWidth = sizeof(CBWorld); + _ASSERT((buffer_desc.ByteWidth % 16) == 0); + + V(device->CreateBuffer(&buffer_desc, nullptr, &m_worldCB)); + } + + // Object constant buffer + { + D3D11_BUFFER_DESC buffer_desc; + ZeroMemory(&buffer_desc, sizeof(buffer_desc)); + buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + buffer_desc.ByteWidth = sizeof(CBObject); + _ASSERT((buffer_desc.ByteWidth % 16) == 0); + + V(device->CreateBuffer(&buffer_desc, nullptr, &m_objectCB)); + } + + // Opaque Render Depth-Stencil state + { + D3D11_DEPTH_STENCIL_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.StencilEnable = FALSE; + desc.DepthEnable = TRUE; + desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; + + V(device->CreateDepthStencilState(&desc, &m_opaqueRenderDSState)); + } + + // Transparency Render Depth-Stencil state + { + D3D11_DEPTH_STENCIL_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.StencilEnable = FALSE; + desc.DepthEnable = TRUE; + desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; + + V(device->CreateDepthStencilState(&desc, &m_transparencyRenderDSState)); + } + + // Linear sampler + { + D3D11_SAMPLER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + desc.MaxAnisotropy = 1; + desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + desc.MinLOD = 0; + desc.MaxLOD = D3D11_FLOAT32_MAX; + V(device->CreateSamplerState(&desc, &m_linearSampler)); + } + + // Point sampler + { + D3D11_SAMPLER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + desc.MaxAnisotropy = 1; + desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + desc.MinLOD = 0; + desc.MaxLOD = D3D11_FLOAT32_MAX; + V(device->CreateSamplerState(&desc, &m_pointSampler)); + } + + // Rasterizer state + initializeDefaultRSState(); + + // init primitive render meshes + for (uint32_t i = 0; i < PrimitiveRenderMeshType::Count; i++) + { + m_primitiveRenderMeshes[i] = nullptr; + } + + // init shadows + ID3D11DeviceContext* pd3dDeviceContext; + m_device->GetImmediateContext(&pd3dDeviceContext); + m_shadow.createResources(m_device, pd3dDeviceContext, &m_camera); + + // init hbao + m_HBAO.createResources(m_device); + + return S_OK; +} + +void Renderer::DeviceDestroyed() +{ + SAFE_RELEASE(m_cameraCB); + SAFE_RELEASE(m_worldCB); + SAFE_RELEASE(m_objectCB); + SAFE_RELEASE(m_RSState); + SAFE_RELEASE(m_opaqueRenderDSState); + SAFE_RELEASE(m_transparencyRenderDSState); + SAFE_RELEASE(m_pointSampler); + SAFE_RELEASE(m_linearSampler); + SAFE_RELEASE(m_debugPrimitiveVB); + SAFE_RELEASE(m_DSTexture); + SAFE_RELEASE(m_DSView); + SAFE_RELEASE(m_DSTextureSRV); + + for (uint32_t i = 0; i < PrimitiveRenderMeshType::Count; i++) + { + SAFE_DELETE(m_primitiveRenderMeshes[i]); + } +} + +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()); + } + + // debug primitive render material and input layout + { + m_debugPrimitiveRenderMaterial = new RenderMaterial("", m_resourceManager, "debug_primitive", ""); + + D3D11_INPUT_ELEMENT_DESC layout[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 } + }; + + m_debugPrimitiveRenderMaterialInstance = m_debugPrimitiveRenderMaterial->getMaterialInstance(layout, ARRAYSIZE(layout)); + } +} + +void Renderer::onTerminate() +{ + SAFE_DELETE(m_debugPrimitiveRenderMaterial); +} + +void Renderer::BackBufferResized(ID3D11Device* /*device*/, const DXGI_SURFACE_DESC* sd) +{ + // Setup the camera's projection parameters + 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); + + SAFE_RELEASE(m_DSTexture); + SAFE_RELEASE(m_DSView); + SAFE_RELEASE(m_DSTextureSRV); + + // create a new Depth-Stencil texture + { + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = sd->Width; + desc.Height = sd->Height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R32_TYPELESS; // Use a typeless type here so that it can be both depth-stencil and shader resource. + desc.SampleDesc.Count = sd->SampleDesc.Count; + desc.SampleDesc.Quality = sd->SampleDesc.Quality; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + V(m_device->CreateTexture2D(&desc, NULL, &m_DSTexture)); + } + + // create Depth-Stencil view + { + D3D11_DEPTH_STENCIL_VIEW_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.ViewDimension = sd->SampleDesc.Count > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; + desc.Format = DXGI_FORMAT_D32_FLOAT; // Make the view see this as D32_FLOAT instead of typeless + desc.Texture2D.MipSlice = 0; + V(m_device->CreateDepthStencilView(m_DSTexture, &desc, &m_DSView)); + } + + // create Depth-Stencil shader resource view + { + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Format = DXGI_FORMAT_R32_FLOAT; // Make the shaders see this as R32_FLOAT instead of typeless + desc.ViewDimension = sd->SampleDesc.Count > 1 ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipLevels = 1; + desc.Texture2D.MostDetailedMip = 0; + V(m_device->CreateShaderResourceView(m_DSTexture, &desc, &m_DSTextureSRV)); + } + + // setup viewport + m_viewport.Width = (FLOAT)sd->Width; + m_viewport.Height = (FLOAT)sd->Height; + m_viewport.MinDepth = 0; + m_viewport.MaxDepth = 1; + m_viewport.TopLeftX = 0; + m_viewport.TopLeftY = 0; + + // setup shadows + m_shadow.setScreenResolution(0, sd->Width, sd->Height, sd->SampleDesc.Count, nullptr); +} + +void Renderer::setAllConstantBuffers(ID3D11DeviceContext* ctx) +{ + ID3D11Buffer* cbs[3] = { m_cameraCB, m_worldCB, m_objectCB }; + ctx->VSSetConstantBuffers(0, 3, cbs); + ctx->GSSetConstantBuffers(0, 3, cbs); + ctx->PSSetConstantBuffers(0, 3, cbs); +} + +void Renderer::Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11RenderTargetView* pRTV, + ID3D11DepthStencilView*) +{ + PROFILER_SCOPED_FUNCTION(); + + 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 projMatrixInv = DirectX::XMMatrixInverse(NULL, projMatrix); + DirectX::XMMATRIX viewProjMatrix = viewMatrix * projMatrix; + + // Fill Camera constant buffer + { + D3D11_MAPPED_SUBRESOURCE mappedResource; + ctx->Map(m_cameraCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + CBCamera* cameraBuffer = (CBCamera*)mappedResource.pData; + cameraBuffer->viewProjection = viewProjMatrix; + cameraBuffer->projectionInv = projMatrixInv; + DirectX::XMStoreFloat3(&(cameraBuffer->viewPos), m_camera.GetEyePt()); + ctx->Unmap(m_cameraCB, 0); + } + + // Fill World constant buffer + { + D3D11_MAPPED_SUBRESOURCE mappedResource; + ctx->Map(m_worldCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + CBWorld* worldBuffer = (CBWorld*)mappedResource.pData; + memcpy(worldBuffer, &m_worldCBData, sizeof(m_worldCBData)); + //worldBuffer->ambientColor = m_CBWorldData.ambientColor; + //worldBuffer->pointLightPos = m_CBWorldData.pointLightPos; + //worldBuffer->pointLightColor = m_CBWorldData.pointLightColor; + //worldBuffer->dirLightDir = m_CBWorldData.dirLightDir; + //worldBuffer->specularPower = m_CBWorldData.specularPower; + //worldBuffer->dirLightColor = m_CBWorldData.dirLightColor; + //worldBuffer->specularIntensity = m_CBWorldData.specularIntensity; + ctx->Unmap(m_worldCB, 0); + } + + ctx->RSSetState(m_RSState); + ctx->PSSetSamplers(0, 1, &m_linearSampler); + ctx->PSSetSamplers(1, 1, &m_pointSampler); + + + if (m_shadowEnabled) + { + // render depth only + { + ctx->OMSetRenderTargets(0, nullptr, m_DSView); + ctx->OMSetDepthStencilState(m_opaqueRenderDSState, 0xFF); + + // set constants buffers + setAllConstantBuffers(ctx); + + for (auto it = m_renderables.begin(); it != m_renderables.end(); it++) + { + if (!(*it)->isTransparent() && !(*it)->isHidden()) + (*it)->renderDepthStencilOnly(*this); + } + } + + // render shadow map + m_shadow.renderShadowMaps(this); + + // render shadow buffer + ctx->OMSetRenderTargets(0, nullptr, nullptr); + m_shadow.renderShadowBuffer(m_DSTextureSRV, nullptr); + } + + // Opaque render + { + ctx->RSSetViewports(1, &m_viewport); + ctx->RSSetState(m_RSState); + ctx->OMSetRenderTargets(1, &pRTV, m_DSView); + ctx->OMSetDepthStencilState(m_opaqueRenderDSState, 0xFF); + + // set constants buffers + setAllConstantBuffers(ctx); + + // Fill Camera constant buffer + { + D3D11_MAPPED_SUBRESOURCE mappedResource; + ctx->Map(m_cameraCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + CBCamera* cameraBuffer = (CBCamera*)mappedResource.pData; + cameraBuffer->viewProjection = viewProjMatrix; + cameraBuffer->projectionInv = projMatrixInv; + DirectX::XMStoreFloat3(&(cameraBuffer->viewPos), m_camera.GetEyePt()); + ctx->Unmap(m_cameraCB, 0); + } + + // Render opaque renderables + m_visibleOpaqueRenderablesCount = 0; + for (auto it = m_renderables.begin(); it != m_renderables.end(); it++) + { + if (!(*it)->isTransparent() && !(*it)->isHidden()) + { + (*it)->render(*this); + m_visibleOpaqueRenderablesCount++; + } + } + } + + // modulate shadows + if (m_shadowEnabled) + { + m_shadow.modulateShadowBuffer(pRTV); + } + + // render AO + if (m_HBAOEnabled) + { + m_HBAO.renderAO(m_context, pRTV, m_DSTextureSRV, projMatrix); + } + + ctx->RSSetViewports(1, &m_viewport); + + // render debug render buffers + while (m_queuedRenderBuffers.size() > 0) + { + render(m_queuedRenderBuffers.back()); + m_queuedRenderBuffers.pop_back(); + } + + // Transparency render + ctx->OMSetRenderTargets(1, &pRTV, m_DSView); + ctx->OMSetDepthStencilState(m_transparencyRenderDSState, 0xFF); + + // depth as SRV isn't used now (uncommenting will produce a warning, probably need readonly depth?) + //ctx->PSSetShaderResources(1, 1, &mDSTextureSRV); + + // Render transparent renderables + m_visibleTransparentRenderablesCount = 0; + for (auto it = m_renderables.begin(); it != m_renderables.end(); it++) + { + if ((*it)->isTransparent() && !(*it)->isHidden()) + { + (*it)->render(*this); + m_visibleTransparentRenderablesCount++; + } + } + + // shadows debug render + if (0) + { + m_shadow.displayMapFrustums(pRTV, m_DSView); + } + + // Reset RT and SRV state + ID3D11ShaderResourceView* nullAttach[16] = { nullptr }; + ctx->PSSetShaderResources(0, 16, nullAttach); + ctx->OMSetRenderTargets(0, nullptr, nullptr); +} + +LRESULT Renderer::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PX_UNUSED(hWnd); + PX_UNUSED(wParam); + PX_UNUSED(lParam); + + if (uMsg == WM_KEYDOWN || uMsg == WM_KEYUP) + { + // Camera overspeed event + int iKeyPressed = static_cast<int>(wParam); + if (iKeyPressed == VK_SHIFT) + { + toggleCameraSpeed(uMsg == WM_KEYDOWN); + } + } + + // Camera events + return m_camera.HandleMessages(hWnd, uMsg, wParam, lParam); +} + +void Renderer::Animate(double fElapsedTimeSeconds) +{ + PROFILER_SCOPED_FUNCTION(); + + m_camera.FrameMove((float)fElapsedTimeSeconds); +} + +void Renderer::renderDepthOnly(DirectX::XMMATRIX* viewProjectionSubstitute) +{ + // Fill Camera constant buffer + if (viewProjectionSubstitute) + { + D3D11_MAPPED_SUBRESOURCE mappedResource; + m_context->Map(m_cameraCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + CBCamera* cameraBuffer = (CBCamera*)mappedResource.pData; + cameraBuffer->viewProjection = *viewProjectionSubstitute; + m_context->Unmap(m_cameraCB, 0); + } + + // set constants buffers + setAllConstantBuffers(m_context); + + // render + for (auto it = m_renderables.begin(); it != m_renderables.end(); it++) + { + if (!(*it)->isTransparent() && !(*it)->isHidden()) + (*it)->renderDepthStencilOnly(*this); + } +} + +void Renderer::render(const PxRenderBuffer* renderBuffer) +{ + // points + uint32_t pointsCount = renderBuffer->getNbPoints(); + if (pointsCount > 0) + { + RenderDebugVertex* verts = new RenderDebugVertex[pointsCount]; + const PxDebugPoint* points = renderBuffer->getPoints(); + for (uint32_t i = 0; i < pointsCount; i++) + { + verts[i].mPos = points[i].pos; + verts[i].mColor = points[i].color; + } + + renderDebugPrimitive(verts, pointsCount, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + delete[] verts; + } + + // lines + uint32_t linesCount = renderBuffer->getNbLines(); + if (linesCount > 0) + { + RenderDebugVertex* verts = new RenderDebugVertex[linesCount * 2]; + const PxDebugLine* lines = renderBuffer->getLines(); + for (uint32_t i = 0; i < linesCount; i++) + { + verts[i * 2].mPos = lines[i].pos0; + verts[i * 2].mColor = lines[i].color0; + verts[i * 2 + 1].mPos = lines[i].pos1; + verts[i * 2 + 1].mColor = lines[i].color1; + } + + renderDebugPrimitive(verts, linesCount * 2, D3D11_PRIMITIVE_TOPOLOGY_LINELIST); + delete[] verts; + } + + // triangles + uint32_t trianglesCount = renderBuffer->getNbTriangles(); + if (trianglesCount > 0) + { + RenderDebugVertex* verts = new RenderDebugVertex[trianglesCount * 3]; + const PxDebugTriangle* triangles = renderBuffer->getTriangles(); + for (uint32_t i = 0; i < trianglesCount; i++) + { + verts[i * 3].mPos = triangles[i].pos0; + verts[i * 3].mColor = triangles[i].color0; + verts[i * 3 + 1].mPos = triangles[i].pos1; + verts[i * 3 + 1].mColor = triangles[i].color1; + verts[i * 3 + 2].mPos = triangles[i].pos2; + verts[i * 3 + 2].mColor = triangles[i].color2; + } + + renderDebugPrimitive(verts, trianglesCount * 3, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + delete[] verts; + } + + // texts? + // .... +} + +void Renderer::renderDebugPrimitive(const Renderer::RenderDebugVertex *vertices, uint32_t verticesCount, D3D11_PRIMITIVE_TOPOLOGY topology) +{ + m_context->IASetPrimitiveTopology(topology); + + m_debugPrimitiveRenderMaterialInstance->bind(*m_context, 0); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + m_context->Map(m_objectCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + CBObject* objectBuffer = (CBObject*)mappedResource.pData; + + objectBuffer->world = PxMat44ToXMMATRIX(PxMat44(PxIdentity)); + + m_context->Unmap(m_objectCB, 0); + + if (m_debugPrimitiveVBVerticesCount < verticesCount) + { + m_debugPrimitiveVBVerticesCount = verticesCount; + SAFE_RELEASE(m_debugPrimitiveVB); + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = sizeof(Renderer::RenderDebugVertex) * m_debugPrimitiveVBVerticesCount; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + + V(m_device->CreateBuffer(&bufferDesc, NULL, &m_debugPrimitiveVB)); + } + + CD3D11_BOX box(0, 0, 0, (LONG)(sizeof(Renderer::RenderDebugVertex) * verticesCount), 1, 1); + m_context->UpdateSubresource(m_debugPrimitiveVB, 0, &box, vertices, 0, 0); + + ID3D11Buffer* pBuffers[1] = { m_debugPrimitiveVB }; + UINT strides[1] = { sizeof(RenderDebugVertex) }; + UINT offsets[1] = { 0 }; + m_context->IASetVertexBuffers(0, 1, pBuffers, strides, offsets); + + m_context->Draw(verticesCount, 0); +} + +IRenderMesh* Renderer::getPrimitiveRenderMesh(PrimitiveRenderMeshType::Enum type) +{ + if (m_primitiveRenderMeshes[type] == NULL) + { + switch (type) + { + case PrimitiveRenderMeshType::Box: + m_primitiveRenderMeshes[type] = new BoxRenderMesh(); + break; + case PrimitiveRenderMeshType::Plane: + m_primitiveRenderMeshes[type] = new PlaneRenderMesh(); + break; + case PrimitiveRenderMeshType::Sphere: + m_primitiveRenderMeshes[type] = new SphereRenderMesh(); + break; +// Add By Lixu Begin + case PrimitiveRenderMeshType::Cone: + m_primitiveRenderMeshes[type] = new ConeRenderMesh(); + break; +// Add By Lixu End + default: + PX_ALWAYS_ASSERT_MESSAGE("Unsupported PxGeometryType"); + return NULL; + } + } + + return m_primitiveRenderMeshes[type]; +} + + +Renderable* Renderer::createRenderable(IRenderMesh& mesh, RenderMaterial& material) +{ + Renderable* renderable = new Renderable(mesh, material); + m_renderables.emplace(renderable); + return renderable; +} + +void Renderer::removeRenderable(Renderable* r) +{ + m_renderables.erase(m_renderables.find(r)); + delete r; +} + +void Renderer::toggleCameraSpeed(bool overspeed) +{ + m_camera.SetScalers(0.002f, overspeed ? 150.f : 25.f); +} + +void Renderer::reloadShaders() +{ + // iterate Renderables materials and call reload() + std::set<RenderMaterial*> materials; + for (auto it = m_renderables.begin(); it != m_renderables.end(); it++) + { + materials.emplace(&((*it)->getMaterial())); + } + for (std::set<RenderMaterial*>::iterator it = materials.begin(); it != materials.end(); it++) + { + (*it)->reload(); + } +} + +void Renderer::drawUI() +{ + // Lighting + if (ImGui::TreeNode("Lighting")) + { + ImGui::ColorEdit3("Ambient Color", &(m_worldCBData.ambientColor.x)); + ImGui::ColorEdit3("Point Light Color", &(m_worldCBData.pointLightColor.x)); + ImGui::DragFloat3("Point Light Pos", &(m_worldCBData.pointLightPos.x)); + ImGui::ColorEdit3("Dir Light Color", &(m_worldCBData.dirLightColor.x)); + ImGui_DragFloat3Dir("Dir Light Dir", &(m_worldCBData.dirLightDir.x)); + ImGui::DragFloat("Specular Power", &(m_worldCBData.specularPower), 1.0f, 1.0f, 500.0f); + ImGui::DragFloat("Specular Intensity", &(m_worldCBData.specularIntensity), 0.01f, 0.0f, 2.0f); + + ImGui::TreePop(); + } + + // Shadow + if (ImGui::TreeNode("Shadow")) + { + ImGui::Checkbox("Shadows Enabled", &m_shadowEnabled); + if (m_shadowEnabled) + { + m_shadow.drawUI(); + } + + ImGui::TreePop(); + } + + // HBAO+ + if (ImGui::TreeNode("HBAO+")) + { + ImGui::Checkbox("HBAO Enabled", &(m_HBAOEnabled)); + if (m_HBAOEnabled) + { + m_HBAO.drawUI(); + } + + ImGui::TreePop(); + } +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.h new file mode 100644 index 0000000..58662a6 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/Renderer.h @@ -0,0 +1,251 @@ +/* +* 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. +*/ + +#ifndef RENDERER_H +#define RENDERER_H + +#include "RenderMaterial.h" +#include <DirectXMath.h> +#include "XInput.h" +#include "DXUTMisc.h" +#include "DXUTCamera.h" +#include "SampleManager.h" +#include "Utils.h" +#include "ResourceManager.h" +#include "PrimitiveRenderMesh.h" +#include "RendererShadow.h" +#include "RendererHBAO.h" +#include <unordered_set> + +class CFirstPersonCamera; +class PhysXPrimitive; +class RenderDebugImpl; + +namespace physx +{ +class PxRenderBuffer; +} + + +/** +3D World Renderer +- use createRenderable() to add objects to render. +- use queueRenderBuffer() every frame to render debug primitives. +- contains ResourceManager to search for file and load resources. +- contains RendererShadow and RendererHBAO, use them through getters to control shadows. +*/ +class Renderer : public ISampleController +{ + friend class Renderable; + + public: + //////// ctor //////// + + Renderer(); + ~Renderer(); + + + //////// public API //////// + + void reloadShaders(); + + bool getWireframeMode() + { + return m_wireframeMode; + } + + void setWireframeMode(bool enabled) + { + if(m_wireframeMode != enabled) + { + m_wireframeMode = enabled; + initializeDefaultRSState(); + } + } + + IRenderMesh* getPrimitiveRenderMesh(PrimitiveRenderMeshType::Enum type); + + Renderable* createRenderable(IRenderMesh& mesh, RenderMaterial& material); + void removeRenderable(Renderable* r); + + void drawUI(); + + + //////// public getters //////// + + float getScreenWidth() const + { + return m_screenWidth; + } + + float getScreenHeight() const + { + return m_screenHeight; + } + + void queueRenderBuffer(const PxRenderBuffer* buffer) + { + m_queuedRenderBuffers.push_back(buffer); + } + + ResourceManager& getResourceManager() + { + return m_resourceManager; + } + + uint32_t getVisibleOpaqueRenderablesCount() + { + return m_visibleOpaqueRenderablesCount; + } + + uint32_t getVisibleTransparentRenderablesCount() + { + return m_visibleTransparentRenderablesCount; + } + + CFirstPersonCamera& getCamera() + { + return m_camera; + } + + + //////// public 'internal' methods //////// + + // for internal usage (used by RenderShadows) + void renderDepthOnly(DirectX::XMMATRIX* viewProjectionSubstitute); + + protected: + + //////// controller callbacks //////// + + virtual HRESULT DeviceCreated(ID3D11Device* pDevice); + virtual void DeviceDestroyed(); + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual void Animate(double fElapsedTimeSeconds); + virtual void onInitialize(); + virtual void onTerminate(); + virtual void BackBufferResized(ID3D11Device* pDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc); + virtual void Render(ID3D11Device* /*device*/, ID3D11DeviceContext* ctx, ID3D11RenderTargetView* pRTV, + ID3D11DepthStencilView* pDSV); + + private: + + //////// internal methods //////// + + struct RenderDebugVertex + { + PxVec3 mPos; + uint32_t mColor; + }; + + void render(const PxRenderBuffer* renderBuffer); + void render(Renderable* renderable); + void renderDebugPrimitive(const RenderDebugVertex *vertices, uint32_t verticesCount, D3D11_PRIMITIVE_TOPOLOGY topology); + void initializeDefaultRSState(); + void setAllConstantBuffers(ID3D11DeviceContext* ctx); + void toggleCameraSpeed(bool overspeed); + + + //////// constant buffers //////// + + struct CBCamera + { + DirectX::XMMATRIX viewProjection; + DirectX::XMMATRIX projectionInv; + DirectX::XMFLOAT3 viewPos; + float unusedPad; + }; + struct CBWorld + { + DirectX::XMFLOAT3 ambientColor; + float unusedPad1; + DirectX::XMFLOAT3 pointLightPos; + float unusedPad2; + DirectX::XMFLOAT3 pointLightColor; + float unusedPad3; + DirectX::XMFLOAT3 dirLightDir; + float specularPower; + DirectX::XMFLOAT3 dirLightColor; + float specularIntensity; // TODO: actually it's per object property + }; + struct CBObject + { + DirectX::XMMATRIX world; + DirectX::XMFLOAT4 color; +// Add By Lixu Begin + float selected; +// Add By Lixu End + }; + + + //////// internal data //////// + + // camera + CFirstPersonCamera m_camera; + float m_screenWidth; + float m_screenHeight; + + // resources + ResourceManager m_resourceManager; + + // additional render modules(libs) + RendererShadow m_shadow; + bool m_shadowEnabled; + RendererHBAO m_HBAO; + bool m_HBAOEnabled; + + // DX11 common + ID3D11Device* m_device; + ID3D11DeviceContext* m_context; + D3D11_VIEWPORT m_viewport; + + // DX11 states + ID3D11RasterizerState* m_RSState; + ID3D11DepthStencilState* m_opaqueRenderDSState; + ID3D11DepthStencilState* m_transparencyRenderDSState; + + // DX11 samplers + ID3D11SamplerState* m_pointSampler; + ID3D11SamplerState* m_linearSampler; + + // Depth Buffer + ID3D11Texture2D* m_DSTexture; + ID3D11DepthStencilView* m_DSView; + ID3D11ShaderResourceView* m_DSTextureSRV; + + // Constant Buffers + ID3D11Buffer* m_cameraCB; + ID3D11Buffer* m_worldCB; + CBWorld m_worldCBData; + ID3D11Buffer* m_objectCB; + + // toggles (options) + bool m_wireframeMode; + + // renderables + std::unordered_set<Renderable*> m_renderables; + + // primitive meshes cache + IRenderMesh* m_primitiveRenderMeshes[PrimitiveRenderMeshType::Count]; + + // stats + uint32_t m_visibleOpaqueRenderablesCount; + uint32_t m_visibleTransparentRenderablesCount; + + // Debug Render + RenderMaterial* m_debugPrimitiveRenderMaterial; + RenderMaterial::InstancePtr m_debugPrimitiveRenderMaterialInstance; + ID3D11Buffer* m_debugPrimitiveVB; + uint32_t m_debugPrimitiveVBVerticesCount; + std::vector<const PxRenderBuffer*> m_queuedRenderBuffers; +}; + + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.cpp new file mode 100644 index 0000000..5e20a49 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.cpp @@ -0,0 +1,81 @@ +/* +* 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. +*/ + + +#include "RendererHBAO.h" +#include "Renderer.h" +#include "imgui.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Renderer HBAO (wrapper for hbao+) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +RendererHBAO::RendererHBAO() +{ + m_SSAOContext = NULL; + + // default parameters + m_SSAOParameters.Radius = 2.0f; +} + + +RendererHBAO::~RendererHBAO() +{ + releaseResources(); +} + + +void RendererHBAO::createResources(ID3D11Device *pd3dDevice) +{ + GFSDK_SSAO_Status status; + status = GFSDK_SSAO_CreateContext_D3D11(pd3dDevice, &m_SSAOContext, nullptr); + assert(status == GFSDK_SSAO_OK); +} + + +void RendererHBAO::releaseResources() +{ + if (m_SSAOContext != NULL) + { + m_SSAOContext->Release(); + } +} + + +void RendererHBAO::renderAO(ID3D11DeviceContext *pd3dDeviceContext, ID3D11RenderTargetView* pRTV, ID3D11ShaderResourceView* pDepthSRV, DirectX::XMMATRIX& projMatrix) +{ + GFSDK_SSAO_InputData_D3D11 InputData; + InputData.DepthData.pFullResDepthTextureSRV = pDepthSRV; + InputData.DepthData.DepthTextureType = GFSDK_SSAO_HARDWARE_DEPTHS; + InputData.DepthData.MetersToViewSpaceUnits = 1.0f; + InputData.DepthData.ProjectionMatrix.Data = GFSDK_SSAO_Float4x4(reinterpret_cast<const GFSDK_SSAO_FLOAT*>(&(projMatrix.r[0]))); + InputData.DepthData.ProjectionMatrix.Layout = GFSDK_SSAO_ROW_MAJOR_ORDER; + + GFSDK_SSAO_Output_D3D11 Output; + Output.pRenderTargetView = pRTV;// m_pSceneRTs->ColorRTV; + Output.Blend.Mode = GFSDK_SSAO_MULTIPLY_RGB; + + m_SSAOContext->RenderAO(pd3dDeviceContext, InputData, m_SSAOParameters, Output); +} + + +void RendererHBAO::drawUI() +{ + ImGui::DragFloat("Radius", &(m_SSAOParameters.Radius), 0.05f, 0.0f, 100.0f); + ImGui::DragFloat("Bias", &(m_SSAOParameters.Bias), 0.01f, 0.0f, 0.5f); + ImGui::DragFloat("NearAO", &(m_SSAOParameters.NearAO), 0.01f, 1.0f, 4.0f); + ImGui::DragFloat("FarAO", &(m_SSAOParameters.FarAO), 0.01, 1.0f, 4.0f); + ImGui::DragFloat("PowerExponent", &(m_SSAOParameters.PowerExponent), 0.01f, 1.0f, 8.0f); + ImGui::Checkbox("ForegroundAO Enabled", (bool*)&(m_SSAOParameters.ForegroundAO.Enable)); + ImGui::DragFloat("ForegroundAO ViewDepth", &(m_SSAOParameters.ForegroundAO.ForegroundViewDepth), 0.01f, 0.0f, 100.0f); + ImGui::Checkbox("BackgroundAO Enabled", (bool*)&(m_SSAOParameters.BackgroundAO.Enable)); + ImGui::DragFloat("BackgroundAO ViewDepth", &(m_SSAOParameters.BackgroundAO.BackgroundViewDepth), 0.01f, 0.0f, 100.0f); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.h new file mode 100644 index 0000000..2478628 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererHBAO.h @@ -0,0 +1,40 @@ +/* +* 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. +*/ + +#ifndef RENDERER_HBAO_H +#define RENDERER_HBAO_H + +#include <DirectXMath.h> +#include "GFSDK_SSAO.h" + + +class Renderer; + +class RendererHBAO +{ +public: + RendererHBAO(); + ~RendererHBAO(); + + void createResources(ID3D11Device *pd3dDevice); + void renderAO(ID3D11DeviceContext *pd3dDeviceContext, ID3D11RenderTargetView* pRTV, ID3D11ShaderResourceView* pDepthSRV, DirectX::XMMATRIX& projMatrix); + + void drawUI(); + +private: + void releaseResources(); + + GFSDK_SSAO_Parameters m_SSAOParameters; + + GFSDK_SSAO_Context_D3D11* m_SSAOContext; +}; + + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.cpp new file mode 100644 index 0000000..28a79e5 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.cpp @@ -0,0 +1,417 @@ +/* +* 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. +*/ + + +#include "RendererShadow.h" + +#include "XInput.h" +#include "DXUTMisc.h" +#include "DXUTCamera.h" +#include "Renderer.h" +#include "UIHelpers.h" + +#define CASCADES 1 + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Renderer Shadows (wrapper for shadow_lib) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +const float DEFAULT_LIGHT_SIZE = 3.0f; +const DirectX::XMFLOAT3 DEFAULT_LIGHT_POS(-25, 25, 25); +const DirectX::XMFLOAT3 DEFAULT_LIGHT_LOOK_AT(0, 0, 0); +const DirectX::XMFLOAT3 DEFAULT_SHADOW_COLOR(0.25f, 0.25f, 0.25f); + +RendererShadow::RendererShadow() +{ + m_shadowLibContext = NULL; + + m_PCSSEnabled = false; + m_lightSize = DEFAULT_LIGHT_SIZE; + m_lightPos = DEFAULT_LIGHT_POS; + m_lightLookAt = DEFAULT_LIGHT_LOOK_AT; + m_shadowColor = DEFAULT_SHADOW_COLOR; + + m_worldSpaceBBox0.x = m_worldSpaceBBox0.y = m_worldSpaceBBox0.z = -100; + m_worldSpaceBBox1.x = m_worldSpaceBBox1.y = m_worldSpaceBBox1.z = 100; + + // Penumbra params + m_PCSSParams.fMaxThreshold = 80.0f; + m_PCSSParams.fMaxClamp = 40.0f; + m_PCSSParams.fMinSizePercent = 3.0f; + m_PCSSParams.fMinWeightExponent = 5.0f; + m_PCSSParams.fMinWeightThresholdPercent = 20.0f; + + m_softShadowTestScale = 0.002f; + + memset(&m_shadowBufferSRV, 0, sizeof(m_shadowBufferSRV)); + + m_shadowMapHandle = NULL; + m_shadowBufferHandle = NULL; +} + + +RendererShadow::~RendererShadow() +{ + ReleaseResources(); +} + + +void RendererShadow::createResources(ID3D11Device *pd3dDevice, ID3D11DeviceContext* context, CFirstPersonCamera* camera) +{ + m_camera = camera; + +#if !CASCADES + uint32_t shadowMapScale = 5; + uint32_t shadowMapWidth = 1024; + uint32_t shadowMapHeight = 1024; + + // SM Desc + m_SMDesc.eViewType = GFSDK_ShadowLib_ViewType_Single; + m_SMDesc.eMapType = GFSDK_ShadowLib_MapType_Texture; +#else + + uint32_t shadowMapScale = 5; + uint32_t shadowMapWidth = 1024; + uint32_t shadowMapHeight = 1024; + + // SM Desc + m_SMDesc.eViewType = GFSDK_ShadowLib_ViewType_Cascades_2; + m_SMDesc.eMapType = GFSDK_ShadowLib_MapType_TextureArray; +#endif + + m_SMDesc.uResolutionWidth = shadowMapWidth * shadowMapScale; + m_SMDesc.uResolutionHeight = shadowMapHeight * shadowMapScale; + m_SMDesc.uArraySize = m_SMDesc.eViewType; + + for (int j = 0; j < GFSDK_ShadowLib_ViewType_Cascades_4; j++) + { + m_SMDesc.ViewLocation[j].uMapID = j; + m_SMDesc.ViewLocation[j].v2Origin.x = 0; + m_SMDesc.ViewLocation[j].v2Origin.y = 0; + m_SMDesc.ViewLocation[j].v2Dimension.x = shadowMapWidth * shadowMapScale; + m_SMDesc.ViewLocation[j].v2Dimension.y = shadowMapHeight * shadowMapScale; + } + + + // SM Render Params + m_SMRenderParams.iDepthBias = 1000; + m_SMRenderParams.fSlopeScaledDepthBias = 8; + + // SB Render Params + m_SBRenderParams.eTechniqueType = GFSDK_ShadowLib_TechniqueType_PCSS; + m_SBRenderParams.eQualityType = GFSDK_ShadowLib_QualityType_High; + + // DLL version + GFSDK_ShadowLib_Version DLLVersion; + GFSDK_ShadowLib_Status retCode = GFSDK_ShadowLib_GetDLLVersion(&DLLVersion); + + // Header version + GFSDK_ShadowLib_Version headerVersion; + headerVersion.uMajor = GFSDK_SHADOWLIB_MAJOR_VERSION; + headerVersion.uMinor = GFSDK_SHADOWLIB_MINOR_VERSION; + + // Do they match? + if (DLLVersion.uMajor == headerVersion.uMajor && DLLVersion.uMinor == headerVersion.uMinor) + { + GFSDK_ShadowLib_DeviceContext deviceAndContext; + deviceAndContext.pD3DDevice = pd3dDevice; + deviceAndContext.pDeviceContext = context; + + retCode = GFSDK_ShadowLib_Create(&headerVersion, &m_shadowLibContext, &deviceAndContext, NULL); + + if (retCode != GFSDK_ShadowLib_Status_Ok) assert(false); + } + else + { + assert(false); + } +} + + +void RendererShadow::ReleaseResources() +{ + SAFE_RELEASE(m_downsampledShadowMap.pTexture); + SAFE_RELEASE(m_downsampledShadowMap.pSRV); + SAFE_RELEASE(m_downsampledShadowMap.pRTV); + + if (m_shadowLibContext != NULL) + { + m_shadowLibContext->Destroy(); + m_shadowLibContext = NULL; + } +} + + +void RendererShadow::setScreenResolution(float FovyRad, UINT Width, UINT Height, UINT uSampleCount, ID3D11DepthStencilView* pReadOnlyDSV) +{ + changeShadowSettings(Width, Height, uSampleCount, pReadOnlyDSV); +} + + +void RendererShadow::changeShadowSettings(UINT Width, UINT Height, UINT uSampleCount, ID3D11DepthStencilView* pReadOnlyDSV) +{ + m_SBDesc.uResolutionWidth = Width; + m_SBDesc.uResolutionHeight = Height; + m_SBDesc.uSampleCount = uSampleCount; + m_SBDesc.ReadOnlyDSV.pDSV = pReadOnlyDSV; + + reloadBuffers(); +} + +void RendererShadow::reloadBuffers() +{ + { + m_shadowLibContext->RemoveMap(&m_shadowMapHandle); + + if (m_SMDesc.eMapType == GFSDK_ShadowLib_MapType_Texture && + m_SMDesc.eViewType == GFSDK_ShadowLib_ViewType_Single && + m_SBRenderParams.eTechniqueType == GFSDK_ShadowLib_TechniqueType_PCSS) + { + m_SMDesc.bDownsample = true; + } + + m_shadowLibContext->AddMap(&m_SMDesc, &m_shadowMapHandle); + } + + if (m_SMDesc.eMapType == GFSDK_ShadowLib_MapType_Texture && m_SMDesc.eViewType == GFSDK_ShadowLib_ViewType_Single) + { + m_downsampledShadowMap.uWidth = m_SMDesc.uResolutionWidth >> 1; + m_downsampledShadowMap.uHeight = m_SMDesc.uResolutionHeight >> 1; + m_downsampledShadowMap.uSampleCount = 1; + m_downsampledShadowMap.Format = DXGI_FORMAT_R32_FLOAT; + SAFE_RELEASE(m_downsampledShadowMap.pTexture); + SAFE_RELEASE(m_downsampledShadowMap.pSRV); + SAFE_RELEASE(m_downsampledShadowMap.pRTV); + m_shadowLibContext->DevModeCreateTexture2D(&m_downsampledShadowMap); + } + + m_shadowLibContext->RemoveBuffer(&m_shadowBufferHandle); + m_shadowLibContext->AddBuffer(&m_SBDesc, &m_shadowBufferHandle); +} + + + +//-------------------------------------------------------------------------------------- +// Data passed to the shadow map render function +//-------------------------------------------------------------------------------------- +struct ShadowMapRenderFunctionParams +{ + Renderer* renderer; +}; +static ShadowMapRenderFunctionParams s_RenderParams; + +//-------------------------------------------------------------------------------------- +// Shadow map render function +//-------------------------------------------------------------------------------------- +static void ShadowMapRenderFunction(void* pParams, gfsdk_float4x4* pViewProj) +{ + ShadowMapRenderFunctionParams* pRP = (ShadowMapRenderFunctionParams*)pParams; + + DirectX::XMMATRIX viewProjection; + memcpy(&viewProjection, &pViewProj->_11, sizeof(gfsdk_float4x4)); + + pRP->renderer->renderDepthOnly(&viewProjection); +} + +void RendererShadow::renderShadowMaps(Renderer* renderer) +{ + // select technique + GFSDK_ShadowLib_TechniqueType technique = m_SBRenderParams.eTechniqueType; + m_SBRenderParams.eTechniqueType = m_PCSSEnabled ? GFSDK_ShadowLib_TechniqueType_PCSS : GFSDK_ShadowLib_TechniqueType_PCF; + if (technique != m_SBRenderParams.eTechniqueType) + reloadBuffers(); + + + DirectX::XMMATRIX viewMatrix = m_camera->GetViewMatrix(); + DirectX::XMMATRIX projMatrix = m_camera->GetProjMatrix(); + + memcpy(&m_SMRenderParams.m4x4EyeViewMatrix, &viewMatrix.r[0], sizeof(gfsdk_float4x4)); + memcpy(&m_SMRenderParams.m4x4EyeProjectionMatrix, &projMatrix.r[0], sizeof(gfsdk_float4x4)); + + // TODO: (better world space bbox needed) + m_SMRenderParams.v3WorldSpaceBBox[0] = m_worldSpaceBBox0; + 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)); + m_SMRenderParams.LightDesc.fLightSize = m_lightSize; + m_SMRenderParams.LightDesc.bLightFalloff = false; + + // Scene specific setup for the shadow map phase that follows + s_RenderParams.renderer = renderer; + m_SMRenderParams.fnpDrawFunction = GFSDK_ShadowLib_FunctionPointer(ShadowMapRenderFunction); + m_SMRenderParams.pDrawFunctionParams = &s_RenderParams; + + // render shadow map + m_shadowLibContext->RenderMap(m_shadowMapHandle, &m_SMRenderParams); +} + + +void RendererShadow::renderShadowBuffer(ID3D11ShaderResourceView* pDepthStencilSRV, ID3D11ShaderResourceView* pResolvedDepthStencilSRV) +{ + if (m_SBRenderParams.eTechniqueType == GFSDK_ShadowLib_TechniqueType_PCSS && + m_SMDesc.eMapType == GFSDK_ShadowLib_MapType_Texture && + m_SMDesc.eViewType == GFSDK_ShadowLib_ViewType_Single) + { + m_tempResources.pDownsampledShadowMap = &m_downsampledShadowMap; + m_shadowLibContext->SetTempResources(&m_tempResources); + } + + 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); +} + + +void RendererShadow::modulateShadowBuffer(ID3D11RenderTargetView* pOutputRTV) +{ + GFSDK_ShadowLib_RenderTargetView ColorRTV; + ColorRTV.pRTV = pOutputRTV; + + gfsdk_float3 v3ShadowColor = { m_shadowColor.x, m_shadowColor.y, m_shadowColor.z }; + m_shadowLibContext->ModulateBuffer(m_shadowBufferHandle, &ColorRTV, v3ShadowColor, GFSDK_ShadowLib_ModulateBufferMask_RGB); +} + + +void RendererShadow::displayShadowMaps(ID3D11RenderTargetView* pOutputRTV, UINT Width, UINT Height) +{ + GFSDK_ShadowLib_RenderTargetView ColorRTV; + ColorRTV.pRTV = pOutputRTV; + + float fMapResW = (float)m_SMDesc.uResolutionWidth; + float fMapResH = (float)m_SMDesc.uResolutionHeight; + + float fWidthScale = Width / ((float)m_SMDesc.uArraySize * fMapResW); + fWidthScale = (fWidthScale > 1.0f) ? (1.0f) : (fWidthScale); + + float fOneFifth = (float)Height / (5.0f); + float fHeightScale = fOneFifth / fMapResH; + fHeightScale = (fHeightScale > 1.0f) ? (1.0f) : (fHeightScale); + + float fScale = (fHeightScale < fWidthScale) ? (fHeightScale) : (fWidthScale); + + fMapResW = floorf(fMapResW * fScale); + fMapResH = floorf(fMapResH * fScale); + + for (unsigned int j = 0; j < (unsigned int)m_SMDesc.uArraySize; j++) + { + m_shadowLibContext->DevModeDisplayMap(m_shadowBufferHandle, + &ColorRTV, + m_shadowMapHandle, + j, + j * (unsigned int)fMapResW + j, + Height - (unsigned int)fMapResH, + fScale); + } +} + + +void RendererShadow::displayMapFrustums(ID3D11RenderTargetView* pOutputRTV, ID3D11DepthStencilView* pDSV) +{ + gfsdk_float3 v3Color; + v3Color.x = 1.0f; + v3Color.y = 0.0f; + v3Color.z = 0.0f; + + GFSDK_ShadowLib_RenderTargetView ColorRTV; + ColorRTV.pRTV = pOutputRTV; + + GFSDK_ShadowLib_DepthStencilView DSV; + DSV.pDSV = pDSV; + + unsigned int NumViews; + NumViews = m_SMDesc.eViewType; + + for (unsigned int j = 0; j < NumViews; j++) + { + switch (j) + { + case 0: + v3Color.x = 1.0f; + v3Color.y = 0.0f; + v3Color.z = 0.0f; + break; + case 1: + v3Color.x = 0.0f; + v3Color.y = 1.0f; + v3Color.z = 0.0f; + break; + case 2: + v3Color.x = 0.0f; + v3Color.y = 0.0f; + v3Color.z = 1.0f; + break; + case 3: + v3Color.x = 1.0f; + v3Color.y = 1.0f; + v3Color.z = 0.0f; + break; + } + + m_shadowLibContext->DevModeDisplayMapFrustum(m_shadowBufferHandle, + &ColorRTV, + &DSV, + m_shadowMapHandle, + j, + v3Color); + } +} + + +void RendererShadow::displayShadowBuffer(ID3D11RenderTargetView* pOutputRTV) +{ + gfsdk_float2 v2Scale; + v2Scale.x = 1.0f; + v2Scale.y = 1.0f; + + GFSDK_ShadowLib_RenderTargetView ColorRTV; + ColorRTV.pRTV = pOutputRTV; + + m_shadowLibContext->DevModeDisplayBuffer(m_shadowBufferHandle, + &ColorRTV, + v2Scale, + NULL); +} + + +void RendererShadow::toggleDisplayCascades(bool bToggle) +{ + m_shadowLibContext->DevModeToggleDebugCascadeShader(m_shadowBufferHandle, + bToggle); +} + + +void RendererShadow::drawUI() +{ + ImGui::Checkbox("PCSS", &m_PCSSEnabled); + ImGui::ColorEdit3("Shadow Color", &(m_shadowColor.x)); + ImGui::DragFloat("Light Size", &m_lightSize, 0.05f, 0.0f, 100.0f); + ImGui::DragFloat3("Light Position", &(m_lightPos.x)); + ImGui_DragFloat3Dir("Light LookAt", &(m_lightLookAt.x)); + ImGui::DragFloat("SoftShadowTestScale", &(m_softShadowTestScale), 0.0001f, 0.0f, 10.0f); + if (m_PCSSEnabled) + { + ImGui::DragFloat("PCSS: fMaxClamp", &(m_PCSSParams.fMaxClamp), 0.001f, 0.0f, 100.0f); + ImGui::DragFloat("PCSS: fMaxThreshold", &(m_PCSSParams.fMaxThreshold), 0.001f, 0.0f, 100.0f); + ImGui::DragFloat("PCSS: fMinSizePercent", &(m_PCSSParams.fMinSizePercent), 0.001f, 0.0f, 100.0f); + ImGui::DragFloat("PCSS: fMinWeightExponent", &(m_PCSSParams.fMinWeightExponent), 0.001f, 0.0f, 100.0f); + ImGui::DragFloat("PCSS: fMinWeightThresholdPercent", &(m_PCSSParams.fMinWeightThresholdPercent), 0.001f, 0.0f, 100.0f); + 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); + } +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.h new file mode 100644 index 0000000..cc81c67 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/RendererShadow.h @@ -0,0 +1,82 @@ +/* +* 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. +*/ + +#ifndef RENDERER_SHADOW_H +#define RENDERER_SHADOW_H + +#include <DirectXMath.h> +#include "Utils.h" +#include "gfsdk_shadowlib.h" + +#include <string> + + +class CFirstPersonCamera; +class Renderer; + +class RendererShadow +{ +public: + RendererShadow(); + ~RendererShadow(); + + void createResources(ID3D11Device *pd3dDevice, ID3D11DeviceContext* context, CFirstPersonCamera* camera); + + 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 renderShadowBuffer(ID3D11ShaderResourceView* pDepthStencilSRV, ID3D11ShaderResourceView* pResolvedDepthStencilSRV); + void modulateShadowBuffer(ID3D11RenderTargetView* pOutputRTV); + void displayShadowMaps(ID3D11RenderTargetView* pOutputRTV, UINT Width, UINT Height); + void displayMapFrustums(ID3D11RenderTargetView* pOutputRTV, ID3D11DepthStencilView* pDSV); + void displayShadowBuffer(ID3D11RenderTargetView* pOutputRTV); + void toggleDisplayCascades(bool bToggle); + + + void drawUI(); + +private: + void reloadBuffers(); + void ReleaseResources(); + + + GFSDK_ShadowLib_Context* m_shadowLibContext; + + GFSDK_ShadowLib_ShaderResourceView m_shadowBufferSRV; + + GFSDK_ShadowLib_Map* m_shadowMapHandle; + GFSDK_ShadowLib_MapDesc m_SMDesc; + GFSDK_ShadowLib_BufferDesc m_SBDesc; + GFSDK_ShadowLib_MapRenderParams m_SMRenderParams; + + GFSDK_ShadowLib_Buffer* m_shadowBufferHandle; + GFSDK_ShadowLib_BufferRenderParams m_SBRenderParams; + + GFSDK_ShadowLib_TempResources m_tempResources; + GFSDK_ShadowLib_Texture2D m_downsampledShadowMap; + + CFirstPersonCamera* m_camera; + + // params + bool m_PCSSEnabled; + float m_lightSize; + DirectX::XMFLOAT3 m_lightPos; + DirectX::XMFLOAT3 m_lightLookAt; + DirectX::XMFLOAT3 m_shadowColor; + GFSDK_ShadowLib_PCSSPenumbraParams m_PCSSParams; + float m_softShadowTestScale; + + gfsdk_float3 m_worldSpaceBBox0; + gfsdk_float3 m_worldSpaceBBox1; + +}; + + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.cpp new file mode 100644 index 0000000..a051f96 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.cpp @@ -0,0 +1,246 @@ +/* +* 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. +*/ + +#include "ResourceManager.h" +#include "PxAssert.h" +#include "PsString.h" +#include "Utils.h" + +#include <windows.h> + + +using namespace physx; + +#define PATH_MAX_LEN 512 + +// Add By Lixu Begin +ResourceManager* pResourceManager = nullptr; +ResourceManager* ResourceManager::ins() +{ + return pResourceManager; +} +// Add By Lixu End + +ResourceManager::ResourceManager() +{ + // search for root folder by default + addSearchDir("."); + +// Add By Lixu Begin + pResourceManager = this; +// Add By Lixu End +} + +const ShaderFileResource* ResourceManager::requestShaderFile(const char* name) +{ + const Resource* resource = requestResource(eSHADER_FILE, name); + return resource != nullptr ? static_cast<const ShaderFileResource*>(resource) : nullptr; +} + +const TextureResource* ResourceManager::requestTexture(const char* name) +{ + const Resource* resource = requestResource(eTEXTURE, name); + return resource != nullptr ? static_cast<const TextureResource*>(resource) : nullptr; +} + +const Resource* ResourceManager::requestResource(ResourceType type, const char* name) +{ + // search in loaded + std::pair<ResourceType, std::string> key(type, name); + auto val = m_loadedResources.find(key); + if (val != m_loadedResources.end()) + { + return val->second.get(); + } + + std::shared_ptr<Resource> resource; + 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)); + } + else + { + PX_ALWAYS_ASSERT_MESSAGE(name); + } + } + else if (type == eTEXTURE) + { + char path[PATH_MAX_LEN]; +// Add By Lixu Begin + const char* exts[] = { "dds", "tga", "jpg", "png" }; +// 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()); + 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) + { + V(DirectX::LoadFromDDSFile(wPath, DirectX::DDS_FLAGS_NONE, &textureResource->metaData, + textureResource->image)); + } + else if (::strcmp(ext, "tga") == 0) + { + V(DirectX::LoadFromTGAFile(wPath, &textureResource->metaData, + textureResource->image)); + } +// Add By Lixu Begin + else if (::strcmp(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) + { + V(DirectX::LoadFromWICFile(wPath, DirectX::TEX_FILTER_DEFAULT | DirectX::WIC_FLAGS_ALL_FRAMES, &textureResource->metaData, + textureResource->image)); + } +// Add By Lixu End + else + { + PX_ALWAYS_ASSERT_MESSAGE("Unsupported texture extension"); + } + resource = textureResource; + } + } + + if (resource.get()) + { + m_loadedResources.emplace(key, resource); + return resource.get(); + } + else + { + PX_ALWAYS_ASSERT_MESSAGE(name); + return nullptr; + } +} + +bool dirExists(const char* dir) +{ + DWORD ftyp = GetFileAttributesA(dir); + if (ftyp == INVALID_FILE_ATTRIBUTES) + return false; // something is wrong with path! + + if (ftyp & FILE_ATTRIBUTE_DIRECTORY) + return true; // this is a directory! + + return false; // this is not a directory! +} + +bool ResourceManager::addSearchDir(const char* dir, bool recursive) +{ + if (dirExists(dir)) + { + m_searchDirs.push_back(SearchDir(dir, recursive)); + return true; + } + return false; +} + + +ResourceManager::~ResourceManager() +{ +} + + +bool ResourceManager::findFileInDir(std::string fileNameFull, const char* path, bool recursive, char* foundPath) +{ + WIN32_FIND_DATAA ffd; + char tmp[PATH_MAX_LEN]; + shdfnd::snprintf(tmp, sizeof(tmp), "%s\\*", path); + HANDLE hFind = FindFirstFileA(tmp, &ffd); + + if(INVALID_HANDLE_VALUE == hFind) + { + return NULL; + } + + do + { + if (0 == shdfnd::strcmp(".", ffd.cFileName) || 0 == shdfnd::strcmp("..", ffd.cFileName)) + continue; + + if(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + shdfnd::snprintf(tmp, sizeof(tmp), "%s\\%s", path, ffd.cFileName); + if(findFileInDir(fileNameFull, tmp, recursive, foundPath)) + return true; + } + else if (shdfnd::stricmp(ffd.cFileName, fileNameFull.c_str()) == 0) + { + shdfnd::snprintf(foundPath, PATH_MAX_LEN, "%s\\%s", path, ffd.cFileName); + return true; + } + } while(FindNextFileA(hFind, &ffd) != 0); + // release handle + FindClose(hFind); + return false; +} + +bool ResourceManager::findFile(std::string fileName, const std::vector<const char*>& exts, char* foundPath) +{ + std::string fileNameOnly = fileName; + size_t ind = fileNameOnly.find_last_of('/'); + if (ind > 0) + fileNameOnly = fileNameOnly.substr(ind + 1); + +// Add By Lixu Begin + std::string fileDir = "."; + size_t fl = fileName.length(); + if (ind >= 0 && ind < fl) + fileDir = fileName.substr(0, ind); + if (findFileInDir(fileNameOnly.c_str(), fileDir.c_str(), true, foundPath)) + return true; +// Add By Lixu End + + for(size_t i = 0; i < m_searchDirs.size(); i++) + { + const SearchDir& searchDir = m_searchDirs[i]; + + for(size_t j = 0; j < exts.size(); j++) + { + const char* ext = exts[j]; + const uint32_t fileMaxLen = 128; + char fileNameFull[fileMaxLen] = { 0 }; + + physx::shdfnd::snprintf(fileNameFull, fileMaxLen, "%s.%s", fileNameOnly.c_str(), ext); + if(findFileInDir(fileNameFull, searchDir.path.c_str(), searchDir.recursive, foundPath)) + return true; + } + + if (findFileInDir(fileNameOnly.c_str(), searchDir.path.c_str(), searchDir.recursive, foundPath)) + return true; + } + return false; +} + +bool ResourceManager::findFile(std::string fileName, std::string& foundPath) +{ + std::vector<const char*> exts; + char path[PATH_MAX_LEN]; + if (findFile(fileName, exts, path)) + { + foundPath = path; + return true; + } + else + { + return false; + } +} + diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.h new file mode 100644 index 0000000..0378438 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ResourceManager.h @@ -0,0 +1,97 @@ +/* +* 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. +*/ + +#ifndef RESOURCE_MANAGER_H +#define RESOURCE_MANAGER_H + +#include <vector> +#include <string> +#include <map> +#include <memory> +#include "DirectXTex.h" + + +struct Resource +{ +private: + Resource& operator = (const Resource&); +}; + + +struct ShaderFileResource : public Resource +{ + ShaderFileResource(const std::string& p) : path(p) {} + std::string path; +}; + + +struct TextureResource : public Resource +{ + DirectX::TexMetadata metaData; + DirectX::ScratchImage image; +}; + + +/** +ResourceManager used to look for files in provided dirs (see addSearchDir). Also it loads resources and caches them. +*/ +class ResourceManager +{ +public: + //////// ctor //////// + + ResourceManager(); + ~ResourceManager(); + +// Add By Lixu Begin + static ResourceManager* ins(); +// Add By Lixu End + + //////// public API //////// + + bool addSearchDir(const char* dir, bool recursive = true); + + const ShaderFileResource* requestShaderFile(const char* name); + + const TextureResource* requestTexture(const char* name); + + bool findFile(std::string fileName, std::string& foundPath); + + bool findFile(std::string fileName, const std::vector<const char*>& exts, char* foundPath); + + +private: + //////// internal methods //////// + + enum ResourceType + { + eSHADER_FILE, + eTEXTURE + }; + + const Resource* requestResource(ResourceType type, const char* name); + + bool findFileInDir(std::string fileNameFull, const char* path, bool recursive, char* foundPath); + + struct SearchDir + { + SearchDir(std::string path_, bool recursive_) : path(path_), recursive(recursive_) {} + + std::string path; + bool recursive; + }; + + + //////// internal data //////// + + std::vector<SearchDir> m_searchDirs; + std::map<std::pair<ResourceType, std::string>, std::shared_ptr<Resource>> m_loadedResources; +}; +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ShaderUtils.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ShaderUtils.h new file mode 100644 index 0000000..778c811 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/ShaderUtils.h @@ -0,0 +1,99 @@ +/* +* 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. +*/ + +#ifndef SHADER_UTILS_H +#define SHADER_UTILS_H + +#include "Utils.h" +#include <d3dcompiler.h> + + +static HRESULT CompileShaderFromFile(const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, + ID3DBlob** ppBlobOut) +{ + HRESULT hr = S_OK; + ID3DBlob* pErrorBlob = NULL; + + WCHAR wFileName[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, szFileName, -1, wFileName, MAX_PATH); + wFileName[MAX_PATH - 1] = 0; + hr = D3DCompileFromFile(wFileName, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, szEntryPoint, szShaderModel, D3D10_SHADER_ENABLE_STRICTNESS, 0, + ppBlobOut, &pErrorBlob); + if(FAILED(hr)) + { + OutputDebugStringA((char*)pErrorBlob->GetBufferPointer()); + SAFE_RELEASE(pErrorBlob); + return hr; + } + SAFE_RELEASE(pErrorBlob); + + return S_OK; +} + +static HRESULT createShader(ID3D11Device* pDev, const void* pData, size_t len, ID3D11VertexShader** ppShd, bool) +{ + return pDev->CreateVertexShader(pData, len, nullptr, ppShd); +} + +static HRESULT createShader(ID3D11Device* pDev, const void* pData, size_t len, ID3D11GeometryShader** ppShd, + bool forceFast) +{ + PX_UNUSED(forceFast); + return pDev->CreateGeometryShader(pData, len, nullptr, ppShd); +} + +static HRESULT createShader(ID3D11Device* pDev, const void* pData, size_t len, ID3D11PixelShader** ppShd, bool) +{ + return pDev->CreatePixelShader(pData, len, nullptr, ppShd); +} + +static const char* shaderModel(ID3D11VertexShader**) +{ + return "vs_5_0"; +} + +static const char* shaderModel(ID3D11GeometryShader**) +{ + return "gs_5_0"; +} + +static const char* shaderModel(ID3D11PixelShader**) +{ + return "ps_5_0"; +} + +// Give back the shader buffer blob for use in CreateVertexLayout. Caller must release the blob. +template <class S> +static HRESULT createShaderFromFile(ID3D11Device* pDev, const char* szFileName, LPCSTR szEntryPoint, S** ppShd, + ID3DBlob*& pShaderBuffer, bool forceFast = false) +{ + HRESULT hr = CompileShaderFromFile(szFileName, szEntryPoint, shaderModel(ppShd), &pShaderBuffer); + if(SUCCEEDED(hr) && pShaderBuffer) + { + const void* shaderBufferData = pShaderBuffer->GetBufferPointer(); + const UINT shaderBufferSize = pShaderBuffer->GetBufferSize(); + createShader(pDev, shaderBufferData, shaderBufferSize, ppShd, forceFast); + } + return hr; +} + +// Overloaded, same as above but don't give back the shader buffer blob. +template <class S> +static HRESULT createShaderFromFile(ID3D11Device* pDev, const char* szFileName, LPCSTR szEntryPoint, S** ppShd, + bool forceFast = false) +{ + ID3DBlob* pShaderBuffer = NULL; + HRESULT hr = createShaderFromFile(pDev, szFileName, szEntryPoint, ppShd, pShaderBuffer, forceFast); + SAFE_RELEASE(pShaderBuffer); + return hr; +} + + +#endif //SHADER_UTILS_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.cpp new file mode 100644 index 0000000..c575d6c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.cpp @@ -0,0 +1,217 @@ +/* +* 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. +*/ + + +#include "SkinnedRenderMesh.h" +#include "Renderer.h" + +SkinnedRenderMesh::SkinnedRenderMesh(const std::vector<const SimpleMesh*>& meshes) +{ + PX_ASSERT_WITH_MESSAGE(meshes.size() <= MeshesCountMax, "meshes.size() have to be <= SkinnedRenderMesh::MeshesCountMax"); + + m_device = GetDeviceManager()->GetDevice(); + + // input element desc setup + 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({ "TEXCOORD", 1, DXGI_FORMAT_R32_UINT, 1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }); + + // reserve VB + uint32_t verticesTotal = 0; + std::for_each(meshes.begin(), meshes.end(), [&](const SimpleMesh* c) { verticesTotal += (uint32_t)c->vertices.size(); }); + std::vector<SimpleMesh::Vertex> vertexBuffer; + vertexBuffer.reserve(verticesTotal); + + // reserve IB + uint32_t indicesTotal = 0; + std::for_each(meshes.begin(), meshes.end(), [&](const SimpleMesh* c) { indicesTotal += (uint32_t)c->indices.size(); }); + m_indices.reserve(indicesTotal); + + // fill VB, IB, MeshInfo + m_meshesInfo.resize(meshes.size()); + for (uint32_t meshIndex = 0; meshIndex < meshes.size(); ++meshIndex) + { + const SimpleMesh* mesh = meshes[meshIndex]; + MeshInfo& meshInfo = m_meshesInfo[meshIndex]; + + meshInfo.firstVertex = (uint32_t)vertexBuffer.size(); + vertexBuffer.insert(vertexBuffer.end(), mesh->vertices.begin(), mesh->vertices.end()); + meshInfo.verticesCount = (uint32_t)mesh->vertices.size(); + + meshInfo.firstIndex = (uint32_t)m_indices.size(); + uint32_t indexOffset = meshInfo.firstVertex; + for (uint32_t index : mesh->indices) + { + m_indices.push_back((uint32_t)index + indexOffset); + } + meshInfo.indicesCount = (uint32_t)mesh->indices.size(); + } + + // vertex buffer + { + D3D11_SUBRESOURCE_DATA vertexBufferData; + + ZeroMemory(&vertexBufferData, sizeof(vertexBufferData)); + vertexBufferData.pSysMem = vertexBuffer.data(); + + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = (uint32_t)(sizeof(SimpleMesh::Vertex) * vertexBuffer.size()); + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + + V(m_device->CreateBuffer(&bufferDesc, &vertexBufferData, &m_vertexBuffer)); + } + + // bone index buffer + { + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.ByteWidth = (uint32_t)(sizeof(uint32_t) * vertexBuffer.size()); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(m_device->CreateBuffer(&bufferDesc, nullptr, &m_boneIndexBuffer)); + } + + // index buffer + { + D3D11_BUFFER_DESC bufferDesc; + + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc.ByteWidth = (uint32_t)(sizeof(uint32_t) * m_indices.size()); + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + + V(m_device->CreateBuffer(&bufferDesc, nullptr, &m_indexBuffer)); + } + + // bone texture + { + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = 4; + desc.Height = (uint32_t)meshes.size(); + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + V(m_device->CreateTexture2D(&desc, nullptr, &m_boneTexture)); + } + + // bone texture SRV + { + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipLevels = 1; + desc.Texture2D.MostDetailedMip = 0; + V(m_device->CreateShaderResourceView(m_boneTexture, &desc, &m_boneTextureSRV)); + } +} + +SkinnedRenderMesh::~SkinnedRenderMesh() +{ + SAFE_RELEASE(m_vertexBuffer); + SAFE_RELEASE(m_boneIndexBuffer); + SAFE_RELEASE(m_indexBuffer); + SAFE_RELEASE(m_boneTexture); + SAFE_RELEASE(m_boneTextureSRV); +} + +void SkinnedRenderMesh::updateVisibleMeshes(const std::vector<uint32_t>& visibleMeshes) +{ + ID3D11DeviceContext* context; + m_device->GetImmediateContext(&context); + + // update bone index buffer + { + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(m_boneIndexBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + + uint32_t* boneIndexBuffer = (uint32_t*)mappedRead.pData; + for (uint32_t i = 0; i < visibleMeshes.size(); ++i) + { + const MeshInfo& info = m_meshesInfo[visibleMeshes[i]]; + for (uint32_t v = info.firstVertex; v < info.firstVertex + info.verticesCount; ++v) + { + boneIndexBuffer[v] = i; + } + } + + context->Unmap(m_boneIndexBuffer, 0); + } + + // update index buffer + { + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(m_indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + + uint32_t* indexBuffer = (uint32_t*)mappedRead.pData; + uint32_t indexCount = 0; + for (uint32_t meshIndex : visibleMeshes) + { + const MeshInfo& info = m_meshesInfo[meshIndex]; + memcpy(indexBuffer + indexCount, &m_indices[info.firstIndex], info.indicesCount * sizeof(uint32_t)); + indexCount += info.indicesCount; + } + context->Unmap(m_indexBuffer, 0); + m_indexCount = indexCount; + PX_ASSERT(m_indexCount % 3 == 0); + } +} + +void SkinnedRenderMesh::updateVisibleMeshTransforms(std::vector<PxMat44>& transforms) +{ + ID3D11DeviceContext* context; + m_device->GetImmediateContext(&context); + + // update bone transform texture + { + D3D11_MAPPED_SUBRESOURCE mappedRead; + V(context->Map(m_boneTexture, 0, D3D11_MAP_WRITE_DISCARD, NULL, &mappedRead)); + for (uint32_t i = 0; i < transforms.size(); ++i) + { + std::memcpy((uint8_t*)mappedRead.pData + i * mappedRead.RowPitch, &transforms[i], sizeof(PxMat44)); + } + context->Unmap(m_boneTexture, 0); + } +} + +void SkinnedRenderMesh::render(ID3D11DeviceContext& context) const +{ + context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + UINT strides[2] = { sizeof(SimpleMesh::Vertex), sizeof(uint32_t) }; + UINT offsets[2] = { 0 }; + ID3D11Buffer* buffers[2] = { m_vertexBuffer, m_boneIndexBuffer }; + context.IASetVertexBuffers(0, 2, buffers, strides, offsets); + + context.IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0); + + context.VSSetShaderResources(1, 1, &m_boneTextureSRV); + + context.DrawIndexed(m_indexCount, 0, 0); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.h new file mode 100644 index 0000000..2f690d8 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/renderer/SkinnedRenderMesh.h @@ -0,0 +1,82 @@ +/* +* 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. +*/ + +#ifndef SKINNED_RENDER_MESH_H +#define SKINNED_RENDER_MESH_H + +#include "Utils.h" +#include <DirectXMath.h> + +#include <vector> +#include "Renderable.h" +#include "Mesh.h" + +/** +SkinnedRenderMesh: + bonde indices are passed as vertex input, + bone transforms are stored in texture + max bone meshes count: SkinnedRenderMesh::MeshesCountMax +*/ +class SkinnedRenderMesh : public IRenderMesh +{ +public: + //////// ctor //////// + + SkinnedRenderMesh(const std::vector<const SimpleMesh*>& meshes); + ~SkinnedRenderMesh(); + + + //////// const //////// + + static const uint32_t MeshesCountMax = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; + + + //////// public API //////// + + void updateVisibleMeshes(const std::vector<uint32_t>& visibleMeshes); + void updateVisibleMeshTransforms(std::vector<PxMat44>& transforms); + + + //////// IRenderMesh implementation //////// + + virtual const std::vector<D3D11_INPUT_ELEMENT_DESC>& getInputElementDesc() const { return m_inputDesc; } + virtual void render(ID3D11DeviceContext& context) const; + +private: + //////// internal data //////// + + struct MeshInfo + { + uint32_t firstIndex; + uint32_t indicesCount; + + uint32_t firstVertex; + uint32_t verticesCount; + }; + + std::vector<D3D11_INPUT_ELEMENT_DESC> m_inputDesc; + + ID3D11Device* m_device; + + ID3D11Buffer* m_vertexBuffer; + ID3D11Buffer* m_boneIndexBuffer; + ID3D11Buffer* m_indexBuffer; + ID3D11Texture2D* m_boneTexture; + ID3D11ShaderResourceView* m_boneTextureSRV; + + uint32_t m_indexCount; + + std::vector<MeshInfo> m_meshesInfo; + std::vector<uint32_t> m_indices; +}; + + + +#endif //SKINNED_RENDER_MESH_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.cpp new file mode 100644 index 0000000..00cf4df --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.cpp @@ -0,0 +1,272 @@ +/* +* 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. +*/ + +#include "SampleAssetListParser.h" +#include <PsFastXml.h> +#include "Sample.h" +#include "PxVec4.h" +#include "PxInputDataFromPxFileBuf.h" + + +using namespace physx; + + +const float DEGREE_TO_RAD = acos(-1.0) / 180.0; + +class AssetListParser : public physx::shdfnd::FastXml::Callback +{ +public: + AssetListParser(AssetList& assetList): m_assetList(assetList){} +protected: + + // encountered a comment in the XML + virtual bool processComment(const char* /*comment*/) + { + return true; + } + + virtual bool processClose(const char* elementName, unsigned int /*depth*/, bool& /*isError*/) + { + if (::strcmp(elementName, "Box") == 0) + { + m_assetList.boxes.push_back(m_boxTemp); + m_boxTemp = AssetList::BoxAsset(); + } + else if (::strcmp(elementName, "Composite") == 0) + { + m_assetList.composites.push_back(m_compositeTemp); + m_compositeTemp = AssetList::CompositeAsset(); + } + return true; + } + + // return true to continue processing the XML document, false to skip. + virtual bool processElement(const char* elementName, // name of the element + const char* elementData, // element data, null if none + const physx::shdfnd::FastXml::AttributePairs& attr, + int /*lineno*/) // line number in the source XML file + { + if (::strcmp(elementName, "Model") == 0) + { + m_assetList.models.resize(m_assetList.models.size() + 1); + auto& model = m_assetList.models.back(); + for (int i = 0; i < attr.getNbAttr(); ++i) + { + if (::strcmp(attr.getKey(i), "id") == 0) + { + model.id = std::string(attr.getValue(i)); + } + else if (::strcmp(attr.getKey(i), "file") == 0) + { + model.file = std::string(attr.getValue(i)); + } + else if (::strcmp(attr.getKey(i), "name") == 0) + { + model.name = std::string(attr.getValue(i)); + } + else if (::strcmp(attr.getKey(i), "isSkinned") == 0) + { + std::string str = attr.getValue(i); + if (::strcmp(&str[0], "true") == 0) + { + model.isSkinned = true; + } + } + } + + model.transform = parseTransform(attr); + + if (model.name.empty()) + { + model.name = model.file; + } + if (model.id.empty()) + { + model.id = model.name; + } + } + else if (::strcmp(elementName, "Box") == 0) + { + for (int i = 0; i < attr.getNbAttr(); ++i) + { + if (::strcmp(attr.getKey(i), "id") == 0) + { + m_boxTemp.id = std::string(attr.getValue(i)); + } + else if (::strcmp(attr.getKey(i), "name") == 0) + { + 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); + if (::strcmp(&str[0], "true") == 0) + { + m_boxTemp.jointAllBonds = true; + } + } + else if (::strcmp(attr.getKey(i), "extents") == 0) + { + std::string str = attr.getValue(i); + sscanf(&str[0], "%f %f %f", &m_boxTemp.extents.x, &m_boxTemp.extents.y, &m_boxTemp.extents.z); + } + } + + if (m_boxTemp.id.empty()) + { + m_boxTemp.id = m_boxTemp.name; + } + } + else if (::strcmp(elementName, "Level") == 0) + { + m_boxTemp.levels.push_back(AssetList::BoxAsset::Level()); + auto& level = m_boxTemp.levels.back(); + for (int i = 0; i < attr.getNbAttr(); ++i) + { + if (::strcmp(attr.getKey(i), "slices") == 0) + { + std::string str = attr.getValue(i); + sscanf(&str[0], "%d %d %d", &level.x, &level.y, &level.z); + } + if (::strcmp(attr.getKey(i), "isSupport") == 0) + { + std::string str = attr.getValue(i); + if (::strcmp(&str[0], "true") == 0) + { + level.isSupport = true; + } + } + } + } + else if (::strcmp(elementName, "Composite") == 0) + { + for (int i = 0; i < attr.getNbAttr(); ++i) + { + if (::strcmp(attr.getKey(i), "id") == 0) + { + m_compositeTemp.id = std::string(attr.getValue(i)); + } + else if (::strcmp(attr.getKey(i), "name") == 0) + { + m_compositeTemp.name = std::string(attr.getValue(i)); + } + } + m_compositeTemp.transform = parseTransform(attr); + + if (m_compositeTemp.id.empty()) + { + m_compositeTemp.id = m_compositeTemp.name; + } + } + else if (::strcmp(elementName, "AssetRef") == 0) + { + m_compositeTemp.assetRefs.push_back(AssetList::CompositeAsset::AssetRef()); + AssetList::CompositeAsset::AssetRef& assetRef = m_compositeTemp.assetRefs.back(); + for (int i = 0; i < attr.getNbAttr(); ++i) + { + if (::strcmp(attr.getKey(i), "id") == 0) + { + assetRef.id = attr.getValue(i); + } + } + assetRef.transform = parseTransform(attr); + } + else if (::strcmp(elementName, "Joint") == 0) + { + m_compositeTemp.joints.push_back(AssetList::CompositeAsset::Joint()); + AssetList::CompositeAsset::Joint& joint = m_compositeTemp.joints.back(); + for (int i = 0; i < attr.getNbAttr(); ++i) + { + if (::strcmp(attr.getKey(i), "asset0") == 0) + { + joint.assetIndices[0] = std::stoi(attr.getValue(i)); + } + else if (::strcmp(attr.getKey(i), "asset1") == 0) + { + joint.assetIndices[1] = std::stoi(attr.getValue(i)); + } + if (::strcmp(attr.getKey(i), "chunk0") == 0) + { + joint.chunkIndices[0] = std::stoi(attr.getValue(i)); + } + else if (::strcmp(attr.getKey(i), "chunk1") == 0) + { + joint.chunkIndices[1] = std::stoi(attr.getValue(i)); + } + else if (::strcmp(attr.getKey(i), "position0") == 0) + { + joint.attachPositions[0] = parsePosition(attr.getValue(i)); + } + else if (::strcmp(attr.getKey(i), "position1") == 0) + { + joint.attachPositions[1] = parsePosition(attr.getValue(i)); + } + } + } + return true; + } + +private: + PxTransform parseTransform(const physx::shdfnd::FastXml::AttributePairs& attr) + { + PxTransform transform(PxIdentity); + for (int i = 0; i < attr.getNbAttr(); ++i) + { + if (::strcmp(attr.getKey(i), "position") == 0) + { + transform.p = parsePosition(attr.getValue(i)); + } + else if (::strcmp(attr.getKey(i), "rotation") == 0) + { + transform.q = parseRotation(attr.getValue(i)); + } + } + return transform; + } + + PxVec3 parsePosition(const char* value) + { + PxVec3 ps; + sscanf(value, "%f %f %f", &ps.x, &ps.y, &ps.z); + return ps; + } + + PxQuat parseRotation(const char* value) + { + PxVec4 ps; + sscanf(value, "%f %f %f %f", &ps.x, &ps.y, &ps.z, &ps.w); + ps.w = ps.w * DEGREE_TO_RAD; + return PxQuat(ps.w, PxVec3(ps.x, ps.y, ps.z).getNormalized());; + } + + AssetList::BoxAsset m_boxTemp; + AssetList::CompositeAsset m_compositeTemp; + AssetList& m_assetList; +}; + + +void parseAssetList(AssetList& assetList, std::string filepath) +{ + physx::PsFileBuffer fileBuffer(filepath.c_str(), physx::general_PxIOStream2::PxFileBuf::OPEN_READ_ONLY); + if (!fileBuffer.isOpen()) + { + return; + } + PxInputDataFromPxFileBuf inputData(fileBuffer); + AssetListParser parser(assetList); + physx::shdfnd::FastXml* xml = physx::shdfnd::createFastXml(&parser); + xml->processXml(inputData, false); + xml->release(); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.h new file mode 100644 index 0000000..b6303ec --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SampleAssetListParser.h @@ -0,0 +1,20 @@ +/* +* 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. +*/ + +#ifndef SAMPLEASSETLISTPARSER_H +#define SAMPLEASSETLISTPARSER_H + +#include <string> + +struct AssetList; + +void parseAssetList(AssetList& assetList, std::string filepath); + +#endif // SAMPLEASSETLISTPARSER_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.cpp new file mode 100644 index 0000000..2466304 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.cpp @@ -0,0 +1,1510 @@ +/* +* 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. +*/ + +#include "SceneController.h" +#include "RenderUtils.h" +#include "Utils.h" + +#include "BlastAssetBoxes.h" +#include "BlastAssetModelSimple.h" +#include "BlastAssetModelSkinned.h" +#include "NvBlastExtPxAsset.h" +#include "NvBlastExtPxFamily.h" +#include "NvBlastExtPxManager.h" + +#include "SampleAssetListParser.h" +#include "BlastReplay.h" +#include "Renderer.h" + +#include "BlastController.h" +#include "CommonUIController.h" +#include "PhysXController.h" + +#include "PxRigidDynamic.h" +#include <PsFastXml.h> +#include "PxInputDataFromPxFileBuf.h" + +#include <algorithm> +#include <imgui.h> +#include <sstream> +#include <tuple> + + + +//////// Simple hash function //////// +static NvBlastID generateIDFromString(const char* str) +{ + uint32_t h[4] = { 5381, 5381, 5381, 5381 }; + int i = 0; + for (const char* ptr = str; *ptr; i = ((i + 1) & 3), ++ptr) + { + h[i] = ((h[i] << 5) + h[i]) ^ static_cast<uint32_t>(*ptr); + } + return *reinterpret_cast<NvBlastID*>(h); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Scenes Setup +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +const DirectX::XMFLOAT4 PICK_POINTER_ACTIVE_COLOR(1.0f, 0.f, 0.f, 0.6f); +const float RIGIDBODY_DENSITY = 2000.0f; + + +class SingleSceneAsset; + +class SceneAsset +{ +public: + SceneAsset() : spawnCount(0) {} + virtual ~SceneAsset() {} + + void initialize(Scene* scene) + { + m_scene = scene; + } + + virtual const char* getID() const = 0; + virtual const char* getName() const = 0; + + virtual void load() = 0; + virtual void unload() = 0; + virtual bool isLoaded() const = 0; + virtual void spawn(PxVec3 shift) = 0; + + virtual ImVec4 getUIColor() const + { + return ImGui::GetStyle().Colors[ImGuiCol_Text]; + } + + uint32_t spawnCount; +protected: + Scene* m_scene; +}; + + +class SceneActor +{ +public: + virtual ~SceneActor() {} + virtual const char* getName() const = 0; + virtual const char* getSubname(int subindex) const { return nullptr; } + virtual ImVec4 getUIColor() const = 0; + virtual void drawUI(int subindex) {} + virtual void drawStatsUI(int subindex) {} + virtual uint32_t getSubactorCount() const { return 0; } + virtual PxVec3 getSpawnShift() const { return PxVec3(PxZero); } + virtual void reload() {} + virtual void removeSubactor(int subindex) {} +}; + + +class Scene +{ +public: + struct ActorIndex + { + int index; + int subindex; + + ActorIndex() { reset(); } + ActorIndex(int i, int s) : index(i), subindex(s) {} + + bool operator==(const ActorIndex& other) const + { + return index == other.index && subindex == other.subindex; + } + + void reset() + { + index = -1; + subindex = -1; + } + }; + + Scene(Renderer& renderer, PhysXController& physXController, BlastController& blastController, CommonUIController& commonUIController) : + m_renderer(renderer), m_physXController(physXController), m_blastController(blastController), m_commonUIController(commonUIController) + { + } + + ~Scene() + { + removeAllSceneActors(); + + for (uint32_t i = 0; i < m_assets.size(); i++) + { + SAFE_DELETE(m_assets[i]); + } + m_assets.clear(); + m_assetsByID.clear(); + m_tkAssetMap.clear(); + } + + void addAsset(SceneAsset* asset) + { + m_assets.push_back(asset); + asset->initialize(this); + m_assetsByID[asset->getID()] = asset; + } + +// Add By Lixu Begin + std::vector<SceneAsset*>& getAssets() + { + return m_assets; + } + + std::vector<SceneActor*>& getActors() + { + return m_sceneActors; + } +// Add By Lixu End + + void drawUI() + { + /////////////////////////////////////////////////////////////////////////////////////////// + // Assets Selection + /////////////////////////////////////////////////////////////////////////////////////////// + { + static int mode = 0; + ImGui::RadioButton("Replace", &mode, 0); ImGui::SameLine(); + ImGui::RadioButton("Append", &mode, 1); + + ImGui::ListBoxHeader("Assets", (int)m_assets.size()); + for (uint32_t i = 0; i < m_assets.size(); ++i) + { + ImVec4 color = m_assets[i]->getUIColor(); + color.w = color.w * (m_assets[i]->isLoaded() ? 1.0f : 0.5f); + ImGui::PushStyleColor(ImGuiCol_Text, color); + if (ImGui::Selectable(m_assets[i]->getName(), m_lastSpawnedAsset == i)) + { + m_lastSpawnedAsset = i; + if (mode == 0) + { + removeAllSceneActors(); + } + m_commonUIController.addDelayedCall([=]() { spawnAsset(m_lastSpawnedAsset); }, "Loading Asset"); + } + ImGui::PopStyleColor(); + } + ImGui::ListBoxFooter(); + } + + ImGui::Spacing(); + ImGui::Separator(); + + /////////////////////////////////////////////////////////////////////////////////////////// + // Actors Selection + /////////////////////////////////////////////////////////////////////////////////////////// + { + // actor's list + { + int itemCount = 0; + for (size_t i = 0; i < m_sceneActors.size(); ++i) + { + itemCount += 1 + m_sceneActors[i]->getSubactorCount(); + } + + ImGui::ListBoxHeader("Scene Actors", itemCount); + for (int i = 0; i < (int)m_sceneActors.size(); ++i) + { + ImVec4 color = m_sceneActors[i]->getUIColor(); + ImGui::PushStyleColor(ImGuiCol_Text, color); + + const bool isSelected = (m_selectedActor.index == i); + + ImGui::PushID(i); + if (ImGui::Selectable(m_sceneActors[i]->getName(), isSelected && m_selectedActor.subindex == -1)) + { + setSelectedActor(i); + } + + for (int s = 0; s < (int)m_sceneActors[i]->getSubactorCount(); ++s) + { + ImGui::PushID(s); + if (ImGui::Selectable(m_sceneActors[i]->getSubname(s), isSelected && m_selectedActor.subindex == s)) + { + setSelectedActor(i, s); + } + ImGui::PopID(); + } + + ImGui::PopID(); + ImGui::PopStyleColor(); + } + ImGui::ListBoxFooter(); + } + + SceneActor* selectedActor = getSelectedActor(); + if (selectedActor) + { + if (ImGui::Button("Remove")) + { + removeSceneActor(m_selectedActor); + } + + ImGui::SameLine(); + + if (ImGui::Button("Reload")) + { + selectedActor->reload(); + } + + ImGui::SameLine(); + } + + if (ImGui::Button("Remove All")) + { + removeAllSceneActors(); + } + ImGui::SameLine(); + if (ImGui::Button("Reload All (R)")) + { + reloadAllActors(); + } + } + + ImGui::Spacing(); + ImGui::Spacing(); + + /////////////////////////////////////////////////////////////////////////////////////////// + // Selected Actor + /////////////////////////////////////////////////////////////////////////////////////////// + { + SceneActor* selectedActor = getSelectedActor(); + if (selectedActor) + { + ImGui::Text("Selected Actor: "); + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Text, ImColor(40, 200, 80, 255)); + ImGui::Text(m_selectedActor.subindex >= 0 ? selectedActor->getSubname(m_selectedActor.subindex) : selectedActor->getName()); + ImGui::PopStyleColor(); + + ImGui::Spacing(); + + selectedActor->drawUI(m_selectedActor.subindex); + } + else + { + ImGui::Text("No Selected Actor"); + } + } + } + + void drawStatsUI() + { + SceneActor* selectedActor = getSelectedActor(); + if (selectedActor) + { + selectedActor->drawStatsUI(m_selectedActor.subindex); + } + } + + void spawnAsset(int32_t num) + { + m_lastSpawnedAsset = physx::PxClamp<int32_t>(num, -1, (uint32_t)m_assets.size() - 1); + + if (m_lastSpawnedAsset < 0) + { + return; + } + + PxVec3 shift(PxZero); +// Add By Lixu Begin + /* + for (SceneActor* a : m_sceneActors) + { + shift += a->getSpawnShift(); + } + */ +// Add By Lixu End + + SceneAsset* asset = m_assets[m_lastSpawnedAsset]; + asset->spawn(shift); + } + + void addSceneActor(SceneActor* actor) + { + m_sceneActors.push_back(actor); + if (!getSelectedActor()) + { + setSelectedActor((uint32_t)m_sceneActors.size() - 1); + } + } + + void removeSceneActor(ActorIndex actorIndex) + { + SceneActor* actor = getActorByIndex(actorIndex.index); + if (actorIndex.subindex < 0) + { + delete actor; + m_sceneActors.erase(std::remove(m_sceneActors.begin(), m_sceneActors.end(), actor)); + } + else + { + actor->removeSubactor(actorIndex.subindex); + + if (actor->getSubactorCount() == 0) + { + removeSceneActor(ActorIndex(actorIndex.index, -1)); + return; + } + } + + SceneActor* selectedActor = getActorByIndex(m_selectedActor.index); + if (selectedActor == nullptr) + { + if (!m_sceneActors.empty()) + { + setSelectedActor((uint32_t)m_sceneActors.size() - 1); + } + } + else + { + int subactorCount = selectedActor->getSubactorCount(); + if (m_selectedActor.subindex >= subactorCount || (m_selectedActor.subindex < 0 && subactorCount > 0)) + { + setSelectedActor(m_selectedActor.index, subactorCount - 1); + } + } + } + + void removeAllSceneActors() + { + for (SceneActor* a : m_sceneActors) + { + delete a; + } + m_sceneActors.clear(); + setSelectedActor(-1); + } + + void setSelectedActor(int index, int subindex = -1) + { + m_selectedActor.index = physx::PxClamp<int32_t>(index, -1, (uint32_t)m_sceneActors.size() - 1); + m_selectedActor.subindex = subindex; + } + + SceneActor* getSelectedActor() const + { + return getActorByIndex(m_selectedActor.index); + } + + SceneActor* getActorByIndex(int index) const + { + return (index >= 0 && index < (int)m_sceneActors.size()) ? m_sceneActors[index] : nullptr; + } + + int releaseAll() + { + removeAllSceneActors(); + + for (size_t i = 0; i < m_assets.size(); ++i) + { + m_assets[i]->unload(); + } + + const int currentAsset = m_lastSpawnedAsset; + m_lastSpawnedAsset = -1; + return currentAsset; + } + + void reloadAllActors() + { + for (SceneActor* a : m_sceneActors) + { + a->reload(); + } + } + + void registerTkAsset(const TkAsset& tkAsset, SingleSceneAsset* asset) + { + m_tkAssetMap[&tkAsset] = asset; + } + + void unregisterTkAsset(const TkAsset& tkAsset) + { + m_tkAssetMap.erase(&tkAsset); + } + + SingleSceneAsset* findSingleSceneAsset(const TkAsset& tkAsset) + { + auto entry = m_tkAssetMap.find(&tkAsset); + return entry != m_tkAssetMap.end() ? entry->second : nullptr; + } + + SceneAsset* findSceneAsset(const std::string& id) + { + auto entry = m_assetsByID.find(id); + return entry != m_assetsByID.end() ? entry->second : nullptr; + } + + + //////// used controllers //////// + + Renderer& getRenderer() const + { + return m_renderer; + } + + PhysXController& getPhysXController() const + { + return m_physXController; + } + + BlastController& getBlastController() const + { + return m_blastController; + } + + CommonUIController& getCommonUIController() const + { + return m_commonUIController; + } + +private: + + Renderer& m_renderer; + PhysXController& m_physXController; + BlastController& m_blastController; + CommonUIController& m_commonUIController; + + std::vector<SceneAsset*> m_assets; + std::vector<SceneActor*> m_sceneActors; + std::map<const TkAsset*, SingleSceneAsset*> m_tkAssetMap; + std::map<std::string, SceneAsset*> m_assetsByID; + + int m_lastSpawnedAsset; + + ActorIndex m_selectedActor; +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Assets +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SingleSceneActor; + +class SingleSceneAsset : public SceneAsset +{ +public: + SingleSceneAsset() : m_asset(nullptr) {} + virtual ~SingleSceneAsset() { unload(); } + + virtual void spawn(PxVec3 shift) override; + + virtual void load() override + { + if (!m_asset) + { + m_asset = createAsset(); + m_scene->registerTkAsset(m_asset->getPxAsset()->getTkAsset(), this); + } + } + + virtual void unload() override + { + if (m_asset) + { + m_scene->unregisterTkAsset(m_asset->getPxAsset()->getTkAsset()); + delete m_asset; + m_asset = nullptr; + } + } + + virtual bool isLoaded() const override + { + return m_asset != nullptr; + } + + BlastAsset* getAsset() const + { + return m_asset; + } + + virtual PxTransform getInitialTransform() = 0; + +protected: + virtual BlastAsset* createAsset() = 0; + +private: + BlastAsset* m_asset; +}; + + +class ModelSceneAsset : public SingleSceneAsset +{ +public: + ModelSceneAsset() {} + + virtual const char* getID() const override{ return desc.id.c_str(); } + virtual const char* getName() const override { return desc.name.c_str(); } + + AssetList::ModelAsset desc; + + virtual PxTransform getInitialTransform() { return desc.transform; } +}; + + +class SimpleModelSceneAsset : public ModelSceneAsset +{ +public: + 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()); + } + + virtual ImVec4 getUIColor() const override + { + return ImColor(255, 255, 200, 255); + } +}; + + +class SkinnedModelSceneAsset : public ModelSceneAsset +{ +public: + 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()); + } + + virtual ImVec4 getUIColor() const override + { + return ImColor(255, 200, 255, 255); + } +}; + + +class BoxesSceneAsset : public SingleSceneAsset +{ +public: + BoxesSceneAsset(const AssetList::BoxAsset& d) : desc(d) + { + for (uint32_t lv = 0; lv < desc.levels.size(); ++lv) + { + const AssetList::BoxAsset::Level& level = desc.levels[lv]; + NvBlastChunkDesc::Flags fl = (level.isSupport) ? NvBlastChunkDesc::Flags::SupportFlag : NvBlastChunkDesc::Flags::NoFlags; + assetDesc.generatorSettings.depths.push_back({ GeneratorAsset::Vec3(level.x, level.y, level.z), fl }); + } + assetDesc.generatorSettings.extents = GeneratorAsset::Vec3(desc.extents.x, desc.extents.y, desc.extents.z); + assetDesc.staticHeight = desc.staticHeight; + assetDesc.jointAllBonds = desc.jointAllBonds; + } + + virtual ImVec4 getUIColor() const override + { + return ImColor(255, 200, 200, 255); + } + + virtual const char* getID() const override { return desc.id.c_str(); } + virtual const char* getName() const override { return desc.name.c_str(); } + + + AssetList::BoxAsset desc; + BlastAssetBoxes::Desc assetDesc; + + virtual BlastAsset* createAsset() + { + return new BlastAssetBoxes(m_scene->getBlastController().getTkFramework(), m_scene->getPhysXController().getPhysics(), + m_scene->getPhysXController().getCooking(), m_scene->getRenderer(), assetDesc); + } + + virtual PxTransform getInitialTransform() { return PxTransform(PxVec3(0, assetDesc.generatorSettings.extents.y / 2, 0)); } +}; + + +class CompositeSceneAsset : public SceneAsset +{ +public: + CompositeSceneAsset(const AssetList::CompositeAsset& desc) + : m_desc(desc) + { + } + + virtual ~CompositeSceneAsset() { unload(); } + + virtual ImVec4 getUIColor() const override + { + return ImColor(200, 255, 255, 255); + } + + 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 load() override + { + if (!isLoaded()) + { + // load dependent assets + for (const auto& assetRef : m_desc.assetRefs) + { + SceneAsset* asset = m_scene->findSceneAsset(assetRef.id); + if (asset) + { + asset->load(); + m_sceneAssets.push_back(static_cast<SingleSceneAsset*>(asset)); + } + else + { + m_scene->getCommonUIController().addPopupMessage("Error", "Wrong asset dependency on composite"); + m_sceneAssets.clear(); + return; + } + } + + // check joints + for (const auto& joint : m_desc.joints) + { + bool ok = (joint.assetIndices[0] >= 0 || joint.assetIndices[1] >= 0); + for (char k = 0; k < 2 && ok; ++k) + { + if (joint.assetIndices[k] < 0) + continue; + ok &= (joint.assetIndices[k] < (int32_t)m_sceneAssets.size()); + if (!ok) + break; + ok &= joint.chunkIndices[k] < m_sceneAssets[joint.assetIndices[k]]->getAsset()->getPxAsset()->getTkAsset().getChunkCount(); + } + if (!ok) + { + m_scene->getCommonUIController().addPopupMessage("Error", "Wrong joint on composite"); + m_sceneAssets.clear(); + return; + } + } + } + } + + virtual void unload() override + { + m_sceneAssets.clear(); + } + + virtual bool isLoaded() const override + { + return !m_sceneAssets.empty(); + } + + virtual PxTransform getInitialTransform() + { + return m_desc.transform; + } + + const AssetList::CompositeAsset& getDesc() const + { + return m_desc; + } + + const std::vector<SingleSceneAsset*>& getSceneAssets() const + { + return m_sceneAssets; + } + +private: + AssetList::CompositeAsset m_desc; + std::vector<SingleSceneAsset*> m_sceneAssets; +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Scene Actors +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SingleSceneActor : public SceneActor +{ +public: + SingleSceneActor(Scene& scene, SingleSceneAsset* asset, PxVec3 shift) + : m_scene(scene) + , m_asset(asset) + , m_shift(shift) + { + m_index = m_asset->spawnCount++; + spawn(); + } + + SingleSceneActor::~SingleSceneActor() + { + remove(); + } + + virtual const char* getName() const override + { + return m_name.c_str(); + } + + virtual const char* getSubname(int) const override + { + return nullptr; + } + + virtual ImVec4 getUIColor() const override + { + return m_asset->getUIColor(); + } + + virtual void drawUI(int) override + { + m_actor->drawUI(); + } + + virtual void drawStatsUI(int) override + { + m_actor->drawStatsUI(); + } + + virtual PxVec3 getSpawnShift() const override + { + return PxVec3(-20, 0, 0); + } + + virtual void reload() override + { + auto settings = m_actor->getSettings(); + remove(); + spawn(); + m_actor->setSettings(settings); + } + +private: + void remove() + { + m_scene.getBlastController().removeFamily(m_actor); + m_actor = nullptr; + } + + void spawn() + { + std::ostringstream str; + str << m_asset->getName(); + if (m_index) + str << " (" << m_index << ")"; + m_name = str.str(); + + PxTransform pose = m_asset->getInitialTransform(); + pose.p += m_shift; + + BlastAsset::ActorDesc actorDesc = { + actorDesc.id = generateIDFromString(m_name.c_str()), + pose, + m_scene.getBlastController().getTkGroup() + }; + + m_actor = m_scene.getBlastController().spawnFamily(m_asset->getAsset(), actorDesc); + } + + Scene& m_scene; + BlastFamilyPtr m_actor; + SingleSceneAsset* m_asset; + PxVec3 m_shift; + uint32_t m_index; + std::string m_name; +}; + +class CompositeSceneActor : public SceneActor +{ +public: + CompositeSceneActor(Scene& scene, CompositeSceneAsset* asset, PxVec3 shift) + : m_scene(scene) + , m_asset(asset) + , m_shift(shift) + { + m_index = m_asset->spawnCount++; + spawn(); + } + + CompositeSceneActor::~CompositeSceneActor() + { + remove(); + } + + virtual uint32_t getSubactorCount() const + { + return (uint32_t)m_actors.size(); + } + + virtual const char* getName() const override + { + return m_name.c_str(); + } + + virtual const char* getSubname(int subindex) const override + { + return m_actors[subindex].name.c_str(); + } + + virtual ImVec4 getUIColor() const override + { + return m_asset->getUIColor(); + } + + virtual void drawUI(int subindex) override + { + if (subindex >= 0) + { + m_actors[subindex].actor->drawUI(); + } + else + { + ImGui::Text("Select subactor to edit settings."); + } + } + + virtual void drawStatsUI(int subindex) override + { + if (subindex >= 0) + { + m_actors[subindex].actor->drawStatsUI(); + } + } + + virtual PxVec3 getSpawnShift() const override + { + return PxVec3(-20, 0, 0); + } + + virtual void reload() override + { + std::map<uint32_t, BlastFamily::Settings> settings; + for (uint32_t i = 0; i < m_actors.size(); ++i) + { + settings[m_actors[i].initialIndex] = m_actors[i].actor->getSettings(); + } + remove(); + spawn(); + for (uint32_t i = 0; i < m_actors.size(); ++i) + { + if (settings.find(i) != settings.end()) + { + m_actors[i].actor->setSettings(settings[i]); + } + } + } + + virtual void removeSubactor(int subindex) + { + if (subindex >= 0 && subindex < (int)m_actors.size()) + { + m_scene.getBlastController().removeFamily(m_actors[subindex].actor); + m_actors[subindex] = m_actors.back(); + m_actors.resize(m_actors.size() - 1); + } + } + +private: + void remove() + { + for (uint32_t i = 0; i < m_actors.size(); ++i) + { + m_scene.getBlastController().removeFamily(m_actors[i].actor); + } + m_actors.clear(); + } + + void spawn() + { + std::ostringstream str; + str << m_asset->getName(); + if (m_index) + str << " (" << m_index << ")"; + m_name = str.str(); + + const AssetList::CompositeAsset& assetDesc = m_asset->getDesc(); + const std::vector<SingleSceneAsset*>& sceneAssets = m_asset->getSceneAssets(); + + const uint32_t actorCount = (uint32_t)sceneAssets.size(); + m_actors.resize(actorCount); + + for (uint32_t i = 0; i < actorCount; ++i) + { + std::ostringstream str; + str << " -> " << i << "." << sceneAssets[i]->getName(); + m_actors[i].name = str.str(); + } + + ExtPxManager& pxManager = m_scene.getBlastController().getExtPxManager(); + for (uint32_t i = 0; i < actorCount; ++i) + { + PxTransform pose = m_asset->getInitialTransform(); + pose.p += m_shift; + pose = assetDesc.assetRefs[i].transform.transform(pose); + + BlastAsset::ActorDesc actorDesc = { + generateIDFromString(m_actors[i].name.c_str()), + pose, + m_scene.getBlastController().getTkGroup() + }; + m_actors[i].actor = m_scene.getBlastController().spawnFamily(sceneAssets[i]->getAsset(), actorDesc); + m_actors[i].initialIndex = i; + } + + for (const auto& joint : assetDesc.joints) + { + TkJointDesc jointDesc; + for (char k = 0; k < 2; ++k) + { + jointDesc.attachPositions[k] = joint.attachPositions[k]; + jointDesc.chunkIndices[k] = joint.chunkIndices[k]; + jointDesc.families[k] = (joint.assetIndices[k] < 0) ? nullptr : &m_actors[joint.assetIndices[k]].actor->getFamily()->getTkFamily(); + } + TkJoint* joint = pxManager.getFramework().createJoint(jointDesc); + if (joint) + { + pxManager.createJoint(*joint); + } + else + { + m_scene.getCommonUIController().addPopupMessage("Error", "Some joints can't be created"); + } + } + } + + struct Subactor + { + BlastFamilyPtr actor; + uint32_t initialIndex; + std::string name; + }; + + Scene& m_scene; + std::vector<Subactor> m_actors; + CompositeSceneAsset* m_asset; + PxVec3 m_shift; + uint32_t m_index; + std::string m_name; +}; + +class PhysXSceneActor : public SceneActor +{ +public: + PhysXSceneActor(PhysXController& physXController, PhysXController::Actor* actor, const char* name) + : m_physXController(physXController) + , m_actor(actor) + , m_name(name) + { + } + + PhysXSceneActor::~PhysXSceneActor() + { + m_physXController.removePhysXPrimitive(m_actor); + } + + virtual const char* getName() const override + { + return m_name; + } + + virtual ImVec4 getUIColor() const override + { + return ImColor(255, 100, 100, 255); + } + + +private: + PhysXController& m_physXController; + PhysXController::Actor* m_actor; + const char* m_name; + +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Assets Implementation +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void SingleSceneAsset::spawn(PxVec3 shift) +{ + load(); + SingleSceneActor* actor = new SingleSceneActor(*m_scene, this, shift); + m_scene->addSceneActor(actor); +} + +void CompositeSceneAsset::spawn(PxVec3 shift) +{ + load(); + if (isLoaded()) + { + CompositeSceneActor* actor = new CompositeSceneActor(*m_scene, this, shift); + m_scene->addSceneActor(actor); + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PackmanConfigParser +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class PackmanConfigParser : public physx::shdfnd::FastXml::Callback +{ +public: + std::vector<std::pair<std::string, std::string>> dependencies; + +protected: + + // encountered a comment in the XML + virtual bool processComment(const char* /*comment*/) + { + return true; + } + + virtual bool processClose(const char* elementName, unsigned int /*depth*/, bool& /*isError*/) + { + return true; + } + + // return true to continue processing the XML document, false to skip. + virtual bool processElement(const char* elementName, // name of the element + const char* elementData, // element data, null if none + const physx::shdfnd::FastXml::AttributePairs& attr, + int /*lineno*/) // line number in the source XML file + { + if (::strcmp(elementName, "dependency") == 0) + { + dependencies.resize(dependencies.size() + 1); + for (int i = 0; i < attr.getNbAttr(); ++i) + { + if (::strcmp(attr.getKey(i), "name") == 0) + { + dependencies.back().first = std::string(attr.getValue(i)); + } + else if (::strcmp(attr.getKey(i), "version") == 0) + { + dependencies.back().second = std::string(attr.getValue(i)); + } + } + } + return true; + } +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Controller +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +SceneController::SceneController() : m_cubeScale(1.0f) +{ + m_scene = NULL; +} + +SceneController::~SceneController() +{ +} + +void SceneController::onSampleStart() +{ + // setup camera + CFirstPersonCamera* camera = &getRenderer().getCamera(); + DirectX::XMVECTORF32 lookAtPt = { 0, 10, 0, 0 }; + DirectX::XMVECTORF32 eyePt = { 0, 20, 60, 0 }; + camera->SetViewParams(eyePt, lookAtPt); + camera->SetRotateButtons(false, false, true, 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 +} + +void SceneController::addAssets(const AssetList& assetList, bool loadModels) +{ + if (loadModels) + { + for (const auto& model : assetList.models) + { + ModelSceneAsset* asset; + if (!model.isSkinned) + { + asset = new SimpleModelSceneAsset(); + } + else + { + asset = new SkinnedModelSceneAsset(); + } + asset->desc = model; + m_scene->addAsset(asset); + } + + for (const auto& composite : assetList.composites) + { + m_scene->addAsset(new CompositeSceneAsset(composite)); + } + } + + for (const auto& box : assetList.boxes) + { + BoxesSceneAsset* asset = new BoxesSceneAsset(box); + m_scene->addAsset(asset); + } +} + +void SceneController::onInitialize() +{ + +} + +void SceneController::onSampleStop() +{ + if (NULL != m_scene) + { + delete m_scene; + m_scene = nullptr; + } +} + +void SceneController::onTerminate() +{ +} + +void SceneController::Animate(double dt) +{ +} + +LRESULT SceneController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == WM_KEYDOWN) + { + int iKeyPressed = static_cast<int>(wParam); + switch (iKeyPressed) + { + case 'R': + m_scene->reloadAllActors(); + return 0; + case 'F': + throwCube(); + return 0; + default: + break; + } + } + + return 1; +} + +void SceneController::drawUI() +{ + /////////////////////////////////////////////////////////////////////////////////////////// + // Scene UI + /////////////////////////////////////////////////////////////////////////////////////////// + + m_scene->drawUI(); + + + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + ImGui::Spacing(); + + /////////////////////////////////////////////////////////////////////////////////////////// + // Replay + /////////////////////////////////////////////////////////////////////////////////////////// + { + ImGui::Text("Replay Control:"); + + BlastReplay* replay = getBlastController().getReplay(); + if (replay->isRecording()) + { + auto getAnimStr = []() + { + const uint32_t count = 5; + const uint64_t periodMS = 150; + static char str[count + 1] = ""; + for (uint32_t i = 0; i < count; i++) + { + uint64_t ts = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count(); + str[i] = (i == (ts % (periodMS * count)) / periodMS) ? '*' : ' '; + } + return str; + }; + ImGui::Text("State: Recording [%s] | Events: %d", getAnimStr(), replay->getEventCount()); + + if (ImGui::Button("Stop Recording")) + { + replay->stopRecording(); + } + } + else if (replay->isPlaying()) + { + ImGui::Text("State: Playing | Events: %d / %d", replay->getCurrentEventIndex(), replay->getEventCount()); + + if (ImGui::Button("Stop Playing")) + { + replay->stopPlayback(); + } + } + else + { + ImGui::Text("State: Idle | Events: %d", replay->getEventCount()); + + static bool syncFamilies = true; + static bool syncPhysics = true; + + ImGui::Checkbox("Sync Initial Actors", &syncFamilies); + if (ImGui::Checkbox("Sync Initial Transforms", &syncPhysics)) + { + syncFamilies = syncPhysics; + } + + if (ImGui::Button("Start Recording")) + { + replay->startRecording(getBlastController().getExtPxManager(), syncFamilies, syncPhysics); + } + + if (replay->hasRecord()) + { + static bool reload = false; + if (ImGui::Button("Start Playback")) + { + if (reload) + m_scene->reloadAllActors(); + replay->startPlayback(getBlastController().getExtPxManager(), getBlastController().getTkGroup()); + } + ImGui::SameLine(); + ImGui::Checkbox("Reload Scene On Playback", &reload); + } + } + } + + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Separator(); + + /////////////////////////////////////////////////////////////////////////////////////////// + // Cube + /////////////////////////////////////////////////////////////////////////////////////////// + { + ImGui::Text("Thrown Cube Params (F)"); + ImGui::DragFloat("Cube Size", &m_cubeScale, 1.0f, 0.0f, 100.0f); + } + +} + +void SceneController::drawStatsUI() +{ + m_scene->drawStatsUI(); +} + +void SceneController::throwCube() +{ + const float CUBE_VELOCITY = 100; + const float CUBE_DENSITY = 20000.0f; + + CFirstPersonCamera* camera = &getRenderer().getCamera(); + PxVec3 eyePos = XMVECTORToPxVec4(camera->GetEyePt()).getXYZ(); + PxVec3 lookAtPos = XMVECTORToPxVec4(camera->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)); + + PxVec3 dir = (lookAtPos - eyePos).getNormalized(); + rigidDynamic->setLinearVelocity(dir * CUBE_VELOCITY); + +// Add By Lixu Begin + std::string validname = ""; + if (m_ReusedNames.size() > 0) + { + validname = m_ReusedNames.back(); + m_ReusedNames.pop_back(); + } + else + { + int projectilesSize = m_Projectiles.size(); + char cubename[10]; + sprintf(cubename, "Cube_%d", projectilesSize); + validname = cubename; + } + cube->setColor(DirectX::XMFLOAT4(1, 1, 1, 1)); + PhysXSceneActor* p = new PhysXSceneActor(getPhysXController(), cube, validname.c_str()); + m_UsedNames.push_back(validname); + m_Projectiles.push_back(p); + m_scene->addSceneActor(p); + + getManager()->m_bNeedRefreshTree = true; +// Add By Lixu End +} + +void SceneController::spawnAsset(int32_t num) +{ + m_scene->spawnAsset(num); +} + +int SceneController::releaseAll() +{ + return m_scene->releaseAll(); +} + +// Add By Lixu Begin +void SceneController::addProjectile() +{ + throwCube(); +} + +void SceneController::clearProjectile() +{ + std::vector<PhysXSceneActor*>::iterator it; + for (it = m_Projectiles.begin(); it != m_Projectiles.end(); it++) + { + std::vector<SceneActor*>& actors = m_scene->getActors(); + std::map<SceneActor*, int> ActorIndexMap; + int actorSize = actors.size(); + for (int i = 0; i < actorSize; i++) + { + ActorIndexMap[actors[i]] = i; + } + + m_scene->removeSceneActor(Scene::ActorIndex(ActorIndexMap[*it], -1)); + } + m_Projectiles.clear(); + m_UsedNames.clear(); + m_ReusedNames.clear(); +} + +void SceneController::ResetScene() +{ + clearProjectile(); + m_scene->reloadAllActors(); + getManager()->m_bNeedRefreshTree = true; +} + +void SceneController::ClearScene() +{ + 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); + } +} +// Add By Lixu End
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.h new file mode 100644 index 0000000..82f08d8 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/scene/SceneController.h @@ -0,0 +1,99 @@ +/* +* 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. +*/ + +#ifndef SCENE_CONTROLLER_H +#define SCENE_CONTROLLER_H + +#include "SampleManager.h" +#include <map> + + +class CFirstPersonCamera; +class BlastAssetBoxes; +class SceneActor; +class BlastAsset; +class SingleSceneAsset; +class Scene; +// Add By Lixu Begin +class PhysXSceneActor; +// Add By Lixu End +class SceneController : public ISampleController +{ +public: + + SceneController(); + virtual ~SceneController(); + + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual void Animate(double dt); + void drawUI(); + void drawStatsUI(); + + virtual void onInitialize(); + virtual void onSampleStart(); + virtual void onSampleStop(); + virtual void onTerminate(); + + // commands + int releaseAll(); + void spawnAsset(int32_t); + +// Add By Lixu Begin + void addProjectile(); + void clearProjectile(); + void ResetScene(); + void ClearScene(); + bool GetAssetDesc(const BlastAsset* asset, AssetList::ModelAsset& desc); + void GetProjectilesNames(std::vector<std::string>& projectilesNames); +// Add By Lixu End + +private: + void addAssets(const AssetList& assetList, bool loadModels = true); + void throwCube(); + + SceneController& operator= (SceneController&); + + //////// used controllers //////// + + Renderer& getRenderer() const + { + return getManager()->getRenderer(); + } + + PhysXController& getPhysXController() const + { + return getManager()->getPhysXController(); + } + + BlastController& getBlastController() const + { + return getManager()->getBlastController(); + } + + CommonUIController& getCommonUIController() const + { + return getManager()->getCommonUIController(); + } + + + //////// internal data //////// + + Scene* m_scene; + + float m_cubeScale; + +// Add By Lixu Begin + std::vector<std::string> m_UsedNames; + std::vector<std::string> m_ReusedNames; + std::vector<PhysXSceneActor*> m_Projectiles; +// Add By Lixu End +}; + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp new file mode 100644 index 0000000..e56a124 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp @@ -0,0 +1,621 @@ +/* +* 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. +*/ + +#include "CommonUIController.h" + +#include "Renderer.h" +#include "BlastController.h" +#include "DamageToolController.h" +#include "SceneController.h" +#include "SampleController.h" +#include "PhysXController.h" +#include "SampleProfiler.h" + +#include "PxVisualizationParameter.h" +#include "PxScene.h" + +#include <imgui.h> +#include "imgui_impl_dx11.h" +#include "UIHelpers.h" + +#include <cstdio> +#include <inttypes.h> + + +inline float memorySizeOutput(const char*& prefix, float value) +{ + for (prefix = "\0\0k\0M\0G\0T\0P\0E"; value >= 1024 && *prefix != 'E'; value /= 1024, prefix += 2); + return value; +} + +CommonUIController::CommonUIController() +{ +} + +HRESULT CommonUIController::DeviceCreated(ID3D11Device* pDevice) +{ + DeviceManager* manager = GetDeviceManager(); + ID3D11DeviceContext* pd3dDeviceContext; + pDevice->GetImmediateContext(&pd3dDeviceContext); + ImGui_ImplDX11_Init(manager->GetHWND(), pDevice, pd3dDeviceContext); + + ImGuiStyle& style = ImGui::GetStyle(); + style.WindowRounding = 8.0f; + style.ScrollbarRounding = 8.0f; + style.FrameRounding = 8.0f; + //style.IndentSpacing = 20; + int mainColor[3] = { 110, 110, 110 }; // previous green one { 50, 110, 30 } + style.Colors[ImGuiCol_TitleBg] = ImColor(mainColor[0], mainColor[1], mainColor[2], 62); + style.Colors[ImGuiCol_TitleBgCollapsed] = ImColor(mainColor[0], mainColor[1], mainColor[2], 52); + style.Colors[ImGuiCol_TitleBgActive] = ImColor(mainColor[0], mainColor[1], mainColor[2], 87); + style.Colors[ImGuiCol_Header] = ImColor(mainColor[0], mainColor[1], mainColor[2], 52); + style.Colors[ImGuiCol_HeaderHovered] = ImColor(mainColor[0], mainColor[1], mainColor[2], 92); + style.Colors[ImGuiCol_HeaderActive] = ImColor(mainColor[0], mainColor[1], mainColor[2], 72); + style.Colors[ImGuiCol_ScrollbarBg] = ImColor(mainColor[0], mainColor[1], mainColor[2], 12); + style.Colors[ImGuiCol_ScrollbarGrab] = ImColor(mainColor[0], mainColor[1], mainColor[2], 52); + style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImColor(mainColor[0], mainColor[1], mainColor[2], 92); + style.Colors[ImGuiCol_ScrollbarGrabActive] = ImColor(mainColor[0], mainColor[1], mainColor[2], 72); + style.Colors[ImGuiCol_Button] = ImColor(40, 100, 80, 30); + style.Colors[ImGuiCol_ButtonHovered] = ImColor(40, 100, 80, 100); + style.Colors[ImGuiCol_ButtonActive] = ImColor(40, 100, 80, 70); + style.Colors[ImGuiCol_PopupBg] = ImColor(10, 23, 18, 230); + style.Colors[ImGuiCol_TextSelectedBg] = ImColor(10, 23, 18, 180); + style.Colors[ImGuiCol_FrameBg] = ImColor(70, 70, 70, 30); + style.Colors[ImGuiCol_FrameBgHovered] = ImColor(70, 70, 70, 70); + style.Colors[ImGuiCol_FrameBgActive] = ImColor(70, 70, 70, 50); + style.Colors[ImGuiCol_ComboBg] = ImColor(20, 20, 20, 252); + + return S_OK; +} + +void CommonUIController::DeviceDestroyed() +{ + ImGui_ImplDX11_Shutdown(); +} + +extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +LRESULT CommonUIController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PX_UNUSED(hWnd); + PX_UNUSED(wParam); + PX_UNUSED(lParam); + + ImGui_ImplDX11_WndProcHandler(hWnd, uMsg, wParam, lParam); + + if (uMsg == WM_KEYDOWN && !ImGui::GetIO().WantCaptureKeyboard) + { + int iKeyPressed = static_cast<int>(wParam); + switch (iKeyPressed) + { + case 'P': + { + getPhysXController().setPaused(!getPhysXController().isPaused()); + break; + } + case 'O': + { + getRenderer().setWireframeMode(!getRenderer().getWireframeMode()); + break; + } + case 'I': + { + getBlastController().debugRenderMode = (BlastFamily::DebugRenderMode)(((int)getBlastController().debugRenderMode + 1) % BlastFamily::DebugRenderMode::DEBUG_RENDER_MODES_COUNT); + break; + } + case VK_F5: + { + getRenderer().reloadShaders(); + break; + } + default: + break; + } + } + + if (ImGui::GetIO().WantCaptureMouse) + return 0; + + return 1; +} + +void CommonUIController::Animate(double fElapsedTimeSeconds) +{ + m_dt = (float)fElapsedTimeSeconds; +} + +void CommonUIController::Render(ID3D11Device*, ID3D11DeviceContext*, ID3D11RenderTargetView*, ID3D11DepthStencilView*) +{ + ImGui_ImplDX11_NewFrame(); + drawUI(); + ImGui::Render(); +} + +void CommonUIController::addDelayedCall(const char* title, const char* message, std::function<void()> func, float delay) +{ + DelayedCall call = { func, title, message, delay, delay }; + m_delayedCalls.emplace(call); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMGUI UI +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +void CommonUIController::drawUI() +{ + const float padding = 8.0f; + ImGui::SetNextWindowPos(ImVec2(padding, padding), ImGuiSetCond_Once/*ImGuiSetCond_FirstUseEver*/); + ImGui::SetNextWindowSize(ImVec2(420, getRenderer().getScreenHeight() - 2 * padding), ImGuiSetCond_Once/*ImGuiSetCond_FirstUseEver*/); + ImGui::SetNextWindowCollapsed(false, ImGuiSetCond_Once); + ImGui::Begin("New Shiny UI", 0, ImGuiWindowFlags_NoTitleBar); + { + ImGui::PushItemWidth(ImGui::GetWindowSize().x * 0.5f); + + /////////////////////////////////////////////////////////////////////////////////////////// + // Scene + /////////////////////////////////////////////////////////////////////////////////////////// + if (ImGui::CollapsingHeader("Scene")) + { + getSceneController().drawUI(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Blast + /////////////////////////////////////////////////////////////////////////////////////////// + if (ImGui::CollapsingHeader("Blast")) + { + getBlastController().drawUI(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Damage Tool + /////////////////////////////////////////////////////////////////////////////////////////// + if (ImGui::CollapsingHeader("Damage Tool")) + { + getDamageToolController().drawUI(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Stats + /////////////////////////////////////////////////////////////////////////////////////////// + if (ImGui::CollapsingHeader("Stats")) + { + BlastController& blastController = getBlastController(); + + const char* prefix; + float sizeVal; + + // FPS + double averageTime = GetDeviceManager()->GetAverageFrameTime(); + float fps = (averageTime > 0) ? 1.0 / averageTime : 0.0; + float frameMs = 1000.0f / fps; + ImGui::Text("Frame Time %.3f ms (%.1f FPS)", frameMs, fps); + + static PlotLinesInstance<> fpsPlot; + fpsPlot.plot("FPS", frameMs, "ms/frame", 0.0f, 100.0f); + + // Render stats + ImGui::PushStyleColor(ImGuiCol_Text, ImColor(0xFF, 0x3B, 0xD8, 0xFF)); + ImGui::Text("Draw Calls (Opaque/Transparent): %d/%d", getRenderer().getVisibleOpaqueRenderablesCount(), getRenderer().getVisibleTransparentRenderablesCount()); + ImGui::PopStyleColor(); + + // Blast stats + const BlastTimers& timers = blastController.getLastBlastTimers(); + + ImGui::Text("Simulation Time: %.2f ms ", getPhysXController().getLastSimulationTime() * 1000); + ImGui::Text("Actor Count: %d", blastController.getActorCount()); + ImGui::Text("Visible Chunk Count: %d", blastController.getTotalVisibleChunkCount()); + + getManager()->getSceneController().drawStatsUI(); + + sizeVal = memorySizeOutput(prefix, (float)blastController.getFamilySize()); + ImGui::Text("Family Size: %.3g %sB", sizeVal, prefix); + sizeVal = memorySizeOutput(prefix, (float)blastController.getBlastAssetsSize()); + ImGui::Text("Blast asset Data size: %.3g %sB", sizeVal, prefix); + + //ImGui::Text(" Last Blast Extern Time: %8.3f ms", timers.mLastExternalTime * 1000); +// ImGui::Text(" Last Damage Time: %8.3f ms", timers.blastDamage * 1000); +#if NV_PROFILE + ImGui::Text("Last Material Time: %8.3f ms", timers.blastDamageMaterial * 1000); + ImGui::Text("Last Fracture Time: %8.3f ms", timers.blastDamageFracture * 1000); +#endif +// ImGui::Text("Last Physics Split Time: %.3f ms", timers.physicsSplit * 1000); +#if NV_PROFILE + ImGui::Text("Last Island Time: %8.3f ms", timers.blastSplitIsland * 1000); + ImGui::Text("Last Partition Time: %8.3f ms", timers.blastSplitPartition * 1000); + ImGui::Text("Last Visibility Time: %8.3f ms", timers.blastSplitVisibility * 1000); +#endif + +#if NV_PROFILE + // Sample Profiler + static bool s_showProfilerWindow = false; + if (ImGui::Button("Code Profiler")) + { + s_showProfilerWindow = !s_showProfilerWindow; + } + if (s_showProfilerWindow) + { + drawCodeProfiler(&s_showProfilerWindow); + } +#endif + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Application + /////////////////////////////////////////////////////////////////////////////////////////// + if (ImGui::CollapsingHeader("Application")) + { + // Paused + bool isPaused = getPhysXController().isPaused(); + if (ImGui::Checkbox("Pause (P)", &isPaused)) + { + getPhysXController().setPaused(isPaused); + } + + // Reload Shaders + if (ImGui::Button("Reload Shaders (F5)")) + { + getRenderer().reloadShaders(); + } + + // ImGui Test Window (just in case) + static bool s_showTestWindow = false; + if (ImGui::Button("ImGui Test Window")) + { + s_showTestWindow = !s_showTestWindow; + } + if (s_showTestWindow) + { + ImGui::ShowTestWindow(); + } + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Debug Render + /////////////////////////////////////////////////////////////////////////////////////////// + if (ImGui::CollapsingHeader("Debug Render")) + { + // WireFrame + bool wireFrameEnabled = getRenderer().getWireframeMode(); + if (ImGui::Checkbox("WireFrame (O)", &wireFrameEnabled)) + { + getRenderer().setWireframeMode(wireFrameEnabled); + } + + // - - - - - - - - + ImGui::Spacing(); + + // Blast Debug Render Mode + const char* debugRenderItems[] = + { + "Disabled", // DEBUG_RENDER_DISABLED + "Health Graph", // DEBUG_RENDER_HEALTH_GRAPH + "Centroids", // DEBUG_RENDER_CENTROIDS + "Health Graph + Centroids", // DEBUG_RENDER_HEALTH_GRAPH_CENTROIDS + "Joints", // DEBUG_RENDER_JOINTS + "Stress Graph", // DEBUG_RENDER_STRESS_GRAPH + "Stress Graph + Nodes Impulses", // DEBUG_RENDER_STRESS_GRAPH_NODES_IMPULSES + "Stress Graph + Bonds Impulses" // DEBUG_RENDER_STRESS_GRAPH_BONDS_IMPULSES + }; + ImGui::Combo("Blast Debug Render Mode (I)", (int*)&getBlastController().debugRenderMode, debugRenderItems, IM_ARRAYSIZE(debugRenderItems), -1); + + // Blast Debug Render Scale + ImGui::DragFloat("Blast Debug Render Scale", &getBlastController().debugRenderScale, 0.01f, 0.0f, 10.0f, "%.3f", 4.0f); + + // - - - - - - - - + ImGui::Spacing(); + + // PhysX Debug Render + if (ImGui::TreeNode("PhysX Debug Render")) + { + auto addParam = [&](physx::PxVisualizationParameter::Enum param, const char* uiName) + { + bool enabled = getPhysXController().getPhysXScene().getVisualizationParameter(param) != 0; + if (ImGui::Checkbox(uiName, &enabled)) + { + getPhysXController().getPhysXScene().setVisualizationParameter(param, enabled ? 1.0f : 0.0f); + } + }; + + addParam(PxVisualizationParameter::eSCALE, "Scale"); + addParam(PxVisualizationParameter::eBODY_AXES, "Body Axes"); + addParam(PxVisualizationParameter::eWORLD_AXES, "World Axes"); + addParam(PxVisualizationParameter::eBODY_MASS_AXES, "Body Mass Axes"); + addParam(PxVisualizationParameter::eBODY_LIN_VELOCITY, "Body Lin Velocity"); + addParam(PxVisualizationParameter::eBODY_ANG_VELOCITY, "Body Ang Velocity"); + addParam(PxVisualizationParameter::eBODY_JOINT_GROUPS, "Body Joint"); + addParam(PxVisualizationParameter::eCONTACT_POINT, "Contact Point"); + addParam(PxVisualizationParameter::eCONTACT_NORMAL, "Contact Normal"); + addParam(PxVisualizationParameter::eCONTACT_ERROR, "Contact Error"); + addParam(PxVisualizationParameter::eCONTACT_FORCE, "Contact Force"); + addParam(PxVisualizationParameter::eACTOR_AXES, "Actor Axes"); + addParam(PxVisualizationParameter::eCOLLISION_AABBS, "Collision AABBs"); + addParam(PxVisualizationParameter::eCOLLISION_SHAPES, "Collision Shapes"); + addParam(PxVisualizationParameter::eCOLLISION_AXES, "Collision Axes"); + addParam(PxVisualizationParameter::eCOLLISION_COMPOUNDS, "Collision Compounds"); + addParam(PxVisualizationParameter::eCOLLISION_FNORMALS, "Collision FNormals"); + addParam(PxVisualizationParameter::eCOLLISION_EDGES, "Collision Edges"); + addParam(PxVisualizationParameter::eCOLLISION_STATIC, "Collision Static"); + addParam(PxVisualizationParameter::eCOLLISION_DYNAMIC, "Collision Dynamic"); + //addParam(PxVisualizationParameter::eDEPRECATED_COLLISION_PAIRS, "Collision Pairs"); + addParam(PxVisualizationParameter::eJOINT_LOCAL_FRAMES, "Joint Local Frames"); + addParam(PxVisualizationParameter::eJOINT_LIMITS, "Joint Limits"); + //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_POSITION, "PS Position"); + //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_VELOCITY, "PS Velocity"); + //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_COLLISION_NORMAL, "PS Collision Normal"); + //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_BOUNDS, "PS Bounds"); + //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_GRID, "PS Grid"); + //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_BROADPHASE_BOUNDS, "PS Broadphase Bounds"); + //addParam(PxVisualizationParameter::ePARTICLE_SYSTEM_MAX_MOTION_DISTANCE, "PS Max Motion Distance"); + addParam(PxVisualizationParameter::eCULL_BOX, "Cull Box"); + //addParam(PxVisualizationParameter::eCLOTH_VERTICAL, "Cloth Vertical"); + //addParam(PxVisualizationParameter::eCLOTH_HORIZONTAL, "Cloth Horizontal"); + //addParam(PxVisualizationParameter::eCLOTH_BENDING, "Cloth Bending"); + //addParam(PxVisualizationParameter::eCLOTH_SHEARING, "Cloth Shearing"); + //addParam(PxVisualizationParameter::eCLOTH_VIRTUAL_PARTICLES, "Cloth Virtual Particles"); + addParam(PxVisualizationParameter::eMBP_REGIONS, "MBP Regions"); + + ImGui::TreePop(); + } + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // PhysX + /////////////////////////////////////////////////////////////////////////////////////////// + if (ImGui::CollapsingHeader("PhysX")) + { + // PhysX + getPhysXController().drawUI(); + + // GPU + getSampleController().drawPhysXGpuUI(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Renderer + /////////////////////////////////////////////////////////////////////////////////////////// + if (ImGui::CollapsingHeader("Renderer")) + { + getRenderer().drawUI(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Hints + /////////////////////////////////////////////////////////////////////////////////////////// + if (ImGui::CollapsingHeader("Hints / Help")) + { + ImGui::BulletText("Rotate camera - RMB"); + ImGui::BulletText("Move camera - WASDQE(SHIFT)"); + ImGui::BulletText("Play/Pause - P"); + ImGui::BulletText("Reload shaders - F5"); + ImGui::BulletText("Wireframe - O"); + ImGui::BulletText("Blast Debug Render - I"); + ImGui::BulletText("Apply damage - LMB"); + ImGui::BulletText("Damage radius - +/-/wheel"); + ImGui::BulletText("Damage profile - 1-9"); + ImGui::BulletText("Explosive - X"); + ImGui::BulletText("Throw cube - F"); + ImGui::BulletText("Restart - R"); + } + + ImGui::PopItemWidth(); + } + ImGui::End(); + + /////////////////////////////////////////////////////////////////////////////////////////// + // Mode Text + /////////////////////////////////////////////////////////////////////////////////////////// + { + ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4()); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0)); + + const char* text = getDamageToolController().isDamageMode() ? "DAMAGE MODE (PRESS SPACE)" : "DRAG MODE (PRESS SPACE)"; + ImVec2 size = ImGui::CalcTextSize(text); + ImGui::SetNextWindowPos(ImVec2((getRenderer().getScreenWidth() - size.x) / 2, 0)); + ImGui::Begin("Mode Text", 0, ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar); + ImGui::Text(text); + ImGui::End(); + + ImGui::PopStyleVar(); + ImGui::PopStyleColor(); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // FPS + /////////////////////////////////////////////////////////////////////////////////////////// + { + ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4()); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); + + double averageTime = GetDeviceManager()->GetAverageFrameTime(); + float fps = (averageTime > 0) ? 1.0 / averageTime : 0.0; + static char buf[32]; + std::sprintf(buf, "%.1f FPS", fps); + ImVec2 size = ImGui::CalcTextSize(buf); + + size.x += 20.0; + ImGui::SetNextWindowSize(size); + ImGui::SetNextWindowPos(ImVec2(getRenderer().getScreenWidth() - size.x, 0)); + ImGui::Begin("FPS", 0, ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar); + ImGui::Text(buf); + ImGui::End(); + + ImGui::PopStyleVar(); + ImGui::PopStyleColor(); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Loading overlay + /////////////////////////////////////////////////////////////////////////////////////////// + if (!m_delayedCalls.empty()) + { + DelayedCall& call = m_delayedCalls.front(); + if (call.delay > 0) + { + const int height = 50; + const char* message = call.message; + const float alpha = PxClamp(lerp(0.0f, 1.0f, (call.delayTotal - call.delay) * 10.0f), 0.0f, 1.0f); + + ImGui::PushStyleColor(ImGuiCol_WindowBg, ImColor(0, 0, 0, 200)); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha); + ImGui::SetNextWindowPosCenter(); + ImVec2 size = ImGui::CalcTextSize(message); + int width = std::max<float>(200, size.x) + 50; + ImGui::SetNextWindowSize(ImVec2(width, height)); + ImGui::Begin(call.title, 0, ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar); + ImGui::SetCursorPos(ImVec2((width - size.x) * 0.5f, (height - size.y) * 0.5f)); + ImGui::Text(message); + ImGui::End(); + ImGui::PopStyleVar(); + ImGui::PopStyleColor(); + + call.delay -= PxClamp(m_dt, 0.0f, 0.1f); + } + else + { + call.func(); + m_delayedCalls.pop(); + } + } +} + + +void CommonUIController::drawCodeProfiler(bool* open) +{ + ImGuiWindowFlags window_flags = 0; + const float padding = 8.0f; + const float width = 550; + const float height = 580; + ImGui::SetNextWindowPos(ImVec2(getRenderer().getScreenWidth() - width - padding, padding), ImGuiSetCond_Once/*ImGuiSetCond_FirstUseEver*/); + ImGui::SetNextWindowSize(ImVec2(width, height), ImGuiSetCond_Once); + if (!ImGui::Begin("Code Profiler", open, window_flags)) + { + // Early out if the window is collapsed, as an optimization. + ImGui::End(); + return; + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Control/Main Bar + /////////////////////////////////////////////////////////////////////////////////////////// + { + if (ImGui::Button("Reset")) + { + PROFILER_INIT(); + } + ImGui::SameLine(); + if (ImGui::Button("Dump To File (profile.txt)")) + { + SampleProfilerDumpToFile("profile.txt"); + } + ImGui::SameLine(); + ImGui::Text("Profiler overhead: %2.3f ms", SampleProfilerGetOverhead().count() * 0.001f); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Legend + /////////////////////////////////////////////////////////////////////////////////////////// + { + ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); + ImGui::Text("Legend: name | calls | time | max time"); + ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Stats Tree + /////////////////////////////////////////////////////////////////////////////////////////// + ImGui::SetNextTreeNodeOpen(true, ImGuiSetCond_Once); + float plotMS = 0.0f; + float plotMaxMS = 0.0f; + const char* plotName = nullptr; + if (ImGui::TreeNode("Root")) + { + auto treeIt = SampleProfilerCreateTreeIterator(); + if (treeIt) + { + uint32_t depth = 1; + uint32_t openeDepth = 1; + while (!treeIt->isDone()) + { + const auto data = treeIt->data(); + + while (data->depth < depth) + { + ImGui::TreePop(); + depth--; + } + + const uint32_t maxLen = 30; + auto hash = data->hash; + static uint64_t selectedNodeHash = 0; + if (selectedNodeHash == hash) + { + plotMS = data->time.count() * 0.001f; + plotMaxMS = data->maxTime.count() * 0.001f; + plotName = data->name; + } + if (ImGui::TreeNodeEx(data->name, data->hasChilds ? 0 : ImGuiTreeNodeFlags_Leaf, "%-*.*s | %d | %2.3f ms | %2.3f ms", + maxLen, maxLen, data->name, data->calls, data->time.count() * 0.001f, data->maxTime.count() * 0.001f)) + { + depth++; + treeIt->next(); + } + else + { + treeIt->next(); + while (!treeIt->isDone() && treeIt->data()->depth > depth) + treeIt->next(); + } + + if (ImGui::IsItemClicked()) + { + selectedNodeHash = hash; + } + } + + while (depth > 0) + { + ImGui::TreePop(); + depth--; + } + + treeIt->release(); + } + else + { + ImGui::Text("Profiler Is Broken. Begin/End Mismatch."); + } + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Selected Item Plot + /////////////////////////////////////////////////////////////////////////////////////////// + { + ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); + if (plotName) + { + static PlotLinesInstance<> selectedNodePlot; + selectedNodePlot.plot("", plotMS, plotName, 0.0f, plotMaxMS); + } + else + { + ImGui::Text("Select item to plot."); + } + } + + ImGui::End(); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h new file mode 100644 index 0000000..da62674 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h @@ -0,0 +1,106 @@ +/* +* 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. +*/ + +#ifndef COMMON_UI_CONTROLLER_H +#define COMMON_UI_CONTROLLER_H + +#include "SampleManager.h" +#include <DirectXMath.h> +#include <string> +#include <list> +#include <queue> +#include <functional> + + +class Renderer; +class PhysXController; +class BlastController; + + +class CommonUIController : public ISampleController +{ + public: + CommonUIController(); + virtual ~CommonUIController() {}; + + virtual HRESULT DeviceCreated(ID3D11Device* pDevice); + virtual void DeviceDestroyed(); + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual void Animate(double fElapsedTimeSeconds); + virtual void Render(ID3D11Device*, ID3D11DeviceContext*, ID3D11RenderTargetView*, ID3D11DepthStencilView*); + + void addDelayedCall(std::function<void()> func, const char* message) + { + addDelayedCall("PLEASE WAIT...", message, func); + } + + void addPopupMessage(const char* title, const char* message, float duration = 2.f) + { + addDelayedCall(title, message, [] {}, duration); + } + + private: + void addDelayedCall(const char* title, const char* message, std::function<void()> func, float delay = 0.1f); + + void drawUI(); + void drawCodeProfiler(bool*); + + + //////// used controllers //////// + + Renderer& getRenderer() const + { + return getManager()->getRenderer(); + } + + PhysXController& getPhysXController() const + { + return getManager()->getPhysXController(); + } + + BlastController&getBlastController() const + { + return getManager()->getBlastController(); + } + + DamageToolController& getDamageToolController() const + { + return getManager()->getDamageToolController(); + } + + SceneController& getSceneController() const + { + return getManager()->getSceneController(); + } + + SampleController& getSampleController() const + { + return getManager()->getSampleController(); + } + + + //////// internal data //////// + + struct DelayedCall + { + std::function<void()> func; + const char* title; + const char* message; + float delay; + float delayTotal; + }; + + std::queue<DelayedCall> m_delayedCalls; + + float m_dt; + +}; + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp new file mode 100644 index 0000000..fba1227 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp @@ -0,0 +1,294 @@ +/* +* 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. +*/ + +#include "DamageToolController.h" +#include "RenderUtils.h" +#include "BlastController.h" +#include "Renderer.h" +#include "PhysXController.h" +#include "SampleProfiler.h" + +#include <imgui.h> + +#include "NvBlastTkActor.h" +#include "NvBlastExtDamageShaders.h" +#include "NvBlastExtPxActor.h" + +#include "PxRigidDynamic.h" +#include "PxScene.h" + + +using namespace Nv::Blast; +using namespace physx; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Setup +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +const DirectX::XMFLOAT4 PICK_POINTER_ACTIVE_COLOR(1.0f, 0.f, 0.f, 0.6f); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +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) +{ + // Damage functions + auto radialDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 position, PxVec3 normal) + { + NvBlastExtRadialDamageDesc desc = + { + m_compressiveDamage, + { position.x, position.y, position.z }, + m_damageRadius, + m_damageRadius + 2.0f + }; + + actor->getTkActor().damage(damager->program, &desc, sizeof(desc)); + }; + auto shearDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 position, PxVec3 normal) + { + PxVec3 force = -2 * normal; + + NvBlastExtShearDamageDesc desc = + { + { force.x, force.y, force.z }, + { position.x, position.y, position.z } + }; + + actor->getTkActor().damage(damager->program, &desc, sizeof(desc)); + }; + auto stressDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 position, PxVec3 normal) + { + PxVec3 force = -m_stressForceFactor * normal * actor->getPhysXActor().getMass(); + + getBlastController().stressDamage(actor, position, force); + }; + + // Damage Tools: + { + Damager dam; + dam.uiName = "Radial Damage (Falloff)"; + dam.program = NvBlastDamageProgram { NvBlastExtFalloffGraphShader, NvBlastExtFalloffSubgraphShader }; + dam.pointerColor = DirectX::XMFLOAT4(1.0f, 1.0f, 1.0f, 0.4f); + dam.executeFunction = radialDamageExecute; + m_armory.push_back(dam); + } + { + Damager dam; + dam.uiName = "Radial Damage (Cutter)"; + dam.program = NvBlastDamageProgram { NvBlastExtCutterGraphShader, NvBlastExtCutterSubgraphShader }; + dam.pointerColor = DirectX::XMFLOAT4(0.5f, 0.5f, 1.0f, 0.4f); + dam.executeFunction = radialDamageExecute; + m_armory.push_back(dam); + } + + { + Damager dam; + dam.uiName = "Shear Damage"; + dam.program = NvBlastDamageProgram { NvBlastExtShearGraphShader, NvBlastExtShearSubgraphShader }; + dam.pointerColor = DirectX::XMFLOAT4(0.5f, 1.0f, 0.5f, 0.4f); + dam.executeFunction = shearDamageExecute; + m_armory.push_back(dam); + } + + { + Damager dam; + dam.uiName = "Stress Damage"; + dam.program = { nullptr, nullptr }; + dam.pointerColor = DirectX::XMFLOAT4(0.5f, 0.5f, 1.0f, 0.4f); + dam.executeFunction = stressDamageExecute; + m_armory.push_back(dam); + } + + for (const Damager& d : m_armory) + { + m_armoryNames.push_back(d.uiName); + } +} + +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)); + + // default tool + setDamageProfile(0); + + // start with damage mode by default + setDamageMode(true); +} + +void DamageToolController::onInitialize() +{ +} + + +void DamageToolController::onSampleStop() +{ + getRenderer().removeRenderable(m_pickPointerRenderable); + SAFE_DELETE(m_pickPointerRenderMaterial); +} + +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); +} + + +LRESULT DamageToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PROFILER_SCOPED_FUNCTION(); + + if (uMsg == WM_LBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP) + { + float mouseX = (short)LOWORD(lParam) / getRenderer().getScreenWidth(); + float mouseY = (short)HIWORD(lParam) / getRenderer().getScreenHeight(); + bool press = uMsg == WM_LBUTTONDOWN; + + // damage mode + if (m_damageMode && m_pickPointerRenderable) + { + 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; + m_pickPointerRenderable->setHidden(false); + m_pickPointerRenderable->setTransform(PxTransform(hit.position)); + + if (press) + { + damage(hit.position, hit.normal); + m_pickPointerColor = PICK_POINTER_ACTIVE_COLOR; + } + } + else + { + m_pickPointerRenderable->setHidden(true); + } + } + } + + if (uMsg == WM_MOUSEWHEEL) + { + int delta = int((short)HIWORD(wParam)) / WHEEL_DELTA; + changeDamageRadius(delta * 0.3f); + } + + if (uMsg == WM_KEYDOWN) + { + int iKeyPressed = static_cast<int>(wParam); + if (iKeyPressed == VK_OEM_PLUS) + { + changeDamageRadius(0.2f); + } + else if (iKeyPressed == VK_OEM_MINUS) + { + changeDamageRadius(-0.2f); + } + else if (iKeyPressed >= '1' && iKeyPressed <= '9') + { + uint32_t num = PxClamp<uint32_t>(iKeyPressed - '1', 0, (uint32_t)m_armory.size() - 1); + setDamageProfile(num); + } + else if (iKeyPressed == VK_SPACE) + { + setDamageMode(!isDamageMode()); + } + + } + + return 1; +} + +void DamageToolController::drawUI() +{ + ImGui::DragFloat("Compressive Damage", &m_compressiveDamage, 0.05f); + 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); + } +} + + +void DamageToolController::setDamageMode(bool enabled) +{ + m_damageMode = enabled; + + getPhysXController().setDraggingEnabled(!m_damageMode); + + if (!m_damageMode) + { + m_pickPointerRenderable->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); + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h new file mode 100644 index 0000000..b6712f2 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h @@ -0,0 +1,129 @@ +/* +* 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. +*/ + +#ifndef DAMAGE_TOOL_CONTROLLER_H +#define DAMAGE_TOOL_CONTROLLER_H + +#include "SampleManager.h" +#include "NvBlastTypes.h" +#include <DirectXMath.h> +#include <functional> +#include "PxVec3.h" + + +class Renderable; +class RenderMaterial; + +namespace Nv +{ +namespace Blast +{ +class ExtPxActor; +} +} + + + +class DamageToolController : public ISampleController +{ +public: + DamageToolController(); + virtual ~DamageToolController(); + + 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(); + + bool isDamageMode() const + { + return m_damageMode; + } + +// Add By Lixu Begin + Renderable* getPickPointer() + { + return m_pickPointerRenderable; + } +// Add By Lixu End + +private: + DamageToolController& operator= (DamageToolController&); + + + //////// 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 //////// + + Renderer& getRenderer() const + { + return getManager()->getRenderer(); + } + + PhysXController& getPhysXController() const + { + return getManager()->getPhysXController(); + } + + BlastController& getBlastController() const + { + return getManager()->getBlastController(); + } + + + //////// internal data //////// + + Renderable* m_pickPointerRenderable; + RenderMaterial* m_pickPointerRenderMaterial; + DirectX::XMFLOAT4 m_pickPointerColor; + + float m_damageRadius; + float m_compressiveDamage; + float m_explosiveImpulse; + float m_stressForceFactor; + uint32_t m_damageProfile; + + 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) + { + executeFunction(this, actor, position, normal); + } + }; + + std::vector<Damager> m_armory; + std::vector<const char*> m_armoryNames; + + bool m_damageMode; +}; + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp new file mode 100644 index 0000000..b02044b --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp @@ -0,0 +1,156 @@ +/* +* 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. +*/ + +#include "EditionToolController.h" +#include "BlastController.h" +#include "Renderer.h" +#include "PhysXController.h" +#include "SampleProfiler.h" +#include "PxRigidDynamic.h" +#include "PxScene.h" +#include "NvBlastExtPxManager.h" +#include "SceneController.h" +#include "NvBlastExtPxActor.h" +using namespace Nv::Blast; +using namespace physx; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Setup +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +EditionToolController::EditionToolController() +{ +} + +EditionToolController::~EditionToolController() +{ +} + +void EditionToolController::onSampleStart() +{ +} + +void EditionToolController::onInitialize() +{ +} + + +void EditionToolController::onSampleStop() +{ +} + +void EditionToolController::Animate(double dt) +{ + PROFILER_SCOPED_FUNCTION(); +} + + +LRESULT EditionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PROFILER_SCOPED_FUNCTION(); + + if (uMsg == WM_LBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP) + { + float mouseX = (short)LOWORD(lParam) / getRenderer().getScreenWidth(); + float mouseY = (short)HIWORD(lParam) / getRenderer().getScreenHeight(); + bool press = uMsg == WM_LBUTTONDOWN; + + if (uMsg == WM_LBUTTONUP) + { + 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; + + PxRigidActor* actor = NULL; + if (hit.shape) + { + actor = hit.actor; + } + fracture(actor); + } + } + + return 1; +} + +void EditionToolController::drawUI() +{ +} + +void EditionToolController::fracture(PxActor* actor) +{ + if (NULL == actor) + { + return; + } + + BlastController& blastController = getBlastController(); + std::vector<BlastFamilyPtr>& families = blastController.getFamilies(); + if (families.size() == 0) + { + 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) + { + 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; + } + } + if (NULL == pBlastFamily) + { + return; + } + + const uint32_t* chunkIndices = extActor->getChunkIndices(); + + const BlastAsset& blastAsset = pBlastFamily->getBlastAsset(); + const BlastAsset* pBlastAsset = &blastAsset; + + SceneController& sceneController = getManager()->getSceneController(); + AssetList::ModelAsset desc; + sceneController.GetAssetDesc(pBlastAsset, desc); + + std::string assetname = desc.id; + getManager()->fractureAsset(assetname, pBlastAsset, chunkIndices[0]); + getManager()->addModelAsset(assetname, desc.isSkinned, desc.transform, false); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h new file mode 100644 index 0000000..b1e88d1 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h @@ -0,0 +1,62 @@ +/* +* 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. +*/ + +#ifndef EDITION_TOOL_CONTROLLER_H +#define EDITION_TOOL_CONTROLLER_H + +#include "SampleManager.h" + +namespace physx +{ + class PxActor; +} + +class EditionToolController : public ISampleController +{ +public: + EditionToolController(); + virtual ~EditionToolController(); + + 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(); + + void fracture(physx::PxActor* actor); + +private: + EditionToolController& operator= (EditionToolController&); + + //////// private methods //////// + + //////// used controllers //////// + + Renderer& getRenderer() const + { + return getManager()->getRenderer(); + } + + PhysXController& getPhysXController() const + { + return getManager()->getPhysXController(); + } + + BlastController& getBlastController() const + { + return getManager()->getBlastController(); + } + + //////// internal data //////// +}; + +#endif // EDITION_TOOL_CONTROLLER_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp new file mode 100644 index 0000000..ff0ffa9 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp @@ -0,0 +1,1210 @@ +/* +* 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. +*/ + +#include "GizmoToolController.h" +#include "RenderUtils.h" +#include "BlastController.h" +#include "SelectionToolController.h" +#include "Renderer.h" +#include "PhysXController.h" +#include "SampleProfiler.h" + +#include <imgui.h> + +#include "NvBlastTkActor.h" +#include "NvBlastExtDamageShaders.h" + +#include "PxRigidDynamic.h" +#include "PxScene.h" +#include <AppMainWindow.h> + + +using namespace Nv::Blast; +using namespace physx; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Setup +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +const DirectX::XMFLOAT4 X_DIRECTION_COLOR_F = DirectX::XMFLOAT4(1, 0, 0, 1); +const DirectX::XMFLOAT4 Y_DIRECTION_COLOR_F = DirectX::XMFLOAT4(0, 1, 0, 1); +const DirectX::XMFLOAT4 Z_DIRECTION_COLOR_F = DirectX::XMFLOAT4(0, 0, 1, 1); +const DirectX::XMFLOAT4 HIGHLIGHT_COLOR_F = DirectX::XMFLOAT4(1, 1, 0, 1); + +const physx::PxU32 X_DIRECTION_COLOR_U = XMFLOAT4ToU32Color(X_DIRECTION_COLOR_F); +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; +const float defaultAxisModifier = -1.0; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +GizmoToolController::GizmoToolController() +{ + m_bGizmoFollowed = false; + + int segment = 36; + double span = PxTwoPi / segment; + PxVec3* vertex = new PxVec3[segment]; + + 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)); + + 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)); + } + m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], Y_DIRECTION_COLOR_U)); + + for (int i = 0; i < segment; i++) + { + vertex[i].x = 10 * PxCos(i * span); + vertex[i].y = 10 * 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; + + resetPos(); +} + +GizmoToolController::~GizmoToolController() +{ +} + +void GizmoToolController::onSampleStart() +{ + m_AxisRenderMaterial = new RenderMaterial("", getRenderer().getResourceManager(), "physx_primitive_transparent"); + + IRenderMesh* coneMesh = getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Cone); + m_AxisConeRenderable[AT_X] = getRenderer().createRenderable(*coneMesh, *m_AxisRenderMaterial); + m_AxisConeRenderable[AT_Y] = getRenderer().createRenderable(*coneMesh, *m_AxisRenderMaterial); + m_AxisConeRenderable[AT_Z] = getRenderer().createRenderable(*coneMesh, *m_AxisRenderMaterial); + m_AxisConeRenderable[AT_X]->setColor(X_DIRECTION_COLOR_F); + m_AxisConeRenderable[AT_Y]->setColor(Y_DIRECTION_COLOR_F); + m_AxisConeRenderable[AT_Z]->setColor(Z_DIRECTION_COLOR_F); + m_AxisConeRenderable[AT_X]->setScale(PxVec3(0.5, 1, 0.5)); + m_AxisConeRenderable[AT_Y]->setScale(PxVec3(0.5, 1, 0.5)); + m_AxisConeRenderable[AT_Z]->setScale(PxVec3(0.5, 1, 0.5)); + m_AxisConeRenderable[AT_X]->setHidden(true); + m_AxisConeRenderable[AT_Y]->setHidden(true); + m_AxisConeRenderable[AT_Z]->setHidden(true); + + IRenderMesh* boxMesh = getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Box); + m_AxisBoxRenderable[AT_X] = getRenderer().createRenderable(*boxMesh, *m_AxisRenderMaterial); + m_AxisBoxRenderable[AT_Y] = getRenderer().createRenderable(*boxMesh, *m_AxisRenderMaterial); + m_AxisBoxRenderable[AT_Z] = getRenderer().createRenderable(*boxMesh, *m_AxisRenderMaterial); + m_AxisBoxRenderable[AT_X]->setColor(X_DIRECTION_COLOR_F); + m_AxisBoxRenderable[AT_Y]->setColor(Y_DIRECTION_COLOR_F); + m_AxisBoxRenderable[AT_Z]->setColor(Z_DIRECTION_COLOR_F); + m_AxisBoxRenderable[AT_X]->setScale(PxVec3(0.5, 0.5, 0.5)); + m_AxisBoxRenderable[AT_Y]->setScale(PxVec3(0.5, 0.5, 0.5)); + m_AxisBoxRenderable[AT_Z]->setScale(PxVec3(0.5, 0.5, 0.5)); + m_AxisBoxRenderable[AT_X]->setHidden(true); + m_AxisBoxRenderable[AT_Y]->setHidden(true); + m_AxisBoxRenderable[AT_Z]->setHidden(true); + + m_Axis[AT_X] = PxVec3(defaultAxisLength, 0.0, 0.0); + m_Axis[AT_Y] = PxVec3(0.0, defaultAxisLength, 0.0); + m_Axis[AT_Z] = PxVec3(0.0, 0.0, defaultAxisLength); +} + +void GizmoToolController::onInitialize() +{ +} + + +void GizmoToolController::onSampleStop() +{ +} + +void GizmoToolController::Animate(double dt) +{ + PROFILER_SCOPED_FUNCTION(); + + if (NULL == m_CurrentActor) + { + m_AxisConeRenderable[AT_X]->setHidden(true); + m_AxisConeRenderable[AT_Y]->setHidden(true); + m_AxisConeRenderable[AT_Z]->setHidden(true); + m_AxisBoxRenderable[AT_X]->setHidden(true); + m_AxisBoxRenderable[AT_Y]->setHidden(true); + m_AxisBoxRenderable[AT_Z]->setHidden(true); + + return; + } + + bool isTranslation = m_GizmoToolMode == GTM_Translate; + bool isScale = m_GizmoToolMode == GTM_Scale; + bool isRotation = m_GizmoToolMode == GTM_Rotation; + bool isLocal = AppMainWindow::Inst().m_bGizmoWithLocal; + + bool showLine = isTranslation || isScale || (isRotation && isLocal); + bool showCone = isTranslation || (isRotation && isLocal); + bool showBox = isScale; + bool showCircle = isRotation; + + m_AxisConeRenderable[AT_X]->setHidden(!isTranslation); + m_AxisConeRenderable[AT_Y]->setHidden(!isTranslation); + m_AxisConeRenderable[AT_Z]->setHidden(!isTranslation); + m_AxisBoxRenderable[AT_X]->setHidden(!isScale); + m_AxisBoxRenderable[AT_Y]->setHidden(!isScale); + m_AxisBoxRenderable[AT_Z]->setHidden(!isScale); + + if (showLine) + { + if (m_bNeedResetPos) + { + m_AxisRenderBuffer.clear(); + m_AxisRenderBuffer.m_lines.push_back(PxDebugLine(m_TargetPos, m_TargetPos + m_Axis[AT_X] * defaultAxisModifier, X_DIRECTION_COLOR_U)); + m_AxisRenderBuffer.m_lines.push_back(PxDebugLine(m_TargetPos, m_TargetPos + m_Axis[AT_Y], Y_DIRECTION_COLOR_U)); + m_AxisRenderBuffer.m_lines.push_back(PxDebugLine(m_TargetPos, m_TargetPos + m_Axis[AT_Z], Z_DIRECTION_COLOR_U)); + } + + if (m_bNeedResetColor) + { + if (m_AxisSelected == AT_X) + { + m_AxisRenderBuffer.m_lines[0].color0 = HIGHLIGHT_COLOR_U; + m_AxisRenderBuffer.m_lines[0].color1 = HIGHLIGHT_COLOR_U; + } + else + { + m_AxisRenderBuffer.m_lines[0].color0 = X_DIRECTION_COLOR_U; + m_AxisRenderBuffer.m_lines[0].color1 = X_DIRECTION_COLOR_U; + } + if (m_AxisSelected == AT_Y) + { + m_AxisRenderBuffer.m_lines[1].color0 = HIGHLIGHT_COLOR_U; + m_AxisRenderBuffer.m_lines[1].color1 = HIGHLIGHT_COLOR_U; + } + else + { + m_AxisRenderBuffer.m_lines[1].color0 = Y_DIRECTION_COLOR_U; + m_AxisRenderBuffer.m_lines[1].color1 = Y_DIRECTION_COLOR_U; + } + if (m_AxisSelected == AT_Z) + { + m_AxisRenderBuffer.m_lines[2].color0 = HIGHLIGHT_COLOR_U; + m_AxisRenderBuffer.m_lines[2].color1 = HIGHLIGHT_COLOR_U; + } + else + { + m_AxisRenderBuffer.m_lines[2].color0 = Z_DIRECTION_COLOR_U; + m_AxisRenderBuffer.m_lines[2].color1 = Z_DIRECTION_COLOR_U; + } + } + + getRenderer().queueRenderBuffer(&m_AxisRenderBuffer); + } + + if (showCone) + { + if (m_bNeedResetPos) + { + PxTransform transform; + + transform.p = m_TargetPos + m_Axis[AT_X] * defaultAxisModifier; + transform.q = CalDirectionQuat(AT_X); + m_AxisConeRenderable[AT_X]->setTransform(transform); + + transform.p = m_TargetPos + m_Axis[AT_Y]; + transform.q = CalDirectionQuat(AT_Y); + m_AxisConeRenderable[AT_Y]->setTransform(transform); + + transform.p = m_TargetPos + m_Axis[AT_Z]; + transform.q = CalDirectionQuat(AT_Z); + m_AxisConeRenderable[AT_Z]->setTransform(transform); + } + + if (m_bNeedResetColor) + { + if (m_AxisSelected == AT_X) + { + m_AxisConeRenderable[AT_X]->setColor(HIGHLIGHT_COLOR_F); + } + else + { + m_AxisConeRenderable[AT_X]->setColor(X_DIRECTION_COLOR_F); + } + if (m_AxisSelected == AT_Y) + { + m_AxisConeRenderable[AT_Y]->setColor(HIGHLIGHT_COLOR_F); + } + else + { + m_AxisConeRenderable[AT_Y]->setColor(Y_DIRECTION_COLOR_F); + } + if (m_AxisSelected == AT_Z) + { + m_AxisConeRenderable[AT_Z]->setColor(HIGHLIGHT_COLOR_F); + } + else + { + m_AxisConeRenderable[AT_Z]->setColor(Z_DIRECTION_COLOR_F); + } + } + } + + if (showBox) + { + if (m_bNeedResetPos) + { + PxTransform transform; + + transform.p = m_TargetPos + m_Axis[AT_X] * defaultAxisModifier; + transform.q = CalDirectionQuat(AT_X); + m_AxisBoxRenderable[AT_X]->setTransform(transform); + + transform.p = m_TargetPos + m_Axis[AT_Y]; + transform.q = CalDirectionQuat(AT_Y); + m_AxisBoxRenderable[AT_Y]->setTransform(transform); + + transform.p = m_TargetPos + m_Axis[AT_Z]; + transform.q = CalDirectionQuat(AT_Z); + m_AxisBoxRenderable[AT_Z]->setTransform(transform); + } + + if (m_bNeedResetColor) + { + if (m_AxisSelected == AT_X) + { + m_AxisBoxRenderable[AT_X]->setColor(HIGHLIGHT_COLOR_F); + } + else + { + m_AxisBoxRenderable[AT_X]->setColor(X_DIRECTION_COLOR_F); + } + if (m_AxisSelected == AT_Y) + { + m_AxisBoxRenderable[AT_Y]->setColor(HIGHLIGHT_COLOR_F); + } + else + { + m_AxisBoxRenderable[AT_Y]->setColor(Y_DIRECTION_COLOR_F); + } + if (m_AxisSelected == AT_Z) + { + m_AxisBoxRenderable[AT_Z]->setColor(HIGHLIGHT_COLOR_F); + } + else + { + m_AxisBoxRenderable[AT_Z]->setColor(Z_DIRECTION_COLOR_F); + } + } + } + + if (showCircle) + { + if (m_bNeedResetPos) + { + PxQuat q = CalConvertQuat(); + + m_CircleRenderBuffer.clear(); + std::vector<PxDebugLine>::iterator it; + for (it = m_CircleRenderData.begin(); it != m_CircleRenderData.end(); it++) + { + PxDebugLine line = (*it); + + line.pos0 = q.rotate(line.pos0); + line.pos1 = q.rotate(line.pos1); + + line.pos0 += m_TargetPos; + line.pos1 += m_TargetPos; + + m_CircleRenderBuffer.m_lines.push_back(line); + } + } + + if (m_bNeedResetColor) + { + std::vector<PxDebugLine>& datas = m_CircleRenderData; + std::vector<PxDebugLine>& lines = m_CircleRenderBuffer.m_lines; + int linesize = lines.size(); + int linesize_per_axis = linesize / 3; + float multiply; + physx::PxU32 color; + + if (m_AxisSelected == AT_X) + { + for (int l = 0; l < linesize_per_axis; l++) + { + multiply = 1.0 * (l + 1) / linesize_per_axis; + color = XMFLOAT4ToU32Color(DirectX::XMFLOAT4(multiply, multiply, 0, 1)); + lines[l].color0 = color; + lines[l].color1 = color; + } + } + else + { + for (int l = 0; l < linesize_per_axis; l++) + { + multiply = 1.0 * (l + 1) / linesize_per_axis; + color = XMFLOAT4ToU32Color(DirectX::XMFLOAT4(multiply, 0, 0, 1)); + lines[l].color0 = color; + lines[l].color1 = color; + } + } + if (m_AxisSelected == AT_Y) + { + for (int l = linesize_per_axis; l < linesize_per_axis * 2; l++) + { + multiply = 1.0 * (l + 1 - linesize_per_axis) / linesize_per_axis; + color = XMFLOAT4ToU32Color(DirectX::XMFLOAT4(multiply, multiply, 0, 1)); + lines[l].color0 = color; + lines[l].color1 = color; + } + } + else + { + for (int l = linesize_per_axis; l < linesize_per_axis * 2; l++) + { + multiply = 1.0 * (l + 1 - linesize_per_axis) / linesize_per_axis; + color = XMFLOAT4ToU32Color(DirectX::XMFLOAT4(0, multiply, 0, 1)); + lines[l].color0 = color; + lines[l].color1 = color; + } + } + if (m_AxisSelected == AT_Z) + { + for (int l = linesize_per_axis * 2; l < linesize; l++) + { + multiply = 1.0 * (l + 1 - linesize_per_axis * 2) / linesize_per_axis; + color = XMFLOAT4ToU32Color(DirectX::XMFLOAT4(multiply, multiply, 0, 1)); + lines[l].color0 = color; + lines[l].color1 = color; + } + } + else + { + for (int l = linesize_per_axis * 2; l < linesize; l++) + { + multiply = 1.0 * (l + 1 - linesize_per_axis * 2) / linesize_per_axis; + color = XMFLOAT4ToU32Color(DirectX::XMFLOAT4(0, 0, multiply, 1)); + lines[l].color0 = color; + lines[l].color1 = color; + } + } + } + + getRenderer().queueRenderBuffer(&m_CircleRenderBuffer); + } + + m_bNeedResetPos = false; + m_bNeedResetColor = false; +} + +#include "PxPhysics.h" +#include "cooking/PxCooking.h" +LRESULT GizmoToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PROFILER_SCOPED_FUNCTION(); + + if (uMsg == WM_LBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP) + { + float mouseX = (short)LOWORD(lParam) / getRenderer().getScreenWidth(); + float mouseY = (short)HIWORD(lParam) / getRenderer().getScreenHeight(); + bool press = uMsg == WM_LBUTTONDOWN; + + if (m_GizmoToolMode == GTM_Translate) + { + 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_bGizmoFollowed) + { + 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) + { + 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; + PxVec3 foot; + 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; + 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); + + 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; + } + } + 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; + + 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); + 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) + { + if (m_bGizmoFollowed) + { + 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(); + 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) + { + 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; + + // 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++) + { + PxVec3 vertex = lines[l].pos1; + double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot); + + if (distance < distanceMin) + { + distanceMin = distance; + line_index = l; + m_LastFoot = foot; + } + } + if (distanceMin < tolerance) + { + as = (AxisType)line_index; + } + } + setAxisSelected(as); + } + } + else if (uMsg == WM_LBUTTONUP) + { + if (m_AxisSelected != AT_Num) + { + if (NULL != m_CurrentActor) + { + ScaleActor(true); + } + + m_Axis[AT_X] = m_LastAxis[AT_X] * defaultAxisLength; + 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_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; + } + } + } + + return 1; +} + +void GizmoToolController::drawUI() +{ +} + +void GizmoToolController::setGizmoToolMode(GizmoToolMode mode) +{ + if (mode == m_GizmoToolMode) + { + return; + } + + m_GizmoToolMode = mode; + + m_bNeedResetPos = true; + m_bNeedResetColor = true; +} + +void GizmoToolController::setAxisSelected(AxisType type) +{ + if (type == m_AxisSelected) + { + return; + } + + m_AxisSelected = type; + m_bNeedResetColor = true; +} + +void GizmoToolController::showAxisRenderables(bool show) +{ + bool isTranslate = m_GizmoToolMode == GTM_Translate; + bool isScale = m_GizmoToolMode == GTM_Scale; + + m_AxisConeRenderable[AT_X]->setHidden(!show || !isTranslate); + m_AxisConeRenderable[AT_Y]->setHidden(!show || !isTranslate); + m_AxisConeRenderable[AT_Z]->setHidden(!show || !isTranslate); + m_AxisBoxRenderable[AT_X]->setHidden(!show || !isScale); + m_AxisBoxRenderable[AT_Y]->setHidden(!show || !isScale); + m_AxisBoxRenderable[AT_Z]->setHidden(!show || !isScale); +} + +void GizmoToolController::resetPos() +{ + m_TargetPos = PxVec3(-100, -100, -100); + m_bNeedResetPos = true; + + m_AxisSelected = AT_Num; + m_bNeedResetColor = true; + + m_CurrentActor = NULL; +} + +bool GizmoToolController::CalPlaneLineIntersectPoint(PxVec3& result, PxVec3 planeNormal, PxVec3 planePoint, PxVec3 linedirection, PxVec3 linePoint) +{ + float dot = planeNormal.dot(linedirection); + if (dot == 0) + { + return false; + } + else + { + float t = ((planePoint[0] - linePoint[0]) * planeNormal[0] + + (planePoint[1] - linePoint[1]) * planeNormal[1] + + (planePoint[2] - linePoint[2]) * planeNormal[2]) / dot; + result = linePoint + linedirection * t; + } + return true; +} + +float GizmoToolController::DistanceFromPointToLine(PxVec3& point, PxVec3& origin, PxVec3& direction, PxVec3& foot) +{ + direction = direction.getNormalized(); + PxVec3 sub = point - origin; + float t = direction.dot(sub); + foot = origin + direction * t; + PxVec3 dis = point - foot; + return dis.magnitude(); +} + +bool GizmoToolController::GetFootFromPointToPlane(PxVec3& point, PxVec3& origin, PxVec3& normal, PxVec3& foot) +{ + return CalPlaneLineIntersectPoint(foot, normal, origin, normal, point); +} + +bool GizmoToolController::GetIntersectBetweenLines(PxVec3& origin1, PxVec3& direction1, PxVec3& origin2, PxVec3& direction2, PxVec3& intersect) +{ + PxVec3 normal1 = direction1.cross(direction2); + PxVec3 normal2 = normal1.cross(direction1); + normal2 = normal2.getNormalized(); + return CalPlaneLineIntersectPoint(intersect, normal2, origin1, direction2, origin2); +} + +PxQuat GizmoToolController::CalDirectionQuat(AxisType type) +{ + PxVec3 origin(0, 1, 0); + PxVec3 target = m_Axis[type]; + if (type == AT_X) + { + target *= defaultAxisModifier; + } + target = target.getNormalized(); + PxVec3 cross = origin.cross(target); + cross = cross.getNormalized(); + float cos = origin.dot(target); + float angle = PxAcos(cos); + PxQuat q(angle, cross); + return q; +} + +PxQuat GizmoToolController::CalConvertQuat() +{ + PxVec3 x_origin(1, 0, 0); + PxVec3 y_origin(0, 1, 0); + PxVec3 z_origin(0, 0, 1); + + PxVec3 x_target = m_Axis[AT_X]; + PxVec3 y_target = m_Axis[AT_Y]; + x_target = x_target.getNormalized(); + y_target = y_target.getNormalized(); + + PxVec3 x_cross = x_origin.cross(x_target); + x_cross = x_cross.getNormalized(); + float x_cos = x_origin.dot(x_target); + float x_angle = PxAcos(x_cos); + PxQuat x_quat(x_angle, x_cross); + + PxVec3 y_interval = x_quat.rotate(y_origin); + + PxVec3 y_cross = y_interval.cross(y_target); + y_cross = y_cross.getNormalized(); + float y_cos = y_interval.dot(y_target); + float y_angle = PxAcos(y_cos); + PxQuat y_quat(y_angle, y_cross); + + PxQuat q = y_quat * x_quat; + return q; +} + +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) + { + return; + } + + std::vector<BlastFamilyPtr>& families = getBlastController().getFamilies(); + if (families.size() == 0) + { + 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; + } + } + if (NULL == pBlastFamily) + { + return; + } + + float multiply = m_Axis[m_AxisSelected].magnitude() / defaultAxisLength; + if (m_Axis[m_AxisSelected].dot(m_LastAxis[m_AxisSelected]) < 0) + { + multiply = -multiply; + } + PxVec3 delta(1, 1, 1); + bool isShift = (GetAsyncKeyState(VK_SHIFT) && 0x8000); + if (isShift) + { + delta *= multiply; + } + else + { + delta[m_AxisSelected] = multiply; + } + PxMat44 scale = PxMat44(PxVec4(delta, 1)); + + bool isLocal = AppMainWindow::Inst().m_bGizmoWithLocal; + if (!isLocal) + { + PxTransform gp = m_CurrentActor->getGlobalPose(); + uint32_t shapesCount = m_CurrentActor->getNbShapes(); + if (shapesCount > 0) + { + std::vector<PxShape*> shapes(shapesCount); + m_CurrentActor->getShapes(&shapes[0], shapesCount); + PxShape* shape = shapes[0]; + PxTransform lp = shape->getLocalPose(); + gp = gp * lp; + } + PxMat44 world = PxMat44(gp); + PxMat44 worldInv = world.inverseRT(); + scale = world * scale * worldInv; + } + + pBlastFamily->setActorScale(*extActor, scale, replace); + + if (!replace) + { + return; + } + + uint32_t shapesCount = m_CurrentActor->getNbShapes(); + if (shapesCount == 0) + { + return; + } + + 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]; + + 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; + PxPhysics& physics = getManager()->getPhysXController().getPhysics(); + PxCooking& cooking = getManager()->getPhysXController().getCooking(); + PxConvexMesh* convexMesh = cooking.createConvexMesh(convexMeshDesc, physics.getPhysicsInsertionCallback()); + if (NULL == convexMesh) + { + delete[] pVertexNew; + continue; + } + + mesh.convexMesh = convexMesh; + + m_CurrentActor->detachShape(*shape); + shape->setGeometry(mesh); + m_CurrentActor->attachShape(*shape); + + pMesh->release(); + delete[] pVertexNew; + } + + getPhysXController().getPhysXScene().addActor(*m_CurrentActor); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h new file mode 100644 index 0000000..215cde5 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h @@ -0,0 +1,124 @@ +/* +* 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. +*/ + +#ifndef GIZMO_TOOL_CONTROLLER_H +#define GIZMO_TOOL_CONTROLLER_H + +#include "SampleManager.h" +#include "DebugRenderBuffer.h" +#include "NvBlastExtPxManager.h" + +class Renderable; +class RenderMaterial; + +namespace Nv +{ +namespace Blast +{ +class ExtPhysicsActor; +} +} + +enum AxisType +{ + AT_X = 0, + AT_Y = 1, + AT_Z = 2, + AT_Num +}; + +enum GizmoToolMode +{ + GTM_Translate = 0, + GTM_Scale, + GTM_Rotation +}; + +class GizmoToolController : public ISampleController +{ +public: + GizmoToolController(); + virtual ~GizmoToolController(); + + 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(); + + void setGizmoToolMode(GizmoToolMode mode); + void setAxisSelected(AxisType type); + void showAxisRenderables(bool show); + void resetPos(); + +private: + GizmoToolController& operator= (GizmoToolController&); + + //////// private methods //////// + + 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); + bool GetIntersectBetweenLines(PxVec3& origin1, PxVec3& direction1, PxVec3& origin2, PxVec3& direction2, PxVec3& intersect); + PxQuat CalDirectionQuat(AxisType type); + PxQuat CalConvertQuat(); + void ScaleActor(bool replace); + //////// used controllers //////// + + Renderer& getRenderer() const + { + return getManager()->getRenderer(); + } + + PhysXController& getPhysXController() const + { + return getManager()->getPhysXController(); + } + + BlastController& getBlastController() const + { + return getManager()->getBlastController(); + } + + SelectionToolController& getSelectionToolController() const + { + return getManager()->getSelectionToolController(); + } + + //////// internal data //////// + + GizmoToolMode m_GizmoToolMode; + + bool m_bGizmoFollowed; + PxVec3 m_LastEyeRay; + PxVec3 m_LastFoot; + PxVec3 m_LastAxis[AT_Num]; + + PxRigidActor* m_CurrentActor; + + bool m_bNeedResetPos; + bool m_bNeedResetColor; + + PxVec3 m_TargetPos; + PxVec3 m_Axis[AT_Num]; + AxisType m_AxisSelected; + Renderable* m_AxisConeRenderable[AT_Num]; + Renderable* m_AxisBoxRenderable[AT_Num]; + + RenderMaterial* m_AxisRenderMaterial; + DebugRenderBuffer m_AxisRenderBuffer; + + std::vector<PxDebugLine> m_CircleRenderData; + DebugRenderBuffer m_CircleRenderBuffer; +}; + +#endif // GIZMO_TOOL_CONTROLLER_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp new file mode 100644 index 0000000..02a511f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp @@ -0,0 +1,445 @@ +/* +* 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. +*/ + +#include "SelectionToolController.h" +#include "RenderUtils.h" +#include "BlastController.h" +#include "Renderer.h" +#include "PhysXController.h" +#include "SampleProfiler.h" + +#include <imgui.h> + +#include "NvBlastTkActor.h" +#include "NvBlastExtDamageShaders.h" + +#include "PxRigidDynamic.h" +#include "PxScene.h" +#include "BlastSceneTree.h" + +using namespace Nv::Blast; +using namespace physx; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Setup +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +SelectionToolController::SelectionToolController() +{ + m_bRectSelecting = false; +} + +SelectionToolController::~SelectionToolController() +{ +} + +void SelectionToolController::onSampleStart() +{ +} + +void SelectionToolController::onInitialize() +{ +} + + +void SelectionToolController::onSampleStop() +{ +} + +void SelectionToolController::Animate(double dt) +{ + PROFILER_SCOPED_FUNCTION(); + + if (m_bRectSelecting) + { + getRenderer().queueRenderBuffer(&m_RectRenderBuffer); + } +} + + +LRESULT SelectionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PROFILER_SCOPED_FUNCTION(); + + if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP) + { + float mouseX = (short)LOWORD(lParam) / getRenderer().getScreenWidth(); + float mouseY = (short)HIWORD(lParam) / getRenderer().getScreenHeight(); + bool press = uMsg == WM_LBUTTONDOWN; + + if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN) + { + PxVec3 eyePos, pickDir; + getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); + + m_RectSelectScreenPos.x = mouseX; + m_RectSelectScreenPos.y = mouseY; + m_RectSelectSpaceDir = pickDir.getNormalized(); + + m_RectRenderBuffer.clear(); + m_bRectSelecting = true; + } + else if (uMsg == WM_MOUSEMOVE) + { + if (m_bRectSelecting) + { + PxVec3 eyePos, pickDir[3]; + getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir[0]); + getPhysXController().getEyePoseAndPickDir(m_RectSelectScreenPos.x, mouseY, eyePos, pickDir[1]); + getPhysXController().getEyePoseAndPickDir(mouseX, m_RectSelectScreenPos.y, eyePos, pickDir[2]); + pickDir[0] = pickDir[0].getNormalized(); + pickDir[1] = pickDir[1].getNormalized(); + pickDir[2] = pickDir[2].getNormalized(); + + PxVec3 lefttop, leftbottom, righttop, rightbottom; + + if (mouseX > m_RectSelectScreenPos.x) // right + { + if (mouseY > m_RectSelectScreenPos.y) // top + { + leftbottom = m_RectSelectSpaceDir; + righttop = pickDir[0]; + lefttop = pickDir[2]; + rightbottom = pickDir[1]; + } + else // bottom + { + leftbottom = pickDir[1]; + righttop = pickDir[2]; + lefttop = m_RectSelectSpaceDir; + rightbottom = pickDir[0]; + } + } + else // left + { + if (mouseY > m_RectSelectScreenPos.y) // top + { + leftbottom = pickDir[2]; + righttop = pickDir[1]; + lefttop = pickDir[0]; + rightbottom = m_RectSelectSpaceDir; + } + else // bottom + { + leftbottom = pickDir[0]; + righttop = m_RectSelectSpaceDir; + lefttop = pickDir[2]; + rightbottom = pickDir[1]; + } + } + + float multiply = 10; // in order to draw line + lefttop = eyePos + lefttop * multiply; + righttop = eyePos + righttop * multiply; + leftbottom = eyePos + leftbottom * multiply; + rightbottom = eyePos + rightbottom * multiply; + + m_RectRenderBuffer.clear(); + + DirectX::XMFLOAT4 LINE_COLOR(1.0f, 0.0f, 0.0f, 1.0f); + m_RectRenderBuffer.m_lines.push_back(PxDebugLine(lefttop, leftbottom, XMFLOAT4ToU32Color(LINE_COLOR))); + m_RectRenderBuffer.m_lines.push_back(PxDebugLine(lefttop, righttop, XMFLOAT4ToU32Color(LINE_COLOR))); + m_RectRenderBuffer.m_lines.push_back(PxDebugLine(righttop, rightbottom, XMFLOAT4ToU32Color(LINE_COLOR))); + m_RectRenderBuffer.m_lines.push_back(PxDebugLine(leftbottom, rightbottom, XMFLOAT4ToU32Color(LINE_COLOR))); + } + } + else if (uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP) + { + if (uMsg == WM_RBUTTONUP && m_actorsSelected.size() > 1) + { + return 1; + } + + if (m_bRectSelecting) + { + bool isShift = (GetAsyncKeyState(VK_SHIFT) && 0x8000); + bool isCtrl = (GetAsyncKeyState(VK_CONTROL) && 0x8000); + + SelectMode selectMode = SM_RESET; + if (isShift && isCtrl) + { + selectMode = SM_REMAIN; + } + else if (isShift) + { + selectMode = SM_ADD; + } + else if (isCtrl) + { + 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) + { + PxVec3 eyePos, pickDir[3]; + getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir[0]); + getPhysXController().getEyePoseAndPickDir(m_RectSelectScreenPos.x, mouseY, eyePos, pickDir[1]); + getPhysXController().getEyePoseAndPickDir(mouseX, m_RectSelectScreenPos.y, eyePos, pickDir[2]); + pickDir[0] = pickDir[0].getNormalized(); + pickDir[1] = pickDir[1].getNormalized(); + pickDir[2] = pickDir[2].getNormalized(); + + PxVec3 lefttop, leftbottom, righttop, rightbottom; + + if (mouseX > m_RectSelectScreenPos.x) // right + { + if (mouseY > m_RectSelectScreenPos.y) // top + { + leftbottom = m_RectSelectSpaceDir; + righttop = pickDir[0]; + lefttop = pickDir[2]; + rightbottom = pickDir[1]; + } + else // bottom + { + leftbottom = pickDir[1]; + righttop = pickDir[2]; + lefttop = m_RectSelectSpaceDir; + rightbottom = pickDir[0]; + } + } + else // left + { + if (mouseY > m_RectSelectScreenPos.y) // top + { + leftbottom = pickDir[2]; + righttop = pickDir[1]; + lefttop = pickDir[0]; + rightbottom = m_RectSelectSpaceDir; + } + else // bottom + { + leftbottom = pickDir[0]; + righttop = m_RectSelectSpaceDir; + lefttop = pickDir[2]; + rightbottom = pickDir[1]; + } + } + + rectSelect(eyePos, lefttop, leftbottom, righttop, rightbottom, selectMode); + } + // point select mode + else + { + 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; + + PxRigidActor* actor = NULL; + if (hit.shape) + { + actor = hit.actor; + } + pointSelect(actor, selectMode); + } + } + + BlastSceneTree::ins()->updateChunkItemSelection(); + m_RectRenderBuffer.clear(); + m_bRectSelecting = false; + } + } + + return 1; +} + +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) + { + setActorSelected(*extActor, true); + m_actorsSelected.emplace(extActor); + } + } + else if (selectMode == SM_ADD) + { + if (NULL != extActor) + { + setActorSelected(*extActor, true); + m_actorsSelected.emplace(extActor); + } + } + else if (selectMode == SM_SUB) + { + if (NULL != extActor) + { + setActorSelected(*extActor, false); + m_actorsSelected.erase(extActor); + } + } +} + +#include "PxPhysics.h" +#include "cooking/PxCooking.h" + +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])) {} + + PxAgain processTouches(const PxOverlapHit* buffer, PxU32 nbHits) + { + for (PxU32 i = 0; i < nbHits; ++i) + { + PxRigidDynamic* rigidDynamic = buffer[i].actor->is<PxRigidDynamic>(); + if (rigidDynamic) + { + ExtPxActor* actor = m_physicsManager.getActorFromPhysXActor(*rigidDynamic); + if (actor != nullptr) + { + m_actorBuffer.insert(actor); + } + } + } + return true; + } + +private: + ExtPxManager& m_physicsManager; + std::set<ExtPxActor*>& 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; + + float nearClip = 1; + PxVec3 nearlefttop = lefttop * nearClip; + PxVec3 nearrighttop = righttop * nearClip; + PxVec3 nearleftbottom = leftbottom * nearClip; + PxVec3 nearrightbottom = rightbottom * nearClip; + + float farClip = 1000; + PxVec3 farlefttop = lefttop * farClip; + PxVec3 farrighttop = righttop * farClip; + PxVec3 farleftbottom = leftbottom * farClip; + PxVec3 farrightbottom = rightbottom * farClip; + + PxVec3 vertices[8] = + { + nearlefttop, nearrighttop, nearleftbottom, nearrightbottom, + farlefttop, farrighttop, farleftbottom, farrightbottom + }; + PxConvexMeshDesc convexMeshDesc; + convexMeshDesc.points.count = 8; + convexMeshDesc.points.data = vertices; + 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) + { + RectSelectionCallback overlapCallback(getBlastController().getExtPxManager(), actorsToSelect); + getManager()->getPhysXController().getPhysXScene().overlap(PxConvexMeshGeometry(convexMesh), PxTransform(eyePos), overlapCallback); + convexMesh->release(); + } + + if (selectMode == SM_RESET) + { + clearSelect(); + + for (ExtPxActor* actor : actorsToSelect) + { + setActorSelected(*actor, true); + m_actorsSelected.emplace(actor); + } + } + else if (selectMode == SM_ADD) + { + for (ExtPxActor* actor : actorsToSelect) + { + setActorSelected(*actor, true); + m_actorsSelected.emplace(actor); + } + } + else if (selectMode == SM_SUB) + { + for (ExtPxActor* actor : actorsToSelect) + { + setActorSelected(*actor, false); + m_actorsSelected.erase(actor); + } + } +} + +void SelectionToolController::clearSelect() +{ + for (ExtPxActor* actor : m_actorsSelected) + { + setActorSelected(*actor, false); + } + + m_actorsSelected.clear(); + SampleManager::ins()->clearChunksSelected(); +} + +void SelectionToolController::setActorSelected(const ExtPxActor& actor, bool selected) +{ + std::vector<BlastFamilyPtr>& families = getBlastController().getFamilies(); + if (families.size() == 0) + { + return; + } + + BlastFamilyPtr pBlastFamily = NULL; + std::vector<BlastFamilyPtr>::iterator it = families.begin(); + for (; it != families.end(); it++) + { + BlastFamilyPtr f = *it; + if (f->find((ExtPxActor*)&actor)) + { + pBlastFamily = f; + break; + } + } + if (NULL == pBlastFamily) + { + return; + } + + pBlastFamily->setActorSelected(actor, selected); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h new file mode 100644 index 0000000..5261b90 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h @@ -0,0 +1,82 @@ +/* +* 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. +*/ + +#ifndef SELECTION_TOOL_CONTROLLER_H +#define SELECTION_TOOL_CONTROLLER_H + +#include "SampleManager.h" +#include "PxVec2.h" +#include "PxVec3.h" +#include "DebugRenderBuffer.h" +#include "BlastFamily.h" +#include "NvBlastExtPxManager.h" +class Renderable; +class RenderMaterial; + +namespace Nv +{ +namespace Blast +{ +class ExtPxActor; +} +} + +class SelectionToolController : public ISampleController +{ +public: + SelectionToolController(); + virtual ~SelectionToolController(); + + 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(); + + 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(); + +private: + SelectionToolController& operator= (SelectionToolController&); + + //////// private methods //////// + + //////// used controllers //////// + + Renderer& getRenderer() const + { + return getManager()->getRenderer(); + } + + PhysXController& getPhysXController() const + { + return getManager()->getPhysXController(); + } + + BlastController& getBlastController() const + { + return getManager()->getBlastController(); + } + + //////// internal data //////// + + PxVec2 m_RectSelectScreenPos; + PxVec3 m_RectSelectSpaceDir; + bool m_bRectSelecting; + DebugRenderBuffer m_RectRenderBuffer; + + void setActorSelected(const ExtPxActor& actor, bool selected); + std::set<ExtPxActor*> m_actorsSelected; +}; + +#endif // SELECTION_TOOL_CONTROLLER_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/imgui_impl_dx11.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/imgui_impl_dx11.cpp new file mode 100644 index 0000000..11f66f0 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/imgui_impl_dx11.cpp @@ -0,0 +1,583 @@ +// ImGui Win32 + DirectX11 binding +// In this binding, ImTextureID is used to store a 'ID3D11ShaderResourceView*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include <imgui.h> +#include "imgui_impl_dx11.h" + +// DirectX +#include <d3d11.h> +#include <d3dcompiler.h> +#define DIRECTINPUT_VERSION 0x0800 +#include <dinput.h> + +// Data +static INT64 g_Time = 0; +static INT64 g_TicksPerSecond = 0; + +static HWND g_hWnd = 0; +static ID3D11Device* g_pd3dDevice = NULL; +static ID3D11DeviceContext* g_pd3dDeviceContext = NULL; +static ID3D11Buffer* g_pVB = NULL; +static ID3D11Buffer* g_pIB = NULL; +static ID3D10Blob * g_pVertexShaderBlob = NULL; +static ID3D11VertexShader* g_pVertexShader = NULL; +static ID3D11InputLayout* g_pInputLayout = NULL; +static ID3D11Buffer* g_pVertexConstantBuffer = NULL; +static ID3D10Blob * g_pPixelShaderBlob = NULL; +static ID3D11PixelShader* g_pPixelShader = NULL; +static ID3D11SamplerState* g_pFontSampler = NULL; +static ID3D11ShaderResourceView*g_pFontTextureView = NULL; +static ID3D11RasterizerState* g_pRasterizerState = NULL; +static ID3D11BlendState* g_pBlendState = NULL; +static ID3D11DepthStencilState* g_pDepthStencilState = NULL; +static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000; + +struct VERTEX_CONSTANT_BUFFER +{ + float mvp[4][4]; +}; + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data) +{ + ID3D11DeviceContext* ctx = g_pd3dDeviceContext; + + // Create and grow vertex/index buffers if needed + if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) + { + if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } + g_VertexBufferSize = draw_data->TotalVtxCount + 5000; + D3D11_BUFFER_DESC desc; + memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.ByteWidth = g_VertexBufferSize * sizeof(ImDrawVert); + desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVB) < 0) + return; + } + if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount) + { + if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } + g_IndexBufferSize = draw_data->TotalIdxCount + 10000; + D3D11_BUFFER_DESC desc; + memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx); + desc.BindFlags = D3D11_BIND_INDEX_BUFFER; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pIB) < 0) + return; + } + + // Copy and convert all vertices into a single contiguous buffer + D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; + if (ctx->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK) + return; + if (ctx->Map(g_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK) + return; + ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData; + ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + memcpy(vtx_dst, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + memcpy(idx_dst, &cmd_list->IdxBuffer[0], cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx)); + vtx_dst += cmd_list->VtxBuffer.size(); + idx_dst += cmd_list->IdxBuffer.size(); + } + ctx->Unmap(g_pVB, 0); + ctx->Unmap(g_pIB, 0); + + // Setup orthographic projection matrix into our constant buffer + { + D3D11_MAPPED_SUBRESOURCE mapped_resource; + if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) + return; + VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData; + float L = 0.0f; + float R = ImGui::GetIO().DisplaySize.x; + float B = ImGui::GetIO().DisplaySize.y; + float T = 0.0f; + float mvp[4][4] = + { + { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.5f, 0.0f }, + { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, + }; + memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); + ctx->Unmap(g_pVertexConstantBuffer, 0); + } + + // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!) + struct BACKUP_DX11_STATE + { + UINT ScissorRectsCount, ViewportsCount; + D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + ID3D11RasterizerState* RS; + ID3D11BlendState* BlendState; + FLOAT BlendFactor[4]; + UINT SampleMask; + UINT StencilRef; + ID3D11DepthStencilState* DepthStencilState; + ID3D11ShaderResourceView* PSShaderResource; + ID3D11SamplerState* PSSampler; + ID3D11PixelShader* PS; + ID3D11VertexShader* VS; + UINT PSInstancesCount, VSInstancesCount; + ID3D11ClassInstance* PSInstances[256], *VSInstances[256]; // 256 is max according to PSSetShader documentation + D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology; + ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer; + UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset; + DXGI_FORMAT IndexBufferFormat; + ID3D11InputLayout* InputLayout; + }; + BACKUP_DX11_STATE old; + old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); + ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); + ctx->RSGetState(&old.RS); + ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask); + ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef); + ctx->PSGetShaderResources(0, 1, &old.PSShaderResource); + ctx->PSGetSamplers(0, 1, &old.PSSampler); + old.PSInstancesCount = old.VSInstancesCount = 256; + ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount); + ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount); + ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer); + ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology); + ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset); + ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); + ctx->IAGetInputLayout(&old.InputLayout); + + // Setup viewport + D3D11_VIEWPORT vp; + memset(&vp, 0, sizeof(D3D11_VIEWPORT)); + vp.Width = ImGui::GetIO().DisplaySize.x; + vp.Height = ImGui::GetIO().DisplaySize.y; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + vp.TopLeftX = vp.TopLeftY = 0.0f; + ctx->RSSetViewports(1, &vp); + + // Bind shader and vertex buffers + unsigned int stride = sizeof(ImDrawVert); + unsigned int offset = 0; + ctx->IASetInputLayout(g_pInputLayout); + ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); + ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); + ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ctx->VSSetShader(g_pVertexShader, NULL, 0); + ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); + ctx->PSSetShader(g_pPixelShader, NULL, 0); + ctx->PSSetSamplers(0, 1, &g_pFontSampler); + + // Setup render state + const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; + ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff); + ctx->OMSetDepthStencilState(g_pDepthStencilState, 0); + ctx->RSSetState(g_pRasterizerState); + + // Render command lists + int vtx_offset = 0; + int idx_offset = 0; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + const D3D11_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; + ctx->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->TextureId); + ctx->RSSetScissorRects(1, &r); + ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); + } + idx_offset += pcmd->ElemCount; + } + vtx_offset += cmd_list->VtxBuffer.size(); + } + + // Restore modified DX state + ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); + ctx->RSSetViewports(old.ViewportsCount, old.Viewports); + ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); + ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); + ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); + ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); + ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); + ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release(); + for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release(); + ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release(); + ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); + for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release(); + ctx->IASetPrimitiveTopology(old.PrimitiveTopology); + ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); + ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); + ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); +} + +IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +{ + ImGuiIO& io = ImGui::GetIO(); + switch (msg) + { + case WM_LBUTTONDOWN: + io.MouseDown[0] = true; + return true; + case WM_LBUTTONUP: + io.MouseDown[0] = false; + return true; + case WM_RBUTTONDOWN: + io.MouseDown[1] = true; + return true; + case WM_RBUTTONUP: + io.MouseDown[1] = false; + return true; + case WM_MBUTTONDOWN: + io.MouseDown[2] = true; + return true; + case WM_MBUTTONUP: + io.MouseDown[2] = false; + return true; + case WM_MOUSEWHEEL: + io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; + return true; + case WM_MOUSEMOVE: + io.MousePos.x = (signed short)(lParam); + io.MousePos.y = (signed short)(lParam >> 16); + return true; + case WM_KEYDOWN: + if (wParam < 256) + io.KeysDown[wParam] = 1; + return true; + case WM_KEYUP: + if (wParam < 256) + io.KeysDown[wParam] = 0; + return true; + case WM_CHAR: + // You can also use ToAscii()+GetKeyboardState() to retrieve characters. + if (wParam > 0 && wParam < 0x10000) + io.AddInputCharacter((unsigned short)wParam); + return true; + } + return 0; +} + +static void ImGui_ImplDX11_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + // Upload texture to graphics system + { + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + + ID3D11Texture2D *pTexture = NULL; + D3D11_SUBRESOURCE_DATA subResource; + subResource.pSysMem = pixels; + subResource.SysMemPitch = desc.Width * 4; + subResource.SysMemSlicePitch = 0; + g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); + + // Create texture view + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + ZeroMemory(&srvDesc, sizeof(srvDesc)); + srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = desc.MipLevels; + srvDesc.Texture2D.MostDetailedMip = 0; + g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView); + pTexture->Release(); + } + + // Store our identifier + io.Fonts->TexID = (void *)g_pFontTextureView; + + // Create texture sampler + { + D3D11_SAMPLER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + desc.MipLODBias = 0.f; + desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + desc.MinLOD = 0.f; + desc.MaxLOD = 0.f; + g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler); + } +} + +bool ImGui_ImplDX11_CreateDeviceObjects() +{ + if (!g_pd3dDevice) + return false; + if (g_pFontSampler) + ImGui_ImplDX11_InvalidateDeviceObjects(); + + // By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) + // If you would like to use this DX11 sample code but remove this dependency you can: + // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [prefered solution] + // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL. + // See https://github.com/ocornut/imgui/pull/638 for sources and details. + + // Create the vertex shader + { + static const char* vertexShader = + "cbuffer vertexBuffer : register(b0) \ + {\ + float4x4 ProjectionMatrix; \ + };\ + struct VS_INPUT\ + {\ + float2 pos : POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + PS_INPUT main(VS_INPUT input)\ + {\ + PS_INPUT output;\ + output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ + output.col = input.col;\ + output.uv = input.uv;\ + return output;\ + }"; + + D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob, NULL); + if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + return false; + if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK) + return false; + + // Create the input layout + D3D11_INPUT_ELEMENT_DESC local_layout[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) + return false; + + // Create the constant buffer + { + D3D11_BUFFER_DESC desc; + desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer); + } + } + + // Create the pixel shader + { + static const char* pixelShader = + "struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + sampler sampler0;\ + Texture2D texture0;\ + \ + float4 main(PS_INPUT input) : SV_Target\ + {\ + float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ + return out_col; \ + }"; + + D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob, NULL); + if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + return false; + if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK) + return false; + } + + // Create the blending setup + { + D3D11_BLEND_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.AlphaToCoverageEnable = false; + desc.RenderTarget[0].BlendEnable = true; + desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + g_pd3dDevice->CreateBlendState(&desc, &g_pBlendState); + } + + // Create the rasterizer state + { + D3D11_RASTERIZER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.FillMode = D3D11_FILL_SOLID; + desc.CullMode = D3D11_CULL_NONE; + desc.ScissorEnable = true; + desc.DepthClipEnable = true; + g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState); + } + + // Create depth-stencil State + { + D3D11_DEPTH_STENCIL_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.DepthEnable = false; + desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + desc.DepthFunc = D3D11_COMPARISON_ALWAYS; + desc.StencilEnable = false; + desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + desc.BackFace = desc.FrontFace; + g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState); + } + + ImGui_ImplDX11_CreateFontsTexture(); + + return true; +} + +void ImGui_ImplDX11_InvalidateDeviceObjects() +{ + if (!g_pd3dDevice) + return; + + if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; } + if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = 0; } + if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } + if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } + + if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; } + if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; } + if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; } + if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; } + if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } + if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; } + if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; } + if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; } + if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; } +} + +bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContext* device_context) +{ + g_hWnd = (HWND)hwnd; + g_pd3dDevice = device; + g_pd3dDeviceContext = device_context; + + if (!QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond)) + return false; + if (!QueryPerformanceCounter((LARGE_INTEGER *)&g_Time)) + return false; + + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime. + io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = VK_UP; + io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN; + io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR; + io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; + io.KeyMap[ImGuiKey_Home] = VK_HOME; + io.KeyMap[ImGuiKey_End] = VK_END; + io.KeyMap[ImGuiKey_Delete] = VK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = VK_BACK; + io.KeyMap[ImGuiKey_Enter] = VK_RETURN; + io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; + io.KeyMap[ImGuiKey_A] = 'A'; + io.KeyMap[ImGuiKey_C] = 'C'; + io.KeyMap[ImGuiKey_V] = 'V'; + io.KeyMap[ImGuiKey_X] = 'X'; + io.KeyMap[ImGuiKey_Y] = 'Y'; + io.KeyMap[ImGuiKey_Z] = 'Z'; + + io.RenderDrawListsFn = ImGui_ImplDX11_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.ImeWindowHandle = g_hWnd; + + return true; +} + +void ImGui_ImplDX11_Shutdown() +{ + ImGui_ImplDX11_InvalidateDeviceObjects(); + ImGui::Shutdown(); + g_pd3dDevice = NULL; + g_pd3dDeviceContext = NULL; + g_hWnd = (HWND)0; +} + +void ImGui_ImplDX11_NewFrame() +{ + if (!g_pFontSampler) + ImGui_ImplDX11_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + RECT rect; + GetClientRect(g_hWnd, &rect); + io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); + + // Setup time step + INT64 current_time; + QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); + io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond; + g_Time = current_time; + + // Read keyboard modifiers inputs + io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0; + io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0; + io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0; + io.KeySuper = false; + // io.KeysDown : filled by WM_KEYDOWN/WM_KEYUP events + // io.MousePos : filled by WM_MOUSEMOVE events + // io.MouseDown : filled by WM_*BUTTON* events + // io.MouseWheel : filled by WM_MOUSEWHEEL events + + // Hide OS mouse cursor if ImGui is drawing it + SetCursor(io.MouseDrawCursor ? NULL : LoadCursor(NULL, IDC_ARROW)); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/imgui_impl_dx11.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/imgui_impl_dx11.h new file mode 100644 index 0000000..7d6f710 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/imgui_impl_dx11.h @@ -0,0 +1,25 @@ +// ImGui Win32 + DirectX11 binding +// In this binding, ImTextureID is used to store a 'ID3D11ShaderResourceView*' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct ID3D11Device; +struct ID3D11DeviceContext; + +IMGUI_API bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContext* device_context); +IMGUI_API void ImGui_ImplDX11_Shutdown(); +IMGUI_API void ImGui_ImplDX11_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplDX11_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplDX11_CreateDeviceObjects(); + +// Handler for Win32 messages, update mouse/keyboard data. +// You may or not need this for your implementation, but it can serve as reference for handling inputs. +// Commented out to avoid dragging dependencies on <windows.h> types. You can copy the extern declaration in your code. +/* +IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +*/ diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/PxInputDataFromPxFileBuf.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/PxInputDataFromPxFileBuf.h new file mode 100644 index 0000000..dfa8260 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/PxInputDataFromPxFileBuf.h @@ -0,0 +1,51 @@ +/* +* 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. +*/ + +#ifndef PXINPUTDATAFROMPXFILEBUF_H +#define PXINPUTDATAFROMPXFILEBUF_H + +#include <PsFileBuffer.h> + + +// Copied from APEX +class PxInputDataFromPxFileBuf : public physx::PxInputData +{ +public: + PxInputDataFromPxFileBuf(physx::PxFileBuf& fileBuf) : mFileBuf(fileBuf) {} + + // physx::PxInputData interface + virtual uint32_t getLength() const + { + return mFileBuf.getFileLength(); + } + + virtual void seek(uint32_t offset) + { + mFileBuf.seekRead(offset); + } + + virtual uint32_t tell() const + { + return mFileBuf.tellRead(); + } + + // physx::PxInputStream interface + virtual uint32_t read(void* dest, uint32_t count) + { + return mFileBuf.read(dest, count); + } + + PX_NOCOPY(PxInputDataFromPxFileBuf) +private: + physx::PxFileBuf& mFileBuf; +}; + + +#endif //PXINPUTDATAFROMPXFILEBUF_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.cpp new file mode 100644 index 0000000..4df23fd --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.cpp @@ -0,0 +1,223 @@ +/* +* 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. +*/ + + +#include "SampleProfiler.h" +#include <map> +#include <iostream> +#include <fstream> +#include <stack> + +using namespace std::chrono; + +struct ProfileData +{ + steady_clock::time_point start; + + microseconds time; + microseconds prevTime; + microseconds maxTime; + uint32_t calls; + uint32_t prevCalls; + + ProfileData() : time(0), prevTime(0), maxTime(0), calls(0), prevCalls(0) + {} +}; + +struct Node +{ + ProfileData data; + std::map<const char*, Node> childs; + Node* parent; +}; + +static std::map<const char*, Node> s_roots; +static Node* s_currentNode; +static bool s_beginEndMismatch; +static microseconds s_overhead; +static microseconds s_prevOverhead; + +void SampleProfilerInit() +{ + s_roots.clear(); + s_currentNode = nullptr; + s_beginEndMismatch = false; + s_overhead = microseconds(); +} + +void SampleProfilerBegin(const char* name) +{ + auto start = steady_clock::now(); + { + Node* parent = s_currentNode; + if (s_currentNode == nullptr) + { + s_currentNode = &s_roots[name]; + } + else + { + s_currentNode = &s_currentNode->childs[name]; + } + s_currentNode->parent = parent; + s_currentNode->data.calls++; + s_currentNode->data.start = steady_clock::now(); + } + s_overhead += duration_cast<microseconds>(steady_clock::now() - start); +} + +void SampleProfilerEnd() +{ + auto start = steady_clock::now(); + { + if (s_currentNode) + { + auto& data = s_currentNode->data; + data.time += duration_cast<microseconds>(steady_clock::now() - data.start); + data.maxTime = data.time > data.maxTime ? data.time : data.maxTime; + s_currentNode = s_currentNode->parent; + } + else + { + s_beginEndMismatch = true; + } + } + s_overhead += duration_cast<microseconds>(steady_clock::now() - start); +} + +struct SampleProfilerTreeIteratorImpl final : public SampleProfilerTreeIterator +{ + struct StackNode + { + Node* node; + const char* name; + }; + + SampleProfilerTreeIteratorImpl(std::map<const char*, Node>& roots) + { + for (auto& root : roots) + { + m_stack.emplace(StackNode { &root.second, root.first }); + } + + next(); + } + + virtual const Data* data() const override + { + return m_valid ? &m_data : nullptr; + } + + Node* node() + { + return m_node; + } + + virtual bool isDone() const + { + return !m_valid; + } + + virtual void next() + { + if (!m_stack.empty()) + { + auto& e = m_stack.top(); + m_stack.pop(); + m_node = e.node; + m_data.depth = 0; + m_data.hash = (uint64_t)m_node; + for (const Node* p = m_node; p != nullptr; p = p->parent) + { + m_data.depth++; + } + m_data.name = e.name; + m_data.calls = m_node->data.prevCalls; + m_data.time = m_node->data.prevTime; + m_data.maxTime = m_node->data.maxTime; + m_data.hasChilds = !m_node->childs.empty(); + + for (auto it = m_node->childs.rbegin(); it != m_node->childs.rend(); ++it) + { + m_stack.emplace(StackNode { &(*it).second, (*it).first }); + } + m_valid = true; + } + else + { + m_valid = false; + } + } + + virtual void release() + { + delete this; + } + + bool m_valid; + Data m_data; + Node* m_node; + std::stack<StackNode > m_stack; +}; + +void SampleProfilerReset() +{ + for (SampleProfilerTreeIteratorImpl it(s_roots); !it.isDone(); it.next()) + { + auto& data = it.node()->data; + data.prevTime = data.time; + data.prevCalls = data.calls; + data.time = microseconds(); + data.calls = 0; + } + s_currentNode = nullptr; + s_beginEndMismatch = false; + s_prevOverhead = s_overhead; + s_overhead = microseconds(); +} + +bool SampleProfilerIsValid() +{ + return !s_beginEndMismatch; +} + +microseconds SampleProfilerGetOverhead() +{ + return s_prevOverhead; +} + +SampleProfilerTreeIterator* SampleProfilerCreateTreeIterator() +{ + return SampleProfilerIsValid() ? new SampleProfilerTreeIteratorImpl(s_roots) : nullptr; +} + +void SampleProfilerDumpToFile(const char* path) +{ + std::ofstream myfile(path, std::ios_base::out); + if (myfile.is_open()) + { + if (s_beginEndMismatch) + { + myfile << "Error: Begin/End Mismatch.\n"; + } + else + { + myfile << "[Root]\n"; + for(SampleProfilerTreeIteratorImpl it(s_roots); !it.isDone(); it.next()) + { + auto data = it.data(); + for (uint32_t i = 0; i < data->depth; ++i) + myfile << "\t"; + myfile << data->name << " --> calls: " << data->calls << ", total: " << data->time.count() * 0.001 << "ms\n"; + } + } + + myfile.close(); + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.h new file mode 100644 index 0000000..1ea3663 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleProfiler.h @@ -0,0 +1,79 @@ +/* +* 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. +*/ + +#ifndef SAMPLEPROFILER_H +#define SAMPLEPROFILER_H + +#include <chrono> + +#if NV_PROFILE + +void SampleProfilerInit(); +void SampleProfilerBegin(const char* name); +void SampleProfilerEnd(); +void SampleProfilerReset(); + +struct SampleProfilerScoped +{ + SampleProfilerScoped(const char* name) + { + SampleProfilerBegin(name); + } + + ~SampleProfilerScoped() + { + SampleProfilerEnd(); + } +}; + +#define PROFILER_INIT() SampleProfilerInit() +#define PROFILER_BEGIN(x) SampleProfilerBegin(x) +#define PROFILER_END() SampleProfilerEnd() +#define PROFILER_SCOPED(x) SampleProfilerScoped __scopedProfiler__(x) +#define PROFILER_SCOPED_FUNCTION() SampleProfilerScoped __scopedProfiler__(__FUNCTION__) +#define PROFILER_RESET() SampleProfilerReset() + +#else + +#define PROFILER_INIT() +#define PROFILER_BEGIN(x) +#define PROFILER_END() +#define PROFILER_SCOPED(x) +#define PROFILER_SCOPED_FUNCTION() +#define PROFILER_RESET() + +#endif + +void SampleProfilerDumpToFile(const char* path); +bool SampleProfilerIsValid(); +std::chrono::microseconds SampleProfilerGetOverhead(); + +struct SampleProfilerTreeIterator +{ + struct Data + { + uint64_t hash; + const char* name; + bool hasChilds; + uint32_t depth; + std::chrono::microseconds time; + std::chrono::microseconds maxTime; + uint32_t calls; + }; + + virtual const Data* data() const = 0; + virtual bool isDone() const = 0; + virtual void next() = 0; + virtual void release() = 0; +}; + +SampleProfilerTreeIterator* SampleProfilerCreateTreeIterator(); + +#endif //SAMPLEPROFILER_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleTime.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleTime.h new file mode 100644 index 0000000..c62ced2 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/SampleTime.h @@ -0,0 +1,58 @@ +/* +* 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. +*/ + +#ifndef SAMPLE_TIME_H +#define SAMPLE_TIME_H + +#include <stdint.h> + +class Time +{ +public: + Time() : m_lastTickCount(getTimeTicks()) {} + + double Time::getElapsedSeconds() + { + const int64_t lastTickCount = m_lastTickCount; + m_lastTickCount = getTimeTicks(); + return (m_lastTickCount - lastTickCount) * s_secondsPerTick; + } + + double Time::peekElapsedSeconds() const + { + return (getTimeTicks() - m_lastTickCount) * s_secondsPerTick; + } + + double Time::getLastTime() const + { + return m_lastTickCount * s_secondsPerTick; + } + +private: + static double getTickDuration() + { + LARGE_INTEGER a; + QueryPerformanceFrequency(&a); + return 1.0 / (double)a.QuadPart; + } + + int64_t getTimeTicks() const + { + LARGE_INTEGER a; + QueryPerformanceCounter(&a); + return a.QuadPart; + } + + int64_t m_lastTickCount; + static const double s_secondsPerTick; +}; + + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/UIHelpers.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/UIHelpers.h new file mode 100644 index 0000000..b23eb84 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/UIHelpers.h @@ -0,0 +1,56 @@ +/* +* 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. +*/ + +#ifndef UI_HELPERS_H +#define UI_HELPERS_H + +#include "imgui.h" +#include "PxVec3.h" + + +static void ImGui_DragFloat3Dir(const char* label, float v[3]) +{ + if (ImGui::Button("Normalize")) + { + ((physx::PxVec3*)v)->normalize(); + } + ImGui::SameLine(); + ImGui::DragFloat3(label, v); +}; + + +#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) + +template<int valuesCount = 90> +class PlotLinesInstance +{ +public: + PlotLinesInstance() + { + memset(m_values, 0, sizeof(float) * valuesCount); + } + + void plot(const char* label, float newValue, const char* overlay_text, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 80)) + { + for (; ImGui::GetTime() > m_time + 1.0f / 60.0f; m_time += 1.0f / 60.0f) + { + m_values[m_offset] = newValue; + m_offset = (m_offset + 1) % valuesCount; + } + ImGui::PlotLines(label, m_values, valuesCount, m_offset, overlay_text, scale_min, scale_max, graph_size); + } + +private: + float m_values[valuesCount]; + int m_offset; + float m_time = ImGui::GetTime(); +}; + +#endif //UI_HELPERS_H
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.cpp new file mode 100644 index 0000000..a271137 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.cpp @@ -0,0 +1,13 @@ +#include "Utils.h" + +#include <string> +#include <cstdarg> + +HRESULT messagebox_printf(const char* caption, UINT mb_type, const char* format, ...) +{ + va_list args; + va_start(args, format); + char formatted_text[512]; + _vsnprintf(formatted_text, 512, format, args); + return MessageBoxA(nullptr, formatted_text, caption, mb_type); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.h new file mode 100644 index 0000000..5d4addc --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/SampleBase/utils/Utils.h @@ -0,0 +1,91 @@ +#ifndef UTILS_H +#define UTILS_H + +#include <DeviceManager.h> +#include <assert.h> + +#include "PxPreprocessor.h" + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// MACROS +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef V_RETURN +#define V_RETURN(x) \ + { \ + hr = (x); \ + if(FAILED(hr)) \ + { \ + return hr; \ + } \ + } +#endif + +#ifndef V +#define V(x) \ + { \ + HRESULT hr = (x); \ + _ASSERT(SUCCEEDED(hr)); \ + } +#endif + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(p) \ + { \ + if(p) \ + { \ + (p)->Release(); \ + (p) = NULL; \ + } \ + } +#endif + +#ifndef SAFE_DELETE +#define SAFE_DELETE(p) \ + { \ + if(p) \ + { \ + delete (p); \ + (p) = NULL; \ + } \ + } +#endif + +#define ASSERT_PRINT(cond, format, ...) \ + if(!(cond)) \ + { \ + messagebox_printf("Assertion Failed!", MB_OK | MB_ICONERROR, #cond "\n" format, __VA_ARGS__); \ + assert(cond); \ + } + +HRESULT messagebox_printf(const char* caption, UINT mb_type, const char* format, ...); + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static const char* strext(const char* str) +{ + const char* ext = NULL; // by default no extension found! + while (str) + { + str = strchr(str, '.'); + if (str) + { + str++; + ext = str; + } + } + return ext; +} + +static inline float lerp(float a, float b, float t) { return a + (b - a) * t; } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.cpp new file mode 100644 index 0000000..b42a4f5 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.cpp @@ -0,0 +1,306 @@ +#include "BlastCompositePanel.h" +#include "ui_BlastCompositePanel.h" +#include "ProjectParams.h" +#include <QtCore/QFileInfo> +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> + +BlastCompositePanel::BlastCompositePanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::BlastCompositePanel), + _selectedAsset(-1) +{ + ui->setupUi(this); + + ui->btnRemoveAsset->setEnabled(false); + ui->btnModifyLandmark->setEnabled(false); + ui->btnRemoveLandmark->setEnabled(false); +} + +BlastCompositePanel::~BlastCompositePanel() +{ + delete ui; +} + +void BlastCompositePanel::updateValues() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + + ui->lineEditComposite->setText(composite.composite.buf); + + _updateAssetComboBox(); + + _updateAssetInstanceListWidget(); + + ui->spinBoxBondByThreshold->setValue(composite.bondThreshold); + ui->spinBoxNewBondStrength->setValue(composite.bondStrength); + + _updateLandmarkListWidget(); + + ui->checkBoxEnableLandmark->setChecked(false); + ui->spinBoxLandmarkRadius->setValue(false); +} + +void BlastCompositePanel::on_btnCollapse_clicked() +{ + +} + +void BlastCompositePanel::on_btnSave_clicked() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + + QByteArray tmp = ui->lineEditComposite->text().toUtf8(); + copy(composite.composite, tmp.data()); +} + +void BlastCompositePanel::on_comboBoxAsset_currentIndexChanged(int index) +{ + _selectedAsset = index; +} + +void BlastCompositePanel::on_btnAddAsset_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new blast instance:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isAssetInstanceNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addAssetInstance(_selectedAsset, name.toUtf8().data()); + _updateAssetInstanceListWidget(); + ui->listWidgetBlastAsset->setCurrentRow(ui->listWidgetBlastAsset->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new preset!"); + } +} + +void BlastCompositePanel::on_btnRemoveAsset_clicked() +{ + QList<QListWidgetItem*> items = ui->listWidgetBlastAsset->selectedItems(); + BlastProject::ins().removeAssetInstance(items.at(0)->text().toUtf8().data()); +} + +void BlastCompositePanel::on_listWidgetBlastAsset_itemSelectionChanged() +{ + QList<QListWidgetItem*> items = ui->listWidgetBlastAsset->selectedItems(); + if (items.count() > 0) + ui->btnRemoveAsset->setEnabled(true); + else + ui->btnRemoveAsset->setEnabled(false); +} + +void BlastCompositePanel::on_spinBoxBondByThreshold_valueChanged(double arg1) +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + composite.bondThreshold = arg1; +} + +void BlastCompositePanel::on_spinBoxNewBondStrength_valueChanged(double arg1) +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + composite.bondStrength = arg1; +} + +void BlastCompositePanel::on_btnAddLandmark_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new landmark:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isLandmarkNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addLandmark(name.toUtf8().data()); + _updateLandmarkListWidget(); + ui->listWidgetLandmark->setCurrentRow(ui->listWidgetLandmark->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new landmark!"); + } +} + +void BlastCompositePanel::on_btnModifyLandmark_clicked() +{ + QList<QListWidgetItem*> items = ui->listWidgetLandmark->selectedItems(); + QByteArray tem = items.at(0)->text().toUtf8(); + const char* oldName = tem.data(); + + bool ok = false; + QString newName = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input new name for the selected landmark:"), + QLineEdit::Normal, + oldName, + &ok); + bool nameExist = BlastProject::ins().isLandmarkNameExist(newName.toUtf8().data()); + if (ok && !newName.isEmpty() && !nameExist) + { + int selectIndex = ui->listWidgetLandmark->currentRow(); + BlastProject::ins().renameLandmark(oldName, newName.toUtf8().data()); + _updateLandmarkListWidget(); + ui->listWidgetLandmark->setCurrentRow(selectIndex); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && newName.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new landmark!"); + } +} + +void BlastCompositePanel::on_btnRemoveLandmark_clicked() +{ + QList<QListWidgetItem*> items = ui->listWidgetLandmark->selectedItems(); + QByteArray tem = items.at(0)->text().toUtf8(); + const char* name = tem.data(); + BlastProject::ins().removeLandmark(name); + _updateLandmarkListWidget(); +} + +void BlastCompositePanel::on_listWidgetLandmark_itemSelectionChanged() +{ + _updateLandmarkUIs(); +} + +void BlastCompositePanel::on_checkBoxEnableLandmark_stateChanged(int arg1) +{ + QList<QListWidgetItem*> items = ui->listWidgetLandmark->selectedItems(); + + int count = items.count(); + for (int i = 0; i < count; ++i) + { + BPPLandmark* landmark = BlastProject::ins().getLandmark(items.at(0)->text().toUtf8().data()); + if (landmark != nullptr) + { + landmark->enable = ui->checkBoxEnableLandmark->isChecked(); + } + } +} + +void BlastCompositePanel::on_spinBoxLandmarkRadius_valueChanged(double arg1) +{ + QList<QListWidgetItem*> items = ui->listWidgetLandmark->selectedItems(); + + int count = items.count(); + for (int i = 0; i < count; ++i) + { + BPPLandmark* landmark = BlastProject::ins().getLandmark(items.at(0)->text().toUtf8().data()); + if (landmark != nullptr) + { + landmark->radius = ui->spinBoxLandmarkRadius->value(); + } + } +} + +void BlastCompositePanel::_updateAssetComboBox() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPAssetArray& blastAssetArray = projectParams.blast.blastAssets; + BPPComposite& composite = projectParams.blast.composite; + + ui->comboBoxAsset->clear(); + int countAssets = blastAssetArray.arraySizes[0]; + if (countAssets > 0) + { + QStringList assets; + for (int i = 0; i < countAssets; ++i) + { + QFileInfo fileInfo(blastAssetArray.buf[i].path.buf); + assets.append(fileInfo.baseName()); + } + ui->comboBoxAsset->addItems(assets); + } + else + { + ui->btnAddAsset->setEnabled(false); + ui->btnRemoveAsset->setEnabled(false); + } +} + +void BlastCompositePanel::_updateAssetInstanceListWidget() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + + ui->listWidgetBlastAsset->clear(); + int countAssetInstances = composite.blastAssetInstances.arraySizes[0]; + if (countAssetInstances > 0) + { + QStringList assetInstances; + + for (int i = 0; i < countAssetInstances; ++i) + { + assetInstances.append(composite.blastAssetInstances.buf[i].name.buf); + } + ui->listWidgetBlastAsset->addItems(assetInstances); + } +} + +void BlastCompositePanel::_updateLandmarkListWidget() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPComposite& composite = projectParams.blast.composite; + + ui->listWidgetLandmark->clear(); + int countJoints = composite.landmarks.arraySizes[0]; + if (countJoints > 0) + { + QStringList landmarks; + + for (int i = 0; i < countJoints; ++i) + { + landmarks.append(composite.landmarks.buf[i].name.buf); + } + ui->listWidgetLandmark->addItems(landmarks); + } +} + +void BlastCompositePanel::_updateLandmarkUIs() +{ + QList<QListWidgetItem*> items = ui->listWidgetLandmark->selectedItems(); + + if (items.count() > 0) + { + BPPLandmark* landmark = BlastProject::ins().getLandmark(items.at(0)->text().toUtf8().data()); + if (landmark != nullptr) + { + ui->btnModifyLandmark->setEnabled(true); + ui->btnRemoveLandmark->setEnabled(true); + ui->checkBoxEnableLandmark->setChecked(landmark->enable); + ui->spinBoxLandmarkRadius->setValue(landmark->radius); + } + } + else + { + ui->btnModifyLandmark->setEnabled(false); + ui->btnRemoveLandmark->setEnabled(false); + ui->checkBoxEnableLandmark->setChecked(false); + ui->spinBoxLandmarkRadius->setValue(0.0f); + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.h new file mode 100644 index 0000000..b4e5bcf --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastCompositePanel.h @@ -0,0 +1,59 @@ +#ifndef BLASTCOMPOSITEPANEL_H +#define BLASTCOMPOSITEPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class BlastCompositePanel; +} + +class BlastCompositePanel : public QWidget +{ + Q_OBJECT + +public: + explicit BlastCompositePanel(QWidget *parent = 0); + ~BlastCompositePanel(); + void updateValues(); + +private slots: + void on_btnCollapse_clicked(); + + void on_btnSave_clicked(); + + void on_comboBoxAsset_currentIndexChanged(int index); + + void on_btnAddAsset_clicked(); + + void on_btnRemoveAsset_clicked(); + + void on_listWidgetBlastAsset_itemSelectionChanged(); + + void on_spinBoxBondByThreshold_valueChanged(double arg1); + + void on_spinBoxNewBondStrength_valueChanged(double arg1); + + void on_btnAddLandmark_clicked(); + + void on_btnModifyLandmark_clicked(); + + void on_btnRemoveLandmark_clicked(); + + void on_listWidgetLandmark_itemSelectionChanged(); + + void on_checkBoxEnableLandmark_stateChanged(int arg1); + + void on_spinBoxLandmarkRadius_valueChanged(double arg1); + +private: + void _updateAssetComboBox(); + void _updateAssetInstanceListWidget(); + void _updateLandmarkListWidget(); + void _updateLandmarkUIs(); + +private: + Ui::BlastCompositePanel *ui; + int _selectedAsset; +}; + +#endif // BLASTCOMPOSITEPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp new file mode 100644 index 0000000..64a7c2f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.cpp @@ -0,0 +1,1804 @@ +#include "BlastSceneTree.h" +#include <QtWidgets/QMessageBox> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QPushButton> +#include <QtWidgets/QCheckBox> +#include <QtWidgets/QMenu> +#include <QtCore/QFileInfo> +#include <assert.h> +#include "ProjectParams.h" +#include <SimpleScene.h> +#include <BlastController.h> +#include <SceneController.h> +#include <NvBlastExtPxAsset.h> +#include <NvBlastTkAsset.h> +#include <NvBlastAsset.h> +#include <BlastFamilyModelSimple.h> + +bool isChunkVisible(std::vector<BlastFamily*>& fs, uint32_t chunkIndex) +{ + int fsSize = fs.size(); + if (fsSize == 0) + { + return false; + } + + bool visible = false; + for (int i = 0; i < fsSize; i++) + { + if (fs[i]->isChunkVisible(chunkIndex)) + { + visible = true; + break; + } + } + return visible; +} + +void setChunkVisible(std::vector<BlastFamily*>& fs, uint32_t chunkIndex, bool visible) +{ + int fsSize = fs.size(); + if (fsSize == 0) + { + return; + } + + for (int i = 0; i < fsSize; i++) + { + fs[i]->setChunkVisible(chunkIndex, visible); + } +} + +void setChunkSelected(std::vector<BlastFamily*>& fs, uint32_t chunkIndex, bool selected) +{ + int fsSize = fs.size(); + if (fsSize == 0) + { + return; + } + + for (int i = 0; i < fsSize; i++) + { + fs[i]->setChunkSelected(chunkIndex, selected); + } +} + +void BlastChunkNode::setVisible(bool val) +{ + BPPChunk* pBPPChunk = (BPPChunk*)_data; + pBPPChunk->visible = val; + + BlastAsset* pBlastAsset = (BlastAsset*)_assetPtr; + + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + + std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap(); + std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset]; + + setChunkVisible(fs, pBPPChunk->ID, val); +} + +void BlastChunkNode::setSelected(bool val) +{ + BPPChunk* pBPPChunk = (BPPChunk*)_data; + pBPPChunk->visible = val; + + BlastAsset* pBlastAsset = (BlastAsset*)_assetPtr; + + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + + std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap(); + std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset]; + + setChunkSelected(fs, pBPPChunk->ID, val); +} + +void BlastAssetInstanceNode::setSelected(bool val) +{ + BPPAssetInstance* pBPPAssetInstance = (BPPAssetInstance*)_data; + std::string name = pBPPAssetInstance->name; + + std::string strAsset = name.substr(0, name.find_first_of("_")); + BlastAsset* pBlastAsset = nullptr; + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = sampleManager.getAssetDescMap(); + std::map<BlastAsset*, AssetList::ModelAsset>::iterator itAssetDescMap; + for (itAssetDescMap = AssetDescMap.begin(); + itAssetDescMap != AssetDescMap.end(); itAssetDescMap++) + { + AssetList::ModelAsset& model = itAssetDescMap->second; + if (model.name == strAsset) + { + pBlastAsset = itAssetDescMap->first; + break; + } + } + + std::string strIndex = name.substr(name.find_last_of("_") + 1); + int nIndex = atoi(strIndex.c_str()); + + sampleManager.setCurrentSelectedInstance(pBlastAsset, nIndex); +} + +BlastTreeData& BlastTreeData::ins() +{ + static BlastTreeData _ins; + return _ins; +} + +bool BlastTreeData::isChild(BlastChunkNode* parent, BlastChunkNode* child) +{ + if (parent == nullptr || child == nullptr) + return false; + + BlastNode* curParent = child->getParent(); + while (eChunk == curParent->getType() && curParent != nullptr) + { + if (curParent == parent) + return true; + curParent = curParent->getParent(); + } + + return false; +} + +std::vector<BlastChunkNode*> BlastTreeData::getTopChunkNodes(std::vector<BlastChunkNode*>& nodes) +{ + std::vector<BlastChunkNode*> result; + + for (size_t i = 0; i < nodes.size(); ++i) + { + bool isCurNodeTop = true; + for (size_t j = 0; j < nodes.size(); ++j) + { + if (i != j && isChild(nodes[i], nodes[j])) + { + isCurNodeTop = false; + break; + } + } + + if (isCurNodeTop) + { + result.push_back(nodes[i]); + } + } + + return result; +} + +bool BlastTreeData::isRoot(BlastChunkNode* node) +{ + if (node == nullptr || node->getParent() == nullptr) + return false; + + return eAsset == node->getParent()->getType(); +} + +bool BlastTreeData::isLeaf(BlastChunkNode* node) +{ + if (node == nullptr) + return false; + + for (BlastNode* curNode : node->children) + { + if (eChunk == curNode->getType()) + return false; + } + + return true; +} + +void removeChunkNodeSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return; + + BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); + chunk->support = false; + + for (BlastNode* curNode : node->children) + { + if (eChunk == curNode->getType()) + { + removeChunkNodeSupport((BlastChunkNode*)curNode); + } + } +} + +void BlastTreeData::makeSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return; + BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); + chunk->staticFlag = false; + chunk->support = true; + + for (BlastNode* curNode : node->children) + { + if (eChunk == curNode->getType()) + { + removeChunkNodeSupport((BlastChunkNode*)curNode); + } + } +} + +void BlastTreeData::makeStaticSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return; + BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); + chunk->staticFlag = true; + chunk->support = true; + + for (BlastNode* curNode : node->children) + { + if (eChunk == curNode->getType()) + { + removeChunkNodeSupport((BlastChunkNode*)curNode); + } + } +} + +void BlastTreeData::removeSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return; + + if (isLeaf(node)) + return; + + BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); + chunk->support = false; + chunk->staticFlag = false; + + for (BlastNode* curNode : node->children) + { + if (eChunk == curNode->getType()) + { + BPPChunk* curChunk = static_cast<BPPChunk*>(curNode->getData()); + curChunk->support = true; + } + } +} + +BlastNode* BlastTreeData::getBlastNodeByProjectData(void* data) +{ + std::map<void*, BlastNode*>::iterator itr = _blastProjectDataToNodeMap.find(data); + if (itr != _blastProjectDataToNodeMap.end()) + return itr->second; + + return nullptr; +} + +struct ChunkSupport +{ + ChunkSupport() + { + m_bSupport = false; + } + + bool m_bSupport; +}; + +struct BondChunkIndices +{ + BondChunkIndices() + { + chunkIndices[0] = -1; + chunkIndices[1] = -1; + } + + void SetIndices(uint32_t chunkIndex0, uint32_t chunkIndex1) + { + if (chunkIndex0 < chunkIndex1) + { + chunkIndices[0] = chunkIndex0; + chunkIndices[1] = chunkIndex1; + } + else + { + chunkIndices[0] = chunkIndex1; + chunkIndices[1] = chunkIndex0; + } + } + + uint32_t chunkIndices[2]; +}; + +void BlastTreeData::update() +{ + _freeBlastNode(); + + BPPBlast& blast = BlastProject::ins().getParams().blast; + std::vector<BlastAsset*> BlastAssetVec; + { + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + + std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager.getAssetFamiliesMap(); + std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = sampleManager.getAssetDescMap(); + + BlastController& blastController = sampleManager.getBlastController(); + SceneController& sceneController = sampleManager.getSceneController(); + + std::vector<BlastFamilyPtr>& families = blastController.getFamilies(); + int familiesSize = families.size(); + + std::map<BlastAsset*, AssetList::ModelAsset>::iterator it; + for (it = AssetDescMap.begin(); it != AssetDescMap.end(); it++) + { + BlastAssetVec.push_back(it->first); + } + int modelAssetsSize = AssetDescMap.size(); + + std::vector<std::string> projectilesNames; + sceneController.GetProjectilesNames(projectilesNames); + + // compoistie + { + BPPComposite& composite = blast.composite; + composite.composite.buf = nullptr; + composite.visible = true; + + copy(composite.composite, "BlastComposite"); + + // asset instance array + { + BPPAssetInstanceArray& instanceArray = composite.blastAssetInstances; + instanceArray.arraySizes[0] = familiesSize; + if (familiesSize > 0) + { + instanceArray.buf = new BPPAssetInstance[familiesSize]; + int curInstanceIndex = 0; + char instancename[50]; + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAssetFamiliesMap; + for (itAssetFamiliesMap = AssetFamiliesMap.begin(); + itAssetFamiliesMap != AssetFamiliesMap.end(); itAssetFamiliesMap++) + { + BlastAsset* pBlastAsset = itAssetFamiliesMap->first; + std::vector<BlastFamily*>& fs = itAssetFamiliesMap->second; + int fsSize = fs.size(); + for (int i = 0; i < fsSize; i++) + { + BPPAssetInstance& instance = instanceArray.buf[curInstanceIndex]; + instance.name.buf = nullptr; + instance.source.buf = nullptr; + instance.visible = true; + + AssetList::ModelAsset desc = AssetDescMap[pBlastAsset]; + sprintf(instancename, "%s_Instance_%d", desc.name.c_str(), i); + copy(instance.name, instancename); + + std::string assetFilePath = SampleManager::ins()->getConfig().additionalResourcesDir.back() + "/models/" + desc.file + ".bpxa"; + sprintf(instancename, "%s", assetFilePath.c_str()); + copy(instance.source, instancename); + + PxVec3 p = desc.transform.p; + PxQuat q = desc.transform.q; + instanceArray.buf[curInstanceIndex].transform.position = nvidia::NvVec3(p.x, p.y, p.z); + instanceArray.buf[curInstanceIndex].transform.rotation = nvidia::NvVec4(q.x, q.y, q.z, q.w); + + curInstanceIndex++; + } + } + } + } + + // landmark array + if (0) + { + BPPLandmarkArray& landmarkArray = composite.landmarks; + landmarkArray.buf = new BPPLandmark[2]; + landmarkArray.arraySizes[0] = 2; + landmarkArray.buf[0].name.buf = nullptr; + landmarkArray.buf[1].name.buf = nullptr; + + copy(landmarkArray.buf[0].name, "Landmark_1"); + copy(landmarkArray.buf[1].name, "Landmark_2"); + } + } + + // asset array + { + BPPAssetArray& assetArray = blast.blastAssets; + assetArray.arraySizes[0] = modelAssetsSize; + if (modelAssetsSize > 0) + { + assetArray.buf = new BPPAsset[modelAssetsSize]; + int curAssetIndex = 0; + + blast.chunks.buf = nullptr; + blast.chunks.arraySizes[0] = 0; + blast.bonds.buf = nullptr; + blast.bonds.arraySizes[0] = 0; + + std::map<BlastAsset*, AssetList::ModelAsset>::iterator itAssetDescMap; + for (itAssetDescMap = AssetDescMap.begin(); + itAssetDescMap != AssetDescMap.end(); itAssetDescMap++) + { + BlastAsset* pBlastAsset = itAssetDescMap->first; + AssetList::ModelAsset& desc = itAssetDescMap->second; + std::vector<BlastFamily*>& fs = AssetFamiliesMap[pBlastAsset]; + + BPPAsset& asset = assetArray.buf[curAssetIndex]; + asset.path.buf = nullptr; + asset.activePreset.buf = nullptr; + std::string assetFilePath = SampleManager::ins()->getConfig().additionalResourcesDir.back() + "/models/" + desc.file + ".bpxa"; + copy(asset.path, assetFilePath.c_str()); + + const ExtPxAsset* pExtPxAsset = pBlastAsset->getPxAsset(); + const ExtPxChunk* pExtPxChunk = pExtPxAsset->getChunks(); + + const TkAsset& tkAsset = pExtPxAsset->getTkAsset(); + uint32_t chunkCount = tkAsset.getChunkCount(); + const NvBlastChunk* pNvBlastChunk = tkAsset.getChunks(); + uint32_t bondCount = tkAsset.getBondCount(); + const NvBlastBond* pNvBlastBond = tkAsset.getBonds(); + + const NvBlastSupportGraph supportGraph = tkAsset.getGraph(); + uint32_t* chunkIndices = supportGraph.chunkIndices; + uint32_t* adjacencyPartition = supportGraph.adjacencyPartition; + uint32_t* adjacentNodeIndices = supportGraph.adjacentNodeIndices; + uint32_t* adjacentBondIndices = supportGraph.adjacentBondIndices; + + ChunkSupport* pSupport = new ChunkSupport[chunkCount]; + BondChunkIndices* pBCIndices = new BondChunkIndices[bondCount]; + + for (uint32_t node0 = 0; node0 < supportGraph.nodeCount; ++node0) + { + const uint32_t chunkIndex0 = supportGraph.chunkIndices[node0]; + + pSupport[chunkIndex0].m_bSupport = true; + + for (uint32_t adjacencyIndex = adjacencyPartition[node0]; adjacencyIndex < adjacencyPartition[node0 + 1]; adjacencyIndex++) + { + uint32_t node1 = supportGraph.adjacentNodeIndices[adjacencyIndex]; + + // add this condition if you don't want to iterate all bonds twice + if (node0 > node1) + continue; + + const uint32_t chunkIndex1 = supportGraph.chunkIndices[node1]; + + uint32_t bondIndex = supportGraph.adjacentBondIndices[adjacencyIndex]; + + pBCIndices[bondIndex].SetIndices(chunkIndex0, chunkIndex1); + } + } + + // chunks + { + BPPChunkArray curArray; + curArray.buf = new BPPChunk[chunkCount]; + curArray.arraySizes[0] = chunkCount; + char chunkname[10]; + for (int cc = 0; cc < chunkCount; ++cc) + { + BPPChunk& chunk = curArray.buf[cc]; + chunk.name.buf = nullptr; + chunk.asset.buf = nullptr; + + std::vector<uint32_t> parentChunkIndexes; + parentChunkIndexes.push_back(cc); + uint32_t parentChunkIndex = cc; + while ((parentChunkIndex = pNvBlastChunk[parentChunkIndex].parentChunkIndex) != -1) + { + parentChunkIndexes.push_back(parentChunkIndex); + } + + std::string strChunkName = "Chunk"; + for (int pcIndex = parentChunkIndexes.size() - 1; pcIndex >= 0; pcIndex--) + { + sprintf(chunkname, "_%d", parentChunkIndexes[pcIndex]); + strChunkName += chunkname; + } + copy(chunk.name, strChunkName.c_str()); + + copy(chunk.asset, asset.path); + chunk.ID = cc; + chunk.parentID = pNvBlastChunk[cc].parentChunkIndex; + chunk.staticFlag = pExtPxChunk[cc].isStatic; + chunk.visible = isChunkVisible(fs, cc); + chunk.support = pSupport[cc].m_bSupport; + } + + merge(blast.chunks, curArray); + freeBlast(curArray); + } + + // bonds + { + BPPBondArray curArray; + curArray.buf = new BPPBond[bondCount]; + curArray.arraySizes[0] = bondCount; + char bondname[10]; + bool visible; + for (int bc = 0; bc < bondCount; ++bc) + { + BPPBond& bond = curArray.buf[bc]; + bond.name.buf = nullptr; + bond.asset.buf = nullptr; + + visible = isChunkVisible(fs, pBCIndices[bc].chunkIndices[0]) + || isChunkVisible(fs, pBCIndices[bc].chunkIndices[1]); + bond.visible = visible; + bond.support.healthMask.buf = nullptr; // ? + bond.fromChunk = pBCIndices[bc].chunkIndices[0]; + bond.toChunk = pBCIndices[bc].chunkIndices[1]; + + sprintf(bondname, "Bond_%d_%d", bond.fromChunk, bond.toChunk); + copy(bond.name, bondname); + copy(bond.asset, asset.path); + } + + merge(blast.bonds, curArray); + freeBlast(curArray); + } + + delete[] pSupport; + pSupport = nullptr; + delete[] pBCIndices; + pBCIndices = nullptr; + + curAssetIndex++; + } + } + } + + // projectile + { + BPPProjectileArray& projectileArray = blast.projectiles; + int BPPProjectileSize = projectilesNames.size(); + projectileArray.arraySizes[0] = BPPProjectileSize; + if (BPPProjectileSize > 0) + { + projectileArray.buf = new BPPProjectile[BPPProjectileSize]; + for (int i = 0; i < BPPProjectileSize; i++) + { + projectileArray.buf[i].name.buf = nullptr; + copy(projectileArray.buf[i].name, projectilesNames[i].c_str()); + projectileArray.buf[i].visible = true; + } + } + } + + // graphics meshes + if (0) + { + BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes; + graphicsMeshArray.buf = new BPPGraphicsMesh[3]; + graphicsMeshArray.arraySizes[0] = 3; + graphicsMeshArray.buf[0].name.buf = nullptr; + copy(graphicsMeshArray.buf[0].name, "SurfaceMesh1"); + graphicsMeshArray.buf[0].visible = true; + + graphicsMeshArray.buf[1].name.buf = nullptr; + copy(graphicsMeshArray.buf[1].name, "SurfaceMesh2"); + graphicsMeshArray.buf[1].visible = true; + + graphicsMeshArray.buf[2].name.buf = nullptr; + copy(graphicsMeshArray.buf[2].name, "DisplayMesh1"); + graphicsMeshArray.buf[2].visible = true; + } + } + + BPPAssetArray& assetArray = blast.blastAssets; + + int count = assetArray.arraySizes[0]; + for (int c = 0; c < count; ++c) + { + BPPAsset& asset = assetArray.buf[c]; + QFileInfo fileInfo(asset.path.buf); + BlastAssetNode* assetNode = new BlastAssetNode(fileInfo.baseName().toUtf8().data(), asset); + _assets.push_back(assetNode); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&asset, assetNode)); + + // get the firlst level chunks whose parentID is -1 + std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset, -1); + + for (size_t i = 0; i < childChunks.size(); ++i) + { + BPPChunk& chunk = *(childChunks[i]); + BlastChunkNode* chunkNode = new BlastChunkNode(chunk.name.buf, chunk, BlastAssetVec[c]); + assetNode->children.push_back(chunkNode); + chunkNode->setParent(assetNode); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&chunk, chunkNode)); + _addChunkNode(chunk, asset, chunkNode, BlastAssetVec[c]); + } + } + + BPPComposite& composite = blast.composite; + _composite = new BlastCompositeNode(composite.composite.buf, composite); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&composite, _composite)); + BPPAssetInstanceArray& assetInstanceArray = composite.blastAssetInstances; + count = assetInstanceArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + BPPAssetInstance& blastAssetInstance = composite.blastAssetInstances.buf[i]; + BlastAssetInstanceNode* blastAssetInstanceNode = new BlastAssetInstanceNode(blastAssetInstance.name.buf, blastAssetInstance); + _composite->children.push_back(blastAssetInstanceNode); + blastAssetInstanceNode->setParent(_composite); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&blastAssetInstance, blastAssetInstanceNode)); + } + + BPPLandmarkArray& landmarkArray = composite.landmarks; + count = landmarkArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + BPPLandmark& landmark = composite.landmarks.buf[i]; + BlastLandmarkNode* landmarkNode = new BlastLandmarkNode(landmark.name.buf, landmark); + _composite->children.push_back(landmarkNode); + landmarkNode->setParent(_composite); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&landmark, landmarkNode)); + } + + BPPProjectileArray& projectileArray = blast.projectiles; + count = projectileArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + BPPProjectile& projectile = projectileArray.buf[i]; + BlastProjectileNode* projectileNode = new BlastProjectileNode(projectile.name.buf, projectile); + _projectiles.push_back(projectileNode); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&projectile, projectileNode)); + } + + BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes; + count = graphicsMeshArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + BPPGraphicsMesh& graphicsMesh = graphicsMeshArray.buf[i]; + BlastGraphicsMeshNode* projectileNode = new BlastGraphicsMeshNode(graphicsMesh.name.buf, graphicsMesh); + _graphicsMeshes.push_back(projectileNode); + } +} + +void BlastTreeData::updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible) +{ + BPPBlast& blast = BlastProject::ins().getParams().blast; + BPPAssetArray& assetArray = blast.blastAssets; + if (assetIndex < assetArray.arraySizes[0]) + { + BPPAsset& asset = assetArray.buf[assetIndex]; + + std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset); + if (chunkIndex < childChunks.size()) + { + BPPChunk& chunk = *(childChunks[chunkIndex]); + chunk.visible = visible; + } + } +} + + +BlastChunkNode* findChunkNode(BlastChunkNode* chunkNode, uint32_t chunkIndex) +{ + if (chunkNode == nullptr) + return nullptr; + + if (((BPPChunk*)chunkNode->getData())->ID == chunkIndex) + return chunkNode; + + std::vector<BlastNode*>& children = chunkNode->children; + for (size_t i = 0; i < children.size(); ++i) + { + BlastNode* node = children[i]; + if (node->getType() == eChunk) + { + BlastChunkNode* chunkNode = findChunkNode(static_cast<BlastChunkNode*>(node), chunkIndex); + if (chunkNode) + { + return chunkNode; + } + else + continue; + } + + else + continue; + } + + return nullptr; +} + +std::vector<BlastChunkNode*> BlastTreeData::getChunkNodeByBlastChunk(const BlastAsset* asset, const std::vector<uint32_t>& chunkIndexes) +{ + std::vector<BlastChunkNode*> chunkNodes; + if (asset == nullptr || chunkIndexes.size() == 0) + { + return chunkNodes; + } + + BlastAssetNode* assetNode = _getAssetNode(asset); + if (assetNode) + { + std::vector<BlastNode*>& children = assetNode->children; + for (BlastNode* node : children) + { + if (node->getType() == eChunk) + { + for (uint32_t chunkId : chunkIndexes) + { + BlastChunkNode* chunkNode = findChunkNode(static_cast<BlastChunkNode*>(node), chunkId); + if (chunkNode) + { + chunkNodes.push_back(chunkNode); + } + } + } + } + } + + return chunkNodes; +} + +bool isCompleteSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return false; + + if (node->isSupport()) + return true; + + const std::vector<BlastNode*>& children = node->children; + for (BlastNode* curNode : children) + { + if (eChunk == curNode->getType()) + { + BlastChunkNode* chunkNode = (BlastChunkNode*)curNode; + if (0 == chunkNode->children.size()) + { + if (!chunkNode->isSupport()) + return false; + } + + if (!isCompleteSupport(chunkNode)) + return false; + } + } + + return true; +} + +bool BlastTreeData::isCompleteSupportAsset(const BlastAsset* asset) +{ + BlastAssetNode* assetNode = _getAssetNode(asset); + return isCompleteSupportAsset(assetNode); +} + +bool BlastTreeData::isCompleteSupportAsset(const BlastAssetNode* node) +{ + if (node == nullptr) + return false; + + const std::vector<BlastNode*>& children = node->children; + for (BlastNode* curNode : children) + { + if (eChunk == curNode->getType()) + { + BlastChunkNode* chunkNode = (BlastChunkNode*)curNode; + if (!isCompleteSupport(chunkNode)) + return false; + } + } + + return true; +} + +bool BlastTreeData::isOverlapSupportAsset(const BlastAsset* asset) +{ + BlastAssetNode* assetNode = _getAssetNode(asset); + return isOverlapSupportAsset(assetNode); +} + +bool isOverlapSupport(BlastChunkNode* node) +{ + if (node == nullptr) + return false; + + bool isParentSupport = node->isSupport(); + + const std::vector<BlastNode*>& children = node->children; + for (BlastNode* curNode : children) + { + if (eChunk == curNode->getType()) + { + BlastChunkNode* chunkNode = (BlastChunkNode*)curNode; + if (0 == chunkNode->children.size()) + { + if (isParentSupport && chunkNode->isSupport()) + return true; + } + + if (isParentSupport && isOverlapSupport(chunkNode)) + return true; + } + } + + return false; +} + +bool BlastTreeData::isOverlapSupportAsset(const BlastAssetNode* node) +{ + if (node == nullptr) + return false; + + const std::vector<BlastNode*>& children = node->children; + for (BlastNode* curNode : children) + { + if (eChunk == curNode->getType()) + { + BlastChunkNode* chunkNode = (BlastChunkNode*)curNode; + if (isOverlapSupport(chunkNode)) + return true; + } + } + + return false; +} + +BlastTreeData::BlastTreeData() +{ + +} + +void BlastTreeData::_addChunkNode(const BPPChunk& parentData, BPPAsset& asset, BlastChunkNode* parentNode, void* assetPtr) +{ + if (parentNode != nullptr) + { + std::vector<BPPBond*> bonds = BlastProject::ins().getBondsByChunk(asset, parentData.ID); + for (size_t i = 0; i < bonds.size(); ++i) + { + BPPBond* bond = bonds[i]; + BlastBondNode* bondNode = new BlastBondNode(bond->name.buf, *bond); + parentNode->children.push_back(bondNode); + bondNode->setParent(parentNode); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)bond, bondNode)); + } + + std::vector<BPPChunk*> childChunks = BlastProject::ins().getChildrenChunks(asset, parentData.ID); + + for (size_t i = 0; i < childChunks.size(); ++i) + { + BPPChunk& chunk = *(childChunks[i]); + BlastChunkNode* chunkNode = new BlastChunkNode(chunk.name.buf, chunk, assetPtr); + parentNode->children.push_back(chunkNode); + chunkNode->setParent(parentNode); + _blastProjectDataToNodeMap.insert(std::make_pair((void*)&chunk, chunkNode)); + _addChunkNode(chunk, asset, chunkNode, assetPtr); + } + } +} + +void freeChunkNode(BlastChunkNode* chunkNode) +{ + if (chunkNode == nullptr) + return; + + std::vector<BlastNode*>& children = chunkNode->children; + for (size_t i = 0; i < children.size(); ++i) + { + BlastNode* node = children[i]; + if (node->getType() == eChunk) + freeChunkNode(static_cast<BlastChunkNode*>(node)); + else + { + delete node; + node = nullptr; + } + } + + delete chunkNode; + chunkNode = nullptr; +} + +void BlastTreeData::_freeBlastNode() +{ + if (_composite) + { + size_t count = _composite->children.size(); + for (size_t i = 0; i < count; ++i) + { + delete _composite->children[i]; + } + delete _composite; + _composite = nullptr; + } + + size_t count = _assets.size(); + for (size_t i = 0; i < count; ++i) + { + std::vector<BlastNode*>& children = _assets[i]->children; + for (size_t j = 0; j < children.size(); ++j) + { + freeChunkNode(static_cast<BlastChunkNode*>(children[j])); + } + delete _assets[i]; + } + _assets.clear(); + + count = _projectiles.size(); + for (size_t i = 0; i < count; ++i) + { + delete _projectiles[i]; + } + _projectiles.clear(); + + count = _graphicsMeshes.size(); + for (size_t i = 0; i < count; ++i) + { + delete _graphicsMeshes[i]; + } + _graphicsMeshes.clear(); + + _blastProjectDataToNodeMap.clear(); +} + +BlastAssetNode* BlastTreeData::_getAssetNode(const BlastAsset* asset) +{ + std::map<BlastAsset*, AssetList::ModelAsset>& assetDescMap = SampleManager::ins()->getAssetDescMap(); + std::map<BlastAsset*, AssetList::ModelAsset>::iterator itrAssetDesc = assetDescMap.find(const_cast<BlastAsset*>(asset)); + + BlastAssetNode* foundAssetNode = nullptr; + for (BlastAssetNode* assetNode : _assets) + { + if (itrAssetDesc->second.name == assetNode->name) + { + foundAssetNode = assetNode; + break; + } + } + + return foundAssetNode; +} + +VisualButton::VisualButton(QWidget* parent, BlastNode* blastItem) + : QWidget(parent) + , _button(new QPushButton(parent)) + , _blastItem(blastItem) +{ + connect(_button, SIGNAL(toggled(bool)), this, SLOT(on_visualbility_toggled(bool))); + _button->setCheckable(true); + _button->setChecked(blastItem->getVisible()); + if (blastItem->getVisible()) + _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_visible.png")); + else + _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_notVisible.png")); + _button->setFixedSize(20, 20); + this->setLayoutDirection(Qt::RightToLeft); + this->setLayout(new QHBoxLayout); + this->layout()->setMargin(0); + this->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + this->layout()->addWidget(_button); +} + +void VisualButton::on_visualbility_toggled(bool checked) +{ + if (checked) + { + _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_visible.png")); + } + else + { + _button->setIcon(QIcon(":/AppMainWindow/images/visibilityToggle_notVisible.png")); + } + + if (_blastItem) + { + _blastItem->setVisible(checked); + } +} + +void VisualButton::_updateBlast(bool visible) +{ + EBlastNodeType type = _blastItem->getType(); + + switch (type) + { + case eBond: + ((BPPBond*)_blastItem->getData())->visible = visible; + break; + case eChunk: + ((BPPChunk*)_blastItem->getData())->visible = visible; + break; + case eAsset: + ((BPPAsset*)_blastItem->getData())->visible = visible; + break; + case eProjectile: + ((BPPBond*)_blastItem->getData())->visible = visible; + break; + case eGraphicsMesh: + ((BPPGraphicsMesh*)_blastItem->getData())->visible = visible; + break; + case eAssetInstance: + ((BPPAssetInstance*)_blastItem->getData())->visible = visible; + break; + case eLandmark: + ((BPPLandmark*)_blastItem->getData())->visible = visible; + break; + case eComposite: + ((BPPComposite*)_blastItem->getData())->visible = visible; + break; + default: + break; + } +} + +static BlastSceneTree* sBlastSceneTree = nullptr; +BlastSceneTree* BlastSceneTree::ins() +{ + return sBlastSceneTree; +} + +BlastSceneTree::BlastSceneTree(QWidget *parent) + : QDockWidget(parent) +{ + ui.setupUi(this); + _updateData = true; + sBlastSceneTree = this; + + ui.blastSceneTree->setStyleSheet("QTreeWidget::item{height:24px}"); + ui.blastSceneTree->setColumnWidth(0, 260); + ui.blastSceneTree->setColumnWidth(1, 20); + + ui.blastSceneTree->setContextMenuPolicy(Qt::CustomContextMenu); + + _treeChunkContextMenu = new QMenu(this); + _makeSupportAction = new QAction(tr("Make Support"), this); + _treeChunkContextMenu->addAction(_makeSupportAction); + connect(_makeSupportAction, SIGNAL(triggered()), this, SLOT(onMakeSupportMenuItemClicked())); + + _makeStaticSupportAction = new QAction(tr("Make Static Support"), this); + _treeChunkContextMenu->addAction(_makeStaticSupportAction); + connect(_makeStaticSupportAction, SIGNAL(triggered()), this, SLOT(onMakeStaticSupportMenuItemClicked())); + + _removeSupportAction = new QAction(tr("Remove Support"), this); + _treeChunkContextMenu->addAction(_removeSupportAction); + connect(_removeSupportAction, SIGNAL(triggered()), this, SLOT(onRemoveSupportMenuItemClicked())); + + _treeBondContextMenu = new QMenu(this); + _bondChunksAction = new QAction(tr("Bond Chunks"), this); + _treeBondContextMenu->addAction(_bondChunksAction); + connect(_bondChunksAction, SIGNAL(triggered()), this, SLOT(onBondChunksMenuItemClicked())); + + _bondChunksWithJointsAction = new QAction(tr("Bond Chunks With Joints"), this); + _treeBondContextMenu->addAction(_bondChunksWithJointsAction); + connect(_bondChunksWithJointsAction, SIGNAL(triggered()), this, SLOT(onBondChunksWithJointsMenuItemClicked())); + + _removeAllBondsAction = new QAction(tr("Remove All Bonds"), this); + _treeBondContextMenu->addAction(_removeAllBondsAction); + connect(_removeAllBondsAction, SIGNAL(triggered()), this, SLOT(onRemoveAllBondsMenuItemClicked())); +} + +BlastSceneTree::~BlastSceneTree() +{ + +} + +void BlastSceneTree::updateValues(bool updataData) +{ + if (updataData) + { + BlastTreeData::ins().update(); + } + + _updateTreeUIs(); +} + +void BlastSceneTree::dataSelected(std::vector<BlastNode*> selections) +{ + for (size_t i = 0; i < selections.size(); ++i) + { + _selectTreeItem(selections[i]); + } +} + +void BlastSceneTree::addObserver(ISceneObserver* observer) +{ + std::vector<ISceneObserver*>::iterator itr = std::find(_observers.begin(), _observers.end(), observer); + if (itr == _observers.end()) + { + _observers.push_back(observer); + } +} + +void BlastSceneTree::removeObserver(ISceneObserver* observer) +{ + std::vector<ISceneObserver*>::iterator itr = std::find(_observers.begin(), _observers.end(), observer); + _observers.erase(itr); +} + +void BlastSceneTree::updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible) +{ + BlastTreeData::ins().updateVisible(assetIndex, chunkIndex, visible); +} + +void BlastSceneTree::updateChunkItemSelection() +{ + _updateData = false; + + ui.blastSceneTree->clearSelection(); + BlastTreeData& treeData = BlastTreeData::ins(); + std::vector<BlastChunkNode*> chunkNodes; + + std::map<BlastAsset*, std::vector<uint32_t>> selectedChunks = SampleManager::ins()->getSelectedChunks(); + std::map<BlastAsset*, std::vector<uint32_t>>::iterator itrAssetSelectedChunks = selectedChunks.begin(); + for (; itrAssetSelectedChunks != selectedChunks.end(); ++itrAssetSelectedChunks) + { + std::vector<BlastChunkNode*> aseetNodes = treeData.getChunkNodeByBlastChunk(itrAssetSelectedChunks->first, itrAssetSelectedChunks->second); + chunkNodes.insert(chunkNodes.end(), aseetNodes.begin(), aseetNodes.end()); + } + + for (BlastChunkNode* node : chunkNodes) + { + _selectTreeItem(node); + } + + _updateData = true; +} + +void BlastSceneTree::makeSupport() +{ + std::vector<BlastChunkNode*> selectedChunkNodes; + QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); + for (int i = 0; i < selectedItems.size(); ++i) + { + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + + if (eChunk == itr.value()->getType()) + { + selectedChunkNodes.push_back((BlastChunkNode*)itr.value()); + } + } + + std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes); + for (size_t i = 0; i < topChunkNodes.size(); ++i) + { + BlastChunkNode* chunkNode = topChunkNodes[i]; + BlastTreeData::makeSupport(chunkNode); + } + + _updateChunkTreeItems(); +} + +void BlastSceneTree::makeStaticSupport() +{ + std::vector<BlastChunkNode*> selectedChunkNodes; + QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); + for (int i = 0; i < selectedItems.size(); ++i) + { + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + + if (eChunk == itr.value()->getType()) + { + selectedChunkNodes.push_back((BlastChunkNode*)itr.value()); + } + } + + std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes); + for (size_t i = 0; i < topChunkNodes.size(); ++i) + { + BlastChunkNode* chunkNode = topChunkNodes[i]; + BlastTreeData::makeStaticSupport(chunkNode); + } + + _updateChunkTreeItems(); +} + +void BlastSceneTree::removeSupport() +{ + std::vector<BlastChunkNode*> selectedChunkNodes; + QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); + for (int i = 0; i < selectedItems.size(); ++i) + { + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + + if (eChunk == itr.value()->getType()) + { + selectedChunkNodes.push_back((BlastChunkNode*)itr.value()); + } + } + + std::vector<BlastChunkNode*> topChunkNodes = BlastTreeData::getTopChunkNodes(selectedChunkNodes); + for (size_t i = 0; i < topChunkNodes.size(); ++i) + { + BlastChunkNode* chunkNode = topChunkNodes[i]; + BlastTreeData::removeSupport(chunkNode); + } + + _updateChunkTreeItems(); +} + +void BlastSceneTree::bondChunks() +{ + +} + +void BlastSceneTree::bondChunksWithJoints() +{ + +} + +void BlastSceneTree::removeAllBonds() +{ + +} + +void BlastSceneTree::on_btnAsset_clicked() +{ + QMessageBox::information(NULL, "test", "on_btnAsset_clicked"); +} + +void BlastSceneTree::on_assetComposite_clicked() +{ + QMessageBox::information(NULL, "test", "on_assetComposite_clicked"); +} + +void BlastSceneTree::on_btnChunk_clicked() +{ + QMessageBox::information(NULL, "test", "on_btnChunk_clicked"); +} + +void BlastSceneTree::on_btnBond_clicked() +{ + QMessageBox::information(NULL, "test", "on_btnBond_clicked"); +} + +void BlastSceneTree::on_btnProjectile_clicked() +{ + QMessageBox::information(NULL, "test", "on_btnProjectile_clicked"); +} + +void BlastSceneTree::on_blastSceneTree_customContextMenuRequested(const QPoint &pos) +{ + QList<QTreeWidgetItem*> items = ui.blastSceneTree->selectedItems(); + + if (items.count() == 1) + { + QTreeWidgetItem* curItem = items.at(0); + + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(curItem); + if (itr != _treeItemDataMap.end()) + { + if (eChunk == itr.value()->getType() || eBond == itr.value()->getType()) + { + _treeChunkContextMenu->exec(QCursor::pos()); + } + } + } + else if (items.count() > 1) + { + bool allSupportChunk = true; + for (int i = 0; i < items.count(); ++i) + { + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(items.at(i)); + if (itr != _treeItemDataMap.end()) + { + if (eChunk != itr.value()->getType()) + { + allSupportChunk = false; + break; + } + } + } + + if (allSupportChunk) + { + _treeBondContextMenu->exec(QCursor::pos()); + } + } + +} + +void BlastSceneTree::on_blastSceneTree_itemSelectionChanged() +{ + if (!_updateData) + return; + + SampleManager::ins()->clearChunksSelected(); + + QList<QTreeWidgetItem*> selectedItems = ui.blastSceneTree->selectedItems(); + std::vector<BlastNode*> nodes; + for (int i = 0; i < selectedItems.count(); ++i) + { + QMap<QTreeWidgetItem*, BlastNode*>::iterator itr = _treeItemDataMap.find(selectedItems.at(i)); + if (itr != _treeItemDataMap.end()) + { + nodes.push_back(itr.value()); + + BlastNode* node = itr.value(); + if (eChunk == node->getType()) + { + ((BlastChunkNode*)node)->setSelected(true); + } + else if (eAssetInstance == node->getType()) + { + ((BlastAssetInstanceNode*)node)->setSelected(true); + } + } + } + + for (size_t i = 0; i < _observers.size(); ++i) + { + _observers[i]->dataSelected(nodes); + } +} + +void BlastSceneTree::onMakeSupportMenuItemClicked() +{ + makeSupport(); +} + +void BlastSceneTree::onMakeStaticSupportMenuItemClicked() +{ + makeStaticSupport(); +} + +void BlastSceneTree::onRemoveSupportMenuItemClicked() +{ + removeSupport(); +} + +void BlastSceneTree::onBondChunksMenuItemClicked() +{ + bondChunks(); +} + +void BlastSceneTree::onBondChunksWithJointsMenuItemClicked() +{ + bondChunksWithJoints(); +} + +void BlastSceneTree::onRemoveAllBondsMenuItemClicked() +{ + removeAllBonds(); +} + +void BlastSceneTree::_updateTreeUIs() +{ + ui.blastSceneTree->clear(); + _treeItemDataMap.clear(); + _treeDataItemMap.clear(); + + BlastCompositeNode* compositeNode = BlastTreeData::ins().getCompsiteNode(); + if (compositeNode != nullptr) + { + QTreeWidgetItem* compositeTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree); + compositeTreeWidgetItem->setText(0, compositeNode->name.c_str()); + compositeTreeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/AssetComposite.png")); + VisualButton* btn = new VisualButton(this, compositeNode); + ui.blastSceneTree->setItemWidget(compositeTreeWidgetItem, 1, btn); + _treeItemDataMap.insert(compositeTreeWidgetItem, compositeNode); + _treeDataItemMap.insert(compositeNode, compositeTreeWidgetItem); + + size_t count = compositeNode->children.size(); + for (size_t i = 0; i < count; ++i) + { + BlastNode* assetInstanceNode = compositeNode->children[i]; + QTreeWidgetItem* assetInstanceWidgetItem = new QTreeWidgetItem(compositeTreeWidgetItem); + assetInstanceWidgetItem->setText(0, assetInstanceNode->name.c_str()); + if (assetInstanceNode->getType() == eAssetInstance) + assetInstanceWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Asset.png")); + VisualButton* btn = new VisualButton(this, assetInstanceNode); + ui.blastSceneTree->setItemWidget(assetInstanceWidgetItem, 1, btn); + _treeItemDataMap.insert(assetInstanceWidgetItem, assetInstanceNode); + _treeDataItemMap.insert(assetInstanceNode, assetInstanceWidgetItem); + } + } + + std::vector<BlastAssetNode*>& assets = BlastTreeData::ins().getAssetNodes(); + size_t count = assets.size(); + for (size_t i = 0; i < count; ++i) + { + BlastAssetNode* assetNode = assets[i]; + + QTreeWidgetItem* assetTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree); + assetTreeWidgetItem->setText(0, assetNode->name.c_str()); + assetTreeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Asset.png")); + VisualButton* btn = new VisualButton(this, assetNode); + ui.blastSceneTree->setItemWidget(assetTreeWidgetItem, 1, btn); + _treeItemDataMap.insert(assetTreeWidgetItem, assetNode); + _treeDataItemMap.insert(assetNode, assetTreeWidgetItem); + + _addChunkUI(assetNode, assetTreeWidgetItem); + } + + std::vector<BlastProjectileNode*>& projectiles = BlastTreeData::ins().getProjectileNodes(); + count = projectiles.size(); + for (int i = 0; i < count; ++i) + { + BlastProjectileNode* projectileNode = projectiles[i]; + + QTreeWidgetItem* projectileTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree); + projectileTreeWidgetItem->setText(0, projectileNode->name.c_str()); + projectileTreeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Projectile.png")); + VisualButton* btn = new VisualButton(this, projectileNode); + ui.blastSceneTree->setItemWidget(projectileTreeWidgetItem, 1, btn); + _treeItemDataMap.insert(projectileTreeWidgetItem, projectileNode); + _treeDataItemMap.insert(projectileNode, projectileTreeWidgetItem); + } + + std::vector<BlastGraphicsMeshNode*>& graphicsMeshes = BlastTreeData::ins().getGraphicsMeshNodes(); + count = graphicsMeshes.size(); + for (int i = 0; i < count; ++i) + { + BlastGraphicsMeshNode* graphicsMesheNode = graphicsMeshes[i]; + + QTreeWidgetItem* graphicsMesheTreeWidgetItem = new QTreeWidgetItem(ui.blastSceneTree); + graphicsMesheTreeWidgetItem->setText(0, graphicsMesheNode->name.c_str()); + VisualButton* btn = new VisualButton(this, graphicsMesheNode); + ui.blastSceneTree->setItemWidget(graphicsMesheTreeWidgetItem, 1, btn); + _treeItemDataMap.insert(graphicsMesheTreeWidgetItem, graphicsMesheNode); + _treeDataItemMap.insert(graphicsMesheNode, graphicsMesheTreeWidgetItem); + } + + //for (int j = 0; j < ui.blastSceneTree->topLevelItemCount(); ++j) + //{ + // QTreeWidgetItem* topLevelItem = ui.blastSceneTree->topLevelItem(j); + // ui.blastSceneTree->expandItem(topLevelItem); + //} + ui.blastSceneTree->expandAll(); +} + +void BlastSceneTree::_addChunkUI(const BlastNode* parentNode, QTreeWidgetItem* parentTreeItem) +{ + if (parentNode != nullptr && parentTreeItem != nullptr) + { + for (size_t i = 0; i < parentNode->children.size(); ++i) + { + BlastNode* node = parentNode->children[i]; + if (node == nullptr) + continue; + + QTreeWidgetItem* treeWidgetItem = nullptr; + + if (node->getType() == eChunk) + { + BlastChunkNode* chunk = static_cast<BlastChunkNode*>(node); + treeWidgetItem = new QTreeWidgetItem(parentTreeItem); + treeWidgetItem->setText(0, chunk->name.c_str()); + if (chunk->isSupport()) + { + treeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png")); + } + else + { + treeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png")); + } + + _addChunkUI(chunk, treeWidgetItem); + } + else if (node->getType() == eBond) + { + BlastBondNode* bond = static_cast<BlastBondNode*>(node); + treeWidgetItem = new QTreeWidgetItem(parentTreeItem); + treeWidgetItem->setIcon(0, QIcon(":/AppMainWindow/images/Bond.png")); + treeWidgetItem->setText(0, bond->name.c_str()); + } + + if (treeWidgetItem == nullptr) + continue; + VisualButton* btn = new VisualButton(this, node); + ui.blastSceneTree->setItemWidget(treeWidgetItem, 1, btn); + _treeItemDataMap.insert(treeWidgetItem, node); + _treeDataItemMap.insert(node, treeWidgetItem); + } + } +} + +void BlastSceneTree::_updateChunkTreeItemAndMenu(BPPChunk* chunk, QTreeWidgetItem* chunkItem) +{ + assert(chunk != nullptr); + + _removeSupportAction->setEnabled(true); + _makeSupportAction->setEnabled(true); + _makeStaticSupportAction->setEnabled(true); + + if (!chunk->support && !chunk->staticFlag) + { + _removeSupportAction->setEnabled(false); + chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png")); + } + else if (chunk->support && !chunk->staticFlag) + { + _makeSupportAction->setEnabled(false); + chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png")); + } + else if (chunk->support && chunk->staticFlag) + { + _makeStaticSupportAction->setEnabled(false); + chunkItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Static.png")); + } +} + +void BlastSceneTree::_updateChunkTreeItems() +{ + for (QMap<BlastNode*, QTreeWidgetItem*>::iterator itr = _treeDataItemMap.begin(); itr != _treeDataItemMap.end(); ++itr) + { + BlastNode* node = itr.key(); + QTreeWidgetItem* treeItem = itr.value(); + if (eChunk == node->getType()) + { + BPPChunk* chunk = static_cast<BPPChunk*>(node->getData()); + if (!chunk->support && !chunk->staticFlag) + { + treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Unsupport_Unstatic.png")); + } + else if (chunk->support && !chunk->staticFlag) + { + treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Unstatic.png")); + } + else if (chunk->support && chunk->staticFlag) + { + treeItem->setIcon(0, QIcon(":/AppMainWindow/images/Chunk_Support_Static.png")); + } + } + } +} + +void BlastSceneTree::_selectTreeItem(BlastNode* node) +{ + QMap<BlastNode*, QTreeWidgetItem*>::iterator itr = _treeDataItemMap.find(node); + if (itr != _treeDataItemMap.end()) + { + ui.blastSceneTree->setItemSelected(itr.value(), true); + } +} + +//void BlastSceneTree::_createTestData() +//{ +// BPPBlast& blast = BlastProject::ins().getParams().blast; +// +// // compoistie +// { +// BPPComposite& composite = blast.composite; +// composite.composite.buf = nullptr; +// composite.visible = true; +// +// copy(composite.composite, "BlastComposite"); +// +// // asset instance array +// { +// BPPAssetInstanceArray& instanceArray = composite.blastAssetInstances; +// instanceArray.buf = new BPPAssetInstance[4]; +// instanceArray.arraySizes[0] = 4; +// instanceArray.buf[0].name.buf = nullptr; +// instanceArray.buf[1].name.buf = nullptr; +// instanceArray.buf[2].name.buf = nullptr; +// instanceArray.buf[3].name.buf = nullptr; +// instanceArray.buf[0].source.buf = nullptr; +// instanceArray.buf[1].source.buf = nullptr; +// instanceArray.buf[2].source.buf = nullptr; +// instanceArray.buf[3].source.buf = nullptr; +// +// copy(instanceArray.buf[0].name, "BlastAsset_instance1"); +// instanceArray.buf[0].visible = true; +// +// copy(instanceArray.buf[1].name, "BlastAsset_instance2"); +// instanceArray.buf[1].visible = true; +// +// copy(instanceArray.buf[2].name, "BlastAsset1_instance1"); +// instanceArray.buf[2].visible = true; +// +// copy(instanceArray.buf[3].name, "BlastAsset1_instance2"); +// instanceArray.buf[3].visible = true; +// } +// +// // landmark array +// { +// BPPLandmarkArray& landmarkArray = composite.landmarks; +// landmarkArray.buf = new BPPLandmark[2]; +// landmarkArray.arraySizes[0] = 2; +// landmarkArray.buf[0].name.buf = nullptr; +// landmarkArray.buf[1].name.buf = nullptr; +// +// copy(landmarkArray.buf[0].name, "Landmark_1"); +// copy(landmarkArray.buf[1].name, "Landmark_2"); +// } +// } +// +// // asset array +// { +// BPPAssetArray& assetArray = blast.blastAssets; +// assetArray.buf = new BPPAsset[2]; +// assetArray.arraySizes[0] = 2; +// +// // asset 0 +// { +// BPPAsset& asset = assetArray.buf[0]; +// asset.path.buf = nullptr; +// asset.activePreset.buf = nullptr; +// asset.bonds.buf = nullptr; +// asset.chunks.buf = nullptr; +// +// copy(asset.path, "c:/temp/BlastAsset.asset"); +// +// // chunks +// { +// asset.chunks.buf = new BPPChunk[10]; +// asset.chunks.arraySizes[0] = 10; +// for (int i = 0; i < 10; ++i) +// { +// asset.chunks.buf[i].name.buf = nullptr; +// asset.chunks.buf[i].visible = true; +// asset.chunks.buf[i].staticFlag = false; +// } +// +// copy(asset.chunks.buf[0].name, "Chunk_L0_00"); +// asset.chunks.buf[0].ID = 0; +// asset.chunks.buf[0].parentID = -1; +// asset.chunks.buf[0].support = false; +// +// copy(asset.chunks.buf[1].name, "Chunk_L0_01"); +// asset.chunks.buf[1].ID = 1; +// asset.chunks.buf[1].parentID = -1; +// asset.chunks.buf[1].support = false; +// +// copy(asset.chunks.buf[2].name, "Chunk_L1_02"); +// asset.chunks.buf[2].ID = 2; +// asset.chunks.buf[2].parentID = 0; +// asset.chunks.buf[2].support = false; +// +// copy(asset.chunks.buf[3].name, "Chunk_L1_03"); +// asset.chunks.buf[3].ID = 3; +// asset.chunks.buf[3].parentID = 0; +// asset.chunks.buf[3].support = false; +// +// copy(asset.chunks.buf[4].name, "Chunk_L1_04"); +// asset.chunks.buf[4].ID = 4; +// asset.chunks.buf[4].parentID = 1; +// asset.chunks.buf[4].support = false; +// +// copy(asset.chunks.buf[5].name, "Chunk_L1_05"); +// asset.chunks.buf[5].ID = 5; +// asset.chunks.buf[5].parentID = 1; +// asset.chunks.buf[5].support = false; +// +// copy(asset.chunks.buf[6].name, "Chunk_L2_06"); +// asset.chunks.buf[6].ID = 6; +// asset.chunks.buf[6].parentID = 2; +// asset.chunks.buf[6].support = true; +// +// copy(asset.chunks.buf[7].name, "Chunk_L2_07"); +// asset.chunks.buf[7].ID = 7; +// asset.chunks.buf[7].parentID = 2; +// asset.chunks.buf[7].support = true; +// +// copy(asset.chunks.buf[8].name, "Chunk_L2_08"); +// asset.chunks.buf[8].ID = 8; +// asset.chunks.buf[8].parentID = 3; +// asset.chunks.buf[8].support = true; +// +// copy(asset.chunks.buf[9].name, "Chunk_L2_09"); +// asset.chunks.buf[9].ID = 9; +// asset.chunks.buf[9].parentID = 3; +// asset.chunks.buf[9].support = true; +// } +// +// // bonds +// { +// asset.bonds.buf = new BPPBond[4]; +// asset.bonds.arraySizes[0] = 4; +// for (int i = 0; i < 4; ++i) +// { +// asset.bonds.buf[i].name.buf = nullptr; +// asset.bonds.buf[i].visible = true; +// asset.bonds.buf[i].support.healthMask.buf = nullptr; +// } +// +// copy(asset.bonds.buf[0].name, "Chunk_L2_08"); +// asset.bonds.buf[0].fromChunk = 6; +// asset.bonds.buf[0].toChunk = 8; +// +// copy(asset.bonds.buf[1].name, "Chunk_L2_06"); +// asset.bonds.buf[1].fromChunk = 6; +// asset.bonds.buf[1].toChunk = 8; +// +// copy(asset.bonds.buf[2].name, "Chunk_L2_09"); +// asset.bonds.buf[2].fromChunk = 7; +// asset.bonds.buf[2].toChunk = 9; +// +// copy(asset.bonds.buf[3].name, "Chunk_L2_07"); +// asset.bonds.buf[3].fromChunk = 7; +// asset.bonds.buf[3].toChunk = 9; +// } +// } +// +// // asset 1 +// { +// BPPAsset& asset = assetArray.buf[1]; +// asset.path.buf = nullptr; +// asset.activePreset.buf = nullptr; +// asset.bonds.buf = nullptr; +// asset.chunks.buf = nullptr; +// +// copy(asset.path, "c:/temp/BlastAsset1.asset"); +// { +// asset.chunks.buf = new BPPChunk[10]; +// asset.chunks.arraySizes[0] = 10; +// for (int i = 0; i < 10; ++i) +// { +// asset.chunks.buf[i].name.buf = nullptr; +// asset.chunks.buf[i].visible = true; +// } +// +// copy(asset.chunks.buf[0].name, "Chunk_L0_00"); +// asset.chunks.buf[0].ID = 0; +// asset.chunks.buf[0].parentID = -1; +// asset.chunks.buf[0].support = false; +// +// copy(asset.chunks.buf[1].name, "Chunk_L0_01"); +// asset.chunks.buf[1].ID = 1; +// asset.chunks.buf[1].parentID = -1; +// asset.chunks.buf[1].support = false; +// +// copy(asset.chunks.buf[2].name, "Chunk_L1_02"); +// asset.chunks.buf[2].ID = 2; +// asset.chunks.buf[2].parentID = 0; +// asset.chunks.buf[2].support = false; +// +// copy(asset.chunks.buf[3].name, "Chunk_L1_03"); +// asset.chunks.buf[3].ID = 3; +// asset.chunks.buf[3].parentID = 0; +// asset.chunks.buf[3].support = false; +// +// copy(asset.chunks.buf[4].name, "Chunk_L1_04"); +// asset.chunks.buf[4].ID = 4; +// asset.chunks.buf[4].parentID = 1; +// asset.chunks.buf[4].support = false; +// +// copy(asset.chunks.buf[5].name, "Chunk_L1_05"); +// asset.chunks.buf[5].ID = 5; +// asset.chunks.buf[5].parentID = 1; +// asset.chunks.buf[5].support = false; +// +// copy(asset.chunks.buf[6].name, "Chunk_L2_06"); +// asset.chunks.buf[6].ID = 6; +// asset.chunks.buf[6].parentID = 2; +// asset.chunks.buf[6].support = true; +// +// copy(asset.chunks.buf[7].name, "Chunk_L2_07"); +// asset.chunks.buf[7].ID = 7; +// asset.chunks.buf[7].parentID = 2; +// asset.chunks.buf[7].support = true; +// +// copy(asset.chunks.buf[8].name, "Chunk_L2_08"); +// asset.chunks.buf[8].ID = 8; +// asset.chunks.buf[8].parentID = 3; +// asset.chunks.buf[8].support = true; +// +// copy(asset.chunks.buf[9].name, "Chunk_L2_09"); +// asset.chunks.buf[9].ID = 9; +// asset.chunks.buf[9].parentID = 3; +// asset.chunks.buf[9].support = true; +// } +// } +// } +// +// // projectile +// { +// BPPProjectileArray& projectileArray = blast.projectiles; +// projectileArray.buf = new BPPProjectile[1]; +// projectileArray.arraySizes[0] = 1; +// projectileArray.buf[0].name.buf = nullptr; +// copy(projectileArray.buf[0].name, "Projectile"); +// projectileArray.buf[0].visible = true; +// } +// +// // graphics meshes +// { +// BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes; +// graphicsMeshArray.buf = new BPPGraphicsMesh[3]; +// graphicsMeshArray.arraySizes[0] = 3; +// graphicsMeshArray.buf[0].name.buf = nullptr; +// copy(graphicsMeshArray.buf[0].name, "SurfaceMesh1"); +// graphicsMeshArray.buf[0].visible = true; +// +// graphicsMeshArray.buf[1].name.buf = nullptr; +// copy(graphicsMeshArray.buf[1].name, "SurfaceMesh2"); +// graphicsMeshArray.buf[1].visible = true; +// +// graphicsMeshArray.buf[2].name.buf = nullptr; +// copy(graphicsMeshArray.buf[2].name, "DisplayMesh1"); +// graphicsMeshArray.buf[2].visible = true; +// } +//} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h new file mode 100644 index 0000000..540f420 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastSceneTree.h @@ -0,0 +1,284 @@ +#ifndef BLASTSCENETREE_H +#define BLASTSCENETREE_H + +#include <QtWidgets/QDockWidget> +#include "ui_BlastSceneTree.h" +#include "ProjectParams.h" +#include <vector> +#include <string> +#include <QtCore/QMap> + +class QTreeWidgetItem; +class BlastAsset; + +enum EBlastNodeType +{ + eBond, + eChunk, + eAsset, + eProjectile, + eGraphicsMesh, + eAssetInstance, + eLandmark, + eComposite, +}; + +class BlastNode +{ +public: + BlastNode(const std::string& inName, void* inData) + : name(inName) + , _data(inData) + { + } + + void* getData() { return _data; } + void setParent(BlastNode* parent) { _parent = parent; } + BlastNode* getParent() { return _parent; } + virtual EBlastNodeType getType() = 0; + virtual bool getVisible() = 0; + virtual void setVisible(bool val) = 0; + + std::string name; + std::vector<BlastNode*> children; + +protected: + void* _data; + BlastNode* _parent; +}; + +class BlastBondNode : public BlastNode +{ +public: + BlastBondNode(const std::string& inName, BPPBond& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eBond; } + virtual bool getVisible() { return ((BPPBond*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPBond*)_data)->visible = val; } + +private: + std::vector<BlastNode*> children; +}; + +class BlastChunkNode : public BlastNode +{ +public: + BlastChunkNode(const std::string& inName, BPPChunk& inData, void* assetPtr) + : BlastNode(inName, &inData) + { + _assetPtr = assetPtr; + } + virtual EBlastNodeType getType() { return eChunk; } + virtual bool getVisible() { return ((BPPChunk*)_data)->visible; } + virtual void setVisible(bool val);// { ((BPPChunk*)_data)->visible = val; } + void setSelected(bool val); + bool isSupport() { return ((BPPChunk*)_data)->support; } + void* _assetPtr; +}; + +class BlastAssetNode : public BlastNode +{ +public: + BlastAssetNode(const std::string& inName, BPPAsset& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eAsset; } + virtual bool getVisible() { return ((BPPAsset*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPAsset*)_data)->visible = val; } +}; + +class BlastProjectileNode : public BlastNode +{ +public: + BlastProjectileNode(const std::string& inName, BPPProjectile& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eProjectile; } + virtual bool getVisible() { return ((BPPProjectile*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPProjectile*)_data)->visible = val; } +}; + +class BlastGraphicsMeshNode : public BlastNode +{ +public: + BlastGraphicsMeshNode(const std::string& inName, BPPGraphicsMesh& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eGraphicsMesh; } + virtual bool getVisible() { return ((BPPGraphicsMesh*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPGraphicsMesh*)_data)->visible = val; } +}; + +class BlastAssetInstanceNode : public BlastNode +{ +public: + BlastAssetInstanceNode(const std::string& inName, BPPAssetInstance& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eAssetInstance; } + virtual bool getVisible() { return ((BPPAssetInstance*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPAssetInstance*)_data)->visible = val; } + void setSelected(bool val); +}; + +class BlastLandmarkNode : public BlastNode +{ +public: + BlastLandmarkNode(const std::string& inName, BPPLandmark& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eLandmark; } + virtual bool getVisible() { return ((BPPLandmark*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPLandmark*)_data)->visible = val; } +}; + +class BlastCompositeNode : public BlastNode +{ +public: + BlastCompositeNode(const std::string& inName, BPPComposite& inData) + : BlastNode(inName, &inData) + { + } + virtual EBlastNodeType getType() { return eComposite; } + virtual bool getVisible() { return ((BPPComposite*)_data)->visible; } + virtual void setVisible(bool val) { ((BPPComposite*)_data)->visible = val; } +}; + +class BlastTreeData +{ +public: + static BlastTreeData& ins(); + static bool isChild(BlastChunkNode* parent, BlastChunkNode* child); + static std::vector<BlastChunkNode*> getTopChunkNodes(std::vector<BlastChunkNode*>& nodes); + static bool isRoot(BlastChunkNode* node); + static bool isLeaf(BlastChunkNode* node); + static void makeSupport(BlastChunkNode* node); + static void makeStaticSupport(BlastChunkNode* node); + static void removeSupport(BlastChunkNode* node); + + BlastNode* getBlastNodeByProjectData(void* blastProjectData); + BlastCompositeNode* getCompsiteNode() { return _composite; } + std::vector<BlastAssetNode*>& getAssetNodes() { return _assets; } + std::vector<BlastProjectileNode*>& getProjectileNodes() { return _projectiles; } + std::vector<BlastGraphicsMeshNode*>& getGraphicsMeshNodes() { return _graphicsMeshes; } + std::vector<BlastChunkNode*> getChunkNodeByBlastChunk(const BlastAsset* asset, const std::vector<uint32_t>& chunkIndexes); + bool isCompleteSupportAsset(const BlastAsset* asset); + bool isCompleteSupportAsset(const BlastAssetNode* node); + bool isOverlapSupportAsset(const BlastAsset* asset); + bool isOverlapSupportAsset(const BlastAssetNode* node); + void update(); + + void updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible); + +private: + BlastTreeData(); + void _addChunkNode(const BPPChunk& parentData, BPPAsset& asset, BlastChunkNode* parentNode, void* assetPtr); + void _freeBlastNode(); + BlastAssetNode* _getAssetNode(const BlastAsset* asset); + +private: + BlastCompositeNode* _composite; + std::vector<BlastAssetNode*> _assets; + std::vector<BlastProjectileNode*> _projectiles; + std::vector<BlastGraphicsMeshNode*> _graphicsMeshes; + std::map<void*, BlastNode*> _blastProjectDataToNodeMap; +}; + +class ISceneObserver +{ +public: + virtual void dataSelected(std::vector<BlastNode*> selections) = 0; +}; + +class VisualButton : public QWidget +{ + Q_OBJECT +public: + VisualButton(QWidget* parent, BlastNode* blastItem); + +protected slots: + void on_visualbility_toggled(bool checked); +private: + void _updateBlast(bool visible); + +private: + QPushButton* _button; + BlastNode* _blastItem; +}; + +class BlastSceneTree : public QDockWidget, public ISceneObserver +{ + Q_OBJECT + +public: + static BlastSceneTree* ins(); + + BlastSceneTree(QWidget *parent = 0); + ~BlastSceneTree(); + + void updateValues(bool updataData = true); + + virtual void dataSelected(std::vector<BlastNode*> selections); + + void addObserver(ISceneObserver* observer); + void removeObserver(ISceneObserver* observer); + + void updateVisible(uint32_t assetIndex, uint32_t chunkIndex, bool visible); + void updateChunkItemSelection(); + + void makeSupport(); + void makeStaticSupport(); + void removeSupport(); + void bondChunks(); + void bondChunksWithJoints(); + void removeAllBonds(); + +protected slots: + void on_btnAsset_clicked(); + void on_assetComposite_clicked(); + void on_btnChunk_clicked(); + void on_btnBond_clicked(); + void on_btnProjectile_clicked(); + void on_blastSceneTree_customContextMenuRequested(const QPoint &pos); + void on_blastSceneTree_itemSelectionChanged(); + void onMakeSupportMenuItemClicked(); + void onMakeStaticSupportMenuItemClicked(); + void onRemoveSupportMenuItemClicked(); + void onBondChunksMenuItemClicked(); + void onBondChunksWithJointsMenuItemClicked(); + void onRemoveAllBondsMenuItemClicked(); + +private: + void _updateTreeUIs(); + void _addChunkUI(const BlastNode* parentNode, QTreeWidgetItem* parentTreeItem); + void _updateChunkTreeItemAndMenu(BPPChunk* chunk, QTreeWidgetItem* chunkItem); + void _updateChunkTreeItems(); + + void _selectTreeItem(BlastNode* node); + + //void _createTestData(); + +private: + Ui::BlastSceneTree ui; + QMap<QTreeWidgetItem*, BlastNode*> _treeItemDataMap; + QMap<BlastNode*, QTreeWidgetItem*> _treeDataItemMap; + QMenu* _treeChunkContextMenu; + QMenu* _treeBondContextMenu; + QAction* _makeSupportAction; + QAction* _makeStaticSupportAction; + QAction* _removeSupportAction; + QAction* _bondChunksAction; + QAction* _bondChunksWithJointsAction; + QAction* _removeAllBondsAction; + std::vector<ISceneObserver*> _observers; + bool _updateData; +}; + +#endif // BLASTSCENETREE_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp new file mode 100644 index 0000000..98b5646 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.cpp @@ -0,0 +1,523 @@ +#include "BlastToolbar.h" + +#include <QtWidgets/QFileDialog> +#include "AppMainWindow.h" +#include "PhysXController.h" +#include "QtUtil.h" + +BlastToolbar::BlastToolbar(QWidget* parent) + : QDockWidget(parent) +{ + // to hide the title bar completely must replace the default widget with a generic one + QWidget* titleWidget = new QWidget(this); + this->setTitleBarWidget(titleWidget); + this->setObjectName(QString::fromUtf8("AppMainToolbar")); + this->setMinimumSize(QSize(0, 50)); + this->setMaximumSize(QSize(16777215, 80)); + + if (this->objectName().isEmpty()) + this->setObjectName(QStringLiteral("AppMainToolbar")); + this->resize(1330, 54); + + QWidget* widget = new QWidget(); + hLayout = new QHBoxLayout(widget); + hLayout->setObjectName(QStringLiteral("hLayout")); + hLayout->setContentsMargins(-1, 3, -1, 3); + + QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + + btnOpenProject = new QPushButton(widget); + setStyledToolTip(btnOpenProject, "Open Blast Asset"); + const QFont& font = btnOpenProject->font(); + QFont fontCopy(font); + fontCopy.setPixelSize(9); + + btnOpenProject->setObjectName(QStringLiteral("btnOpenProject")); + sizePolicy1.setHeightForWidth(btnOpenProject->sizePolicy().hasHeightForWidth()); + btnOpenProject->setSizePolicy(sizePolicy1); + btnOpenProject->setMinimumSize(QSize(40, 40)); + btnOpenProject->setMaximumSize(QSize(40, 40)); + btnOpenProject->setText(QApplication::translate("AppMainToolbar", "Open", 0)); + hLayout->addWidget(btnOpenProject); + + btnSaveProject = new QPushButton(widget); + setStyledToolTip(btnSaveProject, "Not Implement"); + btnSaveProject->setObjectName(QStringLiteral("btnSaveProject")); + sizePolicy1.setHeightForWidth(btnOpenProject->sizePolicy().hasHeightForWidth()); + btnSaveProject->setSizePolicy(sizePolicy1); + btnSaveProject->setMinimumSize(QSize(40, 40)); + btnSaveProject->setMaximumSize(QSize(40, 40)); + btnSaveProject->setText(QApplication::translate("AppMainToolbar", "Save\nAll", 0)); + hLayout->addWidget(btnSaveProject); + + btnExportAssets = new QPushButton(widget); + setStyledToolTip(btnExportAssets, "Not Implement"); + btnExportAssets->setObjectName(QStringLiteral("btnExportAssets")); + sizePolicy1.setHeightForWidth(btnExportAssets->sizePolicy().hasHeightForWidth()); + btnExportAssets->setSizePolicy(sizePolicy1); + btnExportAssets->setMinimumSize(QSize(40, 40)); + btnExportAssets->setMaximumSize(QSize(40, 40)); + btnExportAssets->setText(QApplication::translate("AppMainToolbar", "Export", 0)); + hLayout->addWidget(btnExportAssets); + + vLayoutExport = new QVBoxLayout(); + vLayoutExport->setObjectName(QStringLiteral("vLayoutExport")); + + hLayoutExport = new QHBoxLayout(); + hLayoutExport->setObjectName(QStringLiteral("hLayoutExport")); + + lExportFilepath = new QLabel(widget); + lExportFilepath->setObjectName(QStringLiteral("lExportFilepath")); + lExportFilepath->setText(QApplication::translate("AppMainToolbar", "Export Path", 0)); + hLayoutExport->addWidget(lExportFilepath); + + btnExportFilepath = new QPushButton(widget); + btnExportFilepath->setObjectName(QStringLiteral("btnExportFilepath")); + sizePolicy1.setHeightForWidth(btnExportFilepath->sizePolicy().hasHeightForWidth()); + btnExportFilepath->setSizePolicy(sizePolicy1); + btnExportFilepath->setMinimumSize(QSize(14, 14)); + btnExportFilepath->setMaximumSize(QSize(14, 14)); + btnExportFilepath->setText(QApplication::translate("AppMainToolbar", "", 0)); + btnExportFilepath->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnExportFilepath.png")); + btnExportFilepath->setIconSize(QSize(14, 14)); + hLayoutExport->addWidget(btnExportFilepath); + + vLayoutExport->addLayout(hLayoutExport); + + leExportFilepath = new QLineEdit(widget); + leExportFilepath->setObjectName(QStringLiteral("leExportFilepath")); + sizePolicy1.setHeightForWidth(leExportFilepath->sizePolicy().hasHeightForWidth()); + leExportFilepath->setSizePolicy(sizePolicy1); + leExportFilepath->setMinimumSize(QSize(150, 20)); + leExportFilepath->setMaximumSize(QSize(150, 20)); + leExportFilepath->setText(QApplication::translate("AppMainToolbar", "", 0)); + vLayoutExport->addWidget(leExportFilepath); + + hLayout->addLayout(vLayoutExport); + + fSeparate = new QFrame(widget); + fSeparate->setObjectName(QStringLiteral("fSeparate")); + fSeparate->setFrameShape(QFrame::VLine); + fSeparate->setFrameShadow(QFrame::Sunken); + hLayout->addWidget(fSeparate); + + vLayoutDepthCoverage = new QVBoxLayout(); + vLayoutDepthCoverage->setObjectName(QStringLiteral("vLayoutDepthCoverage")); + + hlDepthPreview = new QHBoxLayout(); + hlDepthPreview->setObjectName(QStringLiteral("hlDepthPreview")); + + lbDepthPreview = new QLabel(widget); + lbDepthPreview->setObjectName(QStringLiteral("lbDepthPreview")); + lbDepthPreview->setText(QApplication::translate("AppMainToolbar", "Depth Preview", 0)); + hlDepthPreview->addWidget(lbDepthPreview); + + ssbiDepthPreview = new SlideSpinBoxInt(widget); + ssbiDepthPreview->setObjectName(QStringLiteral("ssbiDepthPreview")); + QSizePolicy sizePolicy2(QSizePolicy::Minimum, QSizePolicy::Fixed); + sizePolicy2.setHorizontalStretch(0); + sizePolicy2.setVerticalStretch(0); + sizePolicy2.setHeightForWidth(ssbiDepthPreview->sizePolicy().hasHeightForWidth()); + ssbiDepthPreview->setSizePolicy(sizePolicy2); + ssbiDepthPreview->setMinimumSize(QSize(40, 20)); + ssbiDepthPreview->setMaximumSize(QSize(100, 16777215)); + hlDepthPreview->addWidget(ssbiDepthPreview); + + vLayoutDepthCoverage->addLayout(hlDepthPreview); + + hlExactCoverage = new QHBoxLayout(); + hlExactCoverage->setObjectName(QStringLiteral("hlExactCoverage")); + + lbDepthPreview = new QLabel(widget); + lbDepthPreview->setObjectName(QStringLiteral("hlExactCoverage")); + lbDepthPreview->setText(QApplication::translate("AppMainToolbar", "Exact Coverage", 0)); + hlExactCoverage->addWidget(lbDepthPreview); + + cbExactCoverage = new QCheckBox(widget); + cbExactCoverage->setObjectName(QStringLiteral("cbExactCoverage")); + sizePolicy1.setHeightForWidth(cbExactCoverage->sizePolicy().hasHeightForWidth()); + cbExactCoverage->setSizePolicy(sizePolicy1); + cbExactCoverage->setLayoutDirection(Qt::RightToLeft); + hlExactCoverage->addWidget(cbExactCoverage); + + vLayoutDepthCoverage->addLayout(hlExactCoverage); + + hLayout->addLayout(vLayoutDepthCoverage); + + fSeparate = new QFrame(widget); + fSeparate->setObjectName(QStringLiteral("fSeparate")); + fSeparate->setFrameShape(QFrame::VLine); + fSeparate->setFrameShadow(QFrame::Sunken); + hLayout->addWidget(fSeparate); + + btnSelectTool = new QPushButton(widget); + setStyledToolTip(btnSelectTool, "Switch to Selection Mode"); + btnSelectTool->setObjectName(QStringLiteral("btnSelectTool")); + sizePolicy1.setHeightForWidth(btnSelectTool->sizePolicy().hasHeightForWidth()); + btnSelectTool->setSizePolicy(sizePolicy1); + btnSelectTool->setMinimumSize(QSize(40, 40)); + btnSelectTool->setMaximumSize(QSize(40, 40)); + btnSelectTool->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnSelectTool.png")); + btnSelectTool->setIconSize(QSize(40, 40)); + QAction* pointselect_action = new QAction(tr("point select"), this); + QAction* rectselect_action = new QAction(tr("rect select"), this); + QAction* drawselect_action = new QAction(tr("draw select"), this); + connect(pointselect_action, SIGNAL(triggered()), this, SLOT(on_pointselect_action())); + connect(rectselect_action, SIGNAL(triggered()), this, SLOT(on_rectselect_action())); + connect(drawselect_action, SIGNAL(triggered()), this, SLOT(on_drawselect_action())); + QMenu* menu = new QMenu(btnSelectTool); + menu->addAction(pointselect_action); + menu->addAction(rectselect_action); + menu->addAction(drawselect_action); + btnSelectTool->setMenu(menu); + hLayout->addWidget(btnSelectTool); + + btnPaintbrush = new QPushButton(widget); + setStyledToolTip(btnPaintbrush, "Not Implement"); + btnPaintbrush->setObjectName(QStringLiteral("btnPaintbrush")); + sizePolicy1.setHeightForWidth(btnPaintbrush->sizePolicy().hasHeightForWidth()); + btnPaintbrush->setSizePolicy(sizePolicy1); + btnPaintbrush->setMinimumSize(QSize(40, 40)); + btnPaintbrush->setMaximumSize(QSize(40, 40)); + btnPaintbrush->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnPaintbrush.png")); + btnPaintbrush->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnPaintbrush); + + btnFractureTool = new QPushButton(widget); + setStyledToolTip(btnFractureTool, "Not Implement"); + btnFractureTool->setObjectName(QStringLiteral("btnFractureTool")); + sizePolicy1.setHeightForWidth(btnFractureTool->sizePolicy().hasHeightForWidth()); + btnFractureTool->setSizePolicy(sizePolicy1); + btnFractureTool->setMinimumSize(QSize(40, 40)); + btnFractureTool->setMaximumSize(QSize(40, 40)); + btnFractureTool->setText(QApplication::translate("AppMainToolbar", "Fracture", 0)); + btnFractureTool->setFont(fontCopy); + hLayout->addWidget(btnFractureTool); + + btnExplodedViewTool = new QPushButton(widget); + setStyledToolTip(btnExplodedViewTool, "Not Implement"); + btnExplodedViewTool->setObjectName(QStringLiteral("btnExplodedViewTool")); + sizePolicy1.setHeightForWidth(btnExplodedViewTool->sizePolicy().hasHeightForWidth()); + btnExplodedViewTool->setSizePolicy(sizePolicy1); + btnExplodedViewTool->setMinimumSize(QSize(40, 40)); + btnExplodedViewTool->setMaximumSize(QSize(40, 40)); + btnExplodedViewTool->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnExplodedViewTool.png")); + btnExplodedViewTool->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnExplodedViewTool); + + btnJointsTool = new QPushButton(widget); + setStyledToolTip(btnJointsTool, "Not Implement"); + btnJointsTool->setObjectName(QStringLiteral("btnJointsTool")); + sizePolicy1.setHeightForWidth(btnJointsTool->sizePolicy().hasHeightForWidth()); + btnJointsTool->setSizePolicy(sizePolicy1); + btnJointsTool->setMinimumSize(QSize(40, 40)); + btnJointsTool->setMaximumSize(QSize(40, 40)); + btnJointsTool->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnJointsTool.png")); + btnJointsTool->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnJointsTool); + + btnFuseSelectedChunks = new QPushButton(widget); + setStyledToolTip(btnFuseSelectedChunks, "Not Implement"); + btnFuseSelectedChunks->setObjectName(QStringLiteral("btnFuseSelectedChunks")); + sizePolicy1.setHeightForWidth(btnFuseSelectedChunks->sizePolicy().hasHeightForWidth()); + btnFuseSelectedChunks->setSizePolicy(sizePolicy1); + btnFuseSelectedChunks->setMinimumSize(QSize(40, 40)); + btnFuseSelectedChunks->setMaximumSize(QSize(40, 40)); + btnFuseSelectedChunks->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnFuseSelectedChunks.png")); + btnFuseSelectedChunks->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnFuseSelectedChunks); + + fSeparate = new QFrame(widget); + fSeparate->setObjectName(QStringLiteral("fSeparate")); + fSeparate->setFrameShape(QFrame::VLine); + fSeparate->setFrameShadow(QFrame::Sunken); + hLayout->addWidget(fSeparate); + + btnReset = new QPushButton(widget); + setStyledToolTip(btnReset, "Reset Chunks and Switch to Edition Mode"); + btnReset->setObjectName(QStringLiteral("btnReset")); + sizePolicy1.setHeightForWidth(btnReset->sizePolicy().hasHeightForWidth()); + btnReset->setSizePolicy(sizePolicy1); + btnReset->setMinimumSize(QSize(40, 40)); + btnReset->setMaximumSize(QSize(40, 40)); + btnReset->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnReset.png")); + btnReset->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnReset); + + btnSimulatePlay = new QPushButton(widget); + setStyledToolTip(btnSimulatePlay, "Switch to Simulate Mode"); + btnSimulatePlay->setObjectName(QStringLiteral("btnSimulatePlay")); + sizePolicy1.setHeightForWidth(btnSimulatePlay->sizePolicy().hasHeightForWidth()); + btnSimulatePlay->setSizePolicy(sizePolicy1); + btnSimulatePlay->setMinimumSize(QSize(40, 40)); + btnSimulatePlay->setMaximumSize(QSize(40, 40)); + btnSimulatePlay->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnSimulatePlay.png")); + btnSimulatePlay->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnSimulatePlay); + + btnFrameStepForward = new QPushButton(widget); + setStyledToolTip(btnFrameStepForward, "Switch to StepForward Mode"); + btnFrameStepForward->setObjectName(QStringLiteral("btnFrameStepForward")); + sizePolicy1.setHeightForWidth(btnFrameStepForward->sizePolicy().hasHeightForWidth()); + btnFrameStepForward->setSizePolicy(sizePolicy1); + btnFrameStepForward->setMinimumSize(QSize(40, 40)); + btnFrameStepForward->setMaximumSize(QSize(40, 40)); + btnFrameStepForward->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnFrameStepForward.png")); + btnFrameStepForward->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnFrameStepForward); + + fSeparate = new QFrame(widget); + fSeparate->setObjectName(QStringLiteral("fSeparate")); + fSeparate->setFrameShape(QFrame::VLine); + fSeparate->setFrameShadow(QFrame::Sunken); + hLayout->addWidget(fSeparate); + + btnBomb = new QPushButton(widget); + setStyledToolTip(btnBomb, "Not Implement"); + btnBomb->setObjectName(QStringLiteral("btnBomb")); + sizePolicy1.setHeightForWidth(btnBomb->sizePolicy().hasHeightForWidth()); + btnBomb->setSizePolicy(sizePolicy1); + btnBomb->setMinimumSize(QSize(40, 40)); + btnBomb->setMaximumSize(QSize(40, 40)); + btnBomb->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnBomb.png")); + btnBomb->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnBomb); + + btnProjectile = new QPushButton(widget); + setStyledToolTip(btnProjectile, "Throw a Box to Chunks"); + btnProjectile->setObjectName(QStringLiteral("btnProjectile")); + sizePolicy1.setHeightForWidth(btnProjectile->sizePolicy().hasHeightForWidth()); + btnProjectile->setSizePolicy(sizePolicy1); + btnProjectile->setMinimumSize(QSize(40, 40)); + btnProjectile->setMaximumSize(QSize(40, 40)); + btnProjectile->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnProjectile.png")); + btnProjectile->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnProjectile); + + btnDropObject = new QPushButton(widget); + setStyledToolTip(btnDropObject, "Not Implement"); + btnDropObject->setObjectName(QStringLiteral("btnDropObject")); + sizePolicy1.setHeightForWidth(btnDropObject->sizePolicy().hasHeightForWidth()); + btnDropObject->setSizePolicy(sizePolicy1); + btnDropObject->setMinimumSize(QSize(40, 40)); + btnDropObject->setMaximumSize(QSize(40, 40)); + btnDropObject->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnDropObject.png")); + btnDropObject->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnDropObject); + + fSeparate = new QFrame(widget); + fSeparate->setObjectName(QStringLiteral("fSeparate")); + fSeparate->setFrameShape(QFrame::VLine); + fSeparate->setFrameShadow(QFrame::Sunken); + hLayout->addWidget(fSeparate); + + btnPreferences = new QPushButton(widget); + setStyledToolTip(btnPreferences, "Save Blast Asset"); + btnPreferences->setObjectName(QStringLiteral("btnPreferences")); + sizePolicy1.setHeightForWidth(btnPreferences->sizePolicy().hasHeightForWidth()); + btnPreferences->setSizePolicy(sizePolicy1); + btnPreferences->setMinimumSize(QSize(40, 40)); + btnPreferences->setMaximumSize(QSize(40, 40)); + btnPreferences->setIcon(QIcon(":/AppMainWindow/images/Blast_ToolBar_btnPreferences.png")); + btnPreferences->setIconSize(QSize(40, 40)); + hLayout->addWidget(btnPreferences); + + QSpacerItem *horizontalSpacer; + horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + hLayout->addItem(horizontalSpacer); + + this->setWidget(widget); + + connect(btnOpenProject, SIGNAL(clicked()), this, SLOT(on_btnOpenProject_clicked())); + connect(btnSaveProject, SIGNAL(clicked()), this, SLOT(on_btnSaveProject_clicked())); + connect(btnExportAssets, SIGNAL(clicked()), this, SLOT(on_btnExportAssets_clicked())); + connect(btnExportFilepath, SIGNAL(clicked()), this, SLOT(on_btnExportFilepath_clicked())); + connect(ssbiDepthPreview, SIGNAL(valueChanged(int)), this, SLOT(on_ssbiDepthPreview_valueChanged(int))); + connect(cbExactCoverage, SIGNAL(stateChanged(int)), this, SLOT(on_cbExactCoverage_stateChanged(int))); + connect(btnSelectTool, SIGNAL(clicked()), this, SLOT(on_btnSelectTool_clicked())); + connect(btnPaintbrush, SIGNAL(clicked()), this, SLOT(on_btnPaintbrush_clicked())); + connect(btnFractureTool, SIGNAL(clicked()), this, SLOT(on_btnFractureTool_clicked())); + connect(btnExplodedViewTool, SIGNAL(clicked()), this, SLOT(on_btnExplodedViewTool_clicked())); + connect(btnJointsTool, SIGNAL(clicked()), this, SLOT(on_btnJointsTool_clicked())); + connect(btnFuseSelectedChunks, SIGNAL(clicked()), this, SLOT(on_btnFuseSelectedChunks_clicked())); + connect(btnReset, SIGNAL(clicked()), this, SLOT(on_btnReset_clicked())); + connect(btnSimulatePlay, SIGNAL(clicked()), this, SLOT(on_btnSimulatePlay_clicked())); + connect(btnFrameStepForward, SIGNAL(clicked()), this, SLOT(on_btnFrameStepForward_clicked())); + connect(btnBomb, SIGNAL(clicked()), this, SLOT(on_btnBomb_clicked())); + connect(btnProjectile, SIGNAL(clicked()), this, SLOT(on_btnProjectile_clicked())); + connect(btnDropObject, SIGNAL(clicked()), this, SLOT(on_btnDropObject_clicked())); + connect(btnPreferences, SIGNAL(clicked()), this, SLOT(on_btnPreferences_clicked())); +} + +void BlastToolbar::updateValues() +{ +} + +#include <Sample.h> +#include <SimpleScene.h> +#include <SampleManager.h> +#include <SceneController.h> +#include <SourceAssetOpenDlg.h> + +void BlastToolbar::on_btnOpenProject_clicked() +{ + qDebug("%s", __FUNCTION__); + + SourceAssetOpenDlg dlg(true, &AppMainWindow::Inst()); + int res = dlg.exec(); + if (res != QDialog::Accepted || dlg.getFile().isEmpty()) + return; + + QFileInfo fileInfo(dlg.getFile()); + std::string dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + std::string file = fileInfo.baseName().toLocal8Bit(); + + physx::PxTransform t(physx::PxIdentity); + { + QVector3D Position = dlg.getPosition(); + t.p = physx::PxVec3(Position.x(), Position.y(), Position.z()); + + QVector3D RotationAxis = dlg.getRotationAxis(); + physx::PxVec3 Axis = physx::PxVec3(RotationAxis.x(), RotationAxis.y(), RotationAxis.z()); + Axis = Axis.getNormalized(); + float RotationDegree = dlg.getRotationDegree(); + float DEGREE_TO_RAD = acos(-1.0) / 180.0; + RotationDegree = RotationDegree * DEGREE_TO_RAD; + t.q = physx::PxQuat(RotationDegree, Axis); + } + + SimpleScene::Inst()->GetSampleManager().addModelAsset(file, dlg.getSkinned(), t, !dlg.isAppend()); +} + +void BlastToolbar::on_btnSaveProject_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnExportAssets_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnExportFilepath_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_ssbiDepthPreview_valueChanged(int v) +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_cbExactCoverage_stateChanged(int state) +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnSelectTool_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_pointselect_action() +{ + qDebug("%s", __FUNCTION__); + + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + sampleManager.setBlastToolType(BTT_Select); +} + +void BlastToolbar::on_rectselect_action() +{ + qDebug("%s", __FUNCTION__); + + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + sampleManager.setBlastToolType(BTT_Select); +} + +void BlastToolbar::on_drawselect_action() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnPaintbrush_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnFractureTool_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnExplodedViewTool_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnJointsTool_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnFuseSelectedChunks_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnReset_clicked() +{ + qDebug("%s", __FUNCTION__); + + SampleManager* pSampleManager = SampleManager::ins(); + SceneController& sceneController = pSampleManager->getSceneController(); + sceneController.ResetScene(); + pSampleManager->setBlastToolType(BTT_Edit); +} + +void BlastToolbar::on_btnSimulatePlay_clicked() +{ + qDebug("%s", __FUNCTION__); + + SampleManager* pSampleManager = SampleManager::ins(); + pSampleManager->setBlastToolType(BTT_Damage); +} + +void BlastToolbar::on_btnFrameStepForward_clicked() +{ + qDebug("%s", __FUNCTION__); + + SampleManager* pSampleManager = SampleManager::ins(); + pSampleManager->setBlastToolType(BTT_Damage); + PhysXController& physXController = pSampleManager->getPhysXController(); + physXController.m_bForce = true; +} + +void BlastToolbar::on_btnBomb_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnProjectile_clicked() +{ + qDebug("%s", __FUNCTION__); + + SampleManager& sampleManager = SimpleScene::Inst()->GetSampleManager(); + SceneController& sceneController = sampleManager.getSceneController(); + sceneController.addProjectile(); +} + +void BlastToolbar::on_btnDropObject_clicked() +{ + qDebug("%s", __FUNCTION__); +} + +void BlastToolbar::on_btnPreferences_clicked() +{ + qDebug("%s", __FUNCTION__); + + SampleManager* pSampleManager = SampleManager::ins(); + pSampleManager->saveAsset(); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h new file mode 100644 index 0000000..f44dcfb --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/BlastToolBar.h @@ -0,0 +1,94 @@ +#ifndef BlastToolbar_h__ +#define BlastToolbar_h__ + +#include <QtWidgets/QApplication> +#include <QtWidgets/QCheckBox> +#include <QtWidgets/QDockWidget> +#include <QtWidgets/QHBoxLayout> +#include <QtWidgets/QLabel> +#include <QtWidgets/QPushButton> +#include <QtWidgets/QMenu> +#include <QtWidgets/QVBoxLayout> +#include <QtWidgets/QLineEdit> + +#include "SlideSpinBox.h" + +class BlastToolbar : public QDockWidget +{ + Q_OBJECT + +public: + BlastToolbar(QWidget* parent); + + void updateValues(); + +public slots: + void on_btnOpenProject_clicked(); + void on_btnSaveProject_clicked(); + void on_btnExportAssets_clicked(); + + void on_btnExportFilepath_clicked(); + void on_ssbiDepthPreview_valueChanged(int v); + void on_cbExactCoverage_stateChanged(int state); + + void on_btnSelectTool_clicked(); + void on_pointselect_action(); + void on_rectselect_action(); + void on_drawselect_action(); + + void on_btnPaintbrush_clicked(); + void on_btnFractureTool_clicked(); + void on_btnExplodedViewTool_clicked(); + void on_btnJointsTool_clicked(); + void on_btnFuseSelectedChunks_clicked(); + + void on_btnReset_clicked(); + void on_btnSimulatePlay_clicked(); + void on_btnFrameStepForward_clicked(); + + void on_btnBomb_clicked(); + void on_btnProjectile_clicked(); + void on_btnDropObject_clicked(); + + void on_btnPreferences_clicked(); + +private: + QHBoxLayout *hLayout; + QFrame *fSeparate; + + QPushButton *btnOpenProject; + QPushButton *btnSaveProject; + QPushButton *btnExportAssets; + + QVBoxLayout *vLayoutExport; + QHBoxLayout *hLayoutExport; + QLabel *lExportFilepath; + QPushButton *btnExportFilepath; + QLineEdit* leExportFilepath; + + QVBoxLayout *vLayoutDepthCoverage; + QHBoxLayout *hlDepthPreview; + QLabel *lbDepthPreview; + SlideSpinBoxInt* ssbiDepthPreview; + QHBoxLayout *hlExactCoverage; + QLabel *lbExactCoverage; + QCheckBox* cbExactCoverage; + + QPushButton *btnSelectTool; + QPushButton *btnPaintbrush; + QPushButton *btnFractureTool; + QPushButton *btnExplodedViewTool; + QPushButton *btnJointsTool; + QPushButton *btnFuseSelectedChunks; + + QPushButton *btnReset; + QPushButton *btnSimulatePlay; + QPushButton *btnFrameStepForward; + + QPushButton *btnBomb; + QPushButton *btnProjectile; + QPushButton *btnDropObject; + + QPushButton *btnPreferences; +}; +#endif // BlastToolbar_h__ diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.cpp new file mode 100644 index 0000000..4aa2b79 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.cpp @@ -0,0 +1,54 @@ +#include "CollisionToolsDlg.h" +#include "ui_CollisionToolsDlg.h" + +CollisionToolsDlg::CollisionToolsDlg(QWidget *parent) : + QDialog(parent), + ui(new Ui::CollisionToolsDlg) +{ + ui->setupUi(this); +} + +CollisionToolsDlg::~CollisionToolsDlg() +{ + delete ui; +} + +void CollisionToolsDlg::on_comboBoxApplyFilter_currentIndexChanged(int index) +{ + +} + +void CollisionToolsDlg::on_comboBoxCollisionShape_currentIndexChanged(int index) +{ + +} + +void CollisionToolsDlg::on_spinBoxQuality_valueChanged(int arg1) +{ + +} + +void CollisionToolsDlg::on_spinBoxMaxHulls_valueChanged(int arg1) +{ + +} + +void CollisionToolsDlg::on_spinBoxTrimHulls_valueChanged(int arg1) +{ + +} + +void CollisionToolsDlg::on_comboBoxTargetPlatform_currentIndexChanged(int index) +{ + +} + +void CollisionToolsDlg::on_btnReset_clicked() +{ + +} + +void CollisionToolsDlg::on_btnApply_clicked() +{ + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.h new file mode 100644 index 0000000..d3c8c00 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/CollisionToolsDlg.h @@ -0,0 +1,39 @@ +#ifndef COLLISIONTOOLSDLG_H +#define COLLISIONTOOLSDLG_H + +#include <QtWidgets/QDialog> + +namespace Ui { +class CollisionToolsDlg; +} + +class CollisionToolsDlg : public QDialog +{ + Q_OBJECT + +public: + explicit CollisionToolsDlg(QWidget *parent = 0); + ~CollisionToolsDlg(); + +private slots: + void on_comboBoxApplyFilter_currentIndexChanged(int index); + + void on_comboBoxCollisionShape_currentIndexChanged(int index); + + void on_spinBoxQuality_valueChanged(int arg1); + + void on_spinBoxMaxHulls_valueChanged(int arg1); + + void on_spinBoxTrimHulls_valueChanged(int arg1); + + void on_comboBoxTargetPlatform_currentIndexChanged(int index); + + void on_btnReset_clicked(); + + void on_btnApply_clicked(); + +private: + Ui::CollisionToolsDlg *ui; +}; + +#endif // COLLISIONTOOLSDLG_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp new file mode 100644 index 0000000..e52dfb2 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.cpp @@ -0,0 +1,104 @@ +#include "DefaultDamagePanel.h" +#include "ui_DefaultDamagePanel.h" +#include "ProjectParams.h" +#include "BlastSceneTree.h" + +DefaultDamagePanel::DefaultDamagePanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::DefaultDamagePanel) +{ + ui->setupUi(this); +} + +DefaultDamagePanel::~DefaultDamagePanel() +{ + delete ui; +} + +void DefaultDamagePanel::updateValues() +{ + if (_selectedAssets.size() > 0) + { + BPPDefaultDamage& damage = _selectedAssets[0]->defaultDamage; + + ui->spinBoxMinRadius->setValue(damage.minRadius); + ui->spinBoxMaxRadius->setValue(damage.maxRadius); + ui->comboBoxFallOff->setCurrentIndex(damage.FallOff); + ui->spinBoxMaxChunkSpeed->setValue(damage.maxChunkSpeed); + } + else + { + ui->spinBoxMinRadius->setValue(0.0f); + ui->spinBoxMaxRadius->setValue(0.0f); + ui->checkBoxMaxRadius->setChecked(false); + ui->comboBoxFallOff->setCurrentIndex(-1); + ui->spinBoxMaxChunkSpeed->setValue(0.0f); + } +} + +void DefaultDamagePanel::dataSelected(std::vector<BlastNode*> selections) +{ + _selectedAssets.clear(); + + for (BlastNode* node: selections) + { + if (eAsset == node->getType()) + { + BPPAsset* asset = static_cast<BPPAsset*>(node->getData()); + _selectedAssets.push_back(asset); + } + } + + updateValues(); +} + +void DefaultDamagePanel::on_spinBoxMinRadius_valueChanged(double arg1) +{ + for (size_t i = 0; i < _selectedAssets.size(); ++i) + { + BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage; + damage.minRadius = arg1; + } +} + +void DefaultDamagePanel::on_spinBoxMaxRadius_valueChanged(double arg1) +{ + for (size_t i = 0; i < _selectedAssets.size(); ++i) + { + BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage; + + damage.maxRadius = arg1; + + if (arg1 < damage.minRadius) + { + damage.maxRadius = damage.minRadius; + } + } +} + +void DefaultDamagePanel::on_checkBoxMaxRadius_stateChanged(int arg1) +{ + for (size_t i = 0; i < _selectedAssets.size(); ++i) + { + BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage; + damage.maxRadiusEnable = (arg1 != 0 ? true: false); + } +} + +void DefaultDamagePanel::on_comboBoxFallOff_currentIndexChanged(int index) +{ + for (size_t i = 0; i < _selectedAssets.size(); ++i) + { + BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage; + damage.FallOff = index; + } +} + +void DefaultDamagePanel::on_spinBoxMaxChunkSpeed_valueChanged(double arg1) +{ + for (size_t i = 0; i < _selectedAssets.size(); ++i) + { + BPPDefaultDamage& damage = _selectedAssets[i]->defaultDamage; + damage.maxChunkSpeed = arg1; + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h new file mode 100644 index 0000000..bbd4d3e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/DefaultDamagePanel.h @@ -0,0 +1,38 @@ +#ifndef DEFAULTDAMAGEPANEL_H +#define DEFAULTDAMAGEPANEL_H + +#include <QtWidgets/QWidget> +#include "BlastSceneTree.h" + +namespace Ui { +class DefaultDamagePanel; +} + +class DefaultDamagePanel : public QWidget, public ISceneObserver +{ + Q_OBJECT + +public: + explicit DefaultDamagePanel(QWidget *parent = 0); + ~DefaultDamagePanel(); + void updateValues(); + + virtual void dataSelected(std::vector<BlastNode*> selections); + +private slots: + void on_spinBoxMinRadius_valueChanged(double arg1); + + void on_spinBoxMaxRadius_valueChanged(double arg1); + + void on_checkBoxMaxRadius_stateChanged(int arg1); + + void on_comboBoxFallOff_currentIndexChanged(int index); + + void on_spinBoxMaxChunkSpeed_valueChanged(double arg1); + +private: + Ui::DefaultDamagePanel *ui; + std::vector<BPPAsset*> _selectedAssets; +}; + +#endif // DEFAULTDAMAGEPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp new file mode 100644 index 0000000..62b294c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.cpp @@ -0,0 +1,148 @@ +#include "FileReferencesPanel.h" +#include "ui_FileReferencesPanel.h" +#include "AppMainWindow.h" +#include <QtWidgets/QFileDialog> +#include "ProjectParams.h" +#include <QtCore/QFile> +#include <QtCore/QDebug> +#include "GlobalSettings.h" + +FileReferencesPanel::FileReferencesPanel(QWidget *parent) + : QWidget(parent) + , ui(new Ui::FileReferencesPanel) + , _saveFBX(true) + , _saveBlast(true) + , _saveCollision(true) +{ + ui->setupUi(this); + ui->lineEditFBXSourceAsset->setReadOnly(true); + + ui->checkBoxFBX->setChecked(_saveFBX); + ui->checkBoxBlast->setChecked(_saveBlast); + ui->checkBoxCollision->setChecked(_saveCollision); + + updateValues(); +} + +FileReferencesPanel::~FileReferencesPanel() +{ + delete ui; +} + +void FileReferencesPanel::updateValues() +{ + AppMainWindow& window = AppMainWindow::Inst(); + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFileReferences& fileReferences = projectParams.blast.fileReferences; + if (fileReferences.fbxSourceAsset.buf != nullptr) + ui->lineEditFBXSourceAsset->setText(fileReferences.fbxSourceAsset.buf); + else + ui->lineEditFBXSourceAsset->setText(""); + + GlobalSettings& globalSettings = GlobalSettings::Inst(); + QString projectFileName = globalSettings.m_projectFileName.c_str(); + + if (projectFileName.isEmpty()) + { + ui->lineEditFBX->setText("New.fbx"); + ui->lineEditBlast->setText("New.Blast"); + ui->lineEditCollision->setText("New.repx"); + } + else + { + QFileInfo fileInfo(projectFileName); + + if (fileReferences.fbx.buf != nullptr) + ui->lineEditFBX->setText(fileReferences.fbx.buf); + else + { + ui->lineEditFBX->setText(fileInfo.baseName() + " New.fbx"); + } + + if (fileReferences.blast.buf != nullptr) + ui->lineEditBlast->setText(fileReferences.blast.buf); + else + { + ui->lineEditBlast->setText(fileInfo.baseName() + " New.Blast"); + } + + if (fileReferences.collision.buf != nullptr) + ui->lineEditCollision->setText(fileReferences.collision.buf); + else + { + ui->lineEditCollision->setText(fileInfo.baseName() + " New.repX"); + } + } +} + +void FileReferencesPanel::on_btnOpenFile_clicked() +{ + AppMainWindow& window = AppMainWindow::Inst(); + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFileReferences& fileReferences = projectParams.blast.fileReferences; + const char* fbxSourceAsset = fileReferences.fbxSourceAsset.buf; + QString lastDir = (fbxSourceAsset != nullptr ? fbxSourceAsset : window._lastFilePath); + QString fileName = QFileDialog::getOpenFileName(&window, "Open FBX File", lastDir, "FBX File (*.FBX)"); + + ui->lineEditFBXSourceAsset->setText(fileName); +} + +void FileReferencesPanel::on_btnReload_clicked() +{ + +} + +void FileReferencesPanel::on_btnRemove_clicked() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFileReferences& fileReferences = projectParams.blast.fileReferences; + if (fileReferences.fbxSourceAsset.buf != nullptr) + { + ui->lineEditFBXSourceAsset->setText(""); + freeString(fileReferences.fbxSourceAsset); + // to do: remove source fbx file + } +} + +void FileReferencesPanel::on_checkBoxFBX_stateChanged(int arg1) +{ + _saveFBX = (arg1 == 0 ? false : true); +} + +void FileReferencesPanel::on_checkBoxBlast_stateChanged(int arg1) +{ + _saveBlast = (arg1 == 0 ? false : true); +} + +void FileReferencesPanel::on_checkBoxCollision_stateChanged(int arg1) +{ + _saveCollision = (arg1 == 0 ? false : true); +} + +void FileReferencesPanel::on_btnSave_clicked() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFileReferences& fileReferences = projectParams.blast.fileReferences; + + copy(fileReferences.fbxSourceAsset, ui->lineEditFBXSourceAsset->text().toUtf8().data()); + + if (_saveFBX) + { + copy(fileReferences.fbx, ui->lineEditFBX->text().toUtf8().data()); + // to do: save fbx file + } + + if (_saveBlast) + { + copy(fileReferences.blast, ui->lineEditBlast->text().toUtf8().data()); + // to do: save blast file + } + + if (_saveCollision) + { + copy(fileReferences.collision, ui->lineEditCollision->text().toUtf8().data()); + // to do: save collision file + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h new file mode 100644 index 0000000..e393f33 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FileReferencesPanel.h @@ -0,0 +1,41 @@ +#ifndef FILEREFERENCESPANEL_H +#define FILEREFERENCESPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FileReferencesPanel; +} + +class FileReferencesPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FileReferencesPanel(QWidget *parent = 0); + ~FileReferencesPanel(); + void updateValues(); + +private slots: + void on_btnOpenFile_clicked(); + + void on_btnReload_clicked(); + + void on_btnRemove_clicked(); + + void on_checkBoxFBX_stateChanged(int arg1); + + void on_checkBoxBlast_stateChanged(int arg1); + + void on_checkBoxCollision_stateChanged(int arg1); + + void on_btnSave_clicked(); + +private: + Ui::FileReferencesPanel *ui; + bool _saveFBX; + bool _saveBlast; + bool _saveCollision; +}; + +#endif // FILEREFERENCESPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp new file mode 100644 index 0000000..a537140 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.cpp @@ -0,0 +1,389 @@ +#include "FiltersDockWidget.h" +#include "ui_FiltersDockWidget.h" +#include "ProjectParams.h" +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> +#include "SampleManager.h" + +const QString LISTITEM_NORMAL_STYLESHEET = ":enabled { background: rgb(68,68,68); }"; + +const QString LISTITEM_SELECTED_STYLESHEET = ":enabled { background: rgba(118,185,0, 250); }"; + +const QString LISTITEM_BUTTON_STYLESHEET = ":enabled { border: 0px; }"; + +class FilterItemWidget; + +struct FilterItemInfo +{ +public: + FilterItemInfo(FilterItemWidget* inWidget, const QString& inText) + : itemWidget(inWidget) + , text(inText) + { + } + + FilterItemWidget* itemWidget; + QString text; +}; + +FilterItemWidget::FilterItemWidget(FiltersDockWidget* parent, QListWidgetItem* item, const QString& filterPreset, int depth) + : QWidget(parent) + , _relatedListWidgetItem(item) + , _filterPreset(filterPreset) + , _depth(depth) +{ + QHBoxLayout* layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + _label = new QLabel(this); + + _removeBtn = new QPushButton(this); + _removeBtn->setMaximumSize(20, 20); + _removeBtn->setText("X"); + _removeBtn->setStyleSheet(LISTITEM_BUTTON_STYLESHEET); + + layout->addWidget(_label); + layout->addWidget(_removeBtn); + + this->setLayout(layout); + + QObject::connect(_removeBtn, SIGNAL(clicked()), this, SLOT(onRemoveButtonClicked())); + QObject::connect(this, SIGNAL(RemoveItem(QListWidgetItem*)), parent, SLOT(onListWidgetRemoveBtnClicked(QListWidgetItem*))); + + deSelect(); +} + +void FilterItemWidget::setText(const QString& title) +{ + _label->setText(title); +} + +void FilterItemWidget::select() +{ + _label->setStyleSheet(LISTITEM_SELECTED_STYLESHEET); +} + +void FilterItemWidget::deSelect() +{ + _label->setStyleSheet(LISTITEM_NORMAL_STYLESHEET); +} + +void FilterItemWidget::onRemoveButtonClicked() +{ + emit RemoveItem(_relatedListWidgetItem); +} + +FiltersDockWidget::FiltersDockWidget(QWidget *parent) : + QDockWidget(parent), + ui(new Ui::FiltersDockWidget), + _filterUIItems(), + _filterItemWidgets(), + _lastSelectRow(-1) +{ + ui->setupUi(this); + + _depthButtons.push_back(ui->btnDepth0); + _depthButtons.push_back(ui->btnDepth1); + _depthButtons.push_back(ui->btnDepth2); + _depthButtons.push_back(ui->btnDepth3); + _depthButtons.push_back(ui->btnDepth4); + _depthButtons.push_back(ui->btnDepth5); + + _updateFilterItemList(); + _updateFilterDepthBtns(); +} + +FiltersDockWidget::~FiltersDockWidget() +{ + delete ui; +} + +void FiltersDockWidget::updateValues() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFilterPresetArray& filterPresetArray = projectParams.filter.filters; + + ui->comboBoxFilterPreset->clear(); + QStringList filterNames; + int count = filterPresetArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + filterNames.append(filterPresetArray.buf[i].name.buf); + } + ui->comboBoxFilterPreset->addItems(filterNames); + + if (count > 0) + { + ui->btnModifyFilterPreset->setEnabled(true); + ui->btnRemoveFilterPreset->setEnabled(true); + } + else + { + ui->btnModifyFilterPreset->setEnabled(false); + ui->btnRemoveFilterPreset->setEnabled(false); + } +} + +void FiltersDockWidget::on_comboBoxFilterPreset_currentIndexChanged(int index) +{ + BPParams& projectParams = BlastProject::ins().getParams(); + projectParams.filter.activeFilter = index; + + _updateFilterItemList(); + _updateFilterDepthBtns(); +} + +void FiltersDockWidget::on_btnAddFilterPrest_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new filter preset:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isFilterPresetNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addFilterPreset(name.toUtf8().data()); + updateValues(); + ui->comboBoxFilterPreset->setCurrentIndex(ui->comboBoxFilterPreset->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new filter preset!"); + } +} + +void FiltersDockWidget::on_btnModifyFilterPreset_clicked() +{ + QByteArray tmp = ui->comboBoxFilterPreset->currentText().toUtf8(); + const char* oldName = tmp.data(); + + bool ok = false; + QString newName = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input new name for the selected filter preset:"), + QLineEdit::Normal, + oldName, + &ok); + bool nameExist = BlastProject::ins().isFilterPresetNameExist(newName.toUtf8().data()); + if (ok && !newName.isEmpty() && !nameExist) + { + int index = ui->comboBoxFilterPreset->currentIndex(); + BlastProject::ins().renameFilterPreset(oldName, newName.toUtf8().data()); + updateValues(); + ui->comboBoxFilterPreset->setCurrentIndex(index); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && newName.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the selected filter preset!"); + } +} + +void FiltersDockWidget::on_btnRemoveFilterPreset_clicked() +{ + QByteArray tmp = ui->comboBoxFilterPreset->currentText().toUtf8(); + const char* name = tmp.data(); + BlastProject::ins().removeFilterPreset(name); + updateValues(); +} + +void FiltersDockWidget::on_btnDepth0_clicked(bool val) +{ + _addRemoveDepthFilter(0, val); +} + +void FiltersDockWidget::on_btnDepth1_clicked(bool val) +{ + _addRemoveDepthFilter(1, val); +} + +void FiltersDockWidget::on_btnDepth2_clicked(bool val) +{ + _addRemoveDepthFilter(2, val); +} + +void FiltersDockWidget::on_btnDepth3_clicked(bool val) +{ + _addRemoveDepthFilter(3, val); +} + +void FiltersDockWidget::on_btnDepth4_clicked(bool val) +{ + _addRemoveDepthFilter(4, val); +} + +void FiltersDockWidget::on_btnDepth5_clicked(bool val) +{ + _addRemoveDepthFilter(5, val); +} + +void FiltersDockWidget::on_btnAddDepthFilter_clicked() +{ + +} + +void FiltersDockWidget::on_btnAddFilter_clicked() +{ + +} + +void FiltersDockWidget::on_btnSelect_clicked() +{ + std::vector<uint32_t> depths; + int row = ui->listWidget->currentRow(); + if (-1 != row) + { + depths.push_back(_filterItemWidgets[row]->_depth); + } + SampleManager::ins()->setChunkSelected(depths, true); +} + +void FiltersDockWidget::on_btnVisible_clicked() +{ + std::vector<uint32_t> depths; + int row = ui->listWidget->currentRow(); + if (-1 != row) + { + depths.push_back(_filterItemWidgets[row]->_depth); + } + SampleManager::ins()->setChunkVisible(depths, true); +} + +void FiltersDockWidget::on_btnInVisible_clicked() +{ + std::vector<uint32_t> depths; + int row = ui->listWidget->currentRow(); + if (-1 != row) + { + depths.push_back(_filterItemWidgets[row]->_depth); + } + SampleManager::ins()->setChunkVisible(depths, false); +} + +void FiltersDockWidget::on_listWidget_currentRowChanged(int index) +{ + if (-1 != _lastSelectRow && _lastSelectRow < _filterItemWidgets.size()) + static_cast<FilterItemWidget*>(_filterItemWidgets[_lastSelectRow])->deSelect(); + + if (-1 != index && index < _filterItemWidgets.size()) + static_cast<FilterItemWidget*>(_filterItemWidgets[index])->select(); + + _lastSelectRow = index; +} + +void FiltersDockWidget::onListWidgetRemoveBtnClicked(QListWidgetItem* item) +{ + /// remove former ui info + map<QListWidgetItem*, FilterItemInfo*>::iterator toRemoveItem = _filterUIItems.find(item); + if (toRemoveItem != _filterUIItems.end()) + { + FilterItemWidget* itemWidget = toRemoveItem->second->itemWidget; + itemWidget->setParent(nullptr); + + _filterItemWidgets.erase(std::find(_filterItemWidgets.begin(), _filterItemWidgets.end(), toRemoveItem->second->itemWidget)); + + if (ui->comboBoxFilterPreset->currentIndex() != -1) + { + QByteArray filterPreset = itemWidget->_filterPreset.toUtf8(); + BlastProject::ins().removeFilterDepth(filterPreset.data(), itemWidget->_depth); + } + + ui->listWidget->takeItem(ui->listWidget->row(item)); + ui->listWidget->removeItemWidget(item); + delete item; + delete itemWidget; + _filterUIItems.erase(toRemoveItem); + + //_updateFilterItemList(); + _updateFilterDepthBtns(); + } +} + +void FiltersDockWidget::_updateFilterItemList() +{ + /// remove former ui info + map<QListWidgetItem*, FilterItemInfo*>::iterator theEnd = _filterUIItems.end(); + for (map<QListWidgetItem*, FilterItemInfo*>::iterator itr = _filterUIItems.begin(); itr != theEnd; ++itr) + { + itr->second->itemWidget->setParent(nullptr); + delete itr->first; + delete itr->second->itemWidget; + delete itr->second; + } + _filterUIItems.clear(); + ui->listWidget->clear(); + _filterItemWidgets.clear(); + + int filterPresetIndex = ui->comboBoxFilterPreset->currentIndex(); + if (filterPresetIndex < 0) + return; + + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFilterPresetArray& filterPresetArray = projectParams.filter.filters; + BPPFilterPreset& filterPresset = filterPresetArray.buf[filterPresetIndex]; + + int filterCount = filterPresset.depthFilters.arraySizes[0]; + + for (int i = 0; i < filterCount; ++i) + { + QListWidgetItem* item = new QListWidgetItem(NULL); + int depth = filterPresset.depthFilters.buf[i]; + FilterItemWidget* itemWidget = new FilterItemWidget(this, item, filterPresset.name.buf, depth); + + QString depthFilterLabel = QString(QObject::tr("Depth-%1")).arg(depth); + _filterUIItems.insert(std::make_pair(item, new FilterItemInfo(itemWidget, depthFilterLabel))); + itemWidget->setText(depthFilterLabel); + _filterItemWidgets.push_back(itemWidget); + + ui->listWidget->addItem(item); + ui->listWidget->setItemWidget(item, itemWidget); + } +} + +void FiltersDockWidget::_updateFilterDepthBtns() +{ + for (int i = 0; i <= 5; ++i) + _depthButtons[i]->setChecked(false); + + int filterPresetIndex = ui->comboBoxFilterPreset->currentIndex(); + if (filterPresetIndex < 0) + return; + + BPParams& projectParams = BlastProject::ins().getParams(); + BPPFilterPresetArray& filterPresetArray = projectParams.filter.filters; + BPPFilterPreset& filterPresset = filterPresetArray.buf[filterPresetIndex]; + + int filterCount = filterPresset.depthFilters.arraySizes[0]; + + for (int i = 0; i < filterCount; ++i) + { + int depth = filterPresset.depthFilters.buf[i]; + + _depthButtons[depth]->setChecked(true); + } +} + +void FiltersDockWidget::_addRemoveDepthFilter(int depth, bool add) +{ + if (ui->comboBoxFilterPreset->currentIndex() != -1) + { + QByteArray filterPreset = ui->comboBoxFilterPreset->currentText().toUtf8(); + + if (add) + BlastProject::ins().addFilterDepth(filterPreset.data(), depth); + else + BlastProject::ins().removeFilterDepth(filterPreset.data(), depth); + + _updateFilterItemList(); + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h new file mode 100644 index 0000000..cf25073 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FiltersDockWidget.h @@ -0,0 +1,104 @@ +#ifndef FILTERSDOCKWIDGET_H +#define FILTERSDOCKWIDGET_H + +#include <QtWidgets/QDockWidget> +#include <vector> +#include <map> +using namespace std; + +namespace Ui { +class FiltersDockWidget; +} + +class QLabel; +class QPushButton; +class QListWidgetItem; +struct FilterItemInfo; +class FilterItemWidget; +class FiltersDockWidget; + +class FilterItemWidget : public QWidget +{ + Q_OBJECT +public: + FilterItemWidget(FiltersDockWidget* parent, QListWidgetItem* item, const QString& filterPreset, int depth); + ~FilterItemWidget() + { + } + + void setText(const QString& title); + void select(); + void deSelect(); + +signals: + void RemoveItem(QListWidgetItem* item); + +private slots: + void onRemoveButtonClicked(); + +public: + QLabel* _label; + QPushButton* _removeBtn; + QListWidgetItem* _relatedListWidgetItem; + QString _filterPreset; + int _depth; +}; + +class FiltersDockWidget : public QDockWidget +{ + Q_OBJECT + +public: + explicit FiltersDockWidget(QWidget *parent = 0); + ~FiltersDockWidget(); + void updateValues(); + +private slots: + void on_comboBoxFilterPreset_currentIndexChanged(int index); + + void on_btnAddFilterPrest_clicked(); + + void on_btnModifyFilterPreset_clicked(); + + void on_btnRemoveFilterPreset_clicked(); + + void on_btnDepth0_clicked(bool val); + + void on_btnDepth1_clicked(bool val); + + void on_btnDepth2_clicked(bool val); + + void on_btnDepth3_clicked(bool val); + + void on_btnDepth4_clicked(bool val); + + void on_btnDepth5_clicked(bool val); + + void on_btnAddDepthFilter_clicked(); + + void on_btnAddFilter_clicked(); + + void on_btnSelect_clicked(); + + void on_btnVisible_clicked(); + + void on_btnInVisible_clicked(); + + void on_listWidget_currentRowChanged(int index); + + void onListWidgetRemoveBtnClicked(QListWidgetItem* item); + +private: + void _updateFilterItemList(); + void _updateFilterDepthBtns(); + void _addRemoveDepthFilter(int depth, bool add); + +private: + Ui::FiltersDockWidget *ui; + map<QListWidgetItem*, FilterItemInfo*> _filterUIItems; + vector<FilterItemWidget*> _filterItemWidgets; + int _lastSelectRow; + vector<QPushButton*> _depthButtons; +}; + +#endif // FILTERSDOCKWIDGET_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.cpp new file mode 100644 index 0000000..ea24278 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.cpp @@ -0,0 +1,155 @@ +#include "FractureCutoutSettingsPanel.h" +#include "ui_FractureCutoutSettingsPanel.h" +#include "ProjectParams.h" +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> +#include <QtCore/QFileInfo> +#include "AppMainWindow.h" + +FractureCutoutSettingsPanel::FractureCutoutSettingsPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureCutoutSettingsPanel) +{ + ui->setupUi(this); +} + +FractureCutoutSettingsPanel::~FractureCutoutSettingsPanel() +{ + delete ui; +} + +void FractureCutoutSettingsPanel::updateValues() +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + + _updateTextureListWidget(); + + ui->comboBoxCutoutType->setCurrentIndex(cutoutProjection.cutoutType); + ui->spinBoxPixelThreshold->setValue(cutoutProjection.pixelThreshold); + ui->checkBoxTiled->setChecked(cutoutProjection.tiled); + ui->checkBoxInvertU->setChecked(cutoutProjection.invertU); + ui->checkBoxInvertV->setChecked(cutoutProjection.invertV); +} + +void FractureCutoutSettingsPanel::on_btnAddTexture_clicked() +{ + QString texName = AppMainWindow::Inst().OpenTextureFile(); + + if (texName.isEmpty()) + return; + + QFileInfo fileInfo(texName); + QByteArray ba = fileInfo.absoluteFilePath().toLocal8Bit(); + const char* filePath = (const char*)(ba); + + if (!BlastProject::ins().isCutoutTextureNameExist(texName.toUtf8().data())) + { + BlastProject::ins().addCutoutTexture(filePath); + _updateTextureListWidget(); + ui->listWidget->setCurrentRow(ui->listWidget->count() - 1); + } + else + { + QMessageBox::warning(this, "Blast Tool", "The texture you selected is already exist!"); + } +} + +void FractureCutoutSettingsPanel::on_btnReloadTexture_clicked() +{ + +} + +void FractureCutoutSettingsPanel::on_btnRemoveTexture_clicked() +{ + if (ui->listWidget->currentRow() != -1) + { + QListWidgetItem *item = ui->listWidget->currentItem(); + QString texture = _getTexturePathByName(item->text()); + QByteArray ba = texture.toLocal8Bit(); + BlastProject::ins().removeCutoutTexture(ba.data()); + _updateTextureListWidget(); + } +} + +void FractureCutoutSettingsPanel::on_listWidget_currentRowChanged(int currentRow) +{ + +} + +void FractureCutoutSettingsPanel::on_btnTextureMap_clicked() +{ + +} + +void FractureCutoutSettingsPanel::on_comboBoxCutoutType_currentIndexChanged(int index) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + cutoutProjection.cutoutType = index; +} + +void FractureCutoutSettingsPanel::on_spinBoxPixelThreshold_valueChanged(int arg1) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + cutoutProjection.pixelThreshold = arg1; +} + +void FractureCutoutSettingsPanel::on_checkBoxTiled_stateChanged(int arg1) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + cutoutProjection.tiled = (arg1 != 0 ? true : false); +} + +void FractureCutoutSettingsPanel::on_checkBoxInvertU_stateChanged(int arg1) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + cutoutProjection.invertU = (arg1 != 0 ? true : false); +} + +void FractureCutoutSettingsPanel::on_checkBoxInvertV_stateChanged(int arg1) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + cutoutProjection.invertV = (arg1 != 0 ? true : false); +} + +void FractureCutoutSettingsPanel::on_btnFitToObject_clicked() +{ + +} + +void FractureCutoutSettingsPanel::on_btnApplyFracture_clicked() +{ + +} + +QString FractureCutoutSettingsPanel::_getTexturePathByName(const QString& name) +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + BPPStringArray& textureArray = cutoutProjection.textures; + + int count = textureArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + QFileInfo fileInfo(textureArray.buf[i].buf); + if (fileInfo.baseName() == name) + return textureArray.buf[i].buf; + } + + return ""; +} + +void FractureCutoutSettingsPanel::_updateTextureListWidget() +{ + BPPCutoutProjection& cutoutProjection = BlastProject::ins().getParams().fracture.cutoutProjection; + + ui->listWidget->clear(); + QStringList items; + for (int i = 0; i < cutoutProjection.textures.arraySizes[0]; ++i) + { + QFileInfo fileInfo(cutoutProjection.textures.buf[i].buf); + QByteArray ba = fileInfo.baseName().toLocal8Bit(); + const char* texture = (const char*)(ba); + items.append(texture); + } + ui->listWidget->addItems(items); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.h new file mode 100644 index 0000000..7faf2ae --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureCutoutSettingsPanel.h @@ -0,0 +1,52 @@ +#ifndef FRACTURECUTOUTSETTINGSPANEL_H +#define FRACTURECUTOUTSETTINGSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureCutoutSettingsPanel; +} + +class FractureCutoutSettingsPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureCutoutSettingsPanel(QWidget *parent = 0); + ~FractureCutoutSettingsPanel(); + void updateValues(); + +private slots: + void on_btnAddTexture_clicked(); + + void on_btnReloadTexture_clicked(); + + void on_btnRemoveTexture_clicked(); + + void on_listWidget_currentRowChanged(int currentRow); + + void on_btnTextureMap_clicked(); + + void on_comboBoxCutoutType_currentIndexChanged(int index); + + void on_spinBoxPixelThreshold_valueChanged(int arg1); + + void on_checkBoxTiled_stateChanged(int arg1); + + void on_checkBoxInvertU_stateChanged(int arg1); + + void on_checkBoxInvertV_stateChanged(int arg1); + + void on_btnFitToObject_clicked(); + + void on_btnApplyFracture_clicked(); + +private: + QString _getTexturePathByName(const QString& name); + void _updateTextureListWidget(); + +private: + Ui::FractureCutoutSettingsPanel *ui; +}; + +#endif // FRACTURECUTOUTSETTINGSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp new file mode 100644 index 0000000..1f7068d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.cpp @@ -0,0 +1,63 @@ +#include "FractureGeneralPanel.h" +#include "ui_FractureGeneralPanel.h" +#include "ProjectParams.h" + +FractureGeneralPanel::FractureGeneralPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureGeneralPanel) +{ + ui->setupUi(this); +} + +FractureGeneralPanel::~FractureGeneralPanel() +{ + delete ui; +} + +void FractureGeneralPanel::updateValues() +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + + ui->comboBoxFracturePreset->setCurrentIndex(fractureGeneral.fracturePreset); + ui->comboBoxFractureType->setCurrentIndex(fractureGeneral.fractureType); + ui->checkBoxAddDepth->setChecked(fractureGeneral.addDepth); + ui->checkBoxPerChunk->setChecked(fractureGeneral.perChunk); + ui->checkBoxNewMatID->setChecked(fractureGeneral.newMatID); + ui->comboBoxApplyMaterial->setCurrentIndex(fractureGeneral.applyMaterial); +} + +void FractureGeneralPanel::on_comboBoxFracturePreset_currentIndexChanged(int index) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.fracturePreset = index; +} + +void FractureGeneralPanel::on_comboBoxFractureType_currentIndexChanged(int index) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.fractureType = index; +} + +void FractureGeneralPanel::on_checkBoxAddDepth_stateChanged(int arg1) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.addDepth = (arg1 != 0 ? true : false); +} + +void FractureGeneralPanel::on_checkBoxPerChunk_stateChanged(int arg1) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.perChunk = (arg1 != 0 ? true : false); +} + +void FractureGeneralPanel::on_checkBoxNewMatID_stateChanged(int arg1) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.newMatID = (arg1 != 0 ? true:false); +} + +void FractureGeneralPanel::on_comboBoxApplyMaterial_currentIndexChanged(int index) +{ + BPPFractureGeneral& fractureGeneral = BlastProject::ins().getParams().fracture.general; + fractureGeneral.applyMaterial = index; +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h new file mode 100644 index 0000000..4b51f5e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureGeneralPanel.h @@ -0,0 +1,36 @@ +#ifndef FRACTUREGENERALPANEL_H +#define FRACTUREGENERALPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureGeneralPanel; +} + +class FractureGeneralPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureGeneralPanel(QWidget *parent = 0); + ~FractureGeneralPanel(); + void updateValues(); + +private slots: + void on_comboBoxFracturePreset_currentIndexChanged(int index); + + void on_comboBoxFractureType_currentIndexChanged(int index); + + void on_checkBoxAddDepth_stateChanged(int arg1); + + void on_checkBoxPerChunk_stateChanged(int arg1); + + void on_checkBoxNewMatID_stateChanged(int arg1); + + void on_comboBoxApplyMaterial_currentIndexChanged(int index); + +private: + Ui::FractureGeneralPanel *ui; +}; + +#endif // FRACTUREGENERALPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.cpp new file mode 100644 index 0000000..c08e3ba --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.cpp @@ -0,0 +1,40 @@ +#include "FractureShellCutSettingsPanel.h" +#include "ui_FractureShellCutSettingsPanel.h" +#include "ProjectParams.h" + +FractureShellCutSettingsPanel::FractureShellCutSettingsPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureShellCutSettingsPanel) +{ + ui->setupUi(this); +} + +FractureShellCutSettingsPanel::~FractureShellCutSettingsPanel() +{ + delete ui; +} + +void FractureShellCutSettingsPanel::updateValues() +{ + BPPShellCut& shellCut = BlastProject::ins().getParams().fracture.shellCut; + + ui->spinBoxThickness->setValue(shellCut.thickness); + ui->spinBoxThicknessVariation->setValue(shellCut.thicknessVariation); +} + +void FractureShellCutSettingsPanel::on_spinBoxThickness_valueChanged(double arg1) +{ + BPPShellCut& shellCut = BlastProject::ins().getParams().fracture.shellCut; + shellCut.thickness = arg1; +} + +void FractureShellCutSettingsPanel::on_spinBoxThicknessVariation_valueChanged(double arg1) +{ + BPPShellCut& shellCut = BlastProject::ins().getParams().fracture.shellCut; + shellCut.thicknessVariation = arg1; +} + +void FractureShellCutSettingsPanel::on_btnApplyFracture_clicked() +{ + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.h new file mode 100644 index 0000000..a664adb --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureShellCutSettingsPanel.h @@ -0,0 +1,30 @@ +#ifndef FRACTURESHELLCUTSETTINGSPANEL_H +#define FRACTURESHELLCUTSETTINGSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureShellCutSettingsPanel; +} + +class FractureShellCutSettingsPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureShellCutSettingsPanel(QWidget *parent = 0); + ~FractureShellCutSettingsPanel(); + void updateValues(); + +private slots: +void on_spinBoxThickness_valueChanged(double arg1); + + void on_spinBoxThicknessVariation_valueChanged(double arg1); + + void on_btnApplyFracture_clicked(); + +private: + Ui::FractureShellCutSettingsPanel *ui; +}; + +#endif // FRACTURESHELLCUTSETTINGSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp new file mode 100644 index 0000000..fa82ee2 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.cpp @@ -0,0 +1,105 @@ +#include "FractureSliceSettingsPanel.h" +#include "ui_FractureSliceSettingsPanel.h" +#include "ProjectParams.h" +#include "SimpleScene.h" +#include "SampleManager.h" +#include <QtWidgets/QMessageBox> + +FractureSliceSettingsPanel::FractureSliceSettingsPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureSliceSettingsPanel) +{ + ui->setupUi(this); +} + +FractureSliceSettingsPanel::~FractureSliceSettingsPanel() +{ + delete ui; +} + +void FractureSliceSettingsPanel::updateValues() +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + + ui->spinBoxNumSlices->setValue(slice.numSlices); + ui->spinBoxOffsetVariation->setValue(slice.offsetVariation); + ui->spinBoxRotationVariation->setValue(slice.rotationVariation); + ui->spinBoxNoiseAmplitude->setValue(slice.noiseAmplitude); + ui->spinBoxNoiseFrequency->setValue(slice.noiseFrequency); + ui->spinBoxNoiseSeed->setValue(slice.noiseSeed); +} + +void FractureSliceSettingsPanel::on_spinBoxNumSlices_valueChanged(int arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.numSlices = arg1; +} + +void FractureSliceSettingsPanel::on_spinBoxOffsetVariation_valueChanged(double arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.offsetVariation = arg1; +} + +void FractureSliceSettingsPanel::on_spinBoxRotationVariation_valueChanged(double arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.rotationVariation = arg1; +} + +void FractureSliceSettingsPanel::on_spinBoxNoiseAmplitude_valueChanged(double arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.noiseAmplitude = arg1; +} + +void FractureSliceSettingsPanel::on_spinBoxNoiseFrequency_valueChanged(double arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.noiseFrequency = arg1; +} + +void FractureSliceSettingsPanel::on_spinBoxNoiseSeed_valueChanged(int arg1) +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + slice.noiseSeed = arg1; +} + +void FractureSliceSettingsPanel::on_btnApplyFracture_clicked() +{ + BPPSlice& slice = BlastProject::ins().getParams().fracture.slice; + SliceFractureExecutor executor; + executor.applyNoise(slice.noiseAmplitude, slice.noiseAmplitude, 0, 0, 0, slice.noiseSeed); + executor.applyConfig(slice.numSlices, slice.numSlices, slice.numSlices, slice.offsetVariation, slice.rotationVariation); + + bool multiplyChunksSelected = false; + std::map<BlastAsset*, std::vector<uint32_t>> selectedChunks = SampleManager::ins()->getSelectedChunks(); + std::map<BlastAsset*, std::vector<uint32_t>>::iterator itrAssetSelectedChunks = selectedChunks.begin(); + + if (selectedChunks.size() > 1) + { + multiplyChunksSelected = true; + } + else if (selectedChunks.size() == 1 && itrAssetSelectedChunks->second.size() > 1) + { + multiplyChunksSelected = true; + } + else if((selectedChunks.size() == 1 && itrAssetSelectedChunks->second.size() == 0) || (selectedChunks.size() == 0)) + { + return; + } + + if (multiplyChunksSelected) + { + QMessageBox::warning(NULL, "Blast Tool", "Now, this tool can only fracture one chunk!"); + return; + } + + executor.setSourceAsset(itrAssetSelectedChunks->first); + executor.setTargetChunk(itrAssetSelectedChunks->second.at(0)); + executor.execute(); + + //VoronoiFractureExecutor executor; + //executor.setTargetChunk(0); + //executor.execute(); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h new file mode 100644 index 0000000..b85b58f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureSliceSettingsPanel.h @@ -0,0 +1,38 @@ +#ifndef FRACTURESLICESETTINGSPANEL_H +#define FRACTURESLICESETTINGSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureSliceSettingsPanel; +} + +class FractureSliceSettingsPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureSliceSettingsPanel(QWidget *parent = 0); + ~FractureSliceSettingsPanel(); + void updateValues(); + +private slots: + void on_spinBoxNumSlices_valueChanged(int arg1); + + void on_spinBoxOffsetVariation_valueChanged(double arg1); + + void on_spinBoxRotationVariation_valueChanged(double arg1); + + void on_spinBoxNoiseAmplitude_valueChanged(double arg1); + + void on_spinBoxNoiseFrequency_valueChanged(double arg1); + + void on_spinBoxNoiseSeed_valueChanged(int arg1); + + void on_btnApplyFracture_clicked(); + +private: + Ui::FractureSliceSettingsPanel *ui; +}; + +#endif // FRACTURESLICESETTINGSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp new file mode 100644 index 0000000..0f77e27 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.cpp @@ -0,0 +1,36 @@ +#include "FractureVisualizersPanel.h" +#include "ui_FractureVisualizersPanel.h" +#include "ProjectParams.h" + +FractureVisualizersPanel::FractureVisualizersPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureVisualizersPanel) +{ + ui->setupUi(this); +} + +FractureVisualizersPanel::~FractureVisualizersPanel() +{ + delete ui; +} + +void FractureVisualizersPanel::updateValues() +{ + BPPFractureVisualization& fractureVisualization = BlastProject::ins().getParams().fracture.visualization; + + ui->checkBoxFracturePreview->setChecked(fractureVisualization.fracturePreview); + ui->checkBoxDisplayFractureWidget->setChecked(fractureVisualization.displayFractureWidget); +} + +void FractureVisualizersPanel::on_checkBoxFracturePreview_stateChanged(int arg1) +{ + BPPFractureVisualization& fractureVisualization = BlastProject::ins().getParams().fracture.visualization; + fractureVisualization.fracturePreview = (arg1 != 0 ? true : false); +} + +void FractureVisualizersPanel::on_checkBoxDisplayFractureWidget_stateChanged(int arg1) +{ + BPPFractureVisualization& fractureVisualization = BlastProject::ins().getParams().fracture.visualization; + fractureVisualization.displayFractureWidget = (arg1 != 0 ? true : false); +} + diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h new file mode 100644 index 0000000..d542d7f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVisualizersPanel.h @@ -0,0 +1,28 @@ +#ifndef FRACTUREVISUALIZERSPANEL_H +#define FRACTUREVISUALIZERSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureVisualizersPanel; +} + +class FractureVisualizersPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureVisualizersPanel(QWidget *parent = 0); + ~FractureVisualizersPanel(); + void updateValues(); + +private slots: + void on_checkBoxFracturePreview_stateChanged(int arg1); + + void on_checkBoxDisplayFractureWidget_stateChanged(int arg1); + +private: + Ui::FractureVisualizersPanel *ui; +}; + +#endif // FRACTUREVISUALIZERSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp new file mode 100644 index 0000000..2142f80 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.cpp @@ -0,0 +1,354 @@ +#include "FractureVoronoiSettingsPanel.h" +#include "ui_FractureVoronoiSettingsPanel.h" +#include "ProjectParams.h" +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> +#include <QtCore/QFileInfo> +#include "AppMainWindow.h" +#include "ProjectParams.h" +#include "SimpleScene.h" +#include "SampleManager.h" + +FractureVoronoiSettingsPanel::FractureVoronoiSettingsPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::FractureVoronoiSettingsPanel), + _updateData(true) +{ + ui->setupUi(this); + + ui->groupBoxVisualizers->hide(); +} + +FractureVoronoiSettingsPanel::~FractureVoronoiSettingsPanel() +{ + delete ui; +} + +void FractureVoronoiSettingsPanel::updateValues() +{ + _updateData = false; + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + + ui->spinBoxNumberOfSites->setValue(voronoi.numSites); + ui->comboBoxSiteGeneration->setCurrentIndex(voronoi.siteGeneration); + ui->spinBoxGridSize->setValue(voronoi.gridSize); + ui->spinBoxGridScale->setValue(voronoi.gridScale); + ui->spinBoxAmplitude->setValue(voronoi.amplitude); + ui->spinBoxFrequency->setValue(voronoi.frequency); + + _updatePaintMaskComboBox(); + + _updateMeshCutterComboBox(); + ui->checkBoxFractureInsideCutter->setChecked(voronoi.fractureInsideCutter); + ui->checkBoxFractureOutsideCutter->setChecked(voronoi.fractureOutsideCutter); + + ui->spinBoxTextureSites->setValue(voronoi.numTextureSites); + + _updateTextureListWidget(); + _updateData = true; +} + +void FractureVoronoiSettingsPanel::on_checkBoxGridPreview_stateChanged(int arg1) +{ + +} + +void FractureVoronoiSettingsPanel::on_checkBoxFracturePreview_stateChanged(int arg1) +{ + +} + +void FractureVoronoiSettingsPanel::on_checkBoxCutterMesh_stateChanged(int arg1) +{ + +} + +void FractureVoronoiSettingsPanel::on_spinBoxNumberOfSites_valueChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.numSites = arg1; +} + +void FractureVoronoiSettingsPanel::on_comboBoxSiteGeneration_currentIndexChanged(int index) +{ + if (!_updateData) + return; + + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.siteGeneration = index; +} + +void FractureVoronoiSettingsPanel::on_spinBoxGridSize_valueChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.gridSize = arg1; +} + +void FractureVoronoiSettingsPanel::on_spinBoxGridScale_valueChanged(double arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.gridScale = arg1; +} + +void FractureVoronoiSettingsPanel::on_spinBoxAmplitude_valueChanged(double arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.amplitude = arg1; +} + +void FractureVoronoiSettingsPanel::on_spinBoxFrequency_valueChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.frequency = arg1; +} + +void FractureVoronoiSettingsPanel::on_comboBoxPaintMasks_currentIndexChanged(int index) +{ + if (!_updateData) + return; + + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.activePaintMask = index; +} + +void FractureVoronoiSettingsPanel::on_btnAddPaintMasks_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new paint mask:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isPaintMaskNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addPaintMasks(name.toUtf8().data()); + _updatePaintMaskComboBox(); + ui->comboBoxPaintMasks->setCurrentIndex(ui->comboBoxPaintMasks->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new paint mask!"); + } +} + +void FractureVoronoiSettingsPanel::on_btnRemovePaintMasks_clicked() +{ + if (ui->comboBoxPaintMasks->currentIndex() > -1) + { + BlastProject::ins().removePaintMasks(ui->comboBoxPaintMasks->currentText().toUtf8().data()); + _updatePaintMaskComboBox(); + } +} + +void FractureVoronoiSettingsPanel::on_comboBoxMeshCutter_currentIndexChanged(int index) +{ + if (!_updateData) + return; + + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.activeMeshCutter = index; +} + +void FractureVoronoiSettingsPanel::on_btnAddMeshCutter_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new mesh cutter:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isMeshCutterNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addMeshCutter(name.toUtf8().data()); + _updateMeshCutterComboBox(); + ui->comboBoxMeshCutter->setCurrentIndex(ui->comboBoxMeshCutter->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new cutter mesh!"); + } +} + +void FractureVoronoiSettingsPanel::on_btnRemoveMeshCutter_clicked() +{ + if (ui->comboBoxMeshCutter->currentIndex() > -1) + { + BlastProject::ins().removeMeshCutter(ui->comboBoxMeshCutter->currentText().toUtf8().data()); + _updateMeshCutterComboBox(); + } +} + +void FractureVoronoiSettingsPanel::on_checkBoxFractureInsideCutter_stateChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.fractureInsideCutter = (arg1 != 0 ? true : false); +} + +void FractureVoronoiSettingsPanel::on_checkBoxFractureOutsideCutter_stateChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.fractureOutsideCutter = (arg1 != 0 ? true : false); +} + +void FractureVoronoiSettingsPanel::on_btnAddTexture_clicked() +{ + QString texName = AppMainWindow::Inst().OpenTextureFile(); + + if (texName.isEmpty()) + return; + + QFileInfo fileInfo(texName); + QByteArray ba = fileInfo.absoluteFilePath().toLocal8Bit(); + const char* filePath = (const char*)(ba); + + if (!BlastProject::ins().isVoronoiTextureNameExist(texName.toUtf8().data())) + { + BlastProject::ins().addVoronoiTexture(filePath); + _updateTextureListWidget(); + ui->listWidgetTexture->setCurrentRow(ui->listWidgetTexture->count() - 1); + } + else + { + QMessageBox::warning(this, "Blast Tool", "The texture you selected is already exist!"); + } +} + +void FractureVoronoiSettingsPanel::on_btnReloadTexture_clicked() +{ + +} + +void FractureVoronoiSettingsPanel::on_btnRemoveTexture_clicked() +{ + if (ui->listWidgetTexture->currentRow() != -1) + { + QListWidgetItem *item = ui->listWidgetTexture->currentItem(); + QString texture = _getTexturePathByName(item->text()); + QByteArray ba = texture.toLocal8Bit(); + BlastProject::ins().removeVoronoiTexture(ba.data()); + _updateTextureListWidget(); + } +} + +void FractureVoronoiSettingsPanel::on_spinBoxTextureSites_valueChanged(int arg1) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + voronoi.numTextureSites = arg1; +} + +void FractureVoronoiSettingsPanel::on_listWidgetTexture_itemSelectionChanged() +{ + +} + +void FractureVoronoiSettingsPanel::on_btnTextureMap_clicked() +{ + +} + +void FractureVoronoiSettingsPanel::on_btnApplyFracture_clicked() +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + VoronoiFractureExecutor executor; + executor.setCellsCount(voronoi.numSites); + + bool multiplyChunksSelected = false; + std::map<BlastAsset*, std::vector<uint32_t>> selectedChunks = SampleManager::ins()->getSelectedChunks(); + std::map<BlastAsset*, std::vector<uint32_t>>::iterator itrAssetSelectedChunks = selectedChunks.begin(); + + if (selectedChunks.size() > 1) + { + multiplyChunksSelected = true; + } + else if (selectedChunks.size() == 1 && itrAssetSelectedChunks->second.size() > 1) + { + multiplyChunksSelected = true; + } + else if ((selectedChunks.size() == 1 && itrAssetSelectedChunks->second.size() == 0) || (selectedChunks.size() == 0)) + { + return; + } + + if (multiplyChunksSelected) + { + QMessageBox::warning(NULL, "Blast Tool", "Now, this tool can only fracture one chunk!"); + return; + } + + executor.setSourceAsset(itrAssetSelectedChunks->first); + executor.setTargetChunk(itrAssetSelectedChunks->second.at(0)); + executor.execute(); +} + +QString FractureVoronoiSettingsPanel::_getTexturePathByName(const QString& name) +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + BPPStringArray& textureArray = voronoi.textureSites; + + int count = textureArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + QFileInfo fileInfo(textureArray.buf[i].buf); + if (fileInfo.baseName() == name) + return textureArray.buf[i].buf; + } + + return ""; +} + +void FractureVoronoiSettingsPanel::_updatePaintMaskComboBox() +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + + ui->comboBoxPaintMasks->clear(); + QStringList items; + for (int i = 0; i < voronoi.paintMasks.arraySizes[0]; ++i) + { + items.append(voronoi.paintMasks.buf[i].buf); + } + ui->comboBoxPaintMasks->addItems(items); + ui->comboBoxPaintMasks->setCurrentIndex(voronoi.activePaintMask); +} + +void FractureVoronoiSettingsPanel::_updateMeshCutterComboBox() +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + + ui->comboBoxMeshCutter->clear(); + QStringList items; + for (int i = 0; i < voronoi.meshCutters.arraySizes[0]; ++i) + { + items.append(voronoi.meshCutters.buf[i].buf); + } + ui->comboBoxMeshCutter->addItems(items); + ui->comboBoxMeshCutter->setCurrentIndex(voronoi.activeMeshCutter); +} + +void FractureVoronoiSettingsPanel::_updateTextureListWidget() +{ + BPPVoronoi& voronoi = BlastProject::ins().getParams().fracture.voronoi; + + ui->listWidgetTexture->clear(); + QStringList items; + for (int i = 0; i < voronoi.textureSites.arraySizes[0]; ++i) + { + QFileInfo fileInfo(voronoi.textureSites.buf[i].buf); + QByteArray ba = fileInfo.baseName().toLocal8Bit(); + const char* texture = (const char*)(ba); + items.append(texture); + } + ui->listWidgetTexture->addItems(items); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h new file mode 100644 index 0000000..6a0668d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/FractureVoronoiSettingsPanel.h @@ -0,0 +1,79 @@ +#ifndef FRACTUREVORONOISETTINGSPANEL_H +#define FRACTUREVORONOISETTINGSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class FractureVoronoiSettingsPanel; +} + +class FractureVoronoiSettingsPanel : public QWidget +{ + Q_OBJECT + +public: + explicit FractureVoronoiSettingsPanel(QWidget *parent = 0); + ~FractureVoronoiSettingsPanel(); + void updateValues(); + +private slots: + void on_checkBoxGridPreview_stateChanged(int arg1); + + void on_checkBoxFracturePreview_stateChanged(int arg1); + + void on_checkBoxCutterMesh_stateChanged(int arg1); + + void on_spinBoxNumberOfSites_valueChanged(int arg1); + + void on_comboBoxSiteGeneration_currentIndexChanged(int index); + + void on_spinBoxGridSize_valueChanged(int arg1); + + void on_spinBoxGridScale_valueChanged(double arg1); + + void on_spinBoxAmplitude_valueChanged(double arg1); + + void on_spinBoxFrequency_valueChanged(int arg1); + + void on_comboBoxPaintMasks_currentIndexChanged(int index); + + void on_btnAddPaintMasks_clicked(); + + void on_btnRemovePaintMasks_clicked(); + + void on_comboBoxMeshCutter_currentIndexChanged(int index); + + void on_btnAddMeshCutter_clicked(); + + void on_btnRemoveMeshCutter_clicked(); + + void on_checkBoxFractureInsideCutter_stateChanged(int arg1); + + void on_checkBoxFractureOutsideCutter_stateChanged(int arg1); + + void on_btnAddTexture_clicked(); + + void on_btnReloadTexture_clicked(); + + void on_btnRemoveTexture_clicked(); + + void on_spinBoxTextureSites_valueChanged(int arg1); + + void on_listWidgetTexture_itemSelectionChanged(); + + void on_btnTextureMap_clicked(); + + void on_btnApplyFracture_clicked(); + +private: + QString _getTexturePathByName(const QString& name); + void _updatePaintMaskComboBox(); + void _updateMeshCutterComboBox(); + void _updateTextureListWidget(); + +private: + Ui::FractureVoronoiSettingsPanel *ui; + bool _updateData; +}; + +#endif // FRACTUREVORONOISETTINGSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp new file mode 100644 index 0000000..88915f1 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.cpp @@ -0,0 +1,281 @@ +#include "GeneralPanel.h" +#include "ui_GeneralPanel.h" +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> + +GeneralPanel::GeneralPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::GeneralPanel) +{ + ui->setupUi(this); +} + +GeneralPanel::~GeneralPanel() +{ + delete ui; +} + +void GeneralPanel::updateValues() +{ + std::vector<StressSolverUserPreset> presets = BlastProject::ins().getUserPresets(); + ui->comboBoxUserPreset->clear(); + int countUserPresets = (int)presets.size(); + if (countUserPresets > 0) + { + QStringList userPresets; + for (int i = 0; i < countUserPresets; ++i) + { + userPresets.append(presets[i].name.c_str()); + } + ui->comboBoxUserPreset->addItems(userPresets); + } + + std::vector<BPPAsset*> selectedAssets = BlastProject::ins().getSelectedBlastAssets(); + if (selectedAssets.size() > 0) + { + ui->comboBoxUserPreset->setCurrentText(selectedAssets[0]->activePreset.buf); + + _updateStressSolverUIs(); + } + else + { + ui->comboBoxUserPreset->setCurrentIndex(-1); + + } +} + +void GeneralPanel::on_comboBoxUserPreset_currentIndexChanged(int index) +{ + std::vector<BPPAsset*> assets = BlastProject::ins().getSelectedBlastAssets(); + for (size_t i = 0; i < assets.size(); ++i) + { + QByteArray tem = ui->comboBoxUserPreset->currentText().toUtf8(); + copy(assets[i]->activePreset, tem.data()); + + BPPStressSolver* preset = _getUserPreset(tem.data()); + if (preset) + { + copy(assets[i]->stressSolver, *preset); + } + } + _updateStressSolverUIs(); +} + +void GeneralPanel::on_btnAddUserPreset_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new User preset:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isUserPresetNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + BlastProject::ins().addUserPreset(name.toUtf8().data()); + updateValues(); + ui->comboBoxUserPreset->setCurrentIndex(ui->comboBoxUserPreset->count() - 1); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new preset!"); + } +} + +void GeneralPanel::on_btnModifyUserPreset_clicked() +{ + if (ui->comboBoxUserPreset->currentIndex() == -1) + { + QMessageBox::warning(this, "Blast Tool", "You should select an user preset!"); + return; + } + + QByteArray tmp = ui->comboBoxUserPreset->currentText().toUtf8(); + const char* oldName = tmp.data(); + + bool ok = false; + QString newName = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input new name for the selected user preset:"), + QLineEdit::Normal, + oldName, + &ok); + bool nameExist = BlastProject::ins().isUserPresetNameExist(newName.toUtf8().data()); + if (ok && !newName.isEmpty() && !nameExist) + { + int curIndex = ui->comboBoxUserPreset->currentIndex(); + + std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets(); + presets[curIndex].name = newName.toUtf8().data(); + updateValues(); + ui->comboBoxUserPreset->setCurrentIndex(curIndex); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && newName.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the selected graphics material!"); + } +} + +void GeneralPanel::on_btnSaveUserPreset_clicked() +{ + int currentUserPreset = ui->comboBoxUserPreset->currentIndex(); + if (-1 != currentUserPreset) + { + std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets(); + BPPStressSolver& stressSolver = presets[currentUserPreset].stressSolver; + stressSolver.solverMode = ui->comboBoxSolverMode->currentIndex(); + stressSolver.linearFactor = ui->spinBoxLinearFactor->value(); + stressSolver.angularFactor = ui->spinBoxAngularFactor->value(); + stressSolver.meanError = ui->spinBoxMeanError->value(); + stressSolver.varianceError = ui->spinBoxVarianceError->value(); + stressSolver.bondsPerFrame = ui->spinBoxBondsPerFrame->value(); + stressSolver.bondsIterations = ui->spinBoxBondsIterations->value(); + } + + BlastProject::ins().saveUserPreset(); +} + +void GeneralPanel::on_comboBoxSolverMode_currentIndexChanged(int index) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->solverMode = index; + } +} + +void GeneralPanel::on_spinBoxLinearFactor_valueChanged(double arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->linearFactor = arg1; + } + +} + +void GeneralPanel::on_spinBoxAngularFactor_valueChanged(double arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->angularFactor = arg1; + } +} + +void GeneralPanel::on_spinBoxMeanError_valueChanged(double arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->meanError = arg1; + } +} + +void GeneralPanel::on_spinBoxVarianceError_valueChanged(double arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->varianceError = arg1; + } +} + +void GeneralPanel::on_spinBoxBondsPerFrame_valueChanged(int arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->bondsPerFrame = arg1; + } +} + +void GeneralPanel::on_spinBoxBondsIterations_valueChanged(int arg1) +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + + if (stressSolver) + { + stressSolver->bondsIterations = arg1; + } +} + +BPPStressSolver* GeneralPanel::_getCurrentStressSolver() +{ + int currentUserPreset = ui->comboBoxUserPreset->currentIndex(); + + if (-1 != currentUserPreset) + { + std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets(); + return &(presets[currentUserPreset].stressSolver); + } + else + { + std::vector<BPPAsset*> assets = BlastProject::ins().getSelectedBlastAssets(); + + if (assets.size() > 0) + { + return &(assets[0]->stressSolver); + } + } + + return nullptr; +} + +BPPStressSolver* GeneralPanel::_getUserPreset(const char* name) +{ + std::vector<StressSolverUserPreset>& presets = BlastProject::ins().getUserPresets(); + + for (size_t i = 0; i < presets.size(); ++i) + { + if (presets[i].name == name) + return &(presets[i].stressSolver); + } + + return nullptr; +} + +void GeneralPanel::_updateStressSolverUIs() +{ + BPPStressSolver* stressSolver = _getCurrentStressSolver(); + if (stressSolver != nullptr) + { + ui->comboBoxSolverMode->setCurrentIndex(stressSolver->solverMode); + ui->spinBoxLinearFactor->setValue(stressSolver->linearFactor); + ui->spinBoxAngularFactor->setValue(stressSolver->angularFactor); + ui->spinBoxMeanError->setValue(stressSolver->meanError); + ui->spinBoxVarianceError->setValue(stressSolver->varianceError); + ui->spinBoxBondsPerFrame->setValue(stressSolver->bondsPerFrame); + ui->spinBoxBondsIterations->setValue(stressSolver->bondsIterations); + } + else + { + BPPStressSolver noStressSolver; + init(noStressSolver); + + ui->comboBoxSolverMode->setCurrentIndex(noStressSolver.solverMode); + ui->spinBoxLinearFactor->setValue(noStressSolver.linearFactor); + ui->spinBoxAngularFactor->setValue(noStressSolver.angularFactor); + ui->spinBoxMeanError->setValue(noStressSolver.meanError); + ui->spinBoxVarianceError->setValue(noStressSolver.varianceError); + ui->spinBoxBondsPerFrame->setValue(noStressSolver.bondsPerFrame); + ui->spinBoxBondsIterations->setValue(noStressSolver.bondsIterations); + } + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h new file mode 100644 index 0000000..a7a52e3 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/GeneralPanel.h @@ -0,0 +1,52 @@ +#ifndef GENERALPANEL_H +#define GENERALPANEL_H + +#include <QtWidgets/QWidget> +#include "ProjectParams.h" + +namespace Ui { +class GeneralPanel; +} + +class GeneralPanel : public QWidget +{ + Q_OBJECT + +public: + explicit GeneralPanel(QWidget *parent = 0); + ~GeneralPanel(); + void updateValues(); + +private slots: + void on_comboBoxUserPreset_currentIndexChanged(int index); + + void on_btnAddUserPreset_clicked(); + + void on_btnModifyUserPreset_clicked(); + + void on_btnSaveUserPreset_clicked(); + + void on_comboBoxSolverMode_currentIndexChanged(int index); + + void on_spinBoxLinearFactor_valueChanged(double arg1); + + void on_spinBoxAngularFactor_valueChanged(double arg1); + + void on_spinBoxMeanError_valueChanged(double arg1); + + void on_spinBoxVarianceError_valueChanged(double arg1); + + void on_spinBoxBondsPerFrame_valueChanged(int arg1); + + void on_spinBoxBondsIterations_valueChanged(int arg1); + +private: + BPPStressSolver* _getCurrentStressSolver(); + BPPStressSolver* _getUserPreset(const char* name); + void _updateStressSolverUIs(); + +private: + Ui::GeneralPanel *ui; +}; + +#endif // GENERALPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp new file mode 100644 index 0000000..6095f67 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.cpp @@ -0,0 +1,265 @@ +#include "MaterialAssignmentsPanel.h" +#include "ui_MaterialAssignmentsPanel.h" +#include "ProjectParams.h" +#include "RenderMaterial.h" +#include "SampleManager.h" +#include "MaterialLibraryPanel.h" + +MaterialAssignmentsPanel* pMaterialAssignmentsPanel = nullptr; +MaterialAssignmentsPanel* MaterialAssignmentsPanel::ins() +{ + return pMaterialAssignmentsPanel; +} + +MaterialAssignmentsPanel::MaterialAssignmentsPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::MaterialAssignmentsPanel), + _selectedGraphicsMesh(-1) +{ + ui->setupUi(this); + pMaterialAssignmentsPanel = this; + m_bValid = true; +} + +void MaterialAssignmentsPanel::getMaterialNameAndPaths(std::vector<std::string>& materialNames, std::vector<std::string>& materialPaths) +{ + QString m1 = ui->comboBoxMaterialID1->currentText(); + QString m2 = ui->comboBoxMaterialID2->currentText(); + std::string name1 = m1.toUtf8().data(); + std::string name2 = m2.toUtf8().data(); + std::string path1 = ""; + std::string path2 = ""; + + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& theArray = projectParams.graphicsMaterials; + int count = theArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + BPPGraphicsMaterial& item = theArray.buf[i]; + std::string name = item.name.buf; + std::string path = item.diffuseTextureFilePath.buf; + if (name1 == name) + { + path1 = path; + } + else if (name2 == name) + { + path2 = path; + } + else if (path1 != "" && path2 != "") + { + break; + } + } + + materialNames.push_back(name1); + materialNames.push_back(name2); + materialPaths.push_back(path1); + materialPaths.push_back(path2); +} + +MaterialAssignmentsPanel::~MaterialAssignmentsPanel() +{ + delete ui; +} + +void MaterialAssignmentsPanel::updateValues() +{ + m_bValid = false; + ui->comboBoxMaterialID1->clear(); + ui->comboBoxMaterialID2->clear(); + m_bValid = true; + + QStringList materialNames; + materialNames.append("None"); + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& theArray = projectParams.graphicsMaterials; + int count = theArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + BPPGraphicsMaterial& item = theArray.buf[i]; + materialNames.append(item.name.buf); + } + + m_bValid = false; + ui->comboBoxMaterialID1->insertItems(0, materialNames); + ui->comboBoxMaterialID2->insertItems(0, materialNames); + m_bValid = true; + + SampleManager* pSampleManager = SampleManager::ins(); + if (pSampleManager == nullptr) + { + return; + } + + BlastAsset* pBlastAsset = nullptr; + int index = -1; + pSampleManager->getCurrentSelectedInstance(&pBlastAsset, index); + if (pBlastAsset == nullptr || index == -1) + { + return; + } + + RenderMaterial* pRenderMaterial[] = { nullptr, nullptr }; + std::string strMaterialNames[] = { "None", "None" }; + bool ex[] = { true, false }; + for (int i = 0; i < 2; i++) + { + pSampleManager->getMaterialForCurrentFamily(&pRenderMaterial[i], ex[i]); + if (pRenderMaterial[i] != nullptr) + { + std::string m = pRenderMaterial[i]->getMaterialName(); + if (m != "") + { + strMaterialNames[i] = m; + } + } + } + + m_bValid = false; + ui->comboBoxMaterialID1->setCurrentText(strMaterialNames[0].c_str()); + ui->comboBoxMaterialID2->setCurrentText(strMaterialNames[1].c_str()); + m_bValid = true; + + return; + + if (_selectedGraphicsMesh > -1) + { + BPParams& projectParams = BlastProject::ins().getParams(); + BPPBlast& blast = projectParams.blast; + BPPGraphicsMaterialArray& graphicsMaterialsArray = projectParams.graphicsMaterials; + + BPPMaterialAssignments& assignment = blast.graphicsMeshes.buf[_selectedGraphicsMesh].materialAssignments; + + ui->comboBoxMaterialID1->clear(); + ui->comboBoxMaterialID2->clear(); + ui->comboBoxMaterialID3->clear(); + ui->comboBoxMaterialID4->clear(); + + QStringList materialNames; + materialNames.append("None"); + int count = graphicsMaterialsArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + materialNames.append(graphicsMaterialsArray.buf[i].name.buf); + } + + ui->comboBoxMaterialID1->insertItems(0, materialNames); + ui->comboBoxMaterialID2->insertItems(0, materialNames); + ui->comboBoxMaterialID3->insertItems(0, materialNames); + ui->comboBoxMaterialID4->insertItems(0, materialNames); + + ui->comboBoxMaterialID1->setCurrentIndex(assignment.materialIndexes[0] + 1); + ui->comboBoxMaterialID2->setCurrentIndex(assignment.materialIndexes[1] + 1); + ui->comboBoxMaterialID3->setCurrentIndex(assignment.materialIndexes[2] + 1); + ui->comboBoxMaterialID4->setCurrentIndex(assignment.materialIndexes[3] + 1); + } + + +} + +void MaterialAssignmentsPanel::on_comboBoxMaterialID1_currentIndexChanged(int index) +{ + if (index < 0 || !m_bValid) + return; + + RenderMaterial* pRenderMaterial = nullptr; + + QString currentText = ui->comboBoxMaterialID1->currentText(); + std::string name = currentText.toUtf8().data(); + + SampleManager* pSampleManager = SampleManager::ins(); + if (pSampleManager == nullptr) + { + return; + } + std::map<std::string, RenderMaterial*>& renderMaterials = pSampleManager->getRenderMaterials(); + std::map<std::string, RenderMaterial*>::iterator it = renderMaterials.find(name); + if (it != renderMaterials.end()) + { + pRenderMaterial = it->second; + } + else + { + MaterialLibraryPanel* pMaterialLibraryPanel = MaterialLibraryPanel::ins(); + std::map<std::string, RenderMaterial*>& renderMaterials2 = pMaterialLibraryPanel->getRenderMaterials(); + it = renderMaterials2.find(name); + if (it != renderMaterials2.end()) + { + pRenderMaterial = it->second; + } + } + + pSampleManager->setMaterialForCurrentFamily(pRenderMaterial, true); + + return; + assignMaterialToMaterialID(0, index - 1); +} + +void MaterialAssignmentsPanel::on_comboBoxMaterialID2_currentIndexChanged(int index) +{ + if (index < 0 || !m_bValid) + return; + + RenderMaterial* pRenderMaterial = nullptr; + + QString currentText = ui->comboBoxMaterialID2->currentText(); + std::string name = currentText.toUtf8().data(); + + SampleManager* pSampleManager = SampleManager::ins(); + if (pSampleManager == nullptr) + { + return; + } + std::map<std::string, RenderMaterial*>& renderMaterials = pSampleManager->getRenderMaterials(); + std::map<std::string, RenderMaterial*>::iterator it = renderMaterials.find(name); + if (it != renderMaterials.end()) + { + pRenderMaterial = it->second; + } + else + { + MaterialLibraryPanel* pMaterialLibraryPanel = MaterialLibraryPanel::ins(); + std::map<std::string, RenderMaterial*>& renderMaterials2 = pMaterialLibraryPanel->getRenderMaterials(); + it = renderMaterials2.find(name); + if (it != renderMaterials2.end()) + { + pRenderMaterial = it->second; + } + } + + pSampleManager->setMaterialForCurrentFamily(pRenderMaterial, false); + + return; + assignMaterialToMaterialID(1, index - 1); +} + +void MaterialAssignmentsPanel::on_comboBoxMaterialID3_currentIndexChanged(int index) +{ + assignMaterialToMaterialID(2, index - 1); +} + +void MaterialAssignmentsPanel::on_comboBoxMaterialID4_currentIndexChanged(int index) +{ + assignMaterialToMaterialID(3, index - 1); +} + +void MaterialAssignmentsPanel::assignMaterialToMaterialID(int materialID, int materialIndex) +{ + if (materialID < 0 || materialID > 3 || materialIndex < 0) + return; + + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& graphicsMaterialArray = projectParams.graphicsMaterials; + BPPBlast& blast = projectParams.blast; + + if (materialIndex >= graphicsMaterialArray.arraySizes[0]) + return; + + BPPGraphicsMeshArray& graphicsMeshArray = blast.graphicsMeshes; + + if (_selectedGraphicsMesh > -1 && _selectedGraphicsMesh < graphicsMeshArray.arraySizes[0]) + { + graphicsMeshArray.buf[_selectedGraphicsMesh].materialAssignments.materialIndexes[materialID] = materialIndex; + } +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.h new file mode 100644 index 0000000..782baa8 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialAssignmentsPanel.h @@ -0,0 +1,40 @@ +#ifndef MATERIALASSIGNMENTSPANEL_H +#define MATERIALASSIGNMENTSPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class MaterialAssignmentsPanel; +} + +class MaterialAssignmentsPanel : public QWidget +{ + Q_OBJECT + +public: + explicit MaterialAssignmentsPanel(QWidget *parent = 0); + ~MaterialAssignmentsPanel(); + void updateValues(); + + static MaterialAssignmentsPanel* ins(); + void getMaterialNameAndPaths(std::vector<std::string>& materialNames, std::vector<std::string>& materialPaths); + +private slots: + void on_comboBoxMaterialID1_currentIndexChanged(int index); + + void on_comboBoxMaterialID2_currentIndexChanged(int index); + + void on_comboBoxMaterialID3_currentIndexChanged(int index); + + void on_comboBoxMaterialID4_currentIndexChanged(int index); + +private: + void assignMaterialToMaterialID(int materialID, int materialIndex); + +private: + Ui::MaterialAssignmentsPanel *ui; + int _selectedGraphicsMesh; + bool m_bValid; +}; + +#endif // MATERIALASSIGNMENTSPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp new file mode 100644 index 0000000..963326c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.cpp @@ -0,0 +1,473 @@ +#include "MaterialLibraryPanel.h" +#include "ui_MaterialLibraryPanel.h" +#include <QtCore/QFileInfo> +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QMessageBox> +#include "QtUtil.h" +#include "AppMainWindow.h" +#include "SimpleScene.h" +#include "RenderMaterial.h" +#include "ResourceManager.h" +#include "SampleManager.h" +#include "MaterialAssignmentsPanel.h" +#include "Renderable.h" +enum ETextureType +{ + eDiffuseTexture, + eSpecularTexture, + eNormalTexture +}; + +void OnTextureButtonClicked(BPPGraphicsMaterial& material, ETextureType t, QPushButton* pButton) +{ + QString texName = AppMainWindow::Inst().OpenTextureFile(); + + QFileInfo fileInfo(texName); + QByteArray ba = fileInfo.absoluteFilePath().toLocal8Bit(); + const char* filePath = (const char*)(ba); + + switch (t) + { + case eDiffuseTexture: + copy(material.diffuseTextureFilePath, filePath); + break; + case eSpecularTexture: + copy(material.specularTextureFilePath, filePath); + break; + case eNormalTexture: + copy(material.normalTextureFilePath, filePath); + break; + } + + if (texName.isEmpty()) + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + else + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png")); + + SimpleScene::Inst()->SetFurModified(true); +} + +void OnTextureReload(BPPGraphicsMaterial& material, ETextureType t, QPushButton* pButton) +{ + QString texName; + switch (t) + { + case eDiffuseTexture: + texName = material.diffuseTextureFilePath.buf; + // to do: reload texture + break; + case eSpecularTexture: + texName = material.specularTextureFilePath.buf; + // to do: reload texture + break; + case eNormalTexture: + texName = material.normalTextureFilePath.buf; + // to do: reload texture + break; + } + + if (texName.isEmpty()) + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + else + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png")); + + SimpleScene::Inst()->SetFurModified(true); +} + +void OnTextureClear(BPPGraphicsMaterial& material, ETextureType t, QPushButton* pButton) +{ + switch (t) + { + case eDiffuseTexture: + freeString(material.diffuseTextureFilePath); + // to do: clear texture + break; + case eSpecularTexture: + freeString(material.specularTextureFilePath); + // to do: clear texture + break; + case eNormalTexture: + freeString(material.normalTextureFilePath); + // to do: clear texture + break; + } + + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + + SimpleScene::Inst()->SetFurModified(true); +} + +MaterialLibraryPanel* pMaterialLibraryPanel = nullptr; +MaterialLibraryPanel* MaterialLibraryPanel::ins() +{ + return pMaterialLibraryPanel; +} + +void MaterialLibraryPanel::addMaterial(std::string materialName, std::string diffuseTexture) +{ + if (!BlastProject::ins().isGraphicsMaterialNameExist(materialName.c_str())) + { + BlastProject::ins().addGraphicsMaterial(materialName.c_str(), diffuseTexture.c_str()); + updateValues(); + ui->listWidget->setCurrentRow(ui->listWidget->count() - 1); + } +} + +void MaterialLibraryPanel::removeMaterial(std::string name) +{ + BlastProject::ins().removeGraphicsMaterial(name.c_str()); + updateValues(); + ui->listWidget->setCurrentRow(ui->listWidget->count() - 1); +} + +void MaterialLibraryPanel::deleteMaterials() +{ + std::vector<std::string>::iterator itStr; + std::vector<Renderable*>::iterator itRenderable; + + for (itStr = m_NeedDeleteRenderMaterials.begin(); itStr != m_NeedDeleteRenderMaterials.end(); itStr++) + { + std::string materialName = *itStr; + RenderMaterial* pRenderMaterial = m_RenderMaterialMap[materialName]; + std::vector<Renderable*>& renderables = pRenderMaterial->getRelatedRenderables(); + for (itRenderable = renderables.begin(); itRenderable != renderables.end(); itRenderable++) + { + Renderable* pRenderable = *itRenderable; + pRenderable->setMaterial(*RenderMaterial::getDefaultRenderMaterial()); + } + + std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(materialName); + if (it != m_RenderMaterialMap.end()) + { + m_RenderMaterialMap.erase(it); + MaterialLibraryPanel::ins()->removeMaterial(materialName); + } + } + + m_NeedDeleteRenderMaterials.clear(); +} + +MaterialLibraryPanel::MaterialLibraryPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::MaterialLibraryPanel) +{ + ui->setupUi(this); + + pMaterialLibraryPanel = this; +} + +MaterialLibraryPanel::~MaterialLibraryPanel() +{ + delete ui; +} + +void MaterialLibraryPanel::updateValues() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& graphicsMaterialArray = projectParams.graphicsMaterials; + + ui->listWidget->clear(); + QStringList materialNames; + int count = graphicsMaterialArray.arraySizes[0]; + for (int i = 0; i < count; ++i) + { + materialNames.append(graphicsMaterialArray.buf[i].name.buf); + } + ui->listWidget->addItems(materialNames); + + if (count > 0) + { + ui->btnModifyMat->setEnabled(true); + ui->btnRemoveMat->setEnabled(true); + } + else + { + ui->btnModifyMat->setEnabled(false); + ui->btnRemoveMat->setEnabled(false); + } + + MaterialAssignmentsPanel::ins()->updateValues(); +} + +void MaterialLibraryPanel::on_btnAddMat_clicked() +{ + bool ok = false; + QString name = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input name for new graphics material:"), + QLineEdit::Normal, + "", + &ok); + bool nameExist = BlastProject::ins().isGraphicsMaterialNameExist(name.toUtf8().data()); + if (ok && !name.isEmpty() && !nameExist) + { + ResourceManager* pResourceManager = ResourceManager::ins(); + std::string strName = name.toUtf8().data(); + RenderMaterial* pRenderMaterial = new RenderMaterial(strName.c_str(), *pResourceManager, "model_simple_textured_ex"); + m_RenderMaterialMap[strName] = pRenderMaterial; + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && name.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the new graphics material!"); + } +} + +void MaterialLibraryPanel::on_btnModifyMat_clicked() +{ + QList<QListWidgetItem*> items = ui->listWidget->selectedItems(); + if (items.size() == 0) + { + SampleManager::ins()->output("please select a material first !"); + return; + } + QByteArray tmp = items.at(0)->text().toUtf8(); + const char* oldName = tmp.data(); + + bool ok = false; + QString newName = QInputDialog::getText(this, + tr("Blast Tool"), + tr("Please input new name for the selected graphics material:"), + QLineEdit::Normal, + oldName, + &ok); + bool nameExist = BlastProject::ins().isGraphicsMaterialNameExist(newName.toUtf8().data()); + if (ok && !newName.isEmpty() && !nameExist) + { + std::string strOldName = oldName; + std::string strNewName = newName.toUtf8().data(); + + std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(strOldName); + if (it != m_RenderMaterialMap.end()) + { + RenderMaterial* pRenderMaterial = it->second; + m_RenderMaterialMap.erase(it); + m_RenderMaterialMap[strNewName] = pRenderMaterial; + } + + SampleManager::ins()->renameRenderMaterial(strOldName, strNewName); + + BlastProject::ins().renameGraphicsMaterial(oldName, newName.toUtf8().data()); + updateValues(); + } + else if (ok && nameExist) + { + QMessageBox::warning(this, "Blast Tool", "The name you input is already exist!"); + } + else if (ok && newName.isEmpty()) + { + QMessageBox::warning(this, "Blast Tool", "You need input a name for the selected graphics material!"); + } +} + +void MaterialLibraryPanel::on_btnRemoveMat_clicked() +{ + QList<QListWidgetItem*> items = ui->listWidget->selectedItems(); + if (items.size() == 0) + { + SampleManager::ins()->output("please select a material first !"); + return; + } + QByteArray tem = items.at(0)->text().toUtf8(); + + std::string strName = tem.data(); + std::map<std::string, RenderMaterial*>::iterator it = m_RenderMaterialMap.find(strName); + if (it != m_RenderMaterialMap.end()) + { + m_NeedDeleteRenderMaterials.push_back(it->second->getMaterialName()); + } + else + { + SampleManager::ins()->deleteRenderMaterial(strName); + } +} + +void MaterialLibraryPanel::on_listWidget_currentRowChanged(int currentRow) +{ + _refreshMaterialValues(currentRow); +} + +void MaterialLibraryPanel::on_btnDiffuseColor_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + atcore_float4* color = (atcore_float4*)&(material->diffuseColor); + pickColor(*color); + setButtonColor(ui->btnDiffuseColor, color->x, color->y, color->z); + } +} + +void MaterialLibraryPanel::on_btnDiffuseColorTex_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureButtonClicked(*material, eDiffuseTexture, ui->btnDiffuseColorTex); + } +} + +void MaterialLibraryPanel::on_btnDiffuseColorTexReload_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureReload(*material, eDiffuseTexture, ui->btnDiffuseColorTex); + + QString qName = material->name.buf; + std::string strName = qName.toUtf8().data(); + QString qTexture = material->diffuseTextureFilePath.buf; + std::string strTexture = qTexture.toUtf8().data(); + + std::map<std::string, RenderMaterial*>& renderMaterials = SampleManager::ins()->getRenderMaterials(); + std::map<std::string, RenderMaterial*>::iterator it = renderMaterials.find(strName); + if (it != renderMaterials.end()) + { + it->second->setTextureFileName(strTexture); + } + } +} + +void MaterialLibraryPanel::on_btnDiffuseColorTexClear_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureClear(*material, eDiffuseTexture, ui->btnDiffuseColorTex); + + QString qName = material->name.buf; + std::string strName = qName.toUtf8().data(); + QString qTexture = material->diffuseTextureFilePath.buf; + std::string strTexture = qTexture.toUtf8().data(); + + std::map<std::string, RenderMaterial*>& renderMaterials = SampleManager::ins()->getRenderMaterials(); + std::map<std::string, RenderMaterial*>::iterator it = renderMaterials.find(strName); + if (it != renderMaterials.end()) + { + it->second->setTextureFileName(strTexture); + } + } +} + +void MaterialLibraryPanel::on_btnSpecularColor_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + atcore_float4* color = (atcore_float4*)&(material->specularColor); + pickColor(*color); + setButtonColor(ui->btnSpecularColor, color->x, color->y, color->z); + } +} + +void MaterialLibraryPanel::on_btnSpecularColorTex_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureButtonClicked(*material, eSpecularTexture, ui->btnSpecularColorTex); + } +} + +void MaterialLibraryPanel::on_btnSpecularColorTexReload_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureReload(*material, eSpecularTexture, ui->btnSpecularColorTex); + } +} + +void MaterialLibraryPanel::on_btnSpecularColorTexClear_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureClear(*material, eSpecularTexture, ui->btnSpecularColorTex); + } +} + +void MaterialLibraryPanel::on_spinSpecularShin_valueChanged(double arg1) +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + material->specularShininess = (float)arg1; + } +} + +void MaterialLibraryPanel::on_btnNormalColorTex_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureButtonClicked(*material, eNormalTexture, ui->btnNormalColorTex); + } +} + +void MaterialLibraryPanel::on_btnNormalColorTexReload_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureReload(*material, eNormalTexture, ui->btnNormalColorTex); + } +} + +void MaterialLibraryPanel::on_btnNormalColorTexClear_clicked() +{ + BPPGraphicsMaterial* material = _getSelectedMaterial(); + if (material) + { + OnTextureClear(*material, eNormalTexture, ui->btnNormalColorTex); + } +} + +void MaterialLibraryPanel::_refreshMaterialValues(int idx) +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& graphicsMaterialArray = projectParams.graphicsMaterials; + int count = graphicsMaterialArray.arraySizes[0]; + if (idx >= 0 && idx < count) + { + const BPPGraphicsMaterial& material = graphicsMaterialArray.buf[idx]; + + ui->spinSpecularShin->setValue(material.specularShininess); + + const nvidia::NvVec4& diffuseColor = material.diffuseColor; + const nvidia::NvVec4& specularColor = material.specularColor; + setButtonColor(ui->btnDiffuseColor, diffuseColor.x, diffuseColor.y, diffuseColor.z); + setButtonColor(ui->btnSpecularColor, specularColor.x, specularColor.y, specularColor.z); + + updateTextureButton(ui->btnDiffuseColorTex, material.diffuseTextureFilePath.buf); + updateTextureButton(ui->btnSpecularColorTex, material.specularTextureFilePath.buf); + updateTextureButton(ui->btnNormalColorTex, material.normalTextureFilePath.buf); + } + else + { + ui->spinSpecularShin->setValue(0.0f); + + setButtonColor(ui->btnDiffuseColor, 0, 0, 0); + setButtonColor(ui->btnSpecularColor, 0, 0, 0); + updateTextureButton(ui->btnDiffuseColorTex, ""); + updateTextureButton(ui->btnSpecularColorTex, ""); + updateTextureButton(ui->btnNormalColorTex, ""); + } +} + +BPPGraphicsMaterial* MaterialLibraryPanel::_getSelectedMaterial() +{ + BPParams& projectParams = BlastProject::ins().getParams(); + BPPGraphicsMaterialArray& graphicsMaterialArray = projectParams.graphicsMaterials; + + int idx = ui->listWidget->currentRow(); + int count = graphicsMaterialArray.arraySizes[0]; + if (idx < 0 || idx > count) + return nullptr; + + return &(graphicsMaterialArray.buf[idx]); +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h new file mode 100644 index 0000000..5c2c970 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/MaterialLibraryPanel.h @@ -0,0 +1,72 @@ +#ifndef MATERIALLIBRARYPANEL_H +#define MATERIALLIBRARYPANEL_H + +#include <QtWidgets/QWidget> +#include "ProjectParams.h" + +class RenderMaterial; + +namespace Ui { +class MaterialLibraryPanel; +} + +class MaterialLibraryPanel : public QWidget +{ + Q_OBJECT + +public: + explicit MaterialLibraryPanel(QWidget *parent = 0); + ~MaterialLibraryPanel(); + void updateValues(); + + static MaterialLibraryPanel* ins(); + void addMaterial(std::string materialName, std::string diffuseTexture); + void removeMaterial(std::string name); + std::map<std::string, RenderMaterial*>& getRenderMaterials(){ return m_RenderMaterialMap; } + void deleteMaterials(); + +private slots: + void on_btnAddMat_clicked(); + + void on_btnModifyMat_clicked(); + + void on_btnRemoveMat_clicked(); + + void on_listWidget_currentRowChanged(int currentRow); + + void on_btnDiffuseColor_clicked(); + + void on_btnDiffuseColorTex_clicked(); + + void on_btnDiffuseColorTexReload_clicked(); + + void on_btnDiffuseColorTexClear_clicked(); + + void on_btnSpecularColor_clicked(); + + void on_btnSpecularColorTex_clicked(); + + void on_btnSpecularColorTexReload_clicked(); + + void on_btnSpecularColorTexClear_clicked(); + + void on_spinSpecularShin_valueChanged(double arg1); + + void on_btnNormalColorTex_clicked(); + + void on_btnNormalColorTexReload_clicked(); + + void on_btnNormalColorTexClear_clicked(); + +private: + void _refreshMaterialValues(int idx); + BPPGraphicsMaterial* _getSelectedMaterial(); + + std::map<std::string, RenderMaterial*> m_RenderMaterialMap; + std::vector<std::string> m_NeedDeleteRenderMaterials; + +private: + Ui::MaterialLibraryPanel *ui; +}; + +#endif // MATERIALLIBRARYPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.cpp new file mode 100644 index 0000000..748002c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.cpp @@ -0,0 +1,39 @@ +#include "NoiseToolsDlg.h" +#include "ui_NoiseToolsDlg.h" + +NoiseToolsDlg::NoiseToolsDlg(QWidget *parent) : + QDialog(parent), + ui(new Ui::NoiseToolsDlg) +{ + ui->setupUi(this); +} + +NoiseToolsDlg::~NoiseToolsDlg() +{ + delete ui; +} + +void NoiseToolsDlg::on_comboBoxApplyByMaterial_currentIndexChanged(int index) +{ + +} + +void NoiseToolsDlg::on_spinBoxAmplitude_valueChanged(double arg1) +{ + +} + +void NoiseToolsDlg::on_spinBoxFrequency_valueChanged(double arg1) +{ + +} + +void NoiseToolsDlg::on_spinBoxAmplitude_3_valueChanged(double arg1) +{ + +} + +void NoiseToolsDlg::on_btnApply_clicked() +{ + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.h new file mode 100644 index 0000000..057dd42 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/NoiseToolsDlg.h @@ -0,0 +1,33 @@ +#ifndef NOISETOOLSDLG_H +#define NOISETOOLSDLG_H + +#include <QtWidgets/QDialog> + +namespace Ui { +class NoiseToolsDlg; +} + +class NoiseToolsDlg : public QDialog +{ + Q_OBJECT + +public: + explicit NoiseToolsDlg(QWidget *parent = 0); + ~NoiseToolsDlg(); + +private slots: + void on_comboBoxApplyByMaterial_currentIndexChanged(int index); + + void on_spinBoxAmplitude_valueChanged(double arg1); + + void on_spinBoxFrequency_valueChanged(double arg1); + + void on_spinBoxAmplitude_3_valueChanged(double arg1); + + void on_btnApply_clicked(); + +private: + Ui::NoiseToolsDlg *ui; +}; + +#endif // NOISETOOLSDLG_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.cpp new file mode 100644 index 0000000..b2fdd75 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.cpp @@ -0,0 +1,155 @@ +#include "QtUtil.h" + +#include <QtWidgets/QLabel> +#include "AppMainWindow.h" + +#include "SimpleScene.h" + +////////////////////////////////////////////////////////// +void setStyledToolTip(QPushButton *pButton, const char *tooltip) +{ + char styledString[1024]; + sprintf(styledString, "<span style=\"color:black;\">%s</span>", tooltip); + pButton->setToolTip(styledString); +} + +////////////////////////////////////////////////////////// +QString addStar(QString text, bool add) +{ + QByteArray ba = text.toUtf8(); + + const char* in = ba.data(); + char out[1024]; + + int i = 0; + for (i = 0; i < strlen(in); i++) + { + if (in[i] == '*') + break; + out[i] = in[i]; + } + out[i] = 0; + + QString newtext; + if (add) + newtext = QString((const char*)out) + QString("*"); + else + newtext = QString((const char*)out) ; + return newtext; +} + +////////////////////////////////////////////////////////// +void setFocusColor(QWidget* qWidget, bool sameAsDefault, bool sameForAllAssets) +{ + if (!qWidget) + return; + + QString sameStyle = QString("font: ; color: rgb(150,150,150);") ; + QString differentStyle = QString("font: bold; color: rgb(255,55,55);"); + QString style = (sameForAllAssets) ? sameStyle : differentStyle; + + qWidget->setStyleSheet(style); + + QLabel* label = dynamic_cast<QLabel*>(qWidget); + if (label) + { + QString newtext = addStar(label->text(), !sameAsDefault); + + label->setFrameStyle(0); + label->setText(newtext); + } +} + +////////////////////////////////////////////////////////// +void pickColor(atcore_float4& color) +{ + QColor currentColor; + currentColor.setRgbF(color.x, color.y, color.z); + + QColor newColor = QColorDialog::getColor(currentColor, NV_NULL); + if(newColor.isValid()) + { + qreal r,g,b; + newColor.getRgbF(&r, &g, &b); + + color.x = r; + color.y = g; + color.z = b; + } +} + +////////////////////////////////////////////////////////// +void setButtonColor(QPushButton *button, float r, float g, float b) +{ + QColor specColor; + specColor.setRgbF(r,g,b); + QString specBtnStyle = QString("background-color: rgb(%1,%2,%3);") + .arg(specColor.red()) + .arg(specColor.green()) + .arg(specColor.blue()); + + button->setStyleSheet(specBtnStyle); +} + + +///////////////////////////////////////////////////////////////////////////////////// +void updateColorButton(QPushButton* button, int paramID, QLabel* label) +{ + //atcore_float4 v; + //SimpleScene::Inst()->GetFurCharacter().GetHairParam(paramID, &v); + + //setButtonColor(button, v.x, v.y, v.z); + + //if (label) + // setFocusColor(label, paramID); +} + +///////////////////////////////////////////////////////////////////////////////////// +void setClearButtonIcon(QPushButton *pButton) +{ + pButton->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); +} + +///////////////////////////////////////////////////////////////////////////////////// +void setTextureButtons(QPushButton *pTex, QPushButton *pReload, QPushButton *pClear) +{ + pTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + pReload->setIcon(QIcon(":/AppMainWindow/images/Refresh_icon.png")); + pClear->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); + + pTex->setIconSize(QSize(12,12)); + pReload->setIconSize(QSize(12,12)); + pClear->setIconSize(QSize(12,12)); +} + +///////////////////////////////////////////////////////////////////////////////////// +void updateTextureButton(QPushButton* pButton, const QString& texturePath) +{ + if (!texturePath.isEmpty()) setStyledToolTip(pButton, texturePath.toUtf8().data()); + + bool isTextureUsed = true; + QIcon notUsedIcon = QIcon(":/AppMainWindow/images/TextureEnabled_icon.png"); + QIcon isUsedIcon = QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png"); + QIcon disabledIcon = QIcon(":/AppMainWindow/images/TextureDisabled_icon.png"); + + pButton->setIcon(!texturePath.isEmpty() ? isUsedIcon : notUsedIcon); +} + +/////////////////////////////////////////////////////////////////////////////////////// +//bool LoadHairTexture(NvHair::TextureType::Enum textureType) +//{ +// QString texName = AppMainWindow::Inst().OpenTextureFile(); +// return SimpleScene::Inst()->GetFurCharacter().LoadHairTexture(textureType, texName.toLocal8Bit()); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +//bool ReloadHairTexture(NvHair::TextureType::Enum textureType) +//{ +// return SimpleScene::Inst()->GetFurCharacter().ReloadHairTexture(textureType); +//} +// +/////////////////////////////////////////////////////////////////////////////////////// +//bool ClearHairTexture(NvHair::TextureType::Enum textureType) +//{ +// return SimpleScene::Inst()->GetFurCharacter().ClearHairTexture(textureType); +//} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.h new file mode 100644 index 0000000..2372b06 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/QtUtil.h @@ -0,0 +1,37 @@ +#ifndef QtUtil_h__ +#define QtUtil_h__ + +#include <QtCore/QFileInfo> +#include <QtCore/QDir> +#include <QtWidgets/QColorDialog> +#include <QtGui/QPalette> +#include <QtWidgets/QWidget> +#include <QtWidgets/QPushButton> +#include <QtWidgets/QSpinBox> +#include <QtWidgets/QDoubleSpinBox> +#include <QtWidgets/QCheckBox> +#include <QtWidgets/QComboBox> +#include <QtWidgets/QLabel> +#include <QtWidgets/QSlider> +#include "corelib_global.h" + +// utility functions to quickly set and update UI + +void setStyledToolTip(QPushButton *pButton, const char *tooltip); +void pickColor(atcore_float4& color); +void setButtonColor(QPushButton *button, float r, float g, float b); + +void setFocusColor(QWidget* qWidget, bool sameAsDefault, bool sameForAllAssets); + +void updateColorButton(QPushButton* pButton, int paramID, QLabel* label = 0); + +void setTextureButtons(QPushButton *pButton, QPushButton *pReload, QPushButton *pClear); +void updateTextureButton(QPushButton* pButton, const QString& texturePath); + +void setClearButtonIcon(QPushButton *pButton); + +//bool LoadHairTexture(NvHair::TextureType::Enum textureType); +//bool ReloadHairTexture(NvHair::TextureType::Enum textureType); +//bool ClearHairTexture(NvHair::TextureType::Enum textureType); + +#endif diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp new file mode 100644 index 0000000..db40407 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.cpp @@ -0,0 +1,82 @@ +#include "SourceAssetOpenDlg.h" +#include "ui_SourceAssetOpenDlg.h" +#include <QtWidgets/QFileDialog> +#include "AppMainWindow.h" + +SourceAssetOpenDlg::SourceAssetOpenDlg(bool bOpenBlastFile, QWidget *parent) : + QDialog(parent), + ui(new Ui::SourceAssetOpenDlg) +{ + ui->setupUi(this); + + m_bOpenBlastFile = bOpenBlastFile; + ui->buttonBox->button(QDialogButtonBox::Ok)->setFixedWidth(100); + ui->buttonBox->button(QDialogButtonBox::Cancel)->setFixedWidth(100); + ui->spinBoxDegree->setMaximum(180); + ui->spinBoxDegree->setMinimum(-180); +} + +SourceAssetOpenDlg::~SourceAssetOpenDlg() +{ + delete ui; +} + +QString SourceAssetOpenDlg::getFile() +{ + return ui->lineEditFile->text(); +} + +bool SourceAssetOpenDlg::getSkinned() +{ + return ui->checkBoxSkinned->isChecked(); +} + +QVector3D SourceAssetOpenDlg::getPosition() +{ + return QVector3D(ui->spinBoxXPosition->value(), ui->spinBoxYPosition->value(), ui->spinBoxZPosition->value()); +} + +QVector3D SourceAssetOpenDlg::getRotationAxis() +{ + return QVector3D(ui->spinBoxXAxis->value(), ui->spinBoxYAxis->value(), ui->spinBoxZAxis->value()); +} + +double SourceAssetOpenDlg::getRotationDegree() +{ + return ui->spinBoxDegree->value(); +} + +bool SourceAssetOpenDlg::isAppend() +{ + return ui->checkBoxAppend->isChecked(); +} + +void SourceAssetOpenDlg::on_btnOpenFile_clicked() +{ + QString lastDir = AppMainWindow::Inst()._lastFilePath; + QString titleStr = "Open Source Asset File"; + + QString filetype = "Source Asset (*.fbx)"; + if (m_bOpenBlastFile) + { + filetype = "Source Asset (*.bpxa)"; + } + QString fileName = QFileDialog::getOpenFileName(this, titleStr, lastDir, filetype); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + AppMainWindow::Inst()._lastFilePath = fileInfo.absoluteDir().absolutePath(); + } + + ui->lineEditFile->setText(fileName); +} + +void SourceAssetOpenDlg::on_buttonBox_accepted() +{ + +} + +void SourceAssetOpenDlg::on_buttonBox_rejected() +{ + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h new file mode 100644 index 0000000..ec03ee9 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SourceAssetOpenDlg.h @@ -0,0 +1,38 @@ +#ifndef SOURCEASSETOPENDLG_H +#define SOURCEASSETOPENDLG_H + +#include <QtWidgets/QDialog> +#include <QtGui/QVector3D> + +namespace Ui { +class SourceAssetOpenDlg; +} + +class SourceAssetOpenDlg : public QDialog +{ + Q_OBJECT + +public: + explicit SourceAssetOpenDlg(bool bOpenBlastFile = true, QWidget *parent = 0); + ~SourceAssetOpenDlg(); + + QString getFile(); + bool getSkinned(); + QVector3D getPosition(); + QVector3D getRotationAxis(); + double getRotationDegree(); + bool isAppend(); + +private slots: + void on_btnOpenFile_clicked(); + + void on_buttonBox_accepted(); + + void on_buttonBox_rejected(); + +private: + Ui::SourceAssetOpenDlg *ui; + bool m_bOpenBlastFile; +}; + +#endif // SOURCEASSETOPENDLG_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp new file mode 100644 index 0000000..1057402 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.cpp @@ -0,0 +1,49 @@ +#include "SupportPanel.h" +#include "ui_SupportPanel.h" + +SupportPanel::SupportPanel(QWidget *parent) : + QWidget(parent), + ui(new Ui::SupportPanel) +{ + ui->setupUi(this); +} + +SupportPanel::~SupportPanel() +{ + delete ui; +} + +void SupportPanel::updateValues() +{ + +} + +void SupportPanel::on_comboBoxHealthMask_currentIndexChanged(int index) +{ + +} + +void SupportPanel::on_btnAddHealthMask_clicked() +{ + +} + +void SupportPanel::on_btnPen_clicked() +{ + +} + +void SupportPanel::on_btnRemove_clicked() +{ + +} + +void SupportPanel::on_spinBoxBondStrength_valueChanged(double arg1) +{ + +} + +void SupportPanel::on_checkBoxEnableJoint_stateChanged(int arg1) +{ + +} diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.h new file mode 100644 index 0000000..518d2cd --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/Window/SupportPanel.h @@ -0,0 +1,36 @@ +#ifndef SUPPORTPANEL_H +#define SUPPORTPANEL_H + +#include <QtWidgets/QWidget> + +namespace Ui { +class SupportPanel; +} + +class SupportPanel : public QWidget +{ + Q_OBJECT + +public: + explicit SupportPanel(QWidget *parent = 0); + ~SupportPanel(); + void updateValues(); + +private slots: + void on_comboBoxHealthMask_currentIndexChanged(int index); + + void on_btnAddHealthMask_clicked(); + + void on_btnPen_clicked(); + + void on_btnRemove_clicked(); + + void on_spinBoxBondStrength_valueChanged(double arg1); + + void on_checkBoxEnableJoint_stateChanged(int arg1); + +private: + Ui::SupportPanel *ui; +}; + +#endif // SUPPORTPANEL_H diff --git a/NvBlast/tools/ArtistTools/source/BlastPlugin/blastplugin_global.h b/NvBlast/tools/ArtistTools/source/BlastPlugin/blastplugin_global.h new file mode 100644 index 0000000..082519a --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/BlastPlugin/blastplugin_global.h @@ -0,0 +1,11 @@ +#ifdef PLUGINBT_LIB +# define PLUGINBT_EXPORT Q_DECL_EXPORT +#else +# define PLUGINBT_EXPORT Q_DECL_IMPORT +#endif + +#ifdef PLUGINBTRENDER_LIB +# define PLUGINBTRENDER_EXPORT Q_DECL_EXPORT +#else +# define PLUGINBTRENDER_EXPORT Q_DECL_IMPORT +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp new file mode 100644 index 0000000..5ab1563 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.cpp @@ -0,0 +1,419 @@ +// 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. +// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// This file contains wrapper functions to make hair lib easy to setup and use +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#include <vector> +#include <string> + +#include "AnimUtil.h" +#include "MathUtil.h" + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AnimationCache::~AnimationCache() +{ + Release(); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AnimationCache::Initialize(int numBones, NvInt32 frameStart, NvInt32 frameEnd) +{ + m_numBones = numBones; + m_frameStart = frameStart; + m_frameEnd = frameEnd; + + m_numFrames = frameEnd - frameStart + 1; + + Release(); + Allocate(); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AnimationCache::Allocate() +{ + m_pBoneMatrices = new atcore_float4x4[m_numFrames * m_numBones]; +// m_pBoneNames = new char[NV_HAIR_MAX_STRING * m_numBones]; +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AnimationCache::Release() +{ + if (m_pBoneMatrices) + delete []m_pBoneMatrices; + + if (m_pBoneNames) + delete []m_pBoneNames; + + m_pBoneMatrices = 0; + m_pBoneNames = 0; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AnimationCache::GetInterpolationInfo(float frame, int& indexStart, int& indexEnd, float &fracFrame) +{ + if (frame < m_frameStart) + return false; + + if (frame > m_frameEnd) + return false; + + int startFrame = (int)frame; + + fracFrame = frame - startFrame; + + indexStart = (int)(frame - m_frameStart); + indexEnd = indexStart + 1; + + if (indexEnd >= (int)m_numFrames) + { + indexEnd = indexStart; + fracFrame = 0.0f; + } + + return true; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +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; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AnimationCache::FindBoneMapping( int numBones, const NvChar* boneNames, int* mappedBoneId) const +{ + // mappedBoneId must be pre-allocated + + for (int i = 0; i < numBones; i++) + { + //mappedBoneId[i] = FindBone(boneNames + i * NV_HAIR_MAX_STRING); + } + + return true; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void BoneData::Allocate(NvUInt32 numBones) +{ + Release(); + + m_numBones = numBones; + + m_pPoseMatrices = new atcore_float4x4[numBones]; + m_pSkinMatrices = new atcore_float4x4[numBones]; + m_pBoneMatrices = new atcore_float4x4[numBones]; + + m_pSkinDQs = new atcore_dualquaternion[numBones]; + //m_pBoneNames = new char[NV_HAIR_MAX_STRING * m_numBones]; + m_pMappedBoneId = new int[numBones]; + + for (int i = 0; i < numBones; i++) + { + gfsdk_makeIdentity(m_pPoseMatrices[i]); + gfsdk_makeIdentity(m_pSkinMatrices[i]); + m_pMappedBoneId[i] = -1; + } +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void BoneData::Release() +{ + if (m_pPoseMatrices) + { + delete []m_pPoseMatrices; + m_pPoseMatrices = 0; + } + + if (m_pBoneMatrices) + { + delete []m_pBoneMatrices; + m_pBoneMatrices = 0; + } + + if (m_pSkinMatrices) + { + delete []m_pSkinMatrices; + m_pSkinMatrices = 0; + } + + if (m_pSkinDQs) + { + delete []m_pSkinDQs; + m_pSkinDQs = 0; + } + + if (m_pBoneNames) + { + delete []m_pBoneNames; + m_pBoneNames = 0; + } + + if (m_pMappedBoneId) + { + delete []m_pMappedBoneId; + m_pMappedBoneId = 0; + } + + m_numBones = 0; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void BoneData::InitializeAnimationCache(AnimationCache* pGlobalCache, const char* nodeName) +{ + if (!pGlobalCache || !pGlobalCache->isValid()) + return; + + pGlobalCache->FindBoneMapping(m_numBones, m_pBoneNames, m_pMappedBoneId); + + m_nodeId = pGlobalCache->FindBone(nodeName); + + m_pAnimationCache = pGlobalCache; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool BoneData::Update(float frameTime, const char* rootBoneName, bool bindPose, bool zup) +{ + if (!m_pAnimationCache || !m_pAnimationCache->isValid() ) + bindPose = true; + + atcore_float4x4 model; + gfsdk_makeIdentity(model); + + if (bindPose) + { + for (int i = 0; i < m_numBones; i++) + { + m_pBoneMatrices[i] = m_pPoseMatrices[i]; + m_pSkinMatrices[i] = model; + m_pSkinDQs[i] = gfsdk_makeDQ(m_pSkinMatrices[i]); + } + return true; + } + + int indexStart, indexEnd; + float fracFrame = 0.0f; + if (false == m_pAnimationCache->GetInterpolationInfo(frameTime, indexStart, indexEnd, fracFrame)) + return false; + + atcore_float4x4* pBoneStart = m_pAnimationCache->GetNodeMatrices(indexStart); + atcore_float4x4* pBoneEnd = m_pAnimationCache->GetNodeMatrices(indexEnd); + + int numBones = m_numBones; + + atcore_float4x4 root; + gfsdk_makeIdentity(root); + + if (rootBoneName) + { + int rootIndex = m_pAnimationCache->FindBone(rootBoneName); + + if (rootIndex >= 0) + { + root = gfsdk_lerp(pBoneStart[rootIndex], pBoneEnd[rootIndex], fracFrame); + + atcore_float3 lT = gfsdk_getTranslation(root); + + if (zup) + lT.z = 0; + else + lT.y = 0; + + gfsdk_makeIdentity(root); + gfsdk_setTranslation(root, -1.0f * lT); + } + } + + // interpolate skinning matrix + for (int i = 0; i < numBones; i++) + { + atcore_float4x4 bone; + + int index = m_pMappedBoneId[i]; + if (index >= 0) + bone = gfsdk_lerp(pBoneStart[index], pBoneEnd[index], fracFrame); + else + gfsdk_makeIdentity(bone); + + atcore_float4x4 pose = m_pPoseMatrices[i]; + + m_pBoneMatrices[i] = bone; + m_pSkinMatrices[i] = gfsdk_inverse(pose) * bone * root; + m_pSkinDQs[i] = gfsdk_makeDQ(m_pSkinMatrices[i]); + } + + return true; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void MeshDesc::Allocate(NvUInt32 numVertices, NvUInt32 numTriangles) +{ + Release(); + + m_NumTriangles = numTriangles; + m_NumVertices = numVertices; + + m_pVertices = new atcore_float3[numVertices]; + + m_pVertexNormals = new atcore_float3[numTriangles * 3]; + m_pFaceNormals = new atcore_float3[numTriangles * 3]; + + m_pTangents = new atcore_float3[numTriangles * 3]; + + m_pIndices = new NvUInt32[numTriangles * 3]; + m_pTexCoords = new atcore_float2[numTriangles * 3]; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void MeshDesc::Release() +{ + if (m_pVertices) + delete []m_pVertices; + if (m_pVertexNormals) + delete []m_pVertexNormals; + if (m_pFaceNormals) + delete []m_pFaceNormals; + if (m_pTangents) + delete []m_pTangents; + + if (m_pIndices) + delete []m_pIndices; + if (m_pTexCoords) + delete []m_pTexCoords; + + m_NumTriangles = 0; + m_NumVertices = 0; + + m_pVertices = nullptr; + m_pVertexNormals = nullptr; + m_pFaceNormals = nullptr; + m_pTangents = nullptr; + + m_pIndices = nullptr; + m_pTexCoords = nullptr; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void MeshDesc::UpdateNormal(bool updateVertexNormal) +{ + atcore_float3* vertexNormal = new atcore_float3[m_NumVertices]; + memset(vertexNormal, 0, sizeof(atcore_float3) * m_NumVertices); + + for (int i = 0; i < m_NumTriangles; i++) + { + atcore_float3 faceNormal; + + int fidx = i*3; + int id0 = m_pIndices[fidx++]; + int id1 = m_pIndices[fidx++]; + int id2 = m_pIndices[fidx++]; + + atcore_float3 p0 = m_pVertices[id0]; + atcore_float3 p1 = m_pVertices[id1]; + atcore_float3 p2 = m_pVertices[id2]; + atcore_float3 p01 = p1 - p0; + atcore_float3 p02 = p2 - p0; + + faceNormal.x = p01.y * p02.z - p01.z * p02.y; + faceNormal.y = p01.z * p02.x - p01.x * p02.z; + faceNormal.z = p01.x * p02.y - p01.y * p02.x; + + gfsdk_normalize(faceNormal); + + m_pFaceNormals[i * 3 + 0] = faceNormal; + m_pFaceNormals[i * 3 + 1] = faceNormal; + m_pFaceNormals[i * 3 + 2] = faceNormal; + + vertexNormal[id0] += faceNormal; + vertexNormal[id1] += faceNormal; + vertexNormal[id2] += faceNormal; + } + + if (updateVertexNormal) + { + for (int i = 0; i < m_NumVertices; ++i) + gfsdk_normalize(vertexNormal[i]); + + for (int i = 0; i < m_NumTriangles; i++) + { + int fidx = i*3; + int id0 = m_pIndices[fidx++]; + int id1 = m_pIndices[fidx++]; + int id2 = m_pIndices[fidx++]; + + for (int k = 0; k < 3; k++) + { + int fidx = i*3 + k; + int vidx = m_pIndices[fidx]; + m_pVertexNormals[fidx] = vertexNormal[vidx]; + } + } + } + + delete []vertexNormal; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SkinData::Allocate(NvUInt32 numBones, NvUInt32 numVertices) +{ + Release(); + + m_boneData.Allocate(numBones); + + m_pBoneIndices = new atcore_float4[numVertices]; + m_pBoneWeights = new atcore_float4[numVertices]; + + memset(m_pBoneIndices, 0, sizeof(atcore_float4) * numVertices); + memset(m_pBoneWeights, 0, sizeof(atcore_float4) * numVertices); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SkinData::Release() +{ + // clear memory + if (m_pBoneIndices) + delete []m_pBoneIndices; + if (m_pBoneWeights) + delete []m_pBoneWeights; + + m_pBoneIndices = 0; + m_pBoneWeights = 0; + + m_boneData.Release(); +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h b/NvBlast/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h new file mode 100644 index 0000000..8de718c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Anim/AnimUtil.h @@ -0,0 +1,217 @@ +// 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. +// +#pragma once + +#include "MathUtil.h" +#include <string.h> + +//#include <Nv/Blast/NvHairSdk.h> + +//////////////////////////////////////////////////////////////////////////////////////// +// cache for animated bone data +struct CORELIB_EXPORT AnimationCache +{ + NvUInt32 m_numBones; + NvChar* m_pBoneNames; + + NvInt32 m_frameStart; + NvInt32 m_frameEnd; + NvUInt32 m_numFrames; + + atcore_float4x4* m_pBoneMatrices; + + AnimationCache() : + m_numBones(0), + m_frameStart(0), + m_frameEnd(0), + m_numFrames(0), + m_pBoneMatrices(nullptr), + m_pBoneNames(nullptr) + { + } + + bool isValid() const { + return (m_numBones > 0) && (m_numFrames > 0) && (m_pBoneMatrices != 0); + } + + void Allocate(); + void Release(); + void Initialize(int numBones, NvInt32 frameStart, NvInt32 frameEnd); + + bool GetInterpolationInfo(float frameTime, int& indexStart, int& indexEnd, float &fracFrame); + + 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; + } + + void SetBoneName(int index, const char* boneName) + { + 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; + + ~AnimationCache(); +}; + +//////////////////////////////////////////////////////////////////////////////////////// +// bone matrices at each frame +//////////////////////////////////////////////////////////////////////////////////////// +struct CORELIB_EXPORT BoneData +{ + NvUInt32 m_numBones; + NvChar* m_pBoneNames; + + atcore_float4x4* m_pPoseMatrices; // rest pose for each bone + atcore_float4x4* m_pBoneMatrices; // updated bone matrix + atcore_float4x4* m_pSkinMatrices; // interpolated skinning matrix for current frame + atcore_dualquaternion* m_pSkinDQs; // dual quats + + AnimationCache* m_pAnimationCache; + int* m_pMappedBoneId; + int m_nodeId; + +public: + BoneData() : + m_numBones(0), + m_pBoneNames(nullptr), + m_pPoseMatrices(nullptr), + m_pBoneMatrices(nullptr), + m_pSkinMatrices(nullptr), + m_pSkinDQs(nullptr), + m_pAnimationCache(nullptr), + m_pMappedBoneId(nullptr), + m_nodeId(-1) + {} + + void Allocate(NvUInt32 numBones); + void Release(); + /* + const char* getBoneName(int index) + { + return m_pBoneNames + index * NV_HAIR_MAX_STRING; + } + + void setBoneName(int index, const char* boneName) + { + 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); + +}; + +//////////////////////////////////////////////////////////////////////////////////////// +// Skinning data +struct CORELIB_EXPORT SkinData +{ + BoneData m_boneData; + + atcore_float4* m_pBoneIndices; + atcore_float4* m_pBoneWeights; + +public: + SkinData() : + m_pBoneIndices(nullptr), + m_pBoneWeights(nullptr) + {} + + void Allocate(NvUInt32 numBones, NvUInt32 numVertices); + void Release(); +}; + + +//////////////////////////////////////////////////////////////////////////////////////// +struct CORELIB_EXPORT MeshDesc +{ + NvUInt32 m_NumVertices; + NvUInt32 m_NumTriangles; + + atcore_float3* m_pVertices; + atcore_float3* m_pVertexNormals; + atcore_float3* m_pFaceNormals; + atcore_float3* m_pTangents; + + NvUInt32* m_pIndices; + atcore_float2* m_pTexCoords; + +public: + MeshDesc() : + m_NumVertices(0), + m_NumTriangles(0), + + m_pVertices(nullptr), + m_pVertexNormals(nullptr), + m_pFaceNormals(nullptr), + m_pTangents(nullptr), + + m_pIndices(nullptr), + m_pTexCoords(nullptr) + {} + + void Allocate(NvUInt32 numVertices, NvUInt32 numTriangles); + void Release(); + + void UpdateNormal(bool updateVertexNormal = false); +}; + +//////////////////////////////////////////////////////////////////////////////////////// +#define MATERIAL_NAME_SIZE 128 + +struct CORELIB_EXPORT MeshMaterial +{ + NvChar m_name[MATERIAL_NAME_SIZE]; + + atcore_float3 m_ambientColor; + float m_ambientFactor; + + atcore_float3 m_diffuseColor; + float m_diffuseFactor; + + float m_specularFactor; + float m_shininess; + + NvChar m_diffuseTexture[MATERIAL_NAME_SIZE]; + NvChar m_specularTexture[MATERIAL_NAME_SIZE]; + NvChar m_bumpTexture[MATERIAL_NAME_SIZE]; + NvChar m_normalTexture[MATERIAL_NAME_SIZE]; + NvChar m_transparentTexture[MATERIAL_NAME_SIZE]; + +public: + MeshMaterial() + {} +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp new file mode 100644 index 0000000..97ba7d8 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.cpp @@ -0,0 +1,1023 @@ +// 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. +// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// This file contains wrapper functions to make hair lib easy to setup and use +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "fbxsdk.h" +#include <vector> +#include <string> + +#include "FbxUtil.h" +#include "MathUtil.h" + +//#include <Nv/Blast/NvHairSdk.h> + +// local functions used only in this file +namespace { + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Get the geometry offset to a node. It is never inherited by the children. + FbxAMatrix GetGeometry(FbxNode* pNode) + { + const FbxVector4 lT = pNode->GetGeometricTranslation(FbxNode::eSourcePivot); + const FbxVector4 lR = pNode->GetGeometricRotation(FbxNode::eSourcePivot); + const FbxVector4 lS = pNode->GetGeometricScaling(FbxNode::eSourcePivot); + + return FbxAMatrix(lT, lR, lS); + } + + //////////////////////////////////////////////////////////////////////////////////////// + void convertFromFbxMatrix(atcore_float4x4& transform, FbxAMatrix& tmatrix) + { + float* data = (float*)&transform; + + // update skinning matrix + for (int row = 0; row < 4; row++) + for (int col = 0; col < 4; col++) + { + data[ row * 4 + col] = float(tmatrix.Get(row,col)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool checkMesh(FbxNode* pNode) + { + FbxMesh* pMesh = pNode->GetMesh(); + if (!pMesh) + return false; + + return true; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool checkSkinned(FbxNode* pNode) + { + FbxGeometry* pFbxGeometry = pNode->GetGeometry(); + if (!pFbxGeometry) + return false; + + FbxSkin* pFbxSkin = (FbxSkin*)pFbxGeometry->GetDeformer(0, FbxDeformer::eSkin); + if (!pFbxSkin) + return false; + + return true; + } +} + +namespace +{ + FbxManager* s_FbxManager = nullptr; + FbxScene* s_FbxScene = nullptr; + + + ///////////////////////////////////////////////////////////////////////////// + // find node by name + FbxNode* + FindNodeByName(FbxScene* scene, const char* nodeName) + { + if (!scene) + return 0; + + if (!nodeName) + return 0; + + for (int i = 0; i < scene->GetNodeCount(); i++) + { + FbxNode* node = scene->GetNode(i); + const char* name = node->GetName(); + if (!strcmp(nodeName, name)) + return node; + } + return 0; + } +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool +FbxUtil::Release(void) +{ + if (s_FbxScene) + { + s_FbxScene->Destroy(); + s_FbxScene = nullptr; + } + + if (s_FbxManager) + { + s_FbxManager->Destroy(); + s_FbxManager = nullptr; + } + + return true; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool FbxUtil::Initialize(const char* fbxFileName, float sceneUnit) +{ + if (fbxFileName) + { + FbxImporter* s_FbxImporter = nullptr; + + if (!s_FbxManager) + s_FbxManager = FbxManager::Create(); + + if (!s_FbxImporter) + s_FbxImporter = FbxImporter::Create(s_FbxManager, ""); + + if (!s_FbxScene) + s_FbxScene = FbxScene::Create(s_FbxManager, ""); + + if (!s_FbxImporter->Initialize(fbxFileName, -1)) + return false; + + if (!s_FbxImporter->Import(s_FbxScene)) + return false; + + FbxGlobalSettings& settings = s_FbxScene->GetGlobalSettings(); + + FbxSystemUnit fbxUnit = settings.GetSystemUnit(); + + if ((sceneUnit > 0.0f) && (sceneUnit != fbxUnit.GetScaleFactor())) + { + FbxSystemUnit convertUnit(sceneUnit); + convertUnit.ConvertScene(s_FbxScene); + } + + s_FbxImporter->Destroy(); + + // get time info + FbxTimeSpan timespan; + settings.GetTimelineDefaultTimeSpan(timespan); + + FbxTime startTime = timespan.GetStart(); + FbxTime endTime = timespan.GetStop(); + + } + + return true; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool FbxUtil::GetGlobalSettings(float* pStartFrame, float* pEndFrame, float *pFps, int *upAxis, char* rootBoneName) +{ + return false; + + /* + if ( !s_FbxScene) + return false; + + FbxGlobalSettings& settings = s_FbxScene->GetGlobalSettings(); + + FbxTimeSpan timespan; + settings.GetTimelineDefaultTimeSpan(timespan); + + FbxTime startTime = timespan.GetStart(); + FbxTime endTime = timespan.GetStop(); + + if (pStartFrame) + *pStartFrame = (float)startTime.GetFrameCount(); + + if (pEndFrame) + *pEndFrame = (float)endTime.GetFrameCount(); + + if (pFps) + *pFps = (float)endTime.GetFrameRate(FbxTime::GetGlobalTimeMode()); + + if (upAxis) + { + int upSign = 0; + FbxAxisSystem axisSystem = settings.GetAxisSystem(); + FbxAxisSystem::EUpVector upVector = axisSystem.GetUpVector(upSign); + + enum FbxAxisSystem::ECoordSystem coordSystem = axisSystem.GetCoorSystem(); + + switch (upVector) + { + case FbxAxisSystem::eXAxis: *upAxis = 0; break; + case FbxAxisSystem::eYAxis: *upAxis = 1; break; + case FbxAxisSystem::eZAxis: *upAxis = 2; break; + } + } + + if (rootBoneName) + { + FbxNode* pRoot = s_FbxScene->GetRootNode(); + if (pRoot) + { + strncpy(rootBoneName, pRoot->GetName(), NV_HAIR_MAX_STRING); + } + else + strcpy(rootBoneName, ""); + } + + return true; + */ +} + +///////////////////////////////////////////////////////////////////////////// + +bool +FbxUtil::InitializeAnimationCache(AnimationCache& animCache) +{ + return false; + + /* + if (!s_FbxScene) + return false; + + float startFrame, endFrame, fps; + FbxUtil::GetGlobalSettings(&startFrame, &endFrame, &fps); + + int numNodes = s_FbxScene->GetNodeCount(); + + //////////////////////////////////////////// + animCache.Initialize(numNodes, (NvInt32)startFrame, (NvInt32)endFrame); + + for (int i = 0; i < numNodes; i++) + { + FbxNode* node = s_FbxScene->GetNode(i); + const char* nodeName = node->GetName(); + animCache.SetBoneName(i, nodeName); + } + + //////////////////////////////////////////// + for (NvInt frame = animCache.m_frameStart; frame <= animCache.m_frameEnd; frame++) + { + FbxTime lTime; + lTime.SetSecondDouble( frame / fps); + + int index = frame - animCache.m_frameStart; + atcore_float4x4 *pNodeMatrices = animCache.GetNodeMatrices(index); + + for (int i = 0; i < numNodes; i++) + { + FbxNode* node = s_FbxScene->GetNode(i); + FbxAMatrix nodeMatrix = node->EvaluateGlobalTransform(lTime); + convertFromFbxMatrix(pNodeMatrices[i], nodeMatrix); + } + } + + return true; + */ +} + +//////////////////////////////////////////////////////////////////////////////////////// +static FbxSkin* GetFbxSkin( FbxNode* pFbxNode ) +{ + if (!pFbxNode) + return 0; + + FbxMesh* pFbxMesh = pFbxNode->GetMesh(); + if (!pFbxMesh) + return 0; + + FbxGeometry* pFbxGeometry = pFbxNode->GetGeometry(); + if (!pFbxGeometry) + return 0; + + int deformerCount = pFbxGeometry->GetDeformerCount(FbxDeformer::eSkin); + + FbxSkin *pFbxSkin = 0; + if (deformerCount > 0) + pFbxSkin = (FbxSkin*)pFbxGeometry->GetDeformer(0, FbxDeformer::eSkin); + + return pFbxSkin; +} + +//////////////////////////////////////////////////////////////////////////////////////// +static int GetNumMeshPoints( FbxNode* pFbxNode) +{ + if (!pFbxNode) + return 0; + + FbxMesh* pFbxMesh = pFbxNode->GetMesh(); + if (!pFbxMesh) + return 0; + + return pFbxMesh->GetControlPointsCount(); +} + +//////////////////////////////////////////////////////////////////////////////////////// +static bool GetBoneData(FbxSkin *pFbxSkin, FbxNode* pFbxNode, NvChar* pBoneNames, atcore_float4x4 *pBindPoses) +{ + return false; + + /* + if (!pFbxSkin || !pFbxNode) + return false; + + int numBones = (int)pFbxSkin->GetClusterCount(); + + for (int i = 0; i < numBones; i++) + { + FbxCluster* pFbxCluster = pFbxSkin->GetCluster(i); + + FbxNode* pLink = pFbxCluster->GetLink(); + + // copy bone names + const char* boneName = pLink->GetName(); + char* str = pBoneNames + i * NV_HAIR_MAX_STRING; + strcpy_s(str, NV_HAIR_MAX_STRING, boneName); + + // write pose matrix + { + FbxAMatrix lReferenceGlobalInitPosition; + pFbxCluster->GetTransformMatrix(lReferenceGlobalInitPosition); + + FbxAMatrix lReferenceGeometry = GetGeometry(pFbxNode); + lReferenceGlobalInitPosition *= lReferenceGeometry; + + FbxAMatrix lClusterGlobalInitPosition; + pFbxCluster->GetTransformLinkMatrix(lClusterGlobalInitPosition); + + FbxAMatrix lClusterMatrix = lClusterGlobalInitPosition.Inverse() * lReferenceGlobalInitPosition; + convertFromFbxMatrix(pBindPoses[i], lClusterMatrix.Inverse()); + } + } + return true; + */ +} + +//////////////////////////////////////////////////////////////////////////////////////// +static bool GetSkinningWeights(FbxSkin* pFbxSkin, atcore_float4* boneIndices, atcore_float4* boneWeights, int numPoints) +{ + int numClusters = (int)pFbxSkin->GetClusterCount(); + if (numClusters == 0) + return false; + + // copy skinning weights and indices + int* pIndexCounts = new int[numPoints]; + memset(pIndexCounts, 0, sizeof(int) * numPoints); + + for (int i = 0; i < numClusters; i++) + { + if (!pFbxSkin) continue; + + FbxCluster* pFbxCluster = pFbxSkin->GetCluster(i); + + if (!pFbxCluster) continue; + + int cpCount = pFbxCluster->GetControlPointIndicesCount(); + int* pPointIndices = pFbxCluster->GetControlPointIndices(); + double* pWeights = pFbxCluster->GetControlPointWeights(); + + for (int j = 0; j < cpCount; j++) + { + if (pWeights[j] == 0.0f) + continue; + + int pointIndex = pPointIndices[j]; + int& cnt = pIndexCounts[pointIndex]; + + float* pBoneIndex = (float*)&boneIndices[pointIndex]; + float* pBoneWeights = (float*)&boneWeights[pointIndex]; + + if (cnt < 4) + { + pBoneIndex[cnt] = float(i); + pBoneWeights[cnt] = float(pWeights[j]); + cnt++; + } + else // over 4, so we just bind to largest weights + { + float minWeight = (float)pWeights[j]; + int minIndex = -1; + for (int b = 0; b < 4; b++) + { + float w = pBoneWeights[b]; + + if (w < minWeight) + { + minWeight = w; + minIndex = b; + } + } + + if (minIndex >= 0) + { + pBoneIndex[minIndex] = float(i); + pBoneWeights[minIndex] = float(pWeights[j]); + } + + cnt++; + } + } + } + + for (int i = 0; i < numPoints; i++) + { + float* pBoneWeights = (float*)&boneWeights[i]; + + float weightsum = 0; + for (int i = 0; i < 4; i++) + { + weightsum += pBoneWeights[i]; + } + + if (weightsum == 0) + continue; + + for (int i = 0; i < 4; i++) + pBoneWeights[i] /= weightsum; + } + + if (pIndexCounts) delete []pIndexCounts; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////// +bool FbxUtil::InitializeSkinData( const char* meshName, SkinData& skinData) +{ + return false; + + /* + FbxNode* pFbxNode = FindNodeByName(s_FbxScene, meshName); + if (!pFbxNode) + return false; + + FbxSkin* pFbxSkin = GetFbxSkin(pFbxNode); + int numPoints = GetNumMeshPoints(pFbxNode); + + BoneData& boneData = skinData.m_boneData; + + if (pFbxSkin) + { + int numBones = (int)pFbxSkin->GetClusterCount(); + skinData.Allocate(numBones, numPoints); + + // get bone data (bind pose, bone names, ..) + GetBoneData(pFbxSkin, pFbxNode, boneData.m_pBoneNames, boneData.m_pPoseMatrices); + + // get skinning weights + atcore_float4* boneIndices = skinData.m_pBoneIndices; + atcore_float4* boneWeights = skinData.m_pBoneWeights; + + GetSkinningWeights(pFbxSkin, boneIndices, boneWeights, numPoints); + } + else // no skinning, use model matrix + { + int numBones = 1; + + skinData.Allocate(numBones, numPoints); + + // copy bone name + const char* boneName = pFbxNode->GetName(); + boneData.setBoneName(0, boneName); + + // make pose matrix + gfsdk_makeIdentity(boneData.m_pPoseMatrices[0]); + + // all the vertices map to the model matrix + atcore_float4* boneIndices = skinData.m_pBoneIndices; + atcore_float4* boneWeights = skinData.m_pBoneWeights; + + for (int i = 0; i < numPoints; i++) + { + boneIndices[i] = gfsdk_makeFloat4(0, 0, 0, 0); + boneWeights[i] = gfsdk_makeFloat4(1, 0, 0, 0); + } + } + + return true; + */ +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool FbxUtil::GetMeshInfo(int* numMeshes, char** meshNames, char** skinned) +{ + int cnt = 0; + + for (int i = 0; i < s_FbxScene->GetNodeCount(); i++) + { + FbxNode* pNode = s_FbxScene->GetNode(i); + if (checkMesh(pNode)) + cnt++; + } + + char *pNameBuffer = new char[cnt * 128]; + char *pSkinnedBuffer = new char[cnt]; + + cnt = 0; + for (int i = 0; i < s_FbxScene->GetNodeCount(); i++) + { + FbxNode* pNode = s_FbxScene->GetNode(i); + + if (!checkMesh(pNode)) + continue; + + strcpy(pNameBuffer + cnt * 128, pNode->GetName()); + + pSkinnedBuffer[cnt] = checkSkinned(pNode); + + cnt++; + } + + *numMeshes = cnt; + if (skinned) + { + *skinned = pSkinnedBuffer; + } + else + delete []pSkinnedBuffer; + + *meshNames = pNameBuffer; + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool FbxUtil::GetMeshMaterials( const NvChar* meshName, int *numMaterials, MeshMaterial** materials) +{ + if (!s_FbxScene) + return false; + + FbxNode* pNode = FindNodeByName(s_FbxScene, meshName); + if (!pNode) + return false; + + int numMats = pNode->GetMaterialCount(); + + *materials = new MeshMaterial[numMats]; + + int matCnt = 0; + + for (int i = 0; i < numMats; i++) + { + FbxSurfaceMaterial *mat = pNode->GetMaterial(i); + if (!mat) continue; + if (mat->GetUserDataPtr()) continue; + + MeshMaterial& material = (*materials)[matCnt]; + + strcpy(material.m_name, mat->GetName()); + strcpy(material.m_diffuseTexture, ""); + strcpy(material.m_bumpTexture, ""); + strcpy(material.m_transparentTexture, ""); + strcpy(material.m_normalTexture, ""); + + (atcore_float3&)material.m_ambientColor = gfsdk_makeFloat3(1.0f, 1.0f, 1.0f); + (atcore_float3&)material.m_diffuseColor = gfsdk_makeFloat3(1.0f, 1.0f, 1.0f); + + FbxProperty prop; + FbxProperty fact; + FbxDouble3 d3; + + // get ambient + { + fact = mat->FindProperty(FbxSurfaceMaterial::sAmbientFactor); + material.m_ambientFactor = fact.IsValid() ? (float)fact.Get<FbxDouble>() : 0.1f; + + prop = mat->FindProperty(FbxSurfaceMaterial::sAmbient); + if (prop.IsValid()) + { + FbxDouble3 d3 = prop.Get<FbxDouble3>(); + material.m_ambientColor = gfsdk_makeFloat3((float)d3[0], (float)d3[1], (float)d3[2]); + } + } + + // get specular + { + fact = mat->FindProperty(FbxSurfaceMaterial::sSpecularFactor); + material.m_specularFactor = fact.IsValid() ? (float)fact.Get<FbxDouble>() : 0.1f; + + fact = mat->FindProperty(FbxSurfaceMaterial::sShininess); + material.m_shininess = fact.IsValid() ? (float)fact.Get<FbxDouble>() : 20.0f; + } + + // get diffuse + { + fact = mat->FindProperty(FbxSurfaceMaterial::sDiffuseFactor); + material.m_diffuseFactor = fact.IsValid() ? (float)fact.Get<FbxDouble>() : 0.5f; + + prop = mat->FindProperty(FbxSurfaceMaterial::sDiffuse); + if (prop.IsValid()) + { + FbxDouble3 d3 = prop.Get<FbxDouble3>(); + material.m_diffuseColor = gfsdk_makeFloat3((float)d3[0], (float)d3[1], (float)d3[2]); + + const FbxFileTexture* tex = prop.GetSrcObject<FbxFileTexture>(); + if (tex) + strcpy(material.m_diffuseTexture, tex->GetFileName()); + } + } + + // get normal map + { + prop = mat->FindProperty(FbxSurfaceMaterial::sNormalMap); + if (prop.IsValid()) + { + const FbxFileTexture* tex = prop.GetSrcObject<FbxFileTexture>(); + if (tex) + strcpy(material.m_normalTexture, tex->GetFileName()); + } + } + + matCnt++; + } + + *numMaterials = matCnt; + + return true; +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool FbxUtil::CreateMeshDescriptor(const char* meshName, MeshDesc &desc) +{ + if (!s_FbxScene) + return false; + + FbxNode* pNode = FindNodeByName(s_FbxScene, meshName); + if (!pNode) + return false; + + // read growth mesh data + FbxMesh* pMesh = pNode->GetMesh(); + if (!pMesh) + return false; + + int cpCount = pMesh->GetControlPointsCount(); + + int triCount = 0; + for (int i = 0; i < pMesh->GetPolygonCount(); i++) + { + int psize = pMesh->GetPolygonSize(i); + triCount += (psize - 2); + } + + // allocate buffers + desc.Allocate(cpCount, triCount); + + // read positions + FbxVector4* points = pMesh->GetControlPoints(); + 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])); + + memset(desc.m_pTexCoords, 0, sizeof(atcore_float2) * desc.m_NumTriangles * 3); + + // read uvs + FbxLayerElementUV* leUV = pMesh->GetLayer(0)->GetUVs(); + + FbxGeometryElementNormal *lNormals = pMesh->GetElementNormal(); + FbxGeometryElementTangent* lTangents = pMesh->GetElementTangent(); + + int tcnt = 0; + int vertexBase = 0; + for (int i = 0; i < pMesh->GetPolygonCount(); i++) + { + int vcnt = pMesh->GetPolygonSize(i); + for (int j = 0; j < (vcnt-2); j++) + { + int pIndex[3] = { 0, j+1, j+2 }; + + // get polygon index + for (int p = 0; p < 3; ++p) + desc.m_pIndices[tcnt*3+p] = pMesh->GetPolygonVertex(i, pIndex[p]); + + // get face normal + if (lNormals) + { + FbxLayerElement::EMappingMode mode = lNormals->GetMappingMode(); + + for (int p = 0; p < 3; ++p) + { + int vertexId = vertexBase + pIndex[p]; + int normalId = vertexId; + if (mode == FbxGeometryElement::eByPolygonVertex) + { + if (lNormals->GetReferenceMode() == FbxGeometryElement::eIndexToDirect) + normalId = lNormals->GetIndexArray().GetAt(vertexId); + } + else if (mode == FbxGeometryElement::eByControlPoint) + normalId = pMesh->GetPolygonVertex(i, pIndex[p]); + + const FbxVector4 &n = lNormals->GetDirectArray().GetAt(normalId); + desc.m_pVertexNormals[tcnt*3+p] = gfsdk_makeFloat3((float)n[0], (float)n[1], (float)n[2]); + } + } + + // get face normal + if (lTangents) + { + FbxLayerElement::EMappingMode mode = lTangents->GetMappingMode(); + + for (int p = 0; p < 3; ++p) + { + int vertexId = vertexBase + pIndex[p]; + int tangentId = vertexId; + if (mode == FbxGeometryElement::eByPolygonVertex) + { + if (lTangents->GetReferenceMode() == FbxGeometryElement::eIndexToDirect) + tangentId = lTangents->GetIndexArray().GetAt(vertexId); + } + else if (mode == FbxGeometryElement::eByControlPoint) + tangentId = pMesh->GetPolygonVertex(i, pIndex[p]); + + const FbxVector4 &n = lTangents->GetDirectArray().GetAt(tangentId); + desc.m_pTangents[tcnt*3+p] = gfsdk_makeFloat3((float)n[0], (float)n[1], (float)n[2]); + } + } + + if (leUV) + { + int i0 = pMesh->GetTextureUVIndex(i, 0); + int i1 = pMesh->GetTextureUVIndex(i, j+1); + int i2 = pMesh->GetTextureUVIndex(i, j+2); + + FbxVector2 texCoord0 = leUV->GetDirectArray().GetAt(i0); + FbxVector2 texCoord1 = leUV->GetDirectArray().GetAt(i1); + FbxVector2 texCoord2 = leUV->GetDirectArray().GetAt(i2); + + desc.m_pTexCoords[tcnt*3+0] = gfsdk_makeFloat2(1.0f * float(texCoord0[0]), 1.0f - float(texCoord0[1])); + desc.m_pTexCoords[tcnt*3+1] = gfsdk_makeFloat2(1.0f * float(texCoord1[0]), 1.0f - float(texCoord1[1])); + desc.m_pTexCoords[tcnt*3+2] = gfsdk_makeFloat2(1.0f * float(texCoord2[0]), 1.0f - float(texCoord2[1])); + } + + tcnt++; + } + vertexBase += vcnt; + } + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* +bool FbxUtil::CreateHairFromFbx(const char* guideName, const char* growthMeshName, NvHair::AssetDescriptor& hairAsset) +{ + if (!s_FbxScene) + return false; + + // read growth mesh data + MeshDesc meshDesc; + if (false == FbxUtil::CreateMeshDescriptor(growthMeshName, meshDesc)) + return false; + + FbxNode* pHairNode = FindNodeByName(s_FbxScene, guideName); + if (!pHairNode) + return false; + + FbxNode* pMeshNode = FindNodeByName(s_FbxScene, growthMeshName); + if (!pMeshNode) + return false; + + FbxSkin* pFbxSkin = GetFbxSkin(pMeshNode); + int numBones = 1; + + if (pFbxSkin) + numBones = (int)pFbxSkin->GetClusterCount(); + + // get skin data from mesh + int numPoints = meshDesc.m_NumVertices; + + atcore_float4* pMeshBoneIndices = new atcore_float4[numPoints]; + atcore_float4* pMeshBoneWeights = new atcore_float4[numPoints]; + + GetSkinningWeights(pFbxSkin, pMeshBoneIndices, pMeshBoneWeights, numPoints); + + // create raw hair array + FbxLine* pLine = pHairNode->GetLine(); + if (!pLine) + return false; + + int cpCount = pLine->GetControlPointsCount(); + int curveCount = pLine->GetEndPointCount(); + + atcore_float3* pVertices = new atcore_float3[cpCount]; + NvUInt32* pEndIndices = new NvUInt32[curveCount]; + + FbxVector4* pFbxPoints = pLine->GetControlPoints(); + FbxArray<int>* pFbxEndIndices = pLine->GetEndPointArray(); + + for (int i = 0; i < cpCount; i++) + pVertices[i] = gfsdk_makeFloat3(float(pFbxPoints[i][0]), float(pFbxPoints[i][1]), float(pFbxPoints[i][2])); + + for (int i = 0; i < curveCount; i++) + pEndIndices[i] = (*pFbxEndIndices)[i]; + + // check against closest growth mesh points + const float distThreshold = 25.0; + + int numValidHairs = 0; + int numValidHairVertices = 0; + + int* pMeshToHairMap = new int[meshDesc.m_NumVertices]; + int* pHairToMeshMap = new int[curveCount]; + int* pHairToHairMap = new int[curveCount]; + float* pMinDistances = new float[meshDesc.m_NumVertices]; + atcore_float3* pRootVertices = new atcore_float3[curveCount]; + atcore_float3* pTriangleCenters = new atcore_float3[meshDesc.m_NumTriangles]; + + // initialize triangle centers + for (int i = 0; i < meshDesc.m_NumTriangles; i++) + { + NvUInt32 v0 = meshDesc.m_pIndices[i*3 + 0]; + NvUInt32 v1 = meshDesc.m_pIndices[i * 3 + 1]; + NvUInt32 v2 = meshDesc.m_pIndices[i * 3 + 2]; + + atcore_float3 p0 = meshDesc.m_pVertices[v0]; + atcore_float3 p1 = meshDesc.m_pVertices[v1]; + atcore_float3 p2 = meshDesc.m_pVertices[v2]; + + pTriangleCenters[i] = 1.0f / 3.0f * (p0 + p1 + p2); + } + + // initialize mesh to hair map + for (int i = 0; i < meshDesc.m_NumVertices; i++) + { + pMeshToHairMap[i] = -1; + pMinDistances[i] = FLT_MAX; + } + + // copy root vertices of input hairs + + for (int i = 0; i < curveCount; i++) + { + int root = (i == 0) ? 0 : pEndIndices[i-1]+1; + pRootVertices[i] = pVertices[root]; + pHairToMeshMap[i] = -1; + } + + // for each input hair curve, find the closest mesh vertex + for (int i = 0; i < curveCount; i++) + { + atcore_float3 hp = pRootVertices[i]; + + float minDist = FLT_MAX; + int closestTriangle = -1; + for (int j = 0; j < meshDesc.m_NumTriangles; j++) + { + atcore_float3 c = pTriangleCenters[j]; + + float distSquared = gfsdk_lengthSquared(hp - c); + if (distSquared < minDist) + { + minDist = distSquared; + closestTriangle = j; + } + } + + if (closestTriangle >= 0) + { + for (int k = 0; k < 3; k++) + { + NvUInt32 v = meshDesc.m_pIndices[closestTriangle * 3 + k]; + atcore_float3 p = meshDesc.m_pVertices[v]; + + float distSquared = gfsdk_lengthSquared(hp - p); + if (distSquared < pMinDistances[v]) + { + pMinDistances[v] = distSquared; + pMeshToHairMap[v] = i; + } + } + } + } + + // prepare mapping from new hair set to mesh and old hairs + for (int i = 0; i < meshDesc.m_NumVertices; i++) + { + int closestHair = pMeshToHairMap[i]; + if (closestHair < 0) + continue; + + pHairToMeshMap[numValidHairs] = i; + pHairToHairMap[numValidHairs] = closestHair; + pMeshToHairMap[i] = numValidHairs; // update hair with new hair index + + int root = (closestHair == 0) ? 0 : pEndIndices[closestHair-1]+1; + int tip = pEndIndices[closestHair]; + + numValidHairVertices += (tip - root + 1); + numValidHairs++; + } + + // allocate new hairs + hairAsset.m_numGuideHairs = numValidHairs; + hairAsset.m_numVertices = numValidHairVertices; + + hairAsset.m_boneIndices = new atcore_float4[hairAsset.m_numGuideHairs]; + hairAsset.m_boneWeights = new atcore_float4[hairAsset.m_numGuideHairs]; + + hairAsset.m_vertices = new atcore_float3[hairAsset.m_numVertices]; + hairAsset.m_endIndices = new NvUInt32[hairAsset.m_numGuideHairs]; + hairAsset.m_faceIndices = new NvUInt32[meshDesc.m_NumTriangles * 3]; + hairAsset.m_faceUvs = new atcore_float2[meshDesc.m_NumTriangles * 3]; + + hairAsset.m_numBones = numBones; + hairAsset.m_boneNames = new NvChar[NV_HAIR_MAX_STRING * hairAsset.m_numBones]; + hairAsset.m_bindPoses = new atcore_float4x4[hairAsset.m_numBones]; + hairAsset.m_boneParents = new NvInt32[hairAsset.m_numBones]; + + if (pFbxSkin) + GetBoneData(pFbxSkin, pMeshNode, hairAsset.m_boneNames, hairAsset.m_bindPoses); + else + { + strcpy(hairAsset.m_boneNames, "Root"); + gfsdk_makeIdentity(hairAsset.m_bindPoses[0]); + hairAsset.m_boneParents[0] = -1; + } + + // copy vertex data + int vertexCnt = 0; + + for (int i = 0; i < hairAsset.m_numGuideHairs; i++) + { + int oldHair = pHairToHairMap[i]; + + int oldRoot = (oldHair == 0) ? 0 : pEndIndices[oldHair-1]+1; + int oldTip = pEndIndices[oldHair]; + + int offset = oldTip - oldRoot; + + int newRoot = vertexCnt; + int newTip = vertexCnt + offset; + + vertexCnt += (offset + 1); + + hairAsset.m_endIndices[i] = newTip; + + int meshVertex = pHairToMeshMap[i]; + atcore_float3 meshRoot = meshDesc.m_pVertices[meshVertex]; + atcore_float3 hairRoot = pVertices[oldRoot]; + + atcore_float3 rootOffset = meshRoot - hairRoot; + + for (int j = 0; j <= offset; j++) + hairAsset.m_vertices[newRoot + j] = pVertices[oldRoot + j] + rootOffset; + + hairAsset.m_boneIndices[i] = gfsdk_makeFloat4(0,0,0,0); + hairAsset.m_boneWeights[i] = gfsdk_makeFloat4(1,0,0,0); + + if (pFbxSkin) + { + hairAsset.m_boneIndices[i] = pMeshBoneIndices[meshVertex]; + hairAsset.m_boneWeights[i] = pMeshBoneWeights[meshVertex]; + } + } + + // copy face indices and texture uvs + int faceCnt = 0; + for (int i = 0; i < meshDesc.m_NumTriangles; i++) + { + NvUInt32 i0 = meshDesc.m_pIndices[i * 3 + 0]; + NvUInt32 i1 = meshDesc.m_pIndices[i * 3 + 1]; + NvUInt32 i2 = meshDesc.m_pIndices[i * 3 + 2]; + + int h0 = pMeshToHairMap[i0]; + int h1 = pMeshToHairMap[i1]; + int h2 = pMeshToHairMap[i2]; + + if ((h0 < 0) || (h1 < 0) || (h2 < 0)) + continue; // invalid face + + hairAsset.m_faceIndices[ faceCnt * 3 + 0] = h0; + hairAsset.m_faceIndices[ faceCnt * 3 + 1] = h1; + hairAsset.m_faceIndices[ faceCnt * 3 + 2] = h2; + + hairAsset.m_faceUvs[ faceCnt * 3 + 0 ] = meshDesc.m_pTexCoords[i * 3 + 0]; + hairAsset.m_faceUvs[ faceCnt * 3 + 1 ] = meshDesc.m_pTexCoords[i * 3 + 1]; + hairAsset.m_faceUvs[ faceCnt * 3 + 2 ] = meshDesc.m_pTexCoords[i * 3 + 2]; + + faceCnt++; + } + + hairAsset.m_numFaces = faceCnt; + + delete []pMeshBoneIndices; + delete []pMeshBoneWeights; + + delete []pMeshToHairMap; + delete []pHairToMeshMap; + delete []pHairToHairMap; + + return true; +} +*/ diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h b/NvBlast/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h new file mode 100644 index 0000000..26e61a9 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Anim/FbxUtil.h @@ -0,0 +1,64 @@ +// 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. +// +#pragma once + +#include "AnimUtil.h" + +//#include <Nv/Blast/NvHairSdk.h> + +//////////////////////////////////////////////////////////////////////////////////////// +// Helper for fbx file load +class CORELIB_EXPORT FbxUtil +{ +public: + + /// initialize fbx loader. + static bool Initialize(const nvidia::Char* fbxFileName, nvidia::Float sceneUnit = 0.0f); + static bool Release(void); + + static bool InitializeAnimationCache(AnimationCache& cache); + + /// Get global frame range and fps information from fbx. + static bool GetGlobalSettings(nvidia::Float32* pStarfFrame = 0, nvidia::Float32* pEndFrame = 0, nvidia::Float32 *pFps = 0, int* upAxis = 0, char* rootBoneName = 0); + + /// get skinning data from the mesh node + static bool InitializeSkinData( const nvidia::Char* meshName, SkinData& pSkinningDataToUpdate); + + /// create mesh descriptor from fbx mesh node + 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); + + /// get mesh material info from fbx scene + static bool GetMeshMaterials(const nvidia::Char* meshName, int *numMaterials, MeshMaterial** materials); + + /// get hair directly from fbx +// static bool CreateHairFromFbx(const char* guideName, const char* growthMeshName, NvHair::AssetDescriptor &hairAsset); +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.cpp new file mode 100644 index 0000000..222debd --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.cpp @@ -0,0 +1,263 @@ +#include "backdoor.h" +#include <stdio.h> +#include <string.h> +#include <malloc.h> +#include <Windows.h> +#include "Nv.h" + +namespace BACKDOOR +{ + + struct Header + { + int mCount; + int mType; + }; + +#define MAX_BACKDOOR_PACKET 1024 // maximum size of a send/receive packet +#define HEADER_SIZE (sizeof(Header)) +#define DATA_SIZE (MAX_BACKDOOR_PACKET - HEADER_SIZE) +#define STRING_SIZE (DATA_SIZE - 1) +#define MAX_ARGS 32 +#pragma warning(disable:4996) + + // Chagne this helper class to use the memory mapped IO API relevant to your system. + // This implementation uses the Windows API for a memory mapped shared file system. + class MemoryMappedFile + { + public: + + MemoryMappedFile(const char *mappingObject,unsigned int mapSize); + ~MemoryMappedFile(void); + void * getBaseAddress(void); + private: + class MemoryMappedFileImpl *mImpl; + }; + + + class MemoryMappedFileImpl + { + public: + HANDLE mMapFile; + void * mHeader; + }; + + MemoryMappedFile::MemoryMappedFile(const char *mappingObject,unsigned int mapSize) + { + mImpl = (MemoryMappedFileImpl *)::malloc(sizeof(MemoryMappedFileImpl)); + mImpl->mHeader = NV_NULL; + mImpl->mMapFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS,FALSE,mappingObject); + if ( mImpl->mMapFile == NV_NULL ) + { + mImpl->mMapFile = CreateFileMappingA( + INVALID_HANDLE_VALUE, // use paging file + NV_NULL, // default security + PAGE_READWRITE, // read/write access + 0, // maximum object size (high-order DWORD) + mapSize, // maximum object size (low-order DWORD) + mappingObject); + } + if ( mImpl->mMapFile ) + { + mImpl->mHeader = MapViewOfFile(mImpl->mMapFile,FILE_MAP_ALL_ACCESS,0,0,mapSize); + } + + } + + MemoryMappedFile::~MemoryMappedFile(void) + { + + if ( mImpl->mHeader ) + { + UnmapViewOfFile(mImpl->mHeader); + if ( mImpl->mMapFile ) + { + CloseHandle(mImpl->mMapFile); + } + } + + ::free(mImpl); + } + + void * MemoryMappedFile::getBaseAddress(void) + { + return mImpl->mHeader; + } + + + +class _Backdoor : public Backdoor +{ + MemoryMappedFile *mReceiveFile; + MemoryMappedFile *mSendFile; + const char *mArgv[MAX_ARGS]; + char mBuffer[MAX_BACKDOOR_PACKET]; + + int mSendCount; + int mReceiveCount; + +public: + _Backdoor(const char *sendName, // The name of the shared memory file to act as the 'sender' stream. + const char *receiveName) // The name of the shared memory file to act as the 'receive' message stream. + { + mSendCount = 0; // This is a semaphore used to signal when a new message has been sent. + mReceiveCount = 0; // This is a semaphore used to detect if a new message has been received. + mReceiveFile = new MemoryMappedFile(receiveName,MAX_BACKDOOR_PACKET); // Open the receive stream file + mSendFile = new MemoryMappedFile(sendName,MAX_BACKDOOR_PACKET); // Open the send stream file + } + + virtual ~_Backdoor(void) + { + delete mReceiveFile; // Close the receive stream file + delete mSendFile; // Close the send stream file. + } + + virtual void send(const char *fmt,...) + { + char wbuff[DATA_SIZE]; + wbuff[STRING_SIZE] = 0; + _vsnprintf(wbuff,STRING_SIZE, fmt, (char *)(&fmt+1)); + + mSendCount++; // Increment the send counter. + size_t len = strlen(wbuff); + + if ( len < STRING_SIZE && mSendFile ) + { + char *baseAddress = (char *)mSendFile->getBaseAddress(); // get the base address of the shared memory + int *dest = (int *)baseAddress; + + baseAddress+=sizeof(Header); + + memcpy(baseAddress,wbuff,len+1); // First copy the message. + *dest = mSendCount; // Now revised the send count semaphore so the other process knows there is a new message to processs. + } + } + + virtual const char **getInput(int &argc) + { + const char **ret = NV_NULL; + argc = 0; + + if ( mReceiveFile ) + { + const char *baseAddress = (const char *)mReceiveFile->getBaseAddress(); + const int *source = (const int *)baseAddress; + baseAddress+=sizeof(Header); + if ( *source != mReceiveCount ) + { + mReceiveCount = *source; + memcpy(mBuffer,baseAddress,DATA_SIZE); + + char *scan = mBuffer; + while ( *scan == 32 ) scan++; // skip leading spaces + if ( *scan ) // if not EOS + { + argc = 1; + mArgv[0] = scan; // set the first argument + + while ( *scan && argc < MAX_ARGS) // while still data and we haven't exceeded the maximum argument count. + { + while ( *scan && *scan != 32 ) scan++; // scan forward to the next space + if ( *scan == 32 ) // if we hit a space + { + *scan = 0; // null-terminate the argument + scan++; // skip to the next character + while ( *scan == 32 ) scan++; // skip any leading spaces + if ( *scan ) // if there is still a valid non-space character process that as the next argument + { + mArgv[argc] = scan; + argc++; + } + } + } + ret = mArgv; + } + } + } + + return ret; + } + + bool sendData(char* ptr, size_t size, int dataType) + { + if ( size > DATA_SIZE || !mSendFile ) + return false; + + mSendCount++; // Increment the send counter. + + char *baseAddress = (char *)mSendFile->getBaseAddress(); // get the base address of the shared memory + + Header* header = (Header*)baseAddress; + + header->mCount = mSendCount; + header->mType = dataType; + + baseAddress+=sizeof(Header); + memcpy(baseAddress,ptr, size); + + return true; + } + + bool receiveData(char* ptr, size_t size, int dataType) + { + if ( size > DATA_SIZE || !mReceiveFile ) + return false; + + const char *baseAddress = (const char *)mReceiveFile->getBaseAddress(); + const int *source = (const int *)baseAddress; + + Header* header = (Header*)baseAddress; + if (header->mType != dataType) + return false; + + baseAddress+=sizeof(Header); + + if ( *source != mReceiveCount ) + { + mReceiveCount = *source; + memcpy(ptr, baseAddress, size); + } + + return true; + } + + bool checkMessage(const char* msg) + { + if (!mReceiveFile) + return false; + + const char *baseAddress = (const char *)mReceiveFile->getBaseAddress(); + const int *source = (const int *)baseAddress; + + if (*source == mReceiveCount) + return false; + + if ( *source != mReceiveCount ) + { + baseAddress+=sizeof(Header); + + return (!strcmp(baseAddress, msg)); + } + + return false; + } + + virtual void release(void) + { + delete this; + } + + +}; + +}; // end of namespace + +using namespace BACKDOOR; + + +Backdoor * createBackdoor(const char *sendName,const char *receiveName) +{ + _Backdoor *ret = new _Backdoor(sendName,receiveName); + return static_cast< Backdoor *>(ret); +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.h b/NvBlast/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.h new file mode 100644 index 0000000..a8ea1ac --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Backdoor/backdoor.h @@ -0,0 +1,52 @@ +#ifndef BACKDOOR_H + +#define BACKDOOR_H + +// This is a tiny helper class that let's you easily perform communication using shared file memory between +// two processes on the same machine. It is built to comple on Windows; but relatively minor changes +// are necesary to make it work on other platforms; just change the memory mapped IO calls. +// +// This same technique would work as well if you simply opened a file on disk; though shared memory is much +// faster. +// +// This is not meant to be some kind of sophisticated inter-process communciations class. Instead it's just +// used for the very basic use case where you need to easily send simple 'commands' between two proceses. +// +// This code snippet comes with a console application which can be used to send commands to another process +// and display received messaegs from that other process. +// +// Simply launch this console app with a command line argument indicating whether it is considered the 'server' +// or the 'client'. You can test it by launching it twice; once as server and once as client and then send +// chat messages back and forth. +// +// Written by John W. Ratcliff on February 10, 2013 and released into the public domain. +// +// mailto:[email protected] + +class Backdoor +{ +public: + + virtual void send(const char *str,...) = 0; // This sends a 'command' to the other process. Uses the printf style format for convenience. + + // This method consumes an inomcing command from the other process and parses it into an argc/argv format. + virtual const char **getInput(int &argc) = 0; + + virtual bool sendData(char* ptr, size_t size, int dataType) = 0; + + virtual bool receiveData(char* ptr, size_t size, int dataType) = 0; + + virtual bool checkMessage(const char* msg) = 0; + + // This method releases the Backdoor interface class. + virtual void release(void) = 0; +protected: + virtual ~Backdoor(void) + { + } +}; + +Backdoor * createBackdoor(const char *sendName,const char *receiveName); + + +#endif diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/CoreLib.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/CoreLib.cpp new file mode 100644 index 0000000..b94b1d9 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/CoreLib.cpp @@ -0,0 +1,1460 @@ +#include <QtWidgets/QApplication> +#include <QtCore/QTimer> +#include <QtCore/QFile> +#include <QtCore/QDir> +#include <QtWidgets/QMessageBox> +#include <QtCore/QFileInfo> + +#include "Nv.h" + +#include "AppMainWindow.h" +#include "D3DWidget.h" +#include "SimpleScene.h" +#include "Automate.h" +#include "Settings.h" +#include "RenderInterface.h" +#include "GlobalSettings.h" + +#ifndef NV_ARTISTTOOLS +#include "FurCharacter.h" +#include "PluginBlast.h" +#endif // NV_ARTISTTOOLS + +#include "RenderPlugin.h" + +void SetupStyles() +{ + //QFile styleFile( ":/AppMainWindow/ThemeDefault.qss" ); + QString appPath = QCoreApplication::applicationDirPath(); + QString themeFilePath = appPath + "/ArtistToolsTheme.qss"; + QFile styleFile; + if (QFile::exists(themeFilePath)) + { + styleFile.setFileName(themeFilePath); + } + else + { + styleFile.setFileName(":/AppMainWindow/ThemeDark.qss"); + } + styleFile.open(QFile::ReadOnly); + + QString styleSheet(styleFile.readAll()); + QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false); + qApp->setStyleSheet(styleSheet); +} + +int ShowErrorMsg(int errorCode) +{ + const char* errorMsg = 0; + switch (errorCode) + { + case 1: + errorMsg = "Fail to create GPU device and context. " + "Please make sure you are using an independant GPU and choose '3D App - Game Development' in the Global Settings page in its Control Panel."; + break; + case 2: + errorMsg = "Fail to initialize all the shared shaders, resources, etc. " + "Please make sure you are using an independant GPU and choose '3D App - Game Development' in the Global Settings page in its Control Panel."; + break; + case 3: + errorMsg = "Fail to create render window, target, swap chains, etc. " + "Please make sure you are using an independant GPU and choose '3D App - Game Development' in the Global Settings page in its Control Panel."; + break; + case 4: + // Unable to load/start the dll. + errorMsg = "Unable to load and/or start the Blast dll. " + "Please make sure the appropriate hairworks dll is the same directory as the viewer executable."; + break; + default: + errorMsg = "We need define one error message!"; + } + QMessageBox messageBox; + messageBox.information(0, "Error", errorMsg); + return errorCode; +} + +extern void CreateAppMainWindow(); +extern void ReleaseAppMainWindow(); + +int RunApp(QApplication& app) +{ + CreateAppMainWindow(); + + // resolution + int windowWidth = 0; + int windowHeight = 0; + std::string resolution = AppSettings::Inst().GetOptionValue("User/Resolution")->Value.Enum; + int width, height; + sscanf(resolution.c_str(), "%dx%d", &windowWidth, &windowHeight); + + // aa sample count + int sampleCount = 8; + if (stricmp(AppSettings::Inst().GetOptionValue("User/AA")->Value.Enum, "2X") == 0) + { + sampleCount = 2; + } + else if (stricmp(AppSettings::Inst().GetOptionValue("User/AA")->Value.Enum, "4X") == 0) + { + sampleCount = 4; + } + else if (stricmp(AppSettings::Inst().GetOptionValue("User/AA")->Value.Enum, "8X") == 0) + { + sampleCount = 8; + } + else if (stricmp(AppSettings::Inst().GetOptionValue("User/AA")->Value.Enum, "Off") == 0) + { + sampleCount = 1; + } + + // device id + int deviceID = (AppSettings::Inst().GetOptionValue("User/Device")->Value.Int); + if (deviceID < 0 || deviceID > 3) + { + deviceID = -1; // when -1 to choose a good GPU + } + + // backdoor connection mode + int backdoor = 0; + if (stricmp(AppSettings::Inst().GetOptionValue("User/Backdoor")->Value.String, "master") == 0) + { + backdoor = 1; + } + else if (stricmp(AppSettings::Inst().GetOptionValue("User/Backdoor")->Value.String, "slave") == 0) + { + backdoor = 2; + } + + AppMainWindow::setConnectionMode(backdoor); + + SimpleScene::Inst(); +#ifdef NV_ARTISTTOOLS + CoreLib::Inst()->SimpleScene_SimpleScene(); +#endif // NV_ARTISTTOOLS + // initialize main window + // HAIR-285 Viewer - new command line to start Viewer in full screen + AppMainWindow::Inst().InitUI(); + if (windowWidth == 0) + AppMainWindow::Inst().showFullScreen(); + else if (windowWidth<0) + AppMainWindow::Inst().showMaximized(); + else + AppMainWindow::Inst().resize(windowWidth, windowHeight); + + D3DWidget* d3dWidget = AppMainWindow::Inst().GetRenderWidget(); + + HWND hWidget = (HWND)d3dWidget->winId(); + + // create GPU device and context + if (false == RenderInterface::InitDevice(deviceID)) + return ShowErrorMsg(1); + + // initialize all the shared shaders, resources, etc + if (false == RenderInterface::Initialize()) + return ShowErrorMsg(2); + + // create render window, target, swap chains, etc. + if (false == RenderInterface::CreateRenderWindow(hWidget, sampleCount)) + return ShowErrorMsg(3); + + SimpleScene* scene = SimpleScene::Inst(); + if (false == scene->Initialize(hWidget, backdoor)) + return ShowErrorMsg(4); + + GlobalSettings::Inst().setRenderFps(60); + + GlobalSettings::GetFrameTimer().start(); + + QObject::connect(&GlobalSettings::GetFrameTimer(), SIGNAL(timeout()), d3dWidget, SLOT(Timeout())); + QObject::connect(&app, SIGNAL(aboutToQuit()), d3dWidget, SLOT(Shutdown())); + + SetupStyles(); + + AppMainWindow::Inst().show(); + AppMainWindow::Inst().update(); + + std::string title = ""; + +#ifdef NV_ARTISTTOOLS + title = "ArtistTools"; +#else + title = "Blast Viewer"; +#endif // NV_ARTISTTOOLS + +#ifdef _WIN64 + title.append(" x64"); +#endif + +#ifdef _DEBUG + title.append(" (Debug)"); +#else +#endif + + std::string strApi = RenderPlugin::Instance()->GetRenderApi(); + title.append(" "); + title.append(strApi); + + switch (backdoor) + { + case 1: + title.append(" (Master Mode)"); + break; + case 2: + title.append(" (Slave Mode)"); + break; + } + + AppMainWindow::Inst().setWindowTitle(title.c_str()); + + OptionValue* option = AppSettings::Inst().GetOptionValue("User/HideUI"); + if (option) + { + if (option->Value.Bool == OA_TRUE) + { + AppMainWindow::Inst().shortcut_expert(); + } + } + +#ifndef NV_ARTISTTOOLS + option = AppSettings::Inst().GetOptionValue("User/FurAssetPath"); + if (option && option->Value.String && strlen(option->Value.String)) + { + const char* path = option->Value.String; + QFileInfo fi(path); + QByteArray dir = QDir::toNativeSeparators(fi.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file = fi.fileName().toLocal8Bit(); + scene->GetFurCharacter().LoadHairAsset(dir, file); + } +#else + CoreLib::Inst()->CoreLib_RunApp(); +#endif // NV_ARTISTTOOLS + + option = AppSettings::Inst().GetOptionValue("User/ProjectPath"); + if (option && option->Value.String && strlen(option->Value.String)) + { + const char* path = option->Value.String; + QFileInfo fi(path); + QByteArray dir = QDir::toNativeSeparators(fi.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file = fi.fileName().toLocal8Bit(); + scene->LoadProject(dir, file); + } + option = AppSettings::Inst().GetOptionValue("User/Play"); + if (option) + { + if (option->Value.Bool == OA_TRUE) + { + AppMainWindow::Inst().shortcut_pause(); + } + } + + int ret = app.exec(); + // release GUI before releasing QApplication (and QWindowsContext) to avoid crash. + // e.g. GWDCC-415 Blast Viewer crashes when quit after clicked any main menu. + ReleaseAppMainWindow(); + return ret; +} + +static void ShowUsage() +{ + char message[] = { + "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" + "[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" + "-backdoor <master|slave>\n\t: Backdoor options\n" + "-device <0|1|2|3>\n\t: Which GPU to use\n" + "-noui \n\t: Set this option to hide UI\n" + "-play \n\t: Play the default animation if it has\n" + "-fullscreen \n\t: Start the application in full screen\n" + "-maxscreen \n\t: Start the application in max sized screen\n" + "-demoMode playlistname.plist \n\t: Start the application and demo the projects in a fur playlist stored in media/playlists folder.\n" + }; + QMessageBox messageBox; + messageBox.information(0, "Usage", message); +} + +bool ParseCommandLineOptions(int argc, char* argv[]) +{ + AppSettings& settings = AppSettings::Inst(); + + for (int idx = 1; idx < argc; ++idx) + { + if (!stricmp(argv[idx], "-size")) + { + if ((idx + 1) < argc) + { + oaValue value; + value.Enum = argv[idx + 1]; + settings.SetOptionValue("User/Resolution", OA_TYPE_ENUM, &value); + idx++; // Skip next option + } + } + else if (!stricmp(argv[idx], "-fullscreen")) + { + // HAIR-285 Viewer - new command line to start Viewer in full screen + oaValue value; + value.Enum = "0x0"; + settings.SetOptionValue("User/Resolution", OA_TYPE_ENUM, &value);; + } + else if (!stricmp(argv[idx], "-maxscreen")) + { + // HAIR-285 Viewer - new command line to start Viewer in full screen + oaValue value; + value.Enum = "-1x0"; + settings.SetOptionValue("User/Resolution", OA_TYPE_ENUM, &value);; + } + else if (!stricmp(argv[idx], "-backdoor")) + { + if ((idx + 1) < argc) + { + oaValue value; + bool isValid = true; + if (!strcmp(argv[idx + 1], "master")) + value.String = "master"; + else if (!strcmp(argv[idx + 1], "slave")) + value.String = "slave"; + else + isValid = false; + + if (isValid) + settings.SetOptionValue("User/Backdoor", OA_TYPE_STRING, &value); + idx++; // Skip next option + } + } + else if (!stricmp(argv[idx], "-aa")) + { + if ((idx + 1) < argc) + { + oaValue value; + bool isValid = true; + if (!strcmp(argv[idx + 1], "1")) + value.Enum = "Off"; + else if (!strcmp(argv[idx + 1], "2")) + value.Enum = "2X"; + else if (!strcmp(argv[idx + 1], "4")) + value.Enum = "4X"; + else if (!strcmp(argv[idx + 1], "8")) + value.Enum = "8X"; + else + isValid = false; + if (isValid) + settings.SetOptionValue("User/AA", OA_TYPE_ENUM, &value); + idx++; // Skip next option + } + } + else if (!stricmp(argv[idx], "-device")) + { + if ((idx + 1) < argc) + { + oaValue value; + bool isValid = true; + if (!strcmp(argv[idx + 1], "0")) + value.Int = 0; + else if (!strcmp(argv[idx + 1], "1")) + value.Int = 1; + else if (!strcmp(argv[idx + 1], "2")) + value.Int = 2; + else if (!strcmp(argv[idx + 1], "3")) + value.Int = 3; + else + isValid = false; + if (isValid) + settings.SetOptionValue("User/Device", OA_TYPE_INT, &value); + idx++; // Skip next option + } + } + else if (!stricmp(argv[idx], "-noui")) + { + oaValue value; + value.Bool = OA_TRUE; + settings.SetOptionValue("User/HideUI", OA_TYPE_BOOL, &value); + } + else if (!stricmp(argv[idx], "-perf")) + { + oaValue value; + value.Bool = OA_TRUE; + settings.SetOptionValue("User/PerfMode", OA_TYPE_BOOL, &value); + } + else if (!stricmp(argv[idx], "-play")) + { + oaValue value; + value.Bool = OA_TRUE; + settings.SetOptionValue("User/Play", OA_TYPE_BOOL, &value); + } + else if (!stricmp(argv[idx], "-install")) + { + // Install mode + // Just ignore here + } + else if (!stricmp(argv[idx], "-openautomate")) + { + // OpenAutomate mode + // Just ignore here + idx++; // Skip next option + } + else if (!stricmp(argv[idx], "-demoMode")) + { + //QMessageBox messageBox; + //messageBox.information(0, "debug", argv[idx]); + idx++; // check next arg + if (idx < argc) + { + bool isValid = false; + char* extension = strrchr(argv[idx], '.'); + if (extension) + { + if (!_stricmp(extension, ".plist")) + { + oaValue value; + value.String = argv[idx]; + settings.SetOptionValue("User/FurDemoPlaylist", OA_TYPE_STRING, &value); + isValid = true; + } + } + } + } + else // Try to load the file + { + bool isValid = false; + char* extension = strrchr(argv[idx], '.'); + if (extension) + { + if (!_stricmp(extension, ".furproj")) + { + 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; + } + } + if (!isValid) + { + // Invalid option + return false; + } + } + } + return true; +} + +typedef RenderPlugin*(*Func)(void); + +void GetRenderPlugins(QApplication& app, std::vector<std::string>& render_plugins) +{ + HMODULE module = NULL; + Func CreateFunc = NULL; + RenderPlugin* Plugin = NULL; + + QDir pluginsDir(app.applicationDirPath()); + foreach(QString fileName, pluginsDir.entryList(QDir::Files)) { +#ifdef NV_ARTISTTOOLS + if (!fileName.startsWith("Render")) +#else + if (!fileName.startsWith("FurRender")) +#endif + { + continue; + } + +#ifdef _WIN64 +#ifdef _DEBUG + if (!fileName.endsWith(".win64.d.dll")) + { + continue; + } +#else + if (!fileName.endsWith(".win64.dll")) + { + continue; + } +#endif +#else +#ifdef _DEBUG + if (!fileName.endsWith(".win32.d.dll")) + { + continue; + } +#else + if (!fileName.endsWith(".win32.dll")) + { + continue; + } +#endif +#endif + + QByteArray tmp = pluginsDir.absoluteFilePath(fileName).toUtf8(); + const char* pName = tmp.data(); + module = LoadLibraryA(pName); + if (NULL == module) + continue; + + CreateFunc = (Func)GetProcAddress(module, "CreateRenderPlugin"); + if (NULL == CreateFunc) + continue; + + Plugin = CreateFunc(); + if (NULL != Plugin) + { + std::string name = Plugin->GetRenderApi(); + render_plugins.push_back(name); + delete Plugin; + Plugin = NULL; + } + } +} + + +#include "RenderPlugin.h" +#include "CoreLib.h" + +#include <io.h> +#include <stdio.h> +#include <stdlib.h> +#define LINE 10 + +#ifndef NV_ARTISTTOOLS +int CoreLib::CoreMain(int argc, char *argv[]) +#else +int CoreLib::CoreMain(int argc, char *argv[], bool withPlugin) +#endif +{ +#ifdef OPEN_CONSOLE + AllocConsole(); + freopen("CONOUT$", "w", stdout); + freopen("CONOUT$", "w", stderr); +#endif + + QApplication a(argc, argv); + + AppSettings::Inst().InitOptions(); + + if (!ParseCommandLineOptions(argc, argv)) + { + // Invalid option. Show the usage and quit + ShowUsage(); + return 0; + } +#if (0) // Install mode for OpenAutomate is not tested yet + bool isAutomateInstallMode = GetAutomateInstallModeOption(argc, argv); + if (isAutomateInstallMode) + { + if (AutomateInstallApp()) + { + QMessageBox messageBox; + messageBox.information(0, "Info", "Install succeeded"); + } + else + { + QMessageBox messageBox; + messageBox.information(0, "Info", "Install failed. Did you run with admin privilege?"); + } + return 0; + } +#endif + std::string openAutomateOptions = GetAutomateOption(argc, argv); + if (!openAutomateOptions.empty()) + { + AutomateInit(openAutomateOptions.c_str()); + } + + std::vector<std::string> render_plugins; + std::vector<std::string>::iterator it; + + FILE *pf; + if ((_access("RenderPlugin.txt", 0)) == -1) + { + GetRenderPlugins(a, render_plugins); + + if (render_plugins.size() > 1) + { + pf = fopen("RenderPlugin.txt", "a"); + for (it = render_plugins.begin(); it != render_plugins.end(); it++) + { + fprintf(pf, "%s\n", (*it).c_str()); + } + fclose(pf); + } + } + else + { + pf = fopen("RenderPlugin.txt", "r"); + char buf[LINE]; + while (1) { + memset(buf, 0, LINE); + if (fscanf(pf, "%s", buf) == -1) + break; + render_plugins.push_back(buf); + } + fclose(pf); + } + + RenderPlugin::Load(render_plugins); + + std::string strApi = RenderPlugin::Instance()->GetRenderApi(); + if ("" == strApi) + { + return -1; + } + +#ifdef NV_ARTISTTOOLS + if (withPlugin) + { + LoadPlugins(a); + } +#else + bool loaded = PluginBlast::Create(strApi); + if (!loaded) + { + return -1; + } +#endif + + return RunApp(a); +} + +CoreLib::CoreLib() +{ + +} + +CoreLib::~CoreLib() +{ + +} + +CoreLib* CoreLib::Inst() +{ + static CoreLib coreLib; + return &coreLib; +} + +#ifdef NV_ARTISTTOOLS +#include <QtWidgets/QApplication> +#include <QtCore/QTimer> +#include <QtCore/QFile> +#include <QtCore/QDir> +#include <QtWidgets/QMessageBox> +#include <QtCore/QFileInfo> + +#include "Nv.h" + +#include "AppMainWindow.h" +#include "D3DWidget.h" +#include "SimpleScene.h" +#include "Automate.h" +#include "Settings.h" +#include "RenderInterface.h" +#include "Light.h" + +#include <QtCore/QPluginLoader> +void CoreLib::LoadPlugins(QApplication& app) +{ + QDir pluginsDir(app.applicationDirPath()); + foreach(QString fileName, pluginsDir.entryList(QDir::Files)) { + if (!fileName.startsWith("Plugin")) + { + continue; + } + +#ifdef _WIN64 +#ifdef _DEBUG + if (!fileName.endsWith(".win64.d.dll")) + { + continue; + } +#else + if (!fileName.endsWith(".win64.dll")) + { + continue; + } +#endif +#else +#ifdef _DEBUG + if (!fileName.endsWith(".win32.d.dll")) + { + continue; + } +#else + if (!fileName.endsWith(".win32.dll")) + { + continue; + } +#endif +#endif + + PluginInterface* pInterface; + QByteArray tmp = pluginsDir.absoluteFilePath(fileName).toUtf8(); + const char* pName = tmp.data(); + QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName)); + QObject *plugin = pluginLoader.instance(); + if (plugin) { + pInterface = qobject_cast<PluginInterface *>(plugin); + if (pInterface) + { + std::string strApi = RenderPlugin::Instance()->GetRenderApi(); + bool loaded = pInterface->LoadRenderPlugin(strApi); + if (!loaded) + { + continue; + } + + QString name = pInterface->GetPluginName(); + m_PluginInterfaces[name] = pInterface; + } + } + else + { + QMessageBox::critical(nullptr, "", pluginLoader.errorString()); + } + } +} + +PluginInterface* CoreLib::GetPluginInterface(QString name) +{ + PluginInterface* pPluginInterface = 0; + std::map<QString, PluginInterface*>::iterator it; + it = m_PluginInterfaces.find(name); + if (it != m_PluginInterfaces.end()) + { + pPluginInterface = it->second; + } + return pPluginInterface; +} + +bool CoreLib::GetBoneNames(std::vector<std::string>& BoneNames) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->GetBoneNames(BoneNames)) + break; + } + return true; +} + +bool CoreLib::CoreLib_RunApp() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->CoreLib_RunApp()) + break; + } + + return true; +} + +bool CoreLib::MainToolbar_updateValues() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->MainToolbar_updateValues()) + break; + } + return true; +} + +bool CoreLib::CurveEditor_updateValues(int _paramId, float* _values) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->CurveEditor_updateValues(_paramId, _values)) + break; + } + return true; +} +bool CoreLib::CurveEditor_onUpdateValues(int _paramId, float* _values) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->CurveEditor_onUpdateValues(_paramId, _values)) + break; + } + return true; +} + +bool CoreLib::DisplayMeshesPanel_updateValues() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->DisplayMeshesPanel_updateValues()) + break; + } + return true; +} +bool CoreLib::DisplayMeshesPanel_EmitToggleSignal(unsigned int id, bool visible) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->DisplayMeshesPanel_EmitToggleSignal(id, visible)) + break; + } + return true; +} + +bool CoreLib::Camera_LoadParameters(void* ptr, Camera* pCamera) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->Camera_LoadParameters(ptr, pCamera)) + break; + } + return true; +} +bool CoreLib::Camera_SaveParameters(void* ptr, Camera* pCamera) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->Camera_SaveParameters(ptr, pCamera)) + break; + } + return true; +} + +bool CoreLib::Light_loadParameters(NvParameterized::Handle& handle, Light* pLight) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->Light_loadParameters(handle, pLight)) + break; + } + return true; +} + +bool CoreLib::Light_saveParameters(NvParameterized::Handle& handle, Light* pLight) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->Light_saveParameters(handle, pLight)) + break; + } + return true; +} + +bool CoreLib::Gamepad_ToggleSimulation() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->Gamepad_ToggleSimulation()) + break; + } + return true; +} +bool CoreLib::Gamepad_LoadSamples(QString fn) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->Gamepad_LoadSamples(fn)) + break; + } + return true; +} +bool CoreLib::Gamepad_ResetScene() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->Gamepad_ResetScene()) + break; + } + return true; +} + +bool CoreLib::Gamepad_StartAnimation() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->Gamepad_StartAnimation()) + break; + } + return true; +} + +bool CoreLib::GamepadHandler_ShowHair() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->GamepadHandler_ShowHair()) + break; + } + return true; +} + +bool CoreLib::GamepadHandler_SpinWindStrength(float windStrength) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->GamepadHandler_SpinWindStrength(windStrength)) + break; + } + return true; +} + +bool CoreLib::Gamepad_ResetAnimation() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->Gamepad_ResetAnimation()) + break; + } + return true; +} + +bool CoreLib::Gamepad_PlayPauseAnimation() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->Gamepad_PlayPauseAnimation()) + break; + } + return true; +} + +bool CoreLib::SimpleScene_SimpleScene() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_SimpleScene()) + break; + } + return true; +} +bool CoreLib::SimpleScene_Initialize(int backdoor) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_Initialize(backdoor)) + break; + } + return true; +} +bool CoreLib::SimpleScene_Shutdown() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_Shutdown()) + break; + } + return true; +} +bool CoreLib::SimpleScene_Clear() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_Clear()) + break; + } + return true; +} +bool CoreLib::SimpleScene_Draw_DX12() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_Draw_DX12()) + break; + } + return true; +} +bool CoreLib::SimpleScene_Draw_DX11() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_Draw_DX11()) + break; + } + return true; +} +bool CoreLib::SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_FitCamera(center, extents)) + break; + } + return true; +} +bool CoreLib::SimpleScene_DrawGround() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_DrawGround()) + break; + } + return true; +} +bool CoreLib::SimpleScene_DrawWind() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_DrawWind()) + break; + } + return true; +} +bool CoreLib::SimpleScene_DrawAxis() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_DrawAxis()) + break; + } + return true; +} +bool CoreLib::SimpleScene_LoadSceneFromFbx(const char* dir, const char* fbxName) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_LoadSceneFromFbx(dir, fbxName)) + break; + } + return true; +} +bool CoreLib::SimpleScene_LoadProject(const char* dir, const char* file) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_LoadProject(dir, file)) + break; + } + return true; +} +bool CoreLib::SimpleScene_SaveProject(const char* dir, const char* file) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_SaveProject(dir, file)) + break; + } + return true; +} +bool CoreLib::SimpleScene_LoadParameters(NvParameterized::Interface* iface) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_LoadParameters(iface)) + break; + } + return true; +} +bool CoreLib::SimpleScene_SaveParameters(NvParameterized::Interface* iface) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_SaveParameters(iface)) + break; + } + return true; +} + +bool CoreLib::SimpleScene_LoadCameraBookmarks(NvParameterized::Interface* iface) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_LoadCameraBookmarks(iface)) + break; + } + return true; +} + +bool CoreLib::SimpleScene_SaveCameraBookmarks(NvParameterized::Interface* iface) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->SimpleScene_SaveCameraBookmarks(iface)) + break; + } + return true; +} + +bool CoreLib::D3DWidget_resizeEvent(QResizeEvent* e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_resizeEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_paintEvent(QPaintEvent* e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_paintEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_mousePressEvent(QMouseEvent* e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_mousePressEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_mouseReleaseEvent(QMouseEvent* e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_mouseReleaseEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_mouseMoveEvent(QMouseEvent* e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_mouseMoveEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_wheelEvent(QWheelEvent * e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_wheelEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_keyPressEvent(QKeyEvent* e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_keyPressEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_keyReleaseEvent(QKeyEvent* e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_keyReleaseEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_dragEnterEvent(QDragEnterEvent *e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_dragEnterEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_dragMoveEvent(QDragMoveEvent *e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_dragMoveEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_dragLeaveEvent(QDragLeaveEvent *e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_dragLeaveEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_dropEvent(QDropEvent *e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_dropEvent(e)) + break; + } + return true; +} +bool CoreLib::D3DWidget_contextMenuEvent(QContextMenuEvent *e) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3DWidget_contextMenuEvent(e)) + break; + } + return true; +} + +#ifdef NV_ARTISTTOOLS +bool CoreLib::D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->D3D11Shaders_InitializeShadersD3D11(ShaderMap)) + break; + } + return true; +} +#endif // NV_ARTISTTOOLS + +bool CoreLib::AppMainWindow_AppMainWindow() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_AppMainWindow()) + break; + } + return true; +} +bool CoreLib::AppMainWindow_InitMenuItems(QMenuBar* pMenuBar) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_InitMenuItems(pMenuBar)) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_InitMainTab(QWidget *displayScrollAreaContents, QVBoxLayout *displayScrollAreaLayout, int idx) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_InitMainTab(displayScrollAreaContents, displayScrollAreaLayout, idx)) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_InitPluginTab(QTabWidget* pTabWidget) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_InitPluginTab(pTabWidget)) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_InitUI() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_InitUI()) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_updateUI() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_updateUI()) + break; + } + return true; +} +bool CoreLib::AppMainWindow_updatePluginUI() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_updatePluginUI()) + break; + } + return true; +} +bool CoreLib::AppMainWindow_processDragAndDrop(QString fname) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_processDragAndDrop(fname)) + break; + } + return true; +} +bool CoreLib::AppMainWindow_closeEvent(QCloseEvent *event) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_closeEvent(event)) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_menu_about() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_menu_about()) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_menu_opendoc() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_menu_opendoc()) + break; + } + return true; +} +#if USE_CURVE_EDITOR +bool CoreLib::AppMainWindow_UpdateCurveEditor() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_UpdateCurveEditor()) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_ShowCurveEditor(int paramId) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_ShowCurveEditor(paramId)) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_onCurveAttributeChanged(attribute)) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_onColorAttributeChanged(attribute)) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_onReloadColorAttributeTexture(attribute, reloadColorTex, selectedCtrlPntIndex)) + break; + } + return true; +} +#endif +bool CoreLib::AppMainWindow_InitToolbar(QWidget *pQWidget, QVBoxLayout* pLayout) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_InitToolbar(pQWidget, pLayout)) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_shortcut_expert(bool mode) +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_shortcut_expert(mode)) + break; + } + return true; +} + +bool CoreLib::AppMainWindow_updateMainToolbar() +{ + std::map<QString, PluginInterface*>::iterator it; + for (it = m_PluginInterfaces.begin(); it != m_PluginInterfaces.end(); it++) + { + if (!(it->second)->AppMainWindow_updateMainToolbar()) + break; + } + return true; +} + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/CoreLib.h b/NvBlast/tools/ArtistTools/source/CoreLib/CoreLib.h new file mode 100644 index 0000000..3d86bcf --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/CoreLib.h @@ -0,0 +1,121 @@ +#ifndef CORELIB_H +#define CORELIB_H + +#include "corelib_global.h" +#include "PluginInterface.h" +#include "NvParameterized.h" +#if USE_CURVE_EDITOR +#include <Attribute.h> +#endif + +class QCloseEvent; +class Camera; +class Light; +namespace NvParameterized +{ + class Interface; + class Handle; +} +class D3D11RenderShader; + +class CORELIB_EXPORT CoreLib +{ +public: + CoreLib(); + ~CoreLib(); + + static CoreLib* Inst(); +#ifndef NV_ARTISTTOOLS + int CoreMain(int argc, char *argv[]); +#else + int CoreMain(int argc, char *argv[], bool withPlugin = true); + + bool CoreLib_RunApp(); + void LoadPlugins(QApplication& app); + PluginInterface* GetPluginInterface(QString name); + + bool GetBoneNames(std::vector<std::string>& BoneNames); + bool MainToolbar_updateValues(); + + bool CurveEditor_updateValues(int _paramId, float* _values); + bool CurveEditor_onUpdateValues(int _paramId, float* _values); + + bool DisplayMeshesPanel_updateValues(); + bool DisplayMeshesPanel_EmitToggleSignal(unsigned int id, bool visible); + + bool Camera_LoadParameters(void* ptr, Camera* pCamera); + bool Camera_SaveParameters(void* ptr, Camera* pCamera); + bool Light_loadParameters(NvParameterized::Handle& handle, Light* pLight); + bool Light_saveParameters(NvParameterized::Handle& handle, Light* pLight); + + bool Gamepad_ToggleSimulation(); + bool Gamepad_LoadSamples(QString fn); + bool Gamepad_ResetScene(); + bool Gamepad_StartAnimation(); + bool GamepadHandler_ShowHair(); + bool GamepadHandler_SpinWindStrength(float windStrength); + bool Gamepad_ResetAnimation(); + bool Gamepad_PlayPauseAnimation(); + + bool SimpleScene_SimpleScene(); + bool SimpleScene_Initialize(int backdoor); + bool SimpleScene_Shutdown(); + bool SimpleScene_Clear(); + bool SimpleScene_Draw_DX12(); + bool SimpleScene_Draw_DX11(); + bool SimpleScene_FitCamera(atcore_float3& center, atcore_float3& extents); + bool SimpleScene_DrawGround(); + bool SimpleScene_DrawWind(); + bool SimpleScene_DrawAxis(); + bool SimpleScene_LoadSceneFromFbx(const char* dir, const char* fbxName); + bool SimpleScene_LoadProject(const char* dir, const char* file); + bool SimpleScene_SaveProject(const char* dir, const char* file); + bool SimpleScene_LoadParameters(NvParameterized::Interface* iface); + bool SimpleScene_SaveParameters(NvParameterized::Interface* iface); + bool SimpleScene_LoadCameraBookmarks(NvParameterized::Interface* iface); + bool SimpleScene_SaveCameraBookmarks(NvParameterized::Interface* iface); + + bool D3DWidget_resizeEvent(QResizeEvent* e); + bool D3DWidget_paintEvent(QPaintEvent* e); + bool D3DWidget_mousePressEvent(QMouseEvent* e); + bool D3DWidget_mouseReleaseEvent(QMouseEvent* e); + bool D3DWidget_mouseMoveEvent(QMouseEvent* e); + bool D3DWidget_wheelEvent(QWheelEvent * e); + bool D3DWidget_keyPressEvent(QKeyEvent* e); + bool D3DWidget_keyReleaseEvent(QKeyEvent* e); + bool D3DWidget_dragEnterEvent(QDragEnterEvent *e); + bool D3DWidget_dragMoveEvent(QDragMoveEvent *e); + bool D3DWidget_dragLeaveEvent(QDragLeaveEvent *e); + bool D3DWidget_dropEvent(QDropEvent *e); + bool D3DWidget_contextMenuEvent(QContextMenuEvent *e); + + bool D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap); + + bool AppMainWindow_AppMainWindow(); + bool AppMainWindow_InitMenuItems(QMenuBar* pMenuBar); + bool AppMainWindow_InitMainTab(QWidget *displayScrollAreaContents, QVBoxLayout *displayScrollAreaLayout, int idx); + bool AppMainWindow_InitPluginTab(QTabWidget* pTabWidget); + bool AppMainWindow_InitUI(); + bool AppMainWindow_updateUI(); + bool AppMainWindow_updatePluginUI(); + bool AppMainWindow_processDragAndDrop(QString fname); + bool AppMainWindow_closeEvent(QCloseEvent *event); + bool AppMainWindow_InitToolbar(QWidget *pQWidget, QVBoxLayout* pLayout); + bool AppMainWindow_shortcut_expert(bool mode); + bool AppMainWindow_updateMainToolbar(); + + bool AppMainWindow_menu_about(); + bool AppMainWindow_menu_opendoc(); +#if USE_CURVE_EDITOR + bool AppMainWindow_UpdateCurveEditor(); + bool AppMainWindow_ShowCurveEditor(int paramId); + bool AppMainWindow_onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute); + bool AppMainWindow_onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute); + bool AppMainWindow_onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex); +#endif +private: + std::map<QString, PluginInterface*> m_PluginInterfaces; +#endif // NV_ARTISTTOOLS +}; + +#endif // CORELIB_H diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Parameters/FoundationHolder.h b/NvBlast/tools/ArtistTools/source/CoreLib/Parameters/FoundationHolder.h new file mode 100644 index 0000000..5ec7868 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Parameters/FoundationHolder.h @@ -0,0 +1,138 @@ +// 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. +// + +#pragma once + +#include "NvErrorCallback.h" +#include "NsGlobals.h" +#include "NsVersionNumber.h" + +class DefaultErrorCallback : public nvidia::NvErrorCallback +{ +public: + DefaultErrorCallback(void) + { + } + + virtual void reportError(nvidia::NvErrorCode::Enum code, const char* message, const char* file, int line) + { + NV_UNUSED(code); + printf("PhysX: %s : %s : %d\r\n", message, file, line); + } +private: +}; + +class DefaultAllocator : public nvidia::NvAllocatorCallback +{ +public: + DefaultAllocator(void) + { + } + + ~DefaultAllocator(void) + { + } + + virtual void* allocate(size_t size, const char* typeName, const char* filename, int line) + { + NV_UNUSED(typeName); + NV_UNUSED(filename); + NV_UNUSED(line); + void *ret = ::_aligned_malloc(size, 16); + return ret; + } + + virtual void deallocate(void* ptr) + { + ::_aligned_free(ptr); + } +private: +}; + + +#if 0 +class FoundationHolder +{ + NvFoundation* mFoundation; + FoundationHolder() + :mFoundation(nullptr) + { + } + + ~FoundationHolder() + { + if (mFoundation) + { + // to-do + // we should release foundation. but Hair SDK could release it first. + //mFoundation->release(); + mFoundation = nullptr; + } + } + +public: + + static NvFoundation* GetFoundation() + { + static FoundationHolder fh; + if (fh.mFoundation == nullptr) + { + static DefaultAllocator sDefaultAllocator; + static DefaultErrorCallback sDefaultErrorCallback; + fh.mFoundation = NvCreateFoundation(NV_FOUNDATION_VERSION, sDefaultAllocator, sDefaultErrorCallback); + assert(fh.mFoundation != nullptr); + } + return fh.mFoundation; + } +}; + +#else + +class FoundationHolder +{ + bool m_isInitialized; + public: + static void GetFoundation() + { + static FoundationHolder s_holder; + if (!s_holder.m_isInitialized) + { + static DefaultAllocator sDefaultAllocator; + static DefaultErrorCallback sDefaultErrorCallback; + nvidia::shdfnd::initializeSharedFoundation(NV_FOUNDATION_VERSION, sDefaultAllocator, sDefaultErrorCallback); + + s_holder.m_isInitialized = true; + } + } + ~FoundationHolder() + { + //nvidia::terminateSharedFoundation(); + } +}; + +#endif diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/PluginInterface.h b/NvBlast/tools/ArtistTools/source/CoreLib/PluginInterface.h new file mode 100644 index 0000000..aae8da8 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/PluginInterface.h @@ -0,0 +1,137 @@ +#ifndef BlastInterface_H +#define BlastInterface_H + +#include <QtCore/QString> +#include <QtCore/QObject> +#if USE_CURVE_EDITOR +#include <Attribute.h> +#endif +#include <Nv/NvBlastCommon.h> +class QMenuBar; +class QHBoxLayout; +class QVBoxLayout; +class QTabWidget; + +class Camera; +class Light; +enum RenderApi; +namespace NvParameterized +{ + class Interface; + class Handle; +} +class D3D11RenderShader; +class QCloseEvent; +#define NV_AT_UNUSED + +class QResizeEvent; +class QPaintEvent; +class QMouseEvent; +class QWheelEvent; +class QKeyEvent; +class QDragEnterEvent; +class QDragMoveEvent; +class QDragLeaveEvent; +class QDropEvent; +class QContextMenuEvent; + +class PluginInterface +{ +public: + virtual ~PluginInterface() {} + + virtual QString GetPluginName() = 0; + + virtual bool CoreLib_RunApp() = 0; + + virtual bool LoadRenderPlugin(std::string api) = 0; + + virtual bool GetBoneNames(std::vector<std::string>& BoneNames) = 0; + + NV_AT_UNUSED virtual bool MainToolbar_updateValues() = 0; + + NV_AT_UNUSED virtual bool CurveEditor_updateValues(int _paramId, float* _values) = 0; + NV_AT_UNUSED virtual bool CurveEditor_onUpdateValues(int _paramId, float* _values) = 0; + + virtual bool DisplayMeshesPanel_updateValues() = 0; + virtual bool DisplayMeshesPanel_EmitToggleSignal(unsigned int id, bool visible) = 0; + + virtual bool Camera_LoadParameters(void* ptr, Camera* pCamera) = 0; + virtual bool Camera_SaveParameters(void * ptr, Camera* pCamera) = 0; + + 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 GamepadHandler_ShowHair() = 0; + virtual bool GamepadHandler_SpinWindStrength(float windStrength) = 0; + virtual bool Gamepad_ResetAnimation() = 0; + virtual bool Gamepad_PlayPauseAnimation() = 0; + + virtual bool Light_loadParameters(NvParameterized::Handle& handle, Light* pLight) = 0; + virtual bool Light_saveParameters(NvParameterized::Handle& handle, Light* pLight) = 0; + + virtual bool SimpleScene_SimpleScene() = 0; + virtual bool SimpleScene_Initialize(int backdoor) = 0; + virtual bool SimpleScene_Shutdown() = 0; + virtual bool SimpleScene_Clear() = 0; + 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_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; + virtual bool SimpleScene_LoadParameters(NvParameterized::Interface* iface) = 0; + virtual bool SimpleScene_SaveParameters(NvParameterized::Interface* iface) = 0; + virtual bool SimpleScene_LoadCameraBookmarks(NvParameterized::Interface* iface) = 0; + virtual bool SimpleScene_SaveCameraBookmarks(NvParameterized::Interface* iface) = 0; + NV_AT_UNUSED virtual bool SimpleScene_DrawGround() = 0; + NV_AT_UNUSED virtual bool SimpleScene_DrawWind() = 0; + NV_AT_UNUSED virtual bool SimpleScene_DrawAxis() = 0; + + virtual bool D3DWidget_resizeEvent(QResizeEvent* e) = 0; + virtual bool D3DWidget_paintEvent(QPaintEvent* e) = 0; + virtual bool D3DWidget_mousePressEvent(QMouseEvent* e) = 0; + virtual bool D3DWidget_mouseReleaseEvent(QMouseEvent* e) = 0; + virtual bool D3DWidget_mouseMoveEvent(QMouseEvent* e) = 0; + virtual bool D3DWidget_wheelEvent(QWheelEvent * e) = 0; + virtual bool D3DWidget_keyPressEvent(QKeyEvent* e) = 0; + virtual bool D3DWidget_keyReleaseEvent(QKeyEvent* e) = 0; + virtual bool D3DWidget_dragEnterEvent(QDragEnterEvent *e) = 0; + virtual bool D3DWidget_dragMoveEvent(QDragMoveEvent *e) = 0; + virtual bool D3DWidget_dragLeaveEvent(QDragLeaveEvent *e) = 0; + virtual bool D3DWidget_dropEvent(QDropEvent *e) = 0; + virtual bool D3DWidget_contextMenuEvent(QContextMenuEvent *e) = 0; + + virtual bool D3D11Shaders_InitializeShadersD3D11(std::map<int, D3D11RenderShader*>& ShaderMap) = 0; + + virtual bool AppMainWindow_AppMainWindow() = 0; + virtual bool AppMainWindow_InitMenuItems(QMenuBar* pMenuBar) = 0; + virtual bool AppMainWindow_InitMainTab(QWidget *displayScrollAreaContents, QVBoxLayout *displayScrollAreaLayout, int idx) = 0; + virtual bool AppMainWindow_InitPluginTab(QTabWidget* pTabWidget) = 0; + virtual bool AppMainWindow_InitUI() = 0; + virtual bool AppMainWindow_updateUI() = 0; + virtual bool AppMainWindow_updatePluginUI() = 0; + NV_AT_UNUSED virtual bool AppMainWindow_processDragAndDrop(QString fname) = 0; + virtual bool AppMainWindow_closeEvent(QCloseEvent *event) = 0; + virtual bool AppMainWindow_InitToolbar(QWidget *pQWidget, QVBoxLayout* pLayout) = 0; + virtual bool AppMainWindow_shortcut_expert(bool mode) = 0; + virtual bool AppMainWindow_updateMainToolbar() = 0; + + virtual bool AppMainWindow_menu_about() = 0; + virtual bool AppMainWindow_menu_opendoc() = 0; +#if USE_CURVE_EDITOR + virtual bool AppMainWindow_UpdateCurveEditor() = 0; + virtual bool AppMainWindow_ShowCurveEditor(int paramId) = 0; + virtual bool AppMainWindow_onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute) = 0; + virtual bool AppMainWindow_onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute) = 0; + virtual bool AppMainWindow_onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex) = 0; +#endif +}; + +QT_BEGIN_NAMESPACE +#define PluginInterface_iid "com.nvidia.PluginInterface" +Q_DECLARE_INTERFACE(PluginInterface, PluginInterface_iid) +QT_END_NAMESPACE + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.cpp new file mode 100644 index 0000000..4e261f1 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.cpp @@ -0,0 +1,31 @@ +// 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. +// +#include "D3D11Buffer.h" + +// shared path + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.h new file mode 100644 index 0000000..d9d9730 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Buffer.h @@ -0,0 +1,65 @@ +// 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-2015 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. +// + +#pragma once + +#include "RenderResources.h" + +#include "d3d11.h" + +// GPU resources for texture +struct GPUBufferD3D11 : public GPUBufferResource +{ + ID3D11Buffer* m_pD3D11Resource; + +public: + static GPUBufferResource* Create(ID3D11Buffer* pResource) { + GPUBufferD3D11* pBuffer = new GPUBufferD3D11; + pBuffer->m_pD3D11Resource = pResource; + return pBuffer; + } + + static ID3D11Buffer* GetResource(GPUBufferResource* pBuffer) + { + GPUBufferD3D11* pD3D11Buffer = dynamic_cast<GPUBufferD3D11*>(pBuffer); + if (!pD3D11Buffer) + return 0; + return pD3D11Buffer->m_pD3D11Resource; + } + + ~GPUBufferD3D11() + { + Release(); + } + + void Release() + { + SAFE_RELEASE(m_pD3D11Resource); + } +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.cpp new file mode 100644 index 0000000..060a0cb --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.cpp @@ -0,0 +1,138 @@ +// 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-2015 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. +// +#include "D3D11GPUProfiler.h" + +#include "D3D11RenderInterface.h" + +/////////////////////////////////////////////////////////////// +// factory function to create D3D11 GPU profiler +/* +GPUProfiler* GPUProfiler::CreateD3D11() +{ + GPUProfiler* pProfiler = new D3D11GPUProfiler; + pProfiler->Initialize(); + return pProfiler; +} +*/ +/////////////////////////////////////////////////////////////// +D3D11GPUProfiler::~D3D11GPUProfiler() +{ + Release(); +} + +/////////////////////////////////////////////////////////////// +void D3D11GPUProfiler::Initialize() +{ + ID3D11Device *pDevice = RenderInterfaceD3D11::GetDevice(); + + m_pContext = RenderInterfaceD3D11::GetDeviceContext(); + + D3D11_QUERY_DESC desc; + memset(&desc, 0, sizeof(D3D11_QUERY_DESC)); + desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT; + desc.MiscFlags = 0; + + pDevice->CreateQuery(&desc, &m_pQueryDisjoint); + + desc.Query = D3D11_QUERY_TIMESTAMP; + + for (int i = 0; i < MAX_QUERY_COUNT; i++) + { + pDevice->CreateQuery(&desc, &m_pQueryStart[i]); + pDevice->CreateQuery(&desc, &m_pQueryEnd[i]); + } + m_enable = true; +} + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; } +#endif + +/////////////////////////////////////////////////////////////// +void D3D11GPUProfiler::Release() +{ + for (int i = 0; i < MAX_QUERY_COUNT; i++) + { + SAFE_RELEASE(m_pQueryStart[i]); + SAFE_RELEASE(m_pQueryEnd[i]); + } + + SAFE_RELEASE(m_pQueryDisjoint); +} + +/////////////////////////////////////////////////////////////// +void D3D11GPUProfiler::StartProfile(int id) +{ + if (!m_enable) return; + + ID3D11Query* pQuery = m_pQueryStart[id]; + m_pContext->End(pQuery); +} + +/////////////////////////////////////////////////////////////// +void D3D11GPUProfiler::EndProfile(int id) +{ + if (!m_enable) return; + + ID3D11Query* pQuery = m_pQueryEnd[id]; + m_pContext->End(pQuery); +} + +/////////////////////////////////////////////////////////////// +void D3D11GPUProfiler::StartFrame() +{ + if (!m_enable) return; + + m_pContext->Begin(m_pQueryDisjoint); +} + +/////////////////////////////////////////////////////////////// +void D3D11GPUProfiler::EndFrame() +{ + if (!m_enable) return; + + m_pContext->End(m_pQueryDisjoint); + + while(m_pContext->GetData(m_pQueryDisjoint, &m_disjointData, sizeof(D3D11_QUERY_DATA_TIMESTAMP_DISJOINT), 0) != S_OK); +} + +/////////////////////////////////////////////////////////////// +float D3D11GPUProfiler::GetProfileData(int id) +{ + if (!m_enable) + return 0.0f; + + UINT64 startTime = 0; + while(m_pContext->GetData(m_pQueryStart[id], &startTime, sizeof(UINT64), 0) != S_OK); + + UINT64 endTime = 0; + while(m_pContext->GetData(m_pQueryEnd[id], &endTime, sizeof(UINT64), 0) != S_OK); + + float frequency = static_cast<float>(m_disjointData.Frequency); + return (endTime - startTime) / frequency * 1000.0f; +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.h new file mode 100644 index 0000000..4c5b32f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11GPUProfiler.h @@ -0,0 +1,56 @@ +// 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-2015 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. +// + +#pragma once + +#include "d3d11.h" + +#include "GPUProfiler.h" + +#define MAX_QUERY_COUNT 64 +struct D3D11GPUProfiler : public GPUProfiler +{ +public: + ~D3D11GPUProfiler(); + + void Initialize(); + void Release(); + void StartProfile(int id); + void EndProfile(int id); + void StartFrame(); + void EndFrame(); + float GetProfileData(int id); + +protected: + ID3D11Query* m_pQueryDisjoint; + ID3D11Query* m_pQueryStart[MAX_QUERY_COUNT]; + ID3D11Query* m_pQueryEnd[MAX_QUERY_COUNT]; + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT m_disjointData; + ID3D11DeviceContext* m_pContext; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp new file mode 100644 index 0000000..71d1b7d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.cpp @@ -0,0 +1,890 @@ +// 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. +// +#include "D3D11RenderInterface.h" + +#include "D3D11TextureResource.h" +#include "D3D11Shaders.h" +#include "D3D11Buffer.h" +#include "Nv.h" +#ifdef USE_11ON12_WRAPPER +#include "D3D11on12Wrapper.h" +#endif // USE_11ON12_WRAPPER +namespace RenderInterfaceD3D11 +{ + using namespace RenderInterface; + + ID3D11SamplerState* m_pSamplerStates[SAMPLER_TYPE_END]; + ID3D11BlendState* m_pBlendStates[BLEND_STATE_END]; + ID3D11DepthStencilState* m_pDepthStencilStates[DEPTH_STENCIL_STATE_END]; + ID3D11RasterizerState* m_pRasterizerStates[RASTERIZER_STATE_END]; + +#ifdef USE_11ON12_WRAPPER +#else + ID3D11DeviceContext* g_d3dDeviceContext = 0; + ID3D11Device* g_d3dDevice = 0; + IDXGIFactory1* g_pDXGIFactory1 = 0; + IDXGIDevice* g_dxgiDevice = 0; + IDXGIAdapter * g_pAdapter = 0; +#endif // USE_11ON12_WRAPPER + + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +ID3D11DeviceContext* GetDeviceContext() +{ +#ifdef USE_11ON12_WRAPPER + return D3D11on12Wrapper::GetDeviceContext(); +#else + return g_d3dDeviceContext; +#endif // USE_11ON12_WRAPPER +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +ID3D11Device* GetDevice() +{ +#ifdef USE_11ON12_WRAPPER + return D3D11on12Wrapper::GetDevice11(); +#else + return g_d3dDevice; +#endif // USE_11ON12_WRAPPER +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +IDXGIFactory1* GetDXGIFactory() +{ +#ifdef USE_11ON12_WRAPPER + return D3D11on12Wrapper::GetDXGIFactory(); +#else + return g_pDXGIFactory1; +#endif // USE_11ON12_WRAPPER +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +IDXGIDevice* GetDXGIDevice() +{ +#ifdef USE_11ON12_WRAPPER + return nullptr; +#else + return g_dxgiDevice; +#endif // USE_11ON12_WRAPPER +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +IDXGIAdapter* GetAdapter() +{ +#ifdef USE_11ON12_WRAPPER + return D3D11on12Wrapper::GetAdapter(); +#else + return g_pAdapter; +#endif // USE_11ON12_WRAPPER +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IsNvDeviceID(UINT id) +{ + return id == 0x10DE; +} + +IDXGIAdapter* FindAdapter(IDXGIFactory* IDXGIFactory_0001, const WCHAR* targetName, bool& isNv) +{ + IDXGIAdapter* targetAdapter = nullptr; + std::vector<IDXGIAdapter*> adapters; + // check current adapter first. EnumAdapters could fail on some device + IDXGIAdapter* pAdapter = nullptr; + ID3D11Device* pD3dDevice = nullptr; + ID3D11DeviceContext* pD3dDeviceContext = nullptr; + DWORD createDeviceFlags = D3D11_CREATE_DEVICE_DEBUG; + D3D_FEATURE_LEVEL fl; + // This following code is the robust way to get all possible feature levels while handling DirectX 11.0 systems: + // please read https://blogs.msdn.microsoft.com/chuckw/2014/02/05/anatomy-of-direct3d-11-create-device/ + D3D_FEATURE_LEVEL lvl[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; + HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, + createDeviceFlags, lvl, _countof(lvl), + D3D11_SDK_VERSION, &pD3dDevice, &fl, &pD3dDeviceContext); + if (pD3dDevice) + { + IDXGIDevice* dxgiDevice = nullptr; + hr = pD3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice)); + if (SUCCEEDED(hr)) + { + hr = dxgiDevice->GetAdapter(&pAdapter); + if (pAdapter) + { + adapters.push_back(pAdapter); + } + SAFE_RELEASE(dxgiDevice); + } + SAFE_RELEASE(pD3dDeviceContext); + SAFE_RELEASE(pD3dDevice); + } + + // Enum Adapters + unsigned int adapterNo = 0; + HRESULT hres = S_OK; + while (SUCCEEDED(hres = IDXGIFactory_0001->EnumAdapters(adapterNo, (IDXGIAdapter**)&pAdapter))) + { + adapters.push_back(pAdapter); + adapterNo++; + } + if (wcslen(targetName) != 0) + { + // find the adapter with specified name + for (int i = 0; i < adapters.size(); ++i) + { + IDXGIAdapter* pAdapter = adapters[i]; + DXGI_ADAPTER_DESC aDesc; + pAdapter->GetDesc(&aDesc); + std::wstring aName = aDesc.Description; + if (aName.find(targetName) != std::string::npos) + { + targetAdapter = pAdapter; + isNv = IsNvDeviceID(aDesc.VendorId); + } + } + } + else + { + // no name specified, find one NV adapter + for (int i = 0; i < adapters.size(); ++i) + { + IDXGIAdapter* pAdapter = adapters[i]; + DXGI_ADAPTER_DESC aDesc; + pAdapter->GetDesc(&aDesc); + std::wstring aName = aDesc.Description; + if (IsNvDeviceID(aDesc.VendorId)) + { + targetAdapter = pAdapter; + isNv = true; + } + } + } + if (targetAdapter == nullptr) + targetAdapter = adapters[0]; + for (int i = 0; i < adapters.size(); ++i) + { + IDXGIAdapter* pAdapter = adapters[i]; + if(pAdapter != targetAdapter) + { + pAdapter->Release(); + } + } + + return targetAdapter; +} + +HRESULT UseGoodGPUDevice() +{ +#ifdef USE_11ON12_WRAPPER + return S_OK; +#else + // create factory + if (g_pDXGIFactory1 == NV_NULL) + { + HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&g_pDXGIFactory1)); + if (FAILED(hr)) + return hr; + } + + DWORD createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED; // 0; // I changed only this line. +#ifdef _DEBUG + createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; +#endif + bool bNVAdapter = false; + WCHAR* pwName = L""; + g_pAdapter = FindAdapter(g_pDXGIFactory1, pwName, bNVAdapter); + +#ifdef _DEBUG + DXGI_ADAPTER_DESC adapterDesc; + g_pAdapter->GetDesc(&adapterDesc); + std::wstring adapterName = adapterDesc.Description; +#endif + + D3D_FEATURE_LEVEL fl; + HRESULT hr = D3D11CreateDevice(g_pAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, + createDeviceFlags, 0, 0, + D3D11_SDK_VERSION, &g_d3dDevice, &fl, &g_d3dDeviceContext); + + if(g_d3dDevice) + { + IDXGIDevice* dxgiDevice = nullptr; + hr = g_d3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice)); + if (SUCCEEDED(hr)) + { + g_dxgiDevice = dxgiDevice; + return hr; + } + else + { + SAFE_RELEASE(g_d3dDevice); + SAFE_RELEASE(g_pAdapter); + SAFE_RELEASE(g_pDXGIFactory1); + } + } + return hr; +#endif // USE_11ON12_WRAPPER +} + +bool InitDevice(int deviceID) +{ +#ifdef USE_11ON12_WRAPPER + D3D11on12Wrapper::InitDevice(); +#else + if (deviceID == -1) + { + HRESULT hResult = UseGoodGPUDevice(); + if (FAILED(hResult)) + return false; + + return true; + } + + D3D_FEATURE_LEVEL featureLvl; + + // create factory + if (g_pDXGIFactory1 == NV_NULL) + { + HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&g_pDXGIFactory1)); + if (FAILED(hr)) + return false; + } + + // create adapter for selected device + if (g_pAdapter == NV_NULL) + { + HRESULT hr = g_pDXGIFactory1->EnumAdapters(deviceID, &g_pAdapter); + if (FAILED(hr)) + return false; + } + + UINT deviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED; +#ifdef _DEBUG + deviceFlags |= D3D11_CREATE_DEVICE_DEBUG; +#endif + + // create device + HRESULT hResult = D3D11CreateDevice( + g_pAdapter, + D3D_DRIVER_TYPE_UNKNOWN, //D3D_DRIVER_TYPE_HARDWARE, + 0, + deviceFlags, + NV_NULL, + 0, + D3D11_SDK_VERSION, + &g_d3dDevice, + &featureLvl, + &g_d3dDeviceContext); + + if(FAILED(hResult)) + return false; +#endif // USE_11ON12_WRAPPER + + return true; +} + +////////////////////////////////////////////////////////////////////////// +bool Initialize() +{ + if (!GetDevice() || !GetDeviceContext()) + return false; + + D3D11_COMPARISON_FUNC depthFunc = D3D11_COMPARISON_LESS; + + InitializeShadersD3D11(); + InitializeRenderStates(); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +void Shutdown() +{ + DestroyShadersD3D11(); + ClearRenderStates(); + + // release d3d resources + IDXGIFactory1* pDxgiFactory = GetDXGIFactory(); + SAFE_RELEASE(pDxgiFactory); + + IDXGIAdapter* pAdapter = GetAdapter(); + SAFE_RELEASE(pAdapter); + + IDXGIDevice* pDXGIDevice = GetDXGIDevice(); + SAFE_RELEASE(pDXGIDevice); + + ID3D11DeviceContext* pContext = GetDeviceContext(); + SAFE_RELEASE(pContext); + + ID3D11Device* pDevice = GetDevice(); +#if defined(DEBUG) || defined(_DEBUG) + // output d3d leak + ID3D11Debug *d3dDebug; + HRESULT hr = pDevice->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(&d3dDebug)); + if (SUCCEEDED(hr)) + { + hr = d3dDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL); + } + if (d3dDebug != nullptr) + d3dDebug->Release(); +#endif + + SAFE_RELEASE(pDevice); +} + +////////////////////////////////////////////////////////////////////////////////////// +void InitializeRenderStates() +{ + ID3D11Device* pDevice = GetDevice(); + if (!pDevice) + return; + + ///////////////////////////////////////////////////////////////////////////////////////// + // alpha blending state descriptors + ///////////////////////////////////////////////////////////////////////////////////////// + + // alpha blending enabled + { + D3D11_BLEND_DESC desc; + desc.AlphaToCoverageEnable = false; + desc.IndependentBlendEnable = false; + + D3D11_RENDER_TARGET_BLEND_DESC &rtDesc = desc.RenderTarget[0]; + { + rtDesc.BlendEnable = true; + rtDesc.SrcBlend = D3D11_BLEND_SRC_ALPHA; + rtDesc.DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + rtDesc.BlendOp = D3D11_BLEND_OP_ADD; + rtDesc.SrcBlendAlpha = D3D11_BLEND_ZERO; + rtDesc.DestBlendAlpha = D3D11_BLEND_ONE; + rtDesc.BlendOpAlpha = D3D11_BLEND_OP_ADD; + rtDesc.RenderTargetWriteMask = 0x0f; + } + pDevice->CreateBlendState(&desc, &m_pBlendStates[BLEND_STATE_ALPHA]); + } + + // no alpha blending + { + D3D11_BLEND_DESC desc; + desc.AlphaToCoverageEnable = false; + desc.IndependentBlendEnable = false; + + D3D11_RENDER_TARGET_BLEND_DESC &rtDesc = desc.RenderTarget[0]; + { + rtDesc.BlendEnable = false; + rtDesc.SrcBlend = D3D11_BLEND_SRC_ALPHA; + rtDesc.DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + rtDesc.BlendOp = D3D11_BLEND_OP_ADD; + rtDesc.SrcBlendAlpha = D3D11_BLEND_ZERO; + rtDesc.DestBlendAlpha = D3D11_BLEND_ONE; + rtDesc.BlendOpAlpha = D3D11_BLEND_OP_ADD; + rtDesc.RenderTargetWriteMask = 0x0f; + } + pDevice->CreateBlendState(&desc, &m_pBlendStates[BLEND_STATE_NONE]); + } + + + ////////////////////////////////////////////////////////////////////////////////////////////// + // depth and stencil + /////////////////////////////////////////////////////////////////////////////////////////////// + D3D11_DEPTH_STENCIL_DESC depthTestDesc; + { + depthTestDesc.DepthEnable = true; + depthTestDesc.DepthFunc = D3D11_COMPARISON_LESS; + depthTestDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + depthTestDesc.StencilEnable = false; + depthTestDesc.StencilReadMask = 0xff; + depthTestDesc.StencilWriteMask = 0xff; + } + + pDevice->CreateDepthStencilState(&depthTestDesc, &m_pDepthStencilStates[DEPTH_STENCIL_DEPTH_TEST]); + + D3D11_DEPTH_STENCIL_DESC depthNone; + { + depthNone.DepthEnable = false; + depthNone.DepthFunc = D3D11_COMPARISON_LESS; + depthNone.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + depthNone.StencilEnable = false; + depthNone.StencilReadMask = 0xff; + depthNone.StencilWriteMask = 0xff; + } + + pDevice->CreateDepthStencilState(&depthNone, &m_pDepthStencilStates[DEPTH_STENCIL_DEPTH_NONE]); + + ////////////////////////////////////////////////////////////////////////////////////////////// + // rasterizer + /////////////////////////////////////////////////////////////////////////////////////////////// + D3D11_RASTERIZER_DESC rsDesc; + + // solid cull front + { + rsDesc.FillMode = D3D11_FILL_SOLID; + rsDesc.CullMode = D3D11_CULL_FRONT; + rsDesc.AntialiasedLineEnable = false; + rsDesc.MultisampleEnable = true; + rsDesc.FrontCounterClockwise = true; + rsDesc.DepthBias = 10; + rsDesc.DepthBiasClamp = 0; + rsDesc.SlopeScaledDepthBias = 0; + rsDesc.DepthClipEnable = true; + rsDesc.ScissorEnable = 0; + + pDevice->CreateRasterizerState(&rsDesc, &m_pRasterizerStates[RASTERIZER_STATE_FILL_CULL_FRONT]); + }; + + // solid cull back + { + rsDesc.FillMode = D3D11_FILL_SOLID; + rsDesc.CullMode = D3D11_CULL_BACK; + rsDesc.AntialiasedLineEnable = false; + rsDesc.MultisampleEnable = true; + rsDesc.FrontCounterClockwise = true; + rsDesc.DepthBias = 10; + rsDesc.DepthBiasClamp = 0; + rsDesc.SlopeScaledDepthBias = 0; + rsDesc.DepthClipEnable = true; + rsDesc.ScissorEnable = 0; + + pDevice->CreateRasterizerState(&rsDesc, &m_pRasterizerStates[RASTERIZER_STATE_FILL_CULL_BACK]); + } + + // solid cull none + { + rsDesc.FillMode = D3D11_FILL_SOLID; + rsDesc.CullMode = D3D11_CULL_NONE; + rsDesc.AntialiasedLineEnable = false; + rsDesc.MultisampleEnable = true; + rsDesc.FrontCounterClockwise = true; + rsDesc.DepthBias = 10; + rsDesc.DepthBiasClamp = 0; + rsDesc.SlopeScaledDepthBias = 0; + rsDesc.DepthClipEnable = true; + rsDesc.ScissorEnable = 0; + + pDevice->CreateRasterizerState(&rsDesc, &m_pRasterizerStates[RASTERIZER_STATE_FILL_CULL_NONE]); + + } + + // wireframe cull none + { + rsDesc.FillMode = D3D11_FILL_WIREFRAME; + rsDesc.CullMode = D3D11_CULL_NONE; + rsDesc.AntialiasedLineEnable = false; + rsDesc.MultisampleEnable = true; + rsDesc.FrontCounterClockwise = 0; + rsDesc.DepthBias = 0; + rsDesc.DepthBiasClamp = 0; + rsDesc.SlopeScaledDepthBias = 0; + rsDesc.DepthClipEnable = true; + rsDesc.ScissorEnable = 0; + }; + + pDevice->CreateRasterizerState(&rsDesc, &m_pRasterizerStates[RASTERIZER_STATE_WIRE]); + + // samplers + + D3D11_SAMPLER_DESC linearSamplerDesc[1] = { + D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT, + D3D11_TEXTURE_ADDRESS_WRAP, + D3D11_TEXTURE_ADDRESS_WRAP, + D3D11_TEXTURE_ADDRESS_WRAP, + 0.0, 0, D3D11_COMPARISON_NEVER, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, D3D11_FLOAT32_MAX, + }; + pDevice->CreateSamplerState(linearSamplerDesc, &m_pSamplerStates[SAMPLER_TYPE_LINEAR]); + + // create point clamp sampler for PCF sampling for hair + D3D11_SAMPLER_DESC pointClampSamplerDesc[1] = { + D3D11_FILTER_MIN_MAG_MIP_POINT, + D3D11_TEXTURE_ADDRESS_CLAMP, + D3D11_TEXTURE_ADDRESS_CLAMP, + D3D11_TEXTURE_ADDRESS_CLAMP, + 0.0, 0, D3D11_COMPARISON_NEVER, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, D3D11_FLOAT32_MAX, + }; + pDevice->CreateSamplerState(pointClampSamplerDesc, &m_pSamplerStates[SAMPLER_TYPE_POINTCLAMP]); +} + +////////////////////////////////////////////////////////////////////////////////////// +void ClearRenderStates() +{ + for (int i = 0; i < RASTERIZER_STATE_END; i++) + SAFE_RELEASE(m_pRasterizerStates[i]); + + for (int i = 0; i < DEPTH_STENCIL_STATE_END; i++) + SAFE_RELEASE(m_pDepthStencilStates[i]); + + for (int i = 0; i < SAMPLER_TYPE_END; i++) + SAFE_RELEASE(m_pSamplerStates[i]); + + for (int i = 0; i < BLEND_STATE_END; i++) + SAFE_RELEASE(m_pBlendStates[i]); +} + +////////////////////////////////////////////////////////////////////////////////////// +void BindVertexShaderResources( int startSlot, int numSRVs, ID3D11ShaderResourceView** ppSRVs) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + pDeviceContext->VSSetShaderResources( startSlot, numSRVs, ppSRVs); +} + +////////////////////////////////////////////////////////////////////////////////////// +void BindPixelShaderResources( int startSlot, int numSRVs, ID3D11ShaderResourceView** ppSRVs) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + pDeviceContext->PSSetShaderResources( startSlot, numSRVs, ppSRVs); +} + +////////////////////////////////////////////////////////////////////////////////////// +void BindVertexShaderResources( int startSlot, int numSRVs, GPUShaderResource** ppSRVs) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + for (int i = startSlot; i < (startSlot + numSRVs); i++) + { + ID3D11ShaderResourceView* pSRV = D3D11TextureResource::GetResource(ppSRVs[i]); + pDeviceContext->VSSetShaderResources( i, 1, &pSRV); + } +} + +////////////////////////////////////////////////////////////////////////////////////// +void BindPixelShaderResources( int startSlot, int numSRVs, GPUShaderResource** ppSRVs) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + for (int i = startSlot; i < (startSlot + numSRVs); i++) + { + ID3D11ShaderResourceView* pSRV = D3D11TextureResource::GetResource(ppSRVs[i]); + pDeviceContext->PSSetShaderResources( i, 1, &pSRV); + } +} + +////////////////////////////////////////////////////////////////////////////////////// +void ClearPixelShaderResources( int startSlot, int numSRVs) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + // clean up + ID3D11ShaderResourceView* ppSRVNull[128]; + memset(&ppSRVNull, 0, sizeof(ID3D11ShaderResourceView*)*128); + + pDeviceContext->PSSetShaderResources( startSlot, numSRVs, ppSRVNull); +} + +////////////////////////////////////////////////////////////////////////////////////// +void ClearVertexShaderResources( int startSlot, int numSRVs) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + // clean up + ID3D11ShaderResourceView* ppSRVNull[128]; + memset(&ppSRVNull, 0, sizeof(ID3D11ShaderResourceView*)*128); + + pDeviceContext->VSSetShaderResources( startSlot, numSRVs, ppSRVNull); +} + +////////////////////////////////////////////////////////////////////////////////////// +void ClearInputLayout() +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + pDeviceContext->IASetInputLayout(nullptr); +} + +////////////////////////////////////////////////////////////////////////////////////// +void SetPrimitiveTopologyTriangleStrip() +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ); +} + +////////////////////////////////////////////////////////////////////////////////////// +void SetPrimitiveTopologyTriangleList() +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); +} + +////////////////////////////////////////////////////////////////////////////////////// +void SetPrimitiveTopologyLineList() +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_LINELIST ); +} + +////////////////////////////////////////////////////////////////////////////////////// +void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + ID3D11Buffer* pD3D11Buffer = GPUBufferD3D11::GetResource(pBuffer); + if (!pD3D11Buffer) + return; + + pDeviceContext->IASetVertexBuffers( 0, 1, &pD3D11Buffer, &stride, &offset ); +} + +////////////////////////////////////////////////////////////////////////////////////// +void ApplySampler(int slot, RenderInterface::SAMPLER_TYPE st) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + pDeviceContext->PSSetSamplers(slot, 1, &m_pSamplerStates[st] ); +} + +/////////////////////////////////////////////////////////////////////////////// +void ApplyDepthStencilState(DEPTH_STENCIL_STATE state) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + pDeviceContext->OMSetDepthStencilState(m_pDepthStencilStates[state], 0); +} + +/////////////////////////////////////////////////////////////////////////////// +void ApplyRasterizerState(RASTERIZER_STATE state) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + pDeviceContext->RSSetState(m_pRasterizerStates[state]); +} + +/////////////////////////////////////////////////////////////////////////////// +void ApplyBlendState(BLEND_STATE st) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + float zerov[] = {0,0,0,0}; + + pDeviceContext->OMSetBlendState(m_pBlendStates[st], zerov, 0xffffffff); +} + +///////////////////////////////////////////////////////////////////////////////////////// +void SetViewport(const RenderInterface::Viewport& vp) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + D3D11_VIEWPORT d3dViewport; + + d3dViewport.TopLeftX = vp.TopLeftX; + d3dViewport.TopLeftY = vp.TopLeftY; + + d3dViewport.Width = vp.Width; + d3dViewport.Height = vp.Height; + + d3dViewport.MinDepth = vp.MinDepth; + d3dViewport.MaxDepth = vp.MaxDepth; + + pDeviceContext->RSSetViewports(1, &d3dViewport); +} + +///////////////////////////////////////////////////////////////////////////////////////// +void GetViewport(RenderInterface::Viewport& vp) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + UINT numViewports = 1; + D3D11_VIEWPORT d3dViewport; + pDeviceContext->RSGetViewports(&numViewports, &d3dViewport); + + vp.TopLeftX = d3dViewport.TopLeftX; + vp.TopLeftY = d3dViewport.TopLeftY; + + vp.Width = d3dViewport.Width; + vp.Height = d3dViewport.Height; + + vp.MinDepth = d3dViewport.MinDepth; + vp.MaxDepth = d3dViewport.MaxDepth; +} + +/////////////////////////////////////////////////////////////////////////////// +void Draw(unsigned int vertexCount, unsigned int startCount) +{ + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + pDeviceContext->Draw(vertexCount, startCount); +} + +/////////////////////////////////////////////////////////////////////////////// +// gpu buffer management +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////// +ID3D11Buffer* CreateD3D11Buffer( + D3D11_USAGE Usage, UINT ByteWidth, UINT StructureByteStride, + UINT BindFlags, UINT MiscFlags, + UINT CPUAccessFlags, void *pSysMem) +{ + ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice(); + if (!pDevice) + return 0; + + D3D11_BUFFER_DESC desc; + + desc.Usage = Usage; + desc.ByteWidth = ByteWidth; + desc.StructureByteStride = StructureByteStride; + desc.BindFlags = BindFlags; + desc.MiscFlags = MiscFlags; + desc.CPUAccessFlags = CPUAccessFlags; + + D3D11_SUBRESOURCE_DATA InitData; + + InitData.pSysMem = pSysMem; + InitData.SysMemPitch = 0; + InitData.SysMemSlicePitch = 0; + + ID3D11Buffer* pBuffer = 0; + + HRESULT hr = pSysMem ? pDevice->CreateBuffer( &desc, &InitData, &pBuffer) + : pDevice->CreateBuffer( &desc, 0, &pBuffer); + + if( FAILED(hr) ) + return 0; + + return pBuffer; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +ID3D11ShaderResourceView* +CreateD3D11ShaderResourceView( + ID3D11Buffer* pBuffer, + DXGI_FORMAT Format, + D3D11_SRV_DIMENSION ViewDimension, + UINT NumElements, + UINT FirstElement = 0 + ) +{ + ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice(); + if (!pDevice) + return 0; + + ID3D11ShaderResourceView* pSRV = 0; + + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + { + desc.Format = Format; + desc.ViewDimension = ViewDimension; + desc.Buffer.FirstElement = FirstElement; + desc.Buffer.NumElements = NumElements; + } + + pDevice->CreateShaderResourceView( pBuffer, &desc, &pSRV); + + return pSRV; +} + +/////////////////////////////////////////////////////////////////////////////// +GPUBufferResource* CreateVertexBuffer( + unsigned int ByteWidth, void* pSysMem) +{ + ID3D11Buffer* pD3D11Buffer = CreateD3D11Buffer(D3D11_USAGE_DEFAULT, + ByteWidth, 0, D3D11_BIND_VERTEX_BUFFER, 0, 0, pSysMem); + + return GPUBufferD3D11::Create(pD3D11Buffer); +} + +/////////////////////////////////////////////////////////////////////////////// +GPUShaderResource* CreateShaderResource( unsigned int stride, unsigned int numElements, void* pSysMem) +{ + unsigned int byteWidth = numElements * stride; + + ID3D11Buffer* pBuffer = CreateD3D11Buffer( + D3D11_USAGE_DEFAULT, byteWidth, 0, + D3D11_BIND_SHADER_RESOURCE, 0, 0, pSysMem); + + // create SRV for bone indices + ID3D11ShaderResourceView* pSRV = CreateD3D11ShaderResourceView( + pBuffer, + DXGI_FORMAT_R32G32B32A32_FLOAT, + D3D11_SRV_DIMENSION_BUFFER, + numElements); + + SAFE_RELEASE(pBuffer); // dec ref count as this is not explicitly used later + + return D3D11TextureResource::Create(pSRV); +} + +/////////////////////////////////////////////////////////////////////////////// +// create read only shader resource buffer +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +void CopyToDevice( + GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth) +{ + ID3D11Buffer* pBuffer = GPUBufferD3D11::GetResource(pDevicePtr); + if (!pBuffer) + return; + + ID3D11DeviceContext* pDeviceContext = GetDeviceContext(); + if (!pDeviceContext) + return; + + pDeviceContext->UpdateSubresource(pBuffer, 0, NV_NULL, pSysMem, ByteWidth, 0); +} + +} // end namespace diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.h new file mode 100644 index 0000000..e5f3c02 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderInterface.h @@ -0,0 +1,90 @@ +// 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. +// + +#pragma once + +#include "d3d11.h" + +#include "RenderInterface.h" + +#include "RenderPlugin.h" + +#ifdef NV_ARTISTTOOLS +enum HAIR_SHADER_TYPE +{ + SHADER_TYPE_HAIR_SHADER_DEFAULT = RenderInterface::SHADER_TYPE_SIMPLE_COLOR + 1, + SHADER_TYPE_HAIR_SHADER_SHADOW, +}; +#endif + +// abstract interface to D3D calls +namespace RenderInterfaceD3D11 +{ + CORERENDER_EXPORT bool InitDevice(int deviceID); + CORERENDER_EXPORT bool Initialize(); + CORERENDER_EXPORT void Shutdown(); + + CORERENDER_EXPORT ID3D11DeviceContext* GetDeviceContext(); + CORERENDER_EXPORT ID3D11Device* GetDevice(); + IDXGIFactory1* GetDXGIFactory(); + IDXGIAdapter* GetAdapter(); + + CORERENDER_EXPORT void InitializeRenderStates(); + CORERENDER_EXPORT void ClearRenderStates(); + + CORERENDER_EXPORT void ApplySampler(int slot, RenderInterface::SAMPLER_TYPE st); + CORERENDER_EXPORT void ApplyDepthStencilState(RenderInterface::DEPTH_STENCIL_STATE st); + CORERENDER_EXPORT void ApplyRasterizerState(RenderInterface::RASTERIZER_STATE st); + CORERENDER_EXPORT void ApplyBlendState(RenderInterface::BLEND_STATE st); + + CORERENDER_EXPORT void GetViewport(RenderInterface::Viewport& vp); + CORERENDER_EXPORT void SetViewport(const RenderInterface::Viewport& vp); + + CORERENDER_EXPORT void BindVertexShaderResources( int startSlot, int numSRVs, GPUShaderResource** ppSRVs); + CORERENDER_EXPORT void BindPixelShaderResources( int startSlot, int numSRVs, GPUShaderResource** ppSRVs); + + CORERENDER_EXPORT void ClearVertexShaderResources( int startSlot, int numSRVs); + CORERENDER_EXPORT void ClearPixelShaderResources( int startSlot, int numSRVs); + + CORERENDER_EXPORT GPUBufferResource* CreateVertexBuffer( unsigned int ByteWidth, void* pSysMem); + CORERENDER_EXPORT GPUShaderResource* CreateShaderResource( unsigned int stride, unsigned int numElements, void* pSysMem ); + + CORERENDER_EXPORT void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth); + + CORERENDER_EXPORT void ClearInputLayout(); + + CORERENDER_EXPORT void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset = 0); + + CORERENDER_EXPORT void SetPrimitiveTopologyTriangleStrip(); + CORERENDER_EXPORT void SetPrimitiveTopologyTriangleList(); + CORERENDER_EXPORT void SetPrimitiveTopologyLineList(); + + + CORERENDER_EXPORT void Draw(unsigned int vertexCount, unsigned int startCount = 0); +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.cpp new file mode 100644 index 0000000..3a4d27e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.cpp @@ -0,0 +1,256 @@ +// 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-2015 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. +// + +#include "D3D11RenderShader.h" + +#include "D3D11RenderInterface.h" +#include "D3D11Wrapper.h" +#include "Nv.h" + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(x) { if (x) x->Release(); } +#endif + +/////////////////////////////////////////////////////////////////////////////// +D3D11RenderShader::D3D11RenderShader() : + m_pVertexShader(0), + m_pPixelShader(0), + m_pInputLayout(0) +{ + for (int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT; i++) + { + m_pParamBuffers[i] = nullptr; + } +} + +/////////////////////////////////////////////////////////////////////////////// +D3D11RenderShader::~D3D11RenderShader() +{ + SAFE_RELEASE(m_pVertexShader); + SAFE_RELEASE(m_pPixelShader); + SAFE_RELEASE(m_pInputLayout); + + for (int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT; i++) + SAFE_RELEASE(m_pParamBuffers[i]); +} + +/////////////////////////////////////////////////////////////////////////////// +D3D11RenderShader* D3D11RenderShader::Create( + const char *name, + void* pVSBlob, size_t vsBlobSize, + void* pPSBlob, size_t psBlobSize, + UINT cbufferSize0, UINT cbufferSize1, + D3D11_INPUT_ELEMENT_DESC* pElemDesc, UINT numElements) +{ + D3D11RenderShader* pShader = new D3D11RenderShader; + + pShader->CreateVSFromBlob(pVSBlob, vsBlobSize, pElemDesc, numElements); + pShader->CreatePSFromBlob(pPSBlob, psBlobSize); + + if (cbufferSize0 > 0) + { + pShader->CreateParamBuffer(cbufferSize0, 0); + SET_D3D_DEBUG_NAME(pShader->getParamBuffer(0), name); + } + + if (cbufferSize1 > 0) + { + pShader->CreateParamBuffer(cbufferSize1, 1); + SET_D3D_DEBUG_NAME(pShader->getParamBuffer(1), name); + } + + if (pShader->getVertexShader()) + SET_D3D_DEBUG_NAME(pShader->getVertexShader(), name); + + if (pShader->getPixelShader()) + SET_D3D_DEBUG_NAME(pShader->getPixelShader(), name); + + if (pShader->getInputLayout()) + SET_D3D_DEBUG_NAME(pShader->getInputLayout(), name); + + return pShader; +} + +/////////////////////////////////////////////////////////////////////////////// +bool D3D11RenderShader::CreateVSFromBlob( + void* pBlob, size_t blobSize, + D3D11_INPUT_ELEMENT_DESC *desc, int elemCount) +{ + ID3D11Device *pDevice = RenderInterfaceD3D11::GetDevice(); + if (!pDevice) + return false; + + if (!pBlob || (blobSize == 0)) + return false; + + SAFE_RELEASE(m_pVertexShader); + SAFE_RELEASE(m_pInputLayout); + + HRESULT res = pDevice->CreateVertexShader(pBlob, blobSize, NV_NULL, &m_pVertexShader); + + if(FAILED(res)) return false; + + if (desc) + { + res = pDevice->CreateInputLayout(desc, elemCount, + pBlob, blobSize, &m_pInputLayout); + + if(FAILED(res)) return false; + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +bool D3D11RenderShader::CreatePSFromBlob(void* pBlob, size_t blobSize) +{ + ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice(); + if (!pDevice) + return false; + + if (!pBlob || (blobSize == 0)) + return false; + + SAFE_RELEASE(m_pPixelShader); + + HRESULT res = pDevice->CreatePixelShader(pBlob, blobSize, NV_NULL, &m_pPixelShader); + + if (FAILED(res)) + return false; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D11RenderShader::SetConstantBuffer() +{ + ID3D11DeviceContext* pContext = RenderInterfaceD3D11::GetDeviceContext(); + + //for (int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT; i++) + for (int i = 0; i < 2; i++) + { + pContext->PSSetConstantBuffers(i, 1, &m_pParamBuffers[i]); + } +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D11RenderShader::MakeCurrent() +{ + ID3D11DeviceContext* pContext = RenderInterfaceD3D11::GetDeviceContext(); + + if (m_pInputLayout) + pContext->IASetInputLayout(m_pInputLayout); + else + pContext->IASetInputLayout(NV_NULL); + + + if (m_pVertexShader) + { + pContext->VSSetShader( m_pVertexShader, NV_NULL, 0); + if (m_pParamBuffers[0]) + pContext->VSSetConstantBuffers(0, 1, &m_pParamBuffers[0]); + } + + if (m_pPixelShader) + { + pContext->PSSetShader( m_pPixelShader, NV_NULL, 0); + if (m_pParamBuffers[0]) + pContext->PSSetConstantBuffers(0, 1, &m_pParamBuffers[0]); + if (m_pParamBuffers[1]) + pContext->PSSetConstantBuffers(1, 1, &m_pParamBuffers[1]); + } + + pContext->GSSetShader( 0, 0, 0); + pContext->DSSetShader( 0, 0, 0); + pContext->HSSetShader( 0, 0, 0); +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D11RenderShader::Disable() +{ + ID3D11DeviceContext* pContext = RenderInterfaceD3D11::GetDeviceContext(); + + pContext->IASetInputLayout(NV_NULL); + + pContext->VSSetShader( 0, NV_NULL, 0); + pContext->PSSetShader( 0, NV_NULL, 0); + pContext->GSSetShader( 0, 0, 0); + pContext->DSSetShader( 0, 0, 0); + pContext->HSSetShader( 0, 0, 0); +} + +/////////////////////////////////////////////////////////////////////////////// +bool D3D11RenderShader::CreateParamBuffer( UINT sizeBuffer, UINT slot ) +{ + ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice(); + if (!pDevice) + return false; + + SAFE_RELEASE(m_pParamBuffers[slot]); + + D3D11_BUFFER_DESC Desc; + { + Desc.Usage = D3D11_USAGE_DYNAMIC; + Desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + Desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + Desc.MiscFlags = 0; + Desc.ByteWidth = sizeBuffer; + } + + HRESULT hr = pDevice->CreateBuffer( &Desc, NV_NULL, &m_pParamBuffers[slot] ); + if( FAILED(hr) ) + false; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +void* D3D11RenderShader::MapParam(UINT slot) +{ + ID3D11DeviceContext* pContext = RenderInterfaceD3D11::GetDeviceContext(); + + if (!m_pParamBuffers[slot] || !pContext) + return 0; + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT hr = pContext->Map(m_pParamBuffers[slot], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + + if ( FAILED(hr)) + return 0; + + return mappedResource.pData; +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D11RenderShader::UnmapParam( UINT slot ) +{ + ID3D11DeviceContext* pContext = RenderInterfaceD3D11::GetDeviceContext(); + + if (pContext && m_pParamBuffers[slot]) + pContext->Unmap( m_pParamBuffers[slot], 0); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.h new file mode 100644 index 0000000..1aad045 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RenderShader.h @@ -0,0 +1,72 @@ +// 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-2015 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. +// + +#pragma once + +#include <d3d11.h> +#include "RenderPlugin.h" + +class CORERENDER_EXPORT D3D11RenderShader +{ +public: + D3D11RenderShader(); + ~D3D11RenderShader(); + + static D3D11RenderShader* Create( + const char *name, + void* pVSBlob, size_t vsBlobSize, + void* pPSBlob, size_t psBlobSize, + UINT cbufferSize0 = 0, UINT cbufferSize1 = 0, + D3D11_INPUT_ELEMENT_DESC* pElemDesc = 0, UINT numElements = 0); + + void MakeCurrent(); + void Disable(); + void SetConstantBuffer(); + + void* MapParam(UINT slot = 0); + void UnmapParam(UINT slot = 0); + + ID3D11VertexShader* getVertexShader() { return m_pVertexShader; } + ID3D11PixelShader* getPixelShader() { return m_pPixelShader; } + ID3D11InputLayout* getInputLayout() { return m_pInputLayout; } + ID3D11Buffer* getParamBuffer(UINT slot = 0) { return m_pParamBuffers[slot]; } + +protected: + bool CreateVSFromBlob(void* pBlob, size_t blobSize, + D3D11_INPUT_ELEMENT_DESC *desc, int elemCount); + bool CreatePSFromBlob(void* pBlob, size_t blobSize); + bool CreateParamBuffer(UINT sizeBuffer, UINT slot = 0); + +private: + + ID3D11VertexShader* m_pVertexShader; + ID3D11PixelShader* m_pPixelShader; + ID3D11InputLayout* m_pInputLayout; + ID3D11Buffer* m_pParamBuffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT]; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.cpp new file mode 100644 index 0000000..1274ed5 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.cpp @@ -0,0 +1,319 @@ +// 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. +// +#include "D3D11RendererWindow.h" + +#include "windows.h" + +#include "DXUT.h" +#include "DXUTgui.h" +#include "sdkmisc.h" + +#include "D3D11RenderInterface.h" +#include "Nv.h" +#ifdef USE_11ON12_WRAPPER +#include "D3D11on12Wrapper.h" +#endif // USE_11ON12_WRAPPER +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; } +#endif + +/////////////////////////////////////////////////////////////////////////////// +D3D11RenderWindow::D3D11RenderWindow() : + m_sampleCount(8) + , m_sampleQuality(0) +#ifdef USE_11ON12_WRAPPER +#else + , m_pDXGISwapChain(NV_NULL) + , m_pD3D11BackBuffer(NV_NULL) + , m_pD3D11DepthBuffer(NV_NULL) + , m_pD3D11RenderTargetView(NV_NULL) + , m_pD3D11DepthStencilView(NV_NULL) +#endif // USE_11ON12_WRAPPER +{ + +} + +/////////////////////////////////////////////////////////////////////////////// +D3D11RenderWindow::~D3D11RenderWindow() +{ + Free(); +} + +/////////////////////////////////////////////////////////////////////////////// +bool D3D11RenderWindow::Create( HWND hWnd, unsigned int nSamples ) +{ +#ifdef USE_11ON12_WRAPPER +#else + if (m_pD3D11BackBuffer != NV_NULL || m_pD3D11RenderTargetView != NV_NULL) + Free(); +#endif // USE_11ON12_WRAPPER + + ID3D11Device *pDevice = RenderInterfaceD3D11::GetDevice(); + if (!pDevice) + return false; + + ID3D11DeviceContext* pDeviceContext = RenderInterfaceD3D11::GetDeviceContext(); + if (!pDeviceContext) + return false; + + if(nSamples > D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT) + nSamples = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; + + m_sampleCount = nSamples; + m_sampleQuality = 0; + if(nSamples > 1) + { + pDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, nSamples, &m_sampleQuality); + assert(m_sampleQuality > 0); + m_sampleQuality--; + } + + RECT rc; + GetClientRect((HWND)hWnd, &rc); + int wBuf = rc.right - rc.left; + int hBuf = rc.bottom- rc.top; + +#ifdef USE_11ON12_WRAPPER + D3D11on12Wrapper::InitSwapchain(wBuf, hBuf, hWnd); +#else + DXGI_SWAP_CHAIN_DESC swapChainDesc; + { + memset(&swapChainDesc, 0, sizeof(DXGI_SWAP_CHAIN_DESC)); + swapChainDesc.BufferDesc.Width = wBuf; + swapChainDesc.BufferDesc.Height= hBuf; + swapChainDesc.BufferDesc.Format= DXGI_FORMAT_R8G8B8A8_UNORM; + swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; + swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; + swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + + swapChainDesc.BufferCount = 1; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + swapChainDesc.OutputWindow = (HWND)hWnd; + swapChainDesc.SampleDesc.Count = m_sampleCount; + swapChainDesc.SampleDesc.Quality = m_sampleQuality; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapChainDesc.Windowed = true; + } + + // Create the swap chain + IDXGIFactory1* pDXGIFactory = RenderInterfaceD3D11::GetDXGIFactory(); + HRESULT res = pDXGIFactory->CreateSwapChain(pDevice, &swapChainDesc, &m_pDXGISwapChain); + if (FAILED(res)) return false; +#endif // USE_11ON12_WRAPPER + + // create DXUT text rendering class + m_pDialogResourceManager = new CDXUTDialogResourceManager; + m_pDialogResourceManager->OnD3D11CreateDevice(pDevice, pDeviceContext); + m_pTextHelper = new CDXUTTextHelper( pDevice, pDeviceContext, m_pDialogResourceManager, 15 ); + + CreateRenderTarget(); + Resize(wBuf, hBuf); + return true;// SUCCEEDED(res); +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D11RenderWindow::Free() +{ + FreeBuffer(); + + SAFE_DELETE(m_pTextHelper); + +#ifdef USE_11ON12_WRAPPER +#else + SAFE_RELEASE(m_pDXGISwapChain); +#endif // USE_11ON12_WRAPPER + + if (m_pDialogResourceManager) + { + m_pDialogResourceManager->OnD3D11DestroyDevice(); + SAFE_DELETE(m_pDialogResourceManager); + } +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D11RenderWindow::FreeBuffer() +{ +#ifdef USE_11ON12_WRAPPER +#else + SAFE_RELEASE(m_pD3D11RenderTargetView); + SAFE_RELEASE(m_pD3D11BackBuffer); + SAFE_RELEASE(m_pD3D11DepthStencilView); + SAFE_RELEASE(m_pD3D11DepthBuffer); +#endif // USE_11ON12_WRAPPER +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D11RenderWindow::Present() +{ +#ifdef USE_11ON12_WRAPPER + D3D11on12Wrapper::EndScene(); +#else + assert(m_pDXGISwapChain); + + if(m_pDXGISwapChain) + { + //m_pDXGISwapChain->Present(1, 0); // present in vsync + m_pDXGISwapChain->Present(0, 0); // present in vsync off + } +#endif // USE_11ON12_WRAPPER +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D11RenderWindow::Clear(float r, float g, float b) +{ +#ifdef USE_11ON12_WRAPPER + D3D11on12Wrapper::BeginScene(); + D3D11on12Wrapper::ClearScene(r, g, b); +#else + const float clearColor[4] = {r, g, b, 1.0f}; + + ID3D11DeviceContext* pD3DContext = RenderInterfaceD3D11::GetDeviceContext(); + pD3DContext->ClearRenderTargetView(m_pD3D11RenderTargetView, clearColor); + pD3DContext->ClearDepthStencilView(m_pD3D11DepthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0); +#endif // USE_11ON12_WRAPPER +} + +/////////////////////////////////////////////////////////////////////////////// +bool D3D11RenderWindow::Resize(int w, int h) +{ + assert(w > 0 && h > 0); + DXGI_SWAP_CHAIN_DESC swapChainDesc; + HRESULT res0 = m_pDXGISwapChain->GetDesc(&swapChainDesc); + if (w == (LONG)swapChainDesc.BufferDesc.Width && + h == (LONG)swapChainDesc.BufferDesc.Height) + return true; + +#ifdef USE_11ON12_WRAPPER +#else + //ID3D11DeviceContext* pD3DContext = RenderInterfaceD3D11::GetDeviceContext(); + //ID3D11RenderTargetView *nullRTV = NULL; + //pD3DContext->OMSetRenderTargets(1, &nullRTV, NULL); + FreeBuffer(); + swapChainDesc.BufferDesc.Width = w; + swapChainDesc.BufferDesc.Height = h; + //HRESULT res = m_pDXGISwapChain->ResizeBuffers(1, w, h, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + HRESULT res = m_pDXGISwapChain->ResizeBuffers(swapChainDesc.BufferCount, swapChainDesc.BufferDesc.Width, + swapChainDesc.BufferDesc.Height, swapChainDesc.BufferDesc.Format, + swapChainDesc.Flags); + assert(SUCCEEDED(res)); +#endif + return CreateRenderTarget(); +} + +bool D3D11RenderWindow::CreateRenderTarget() +{ +#ifdef USE_11ON12_WRAPPER + D3D11on12Wrapper::ResizeScene(w, h); +#else + ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice(); + // Retrieve the 2D back buffer + HRESULT res = m_pDXGISwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&m_pD3D11BackBuffer); + assert(SUCCEEDED(res)); + + D3D11_TEXTURE2D_DESC descTex2D; + m_pD3D11BackBuffer->GetDesc(&descTex2D); + + // Create the render target view + D3D11_RENDER_TARGET_VIEW_DESC descRenderTargetView; + { + memset(&descRenderTargetView, 0, sizeof(D3D11_RENDER_TARGET_VIEW_DESC)); + descRenderTargetView.Format = descTex2D.Format; + descRenderTargetView.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; // -MS dimension to support MSAA + descRenderTargetView.Texture2D.MipSlice = 0; + } + + res = pDevice->CreateRenderTargetView(m_pD3D11BackBuffer, &descRenderTargetView, &m_pD3D11RenderTargetView); + + assert(SUCCEEDED(res)); + + DXGI_SWAP_CHAIN_DESC swapChainDesc; + HRESULT res0 = m_pDXGISwapChain->GetDesc(&swapChainDesc); + // Create the depth/stencil buffer and view + D3D11_TEXTURE2D_DESC depthStencilDesc; + + depthStencilDesc.Width = swapChainDesc.BufferDesc.Width; + depthStencilDesc.Height = swapChainDesc.BufferDesc.Height; + depthStencilDesc.MipLevels = 1; + depthStencilDesc.ArraySize = 1; + depthStencilDesc.Format = DXGI_FORMAT_R24G8_TYPELESS; + depthStencilDesc.SampleDesc.Count = m_sampleCount; + depthStencilDesc.SampleDesc.Quality = m_sampleQuality; + depthStencilDesc.Usage = D3D11_USAGE_DEFAULT; + depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; + depthStencilDesc.CPUAccessFlags = 0; + depthStencilDesc.MiscFlags = 0; + + res = pDevice->CreateTexture2D(&depthStencilDesc, 0, &m_pD3D11DepthBuffer); + assert(SUCCEEDED(res)); + + D3D11_DEPTH_STENCIL_VIEW_DESC descDepthStencilView; + memset(&descDepthStencilView, 0, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC)); + descDepthStencilView.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + descDepthStencilView.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; // -MS dimension to support MSAA + descDepthStencilView.Texture2D.MipSlice = 0; + + res = pDevice->CreateDepthStencilView(m_pD3D11DepthBuffer, &descDepthStencilView, &m_pD3D11DepthStencilView); + assert(SUCCEEDED(res)); + + m_Width = swapChainDesc.BufferDesc.Width; + m_Height= swapChainDesc.BufferDesc.Height; + + ///////////////////////////////////////// + if (m_pDialogResourceManager) + { + DXGI_SURFACE_DESC backbufferDesc; + backbufferDesc.Width = descTex2D.Width; + backbufferDesc.Height = descTex2D.Height; + backbufferDesc.Format = descTex2D.Format; + backbufferDesc.SampleDesc = descTex2D.SampleDesc; + + m_pDialogResourceManager->OnD3D11ResizedSwapChain(pDevice, &backbufferDesc); + } + + // assume always the current render window, bind to render context immediately + ID3D11DeviceContext* pD3DContext = RenderInterfaceD3D11::GetDeviceContext(); + pD3DContext->OMSetRenderTargets(1, &m_pD3D11RenderTargetView, m_pD3D11DepthStencilView); + + // set the viewport transform + D3D11_VIEWPORT vp; + { + vp.TopLeftX = 0; + vp.TopLeftY = 0; + vp.Width = (float)m_Width; + vp.Height = (float)m_Height; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + } + pD3DContext->RSSetViewports(1, &vp); +#endif // USE_11ON12_WRAPPER + + return true; +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.h new file mode 100644 index 0000000..88d5c8f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11RendererWindow.h @@ -0,0 +1,43 @@ +#pragma once + +#include <d3d11.h> + +// DXUT stuffs for text rendering +class CDXUTDialogResourceManager; +class CDXUTTextHelper; + +struct D3D11RenderWindow +{ +public: + D3D11RenderWindow(); + ~D3D11RenderWindow(); + + bool Create(HWND hWnd, unsigned int nSamples = 1); + bool Resize(int w, int h); + void Present(); + void Clear(float r, float g, float b); + bool CreateRenderTarget(); + + // sample desc + UINT m_sampleCount; + UINT m_sampleQuality; +#ifdef USE_11ON12_WRAPPER +#else + int m_Height, m_Width; + + IDXGISwapChain* m_pDXGISwapChain; + ID3D11Texture2D* m_pD3D11BackBuffer; + ID3D11Texture2D* m_pD3D11DepthBuffer; + ID3D11RenderTargetView* m_pD3D11RenderTargetView; + ID3D11DepthStencilView* m_pD3D11DepthStencilView; +#endif // USE_11ON12_WRAPPER + + CDXUTDialogResourceManager* m_pDialogResourceManager; + CDXUTTextHelper* m_pTextHelper; + +private: + void Free(); + void FreeBuffer(); + +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp new file mode 100644 index 0000000..eba1184 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.cpp @@ -0,0 +1,225 @@ +// 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. +// +#include "D3D11Shaders.h" + +#include "MeshShaderParam.h" +#include "LightShaderParam.h" + +//#include <Nv/Blast/NvHairSdk.h> +#include "D3D11RenderShader.h" + +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" + #include "Shaders/BodyShader_PS.h" +} + +namespace BodyShadowBlobs +{ + #include "Shaders/BodyShadow_VS.h" + #include "Shaders/BodyShadow_PS.h" +} + +namespace ScreenQuadBlobs +{ + #include "Shaders/ScreenQuad_VS.h" + #include "Shaders/ScreenQuad_PS.h" +} + +namespace ScreenQuadColorBlobs +{ + #include "Shaders/ScreenQuadColor_VS.h" + #include "Shaders/ScreenQuadColor_PS.h" +} + +namespace VisualizeShadowBlobs +{ + #include "Shaders/VisualizeShadow_VS.h" + #include "Shaders/VisualizeShadow_PS.h" +} + +namespace ColorBlobs +{ + #include "Shaders/Color_VS.h" + #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 }, + { "VERTEX_NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "FACE_NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "VERTEX_ID", 0, DXGI_FORMAT_R32_FLOAT, 0, 56, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + UINT numElements = sizeof(layoutBodyRender)/sizeof(D3D11_INPUT_ELEMENT_DESC); + + g_pShaders[SHADER_TYPE_MESH_RENDERING] = D3D11RenderShader::Create( "MeshRenderShader", + (void*)BodyShaderBlobs::g_vs_main, sizeof(BodyShaderBlobs::g_vs_main), + (void*)BodyShaderBlobs::g_ps_main, sizeof(BodyShaderBlobs::g_ps_main), + sizeof(MeshShaderParam), 0, + &layoutBodyRender[0], numElements); + + g_pShaders[SHADER_TYPE_MESH_SHADOW] = D3D11RenderShader::Create( "MeshShadowShader", + (void*)BodyShadowBlobs::g_vs_main, sizeof(BodyShadowBlobs::g_vs_main), + (void*)BodyShadowBlobs::g_ps_main, sizeof(BodyShadowBlobs::g_ps_main), + sizeof(MeshShadowShaderParam), 0, + &layoutBodyRender[0], numElements); + + g_pShaders[SHADER_TYPE_SCREEN_QUAD] = D3D11RenderShader::Create( "ScreenQuadShader", + (void*)ScreenQuadBlobs::g_vs_main, sizeof(ScreenQuadBlobs::g_vs_main), + (void*)ScreenQuadBlobs::g_ps_main, sizeof(ScreenQuadBlobs::g_ps_main)); + + g_pShaders[SHADER_TYPE_SCREEN_QUAD_COLOR] = D3D11RenderShader::Create( "ScreenQuadColorShader", + (void*)ScreenQuadColorBlobs::g_vs_main, sizeof(ScreenQuadColorBlobs::g_vs_main), + (void*)ScreenQuadColorBlobs::g_ps_main, sizeof(ScreenQuadColorBlobs::g_ps_main)); + + g_pShaders[SHADER_TYPE_VISUALIZE_SHADOW] = D3D11RenderShader::Create( "VisualizeShadowShader", + (void*)VisualizeShadowBlobs::g_vs_main, sizeof(VisualizeShadowBlobs::g_vs_main), + (void*)VisualizeShadowBlobs::g_ps_main, sizeof(VisualizeShadowBlobs::g_ps_main), + sizeof(ShadowVizParam)); + + D3D11_INPUT_ELEMENT_DESC layout_Position_And_Color[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + UINT numElements2 = sizeof(layout_Position_And_Color)/sizeof(D3D11_INPUT_ELEMENT_DESC); + + g_pShaders[SHADER_TYPE_SIMPLE_COLOR] = D3D11RenderShader::Create( "Color", + (void*)ColorBlobs::g_vs_main, sizeof(ColorBlobs::g_vs_main), + (void*)ColorBlobs::g_ps_main, sizeof(ColorBlobs::g_ps_main), + 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; +} + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; } +#endif + +#ifndef SAFE_DELETE +#define SAFE_DELETE(x) { if (x) delete x; x = 0; } +#endif + +/////////////////////////////////////////////////////////////////////////////// +void DestroyShadersD3D11() +{ + for (int i = 0; i < g_pShaders.size(); i++) + { + D3D11RenderShader*& pShader = g_pShaders[i]; + if (pShader) + { + delete pShader; + pShader = 0; + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +D3D11RenderShader* GetShaderD3D11(SHADER_TYPE st) +{ + return g_pShaders[st]; +} + +/////////////////////////////////////////////////////////////////////////////// +void ApplyShaderD3D11(SHADER_TYPE st) +{ + D3D11RenderShader* pD3D11Shader = GetShaderD3D11(st); + if (!pD3D11Shader) + return; + + pD3D11Shader->MakeCurrent(); +} + +/////////////////////////////////////////////////////////////////////////////// +void DisableShaderD3D11(RenderInterface::SHADER_TYPE st) +{ + D3D11RenderShader* pD3D11Shader = GetShaderD3D11(st); + if (!pD3D11Shader) + return; + + pD3D11Shader->Disable(); +} + +/////////////////////////////////////////////////////////////////////////////// +void CopyShaderParamD3D11(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot) +{ + D3D11RenderShader* pD3D11Shader = GetShaderD3D11(st); + if (!pD3D11Shader) + return; + + void* mappedParam = pD3D11Shader->MapParam(slot); + + memcpy(mappedParam, pSysMem, bytes); + + pD3D11Shader->UnmapParam(slot); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.h new file mode 100644 index 0000000..b1d4929 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Shaders.h @@ -0,0 +1,43 @@ +// 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. +// + +#pragma once + +#include "RenderInterface.h" + +#include "RenderPlugin.h" + +/////////////////////////////////////////////////////////////////// +// default shaders +/////////////////////////////////////////////////////////////////// +CORERENDER_EXPORT bool InitializeShadersD3D11(); +CORERENDER_EXPORT void DestroyShadersD3D11(); + +CORERENDER_EXPORT void ApplyShaderD3D11(RenderInterface::SHADER_TYPE st); +CORERENDER_EXPORT void DisableShaderD3D11(RenderInterface::SHADER_TYPE st); +CORERENDER_EXPORT void CopyShaderParamD3D11(RenderInterface::SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0); diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.cpp new file mode 100644 index 0000000..90e30b2 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.cpp @@ -0,0 +1,208 @@ +// 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-2015 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. +// +#include "D3D11ShadowMap.h" + +#include "RenderResources.h" + +#include "D3D11RenderInterface.h" +#include "D3D11TextureResource.h" + +namespace +{ +////////////////////////////////////////////////////////////////////////////////////////////////// +D3D11_TEXTURE2D_DESC CreateD3D11TextureDesc( + DXGI_FORMAT Format, UINT Width, UINT Height, + UINT BindFlags, UINT SampleCount = 1, D3D11_USAGE Usage = D3D11_USAGE_DEFAULT, UINT CPUAccessFlags = 0, + UINT MiscFlags = 0, UINT ArraySize = 1, UINT MipLevels = 1) +{ + + D3D11_TEXTURE2D_DESC desc; + + desc.Format = Format; + desc.Width = Width; + desc.Height = Height; + + desc.ArraySize = ArraySize; + desc.MiscFlags = MiscFlags; + desc.MipLevels = MipLevels; + + desc.SampleDesc.Count = SampleCount; + desc.SampleDesc.Quality = 0; + desc.BindFlags = BindFlags; + desc.Usage = Usage; + desc.CPUAccessFlags = CPUAccessFlags; + + return desc; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +D3D11_DEPTH_STENCIL_VIEW_DESC CreateD3D11DSVDesc( + DXGI_FORMAT Format, D3D11_DSV_DIMENSION ViewDimension, + UINT Flags = 0, UINT MipSlice = 0) +{ + D3D11_DEPTH_STENCIL_VIEW_DESC desc; + + desc.Format = Format; + desc.ViewDimension = ViewDimension; + desc.Flags = Flags; + desc.Texture2D.MipSlice = MipSlice; + + return desc; +} + +} + +////////////////////////////////////////////////////////////////////////////// +D3D11ShadowMap::D3D11ShadowMap(int resolution) +{ + m_pShadowTexture = nullptr; + m_pShadowRTV = nullptr; + m_pShadowSRV = nullptr; + + m_pDepthTexture = nullptr; + m_pDepthDSV = nullptr; + + ID3D11Device* pd3dDevice = RenderInterfaceD3D11::GetDevice(); + if (!pd3dDevice) + return; + + { + m_viewport.Width = float(resolution); + m_viewport.Height = float(resolution); + m_viewport.MinDepth = 0; + m_viewport.MaxDepth = 1; + m_viewport.TopLeftX = 0; + m_viewport.TopLeftY = 0; + } + + HRESULT hr; + + // create shadow render target + { + D3D11_TEXTURE2D_DESC texDesc = CreateD3D11TextureDesc( + DXGI_FORMAT_R32_FLOAT, UINT(m_viewport.Width), UINT(m_viewport.Height), + D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE); + + hr = pd3dDevice->CreateTexture2D( &texDesc, NULL, &m_pShadowTexture ); + hr = pd3dDevice->CreateShaderResourceView( m_pShadowTexture, NULL, &m_pShadowSRV ); + hr = pd3dDevice->CreateRenderTargetView(m_pShadowTexture, NULL, &m_pShadowRTV); + + m_shadowResource.m_pD3D11Resource = m_pShadowSRV; + } + + // create shadow depth stencil + { + D3D11_TEXTURE2D_DESC texDesc = CreateD3D11TextureDesc( + DXGI_FORMAT_R32_TYPELESS, UINT(m_viewport.Width), UINT(m_viewport.Height), + D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE); + + hr = pd3dDevice->CreateTexture2D( &texDesc, NULL, &m_pDepthTexture ); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc = CreateD3D11DSVDesc( + DXGI_FORMAT_D32_FLOAT, D3D11_DSV_DIMENSION_TEXTURE2D); + + hr = pd3dDevice->CreateDepthStencilView(m_pDepthTexture, &dsvDesc, &m_pDepthDSV); + } +} + +////////////////////////////////////////////////////////////////////////////// +D3D11ShadowMap::~D3D11ShadowMap() +{ + Release(); +} + +////////////////////////////////////////////////////////////////////////////// +void D3D11ShadowMap::Release() +{ + SAFE_RELEASE(m_pShadowTexture); + SAFE_RELEASE(m_pShadowRTV); + SAFE_RELEASE(m_pShadowSRV); + SAFE_RELEASE(m_pDepthTexture); + SAFE_RELEASE(m_pDepthDSV); + + m_shadowResource.m_pD3D11Resource = 0; +} + +////////////////////////////////////////////////////////////////////////////// +GPUShaderResource* D3D11ShadowMap::GetShadowSRV() +{ + return &m_shadowResource; +} + +////////////////////////////////////////////////////////////////////////////// +bool D3D11ShadowMap::isValid() +{ + return m_pShadowTexture && m_pShadowRTV && m_pShadowSRV && m_pDepthTexture && m_pDepthDSV; +} + +////////////////////////////////////////////////////////////////////////////// +void D3D11ShadowMap::BeginRendering(float clearDepth) +{ + if (!isValid()) + return; + + ID3D11DeviceContext* pd3dContext = RenderInterfaceD3D11::GetDeviceContext(); + if (!pd3dContext) + return; + + pd3dContext->OMGetRenderTargets(1, &m_pPreviousRTV, &m_pPreviousDSV); + m_numPreviousViewports = 1; + pd3dContext->RSGetViewports(&m_numPreviousViewports, m_previousViewport); + + pd3dContext->OMSetRenderTargets( 1, &m_pShadowRTV, m_pDepthDSV); + pd3dContext->RSSetViewports(1, &m_viewport); + + float ClearColor[4] = { clearDepth, clearDepth, clearDepth, clearDepth}; + + pd3dContext->ClearRenderTargetView( m_pShadowRTV, ClearColor ); + pd3dContext->ClearDepthStencilView( m_pDepthDSV, D3D11_CLEAR_DEPTH, 1.0, 0 ); +} + +////////////////////////////////////////////////////////////////////////////// +void D3D11ShadowMap::EndRendering() +{ + if (!isValid()) + return; + + ID3D11DeviceContext* pd3dContext = RenderInterfaceD3D11::GetDeviceContext(); + if (!pd3dContext) + return; + + pd3dContext->OMSetRenderTargets(0, NULL, NULL); + + if (m_pPreviousRTV) + { + pd3dContext->OMSetRenderTargets(1, &m_pPreviousRTV, m_pPreviousDSV); + m_pPreviousRTV->Release(); + if (m_pPreviousDSV) m_pPreviousDSV->Release(); + } + + if (m_numPreviousViewports) + pd3dContext->RSSetViewports(m_numPreviousViewports, m_previousViewport); +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.h new file mode 100644 index 0000000..fc9fe79 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11ShadowMap.h @@ -0,0 +1,72 @@ +// 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-2015 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. +// + +#pragma once + +#include "ShadowMap.h" + +#include "d3d11.h" +#include "D3D11TextureResource.h" + +class GPUShaderResource; +class D3D11TextureResource; + +struct D3D11ShadowMap : public ShadowMap +{ + D3D11_VIEWPORT m_viewport; + + ID3D11Texture2D* m_pShadowTexture; + ID3D11RenderTargetView* m_pShadowRTV; + ID3D11ShaderResourceView* m_pShadowSRV; + + ID3D11Texture2D* m_pDepthTexture; + ID3D11DepthStencilView* m_pDepthDSV; + ID3D11ShaderResourceView* m_pDepthSRV; + + D3D11TextureResource m_shadowResource; + +public: + D3D11ShadowMap(int resolution ); + ~D3D11ShadowMap(); + + void Release(); + void BeginRendering(float clearDepth); + void EndRendering(); + + GPUShaderResource* GetShadowSRV(); + +protected: + + bool isValid(); + + ID3D11RenderTargetView* m_pPreviousRTV; + ID3D11DepthStencilView* m_pPreviousDSV; + UINT m_numPreviousViewports; + D3D11_VIEWPORT m_previousViewport[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.cpp new file mode 100644 index 0000000..2a8f7ee --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.cpp @@ -0,0 +1,29 @@ +// 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. +// +#include "D3D11TextureResource.h" + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.h new file mode 100644 index 0000000..91d6539 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11TextureResource.h @@ -0,0 +1,64 @@ +// 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-2015 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. +// + +#pragma once + +#include "RenderResources.h" + +#include "d3d11.h" + +// GPU resources for texture +struct D3D11TextureResource : public GPUShaderResource +{ + ID3D11ShaderResourceView* m_pD3D11Resource; + +public: + static GPUShaderResource* Create(ID3D11ShaderResourceView* pResource) { + D3D11TextureResource* pBuffer = new D3D11TextureResource; + pBuffer->m_pD3D11Resource = pResource; + return pBuffer; + } + + static ID3D11ShaderResourceView* GetResource(GPUShaderResource* pBuffer) + { + D3D11TextureResource* pD3D11Buffer = dynamic_cast<D3D11TextureResource*>(pBuffer); + if (!pD3D11Buffer) + return 0; + return pD3D11Buffer->m_pD3D11Resource; + } + + ~D3D11TextureResource() + { + } + + void Release() + { + SAFE_RELEASE(m_pD3D11Resource); + } +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.cpp new file mode 100644 index 0000000..b13c8e3 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.cpp @@ -0,0 +1,333 @@ +// 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. +// +#include "D3D11Util.h" + +#include "D3D11Shaders.h" +#include "D3D11RenderShader.h" + +#include "D3DX10tex.h" +#include "D3DX11tex.h" + +#include "D3D11Wrapper.h" +#include "DXUT.h" +#include "DXUTgui.h" +#include "sdkmisc.h" +#include "D3D11RendererWindow.h" +#include "SimpleRenderable.h" +//#include "MeshShaderParam.h" +#include "D3D11RenderInterface.h" +#include "D3D11TextureResource.h" + +namespace D3D11Util +{ + using namespace RenderInterface; + + // D3D hook to render window + D3D11RenderWindow* g_pRenderWindow = 0; + +/////////////////////////////////////////////////////////////////////////////// +#include "../../../../../../external/stb_image/stb_image.c" + +GPUShaderResource* +CreateTextureSRV(const char* texturename) +{ + ID3D11Device* pDevice = RenderInterfaceD3D11::GetDevice(); + if (!pDevice) + return 0; + + D3DX11_IMAGE_LOAD_INFO texLoadInfo; + + texLoadInfo.MipLevels = 8; + texLoadInfo.MipFilter = D3DX10_FILTER_TRIANGLE; + texLoadInfo.Filter = D3DX10_FILTER_TRIANGLE; + + ID3D11Resource *pRes = 0; + + HRESULT hr; + D3DX11CreateTextureFromFileA(pDevice, texturename, &texLoadInfo, NULL, &pRes, &hr); + + ID3D11Texture2D* texture = NULL; + + if (!pRes) + { + // Try stb_image for .TGA + int width = 0; + int height = 0; + int numComponents = 0; + unsigned char *pSTBIRes = stbi_load(texturename, &width, &height, &numComponents, 4); + + if (!pSTBIRes) + return 0; + + const int requestedMipLevels = texLoadInfo.MipLevels; + + D3D11_SUBRESOURCE_DATA* initData = new D3D11_SUBRESOURCE_DATA[requestedMipLevels]; + ZeroMemory(initData, sizeof(D3D11_SUBRESOURCE_DATA)*requestedMipLevels); + + struct Pixel + { + unsigned char rgba[4]; + }; + + // prepare target buffer just large enough to include all the mip levels + Pixel* targets = new Pixel[width*height*2]; + + // copy the first mip level + memcpy(targets, pSTBIRes, width*height*4); + + // now it's OK to delete the original + if (pSTBIRes) + stbi_image_free(pSTBIRes); + + // current mip level width and height + int mipWidth = width; + int mipHeight = height; + + // actual mip levels + int mipLevels = 0; + + // current data + Pixel* source = targets; + Pixel* target = nullptr; + + for (int idx = 0; idx < requestedMipLevels; ++idx) + { + // set initData + initData[idx].pSysMem = source; + initData[idx].SysMemPitch = mipWidth*4; + mipLevels++; + + // skip generating mip for 1x1 + if ((mipWidth == 1) && (mipHeight == 1)) + break; + + // skip generating mip for the last level + if (idx == (requestedMipLevels-1)) + break; + + // buffer for the next mip level + target = &source[mipWidth*mipHeight]; + + const int prevWidth = mipWidth; // previous mip's width + + // generate the next mip level + mipWidth = max(1, mipWidth >> 1); + mipHeight = max(1, mipHeight >> 1); + + Pixel samples[4]; + + for (int y = 0; y < mipHeight; ++y) + { + for (int x = 0; x < mipWidth; ++x) + { + const int px = x*2; // x in previous mip + const int py = y*2; // y in previous mip + + samples[0] = source[py*prevWidth + px]; // left top + samples[1] = source[py*prevWidth + px+1]; // right top + samples[2] = source[(py+1)*prevWidth + px]; // left bottom + samples[3] = source[(py+1)*prevWidth + px+1]; // right bottom + + // for each component + for (int comp = 0; comp < 4; ++comp) + { + // do the linear box filter for lower mip level + target[y*mipWidth + x].rgba[comp] = (samples[0].rgba[comp] + samples[1].rgba[comp] + samples[2].rgba[comp] + samples[3].rgba[comp])/4; + } + } + } + + // update source + source = target; + } + + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC)); + desc.ArraySize = 1; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.Height = height; + desc.Width = width; + desc.MipLevels = mipLevels; + desc.MiscFlags = 0; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + + HRESULT ret = pDevice->CreateTexture2D(&desc, initData, &texture); + + delete initData; + delete targets; + + if (ret != S_OK) + return 0; + } + else + { + pRes->QueryInterface(__uuidof( ID3D11Texture2D ), (LPVOID*)&texture); + } + + D3D11_TEXTURE2D_DESC desc; + texture->GetDesc( &desc ); + + ID3D11ShaderResourceView* pTextureSRV = 0; + + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + ZeroMemory( &SRVDesc, sizeof(SRVDesc) ); + SRVDesc.Format = desc.Format; + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + SRVDesc.Texture2D.MostDetailedMip = 0; + SRVDesc.Texture2D.MipLevels = desc.MipLevels; + pDevice->CreateShaderResourceView(texture, &SRVDesc, &pTextureSRV); + + if (texture) texture->Release(); + + if (pRes) + pRes->Release(); + + return D3D11TextureResource::Create(pTextureSRV); +} + + +/////////////////////////////////////////////////////////////////////////////// +bool GetDeviceInfoString(wchar_t *str) +{ + IDXGIAdapter* pAdapter = RenderInterfaceD3D11::GetAdapter(); + if (!pAdapter) + return false; + + auto adapterDescription = DXGI_ADAPTER_DESC(); + pAdapter->GetDesc(&adapterDescription); + + WCHAR* pDescStr = adapterDescription.Description; + float memInGB = float(adapterDescription.DedicatedVideoMemory) / 1e9f; + swprintf_s(str, 1000, L"%s(%.1fGb)\n", pDescStr, memInGB); + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Render window interafce +///////////////////////////////////////////////////////////////////////////////////////// +bool CreateRenderWindow(HWND hWnd, int nSamples) +{ + SAFE_DELETE(g_pRenderWindow); + + g_pRenderWindow = new D3D11RenderWindow; + return g_pRenderWindow->Create(hWnd, nSamples); +} + +D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles) +{ + deviceHandles.pAdapter = RenderInterfaceD3D11::GetAdapter(); + deviceHandles.pFactory = RenderInterfaceD3D11::GetDXGIFactory(); + deviceHandles.pDevice = RenderInterfaceD3D11::GetDevice(); + deviceHandles.pDeviceContext = RenderInterfaceD3D11::GetDeviceContext(); + + deviceHandles.pDXGISwapChain = g_pRenderWindow->m_pDXGISwapChain; + deviceHandles.pD3D11BackBuffer = g_pRenderWindow->m_pD3D11BackBuffer; + deviceHandles.pD3D11RenderTargetView = g_pRenderWindow->m_pD3D11RenderTargetView; + deviceHandles.pD3D11DepthBuffer = g_pRenderWindow->m_pD3D11DepthBuffer; + deviceHandles.pD3D11DepthStencilView = g_pRenderWindow->m_pD3D11DepthStencilView; + return deviceHandles; +} + +void DestroyRenderWindow() +{ + SAFE_DELETE(g_pRenderWindow); +} + +bool ResizeRenderWindow(int w, int h) +{ + if (!g_pRenderWindow) + return false; + + return g_pRenderWindow->Resize(w,h); +} + +void PresentRenderWindow() +{ + if (!g_pRenderWindow) + return; + + g_pRenderWindow->Present(); +} + +void ClearRenderWindow(float r, float g, float b) +{ + if (!g_pRenderWindow) + return; + + g_pRenderWindow->Clear(r,g,b); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Text draw helper functions (using DXUT) +///////////////////////////////////////////////////////////////////////////////////////// +void TxtHelperBegin() +{ + if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper) + return; + + g_pRenderWindow->m_pTextHelper->Begin(); +} + +void TxtHelperEnd() +{ + if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper) + return; + + g_pRenderWindow->m_pTextHelper->End(); +} + +void TxtHelperSetInsertionPos(int x, int y) +{ + if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper) + return; + + g_pRenderWindow->m_pTextHelper->SetInsertionPos(x, y); +} + +void TxtHelperSetForegroundColor(float r, float g, float b, float a) +{ + if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper) + return; + + g_pRenderWindow->m_pTextHelper->SetForegroundColor(DirectX::XMFLOAT4(r,g,b,a)); +} + +void TxtHelperDrawTextLine(wchar_t* str) +{ + if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper) + return; + + g_pRenderWindow->m_pTextHelper->DrawTextLine(str); +} + +} // end namespace
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.h new file mode 100644 index 0000000..8a9176e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Util.h @@ -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. +// + +#pragma once + +#include "d3d11.h" + +#include "RenderPlugin.h" + +class GPUShaderResource; +class IDXGISwapChain; + +namespace D3D11Util +{ + /////////////////////////////////////////////////////////////////// + // render window management + /////////////////////////////////////////////////////////////////// + D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles); + bool CreateRenderWindow(HWND hWnd, int nSamples); + void DestroyRenderWindow(); + bool ResizeRenderWindow(int w, int h); + void PresentRenderWindow(); + void ClearRenderWindow(float r, float g, float b); + + /////////////////////////////////////////////////////////////////// + // background textures + bool LoadBackgroundTexture(const char* filePath); + void RenderBackgroundTexture(); + void ClearBackgroundTexture(); + GPUShaderResource* CreateTextureSRV(const char* texturename); + + /////////////////////////////////////////////////////////////////// + CORERENDER_EXPORT bool GetDeviceInfoString(wchar_t *str); + + /////////////////////////////////////////////////////////////////// + // text helpers + CORERENDER_EXPORT void TxtHelperBegin(); + CORERENDER_EXPORT void TxtHelperEnd(); + CORERENDER_EXPORT void TxtHelperSetInsertionPos(int x, int y); + CORERENDER_EXPORT void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f); + CORERENDER_EXPORT void TxtHelperDrawTextLine(wchar_t* str); + + +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.cpp new file mode 100644 index 0000000..5a117f1 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.cpp @@ -0,0 +1,33 @@ +// 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. +// +#include "D3D11Wrapper.h" + +namespace D3DWrapper +{ + +} // end namespace
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.h new file mode 100644 index 0000000..0d752d8 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/D3D11Wrapper.h @@ -0,0 +1,14 @@ +#pragma once + +#include "d3d11.h" + +namespace D3DWrapper +{ + inline void SetDebugName(ID3D11DeviceChild* pResource, const char *name) + { + if (pResource) pResource->SetPrivateData( WKPDID_D3DDebugObjectName, strlen(name), name); + } +} + +#define SET_D3D_DEBUG_NAME(x, name) D3DWrapper::SetDebugName(x, name); +#define SET_D3D_DEBUG_NAME_VAR(x) D3DWrapper::SetDebugName(x, #x); diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.cpp new file mode 100644 index 0000000..93d3fdf --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.cpp @@ -0,0 +1,315 @@ +#include "RenderPluginDx11.h" + +#include "D3D11RenderInterface.h" +#include "D3D11Util.h" +#include "D3D11Shaders.h" +#include "D3D11GPUProfiler.h" +#include "D3D11ShadowMap.h" + +RenderPlugin* CreateRenderPlugin(void) +{ + return new RenderPluginDx11; +} + +RenderPluginDx11::RenderPluginDx11() +{ + m_RenderApi = "Dx11"; +} + +RenderPluginDx11::~RenderPluginDx11() +{ +} + +// interface +bool RenderPluginDx11::InitDevice(int deviceID) +{ + return RenderInterfaceD3D11::InitDevice(deviceID); +} + +bool RenderPluginDx11::Initialize() +{ + return RenderInterfaceD3D11::Initialize(); +} + +void RenderPluginDx11::Shutdown() +{ + D3D11Util::DestroyRenderWindow(); + RenderInterfaceD3D11::Shutdown(); +} + +void RenderPluginDx11::CopyToDevice(GPUBufferResource *pDevicePtr, + void* pSysMem, unsigned int ByteWidth) +{ + RenderInterfaceD3D11::CopyToDevice(pDevicePtr, pSysMem, ByteWidth); +} + +void RenderPluginDx11::ApplyDepthStencilState(DEPTH_STENCIL_STATE state) +{ + RenderInterfaceD3D11::ApplyDepthStencilState(state); +} + +void RenderPluginDx11::ApplyRasterizerState(RASTERIZER_STATE state) +{ + RenderInterfaceD3D11::ApplyRasterizerState(state); +} + +void RenderPluginDx11::ApplySampler(int slot, SAMPLER_TYPE state) +{ + RenderInterfaceD3D11::ApplySampler(slot, state); +} + +void RenderPluginDx11::ApplyBlendState(BLEND_STATE state) +{ + RenderInterfaceD3D11::ApplyBlendState(state); +} + +void RenderPluginDx11::GetViewport(Viewport& vp) +{ + RenderInterfaceD3D11::GetViewport(vp); +} + +void RenderPluginDx11::SetViewport(const Viewport& vp) +{ + RenderInterfaceD3D11::SetViewport(vp); +} + +void RenderPluginDx11::BindVertexShaderResources(int startSlot, + int numSRVs, GPUShaderResource** ppSRVs) +{ + RenderInterfaceD3D11::BindVertexShaderResources(startSlot, numSRVs, ppSRVs); +} + +void RenderPluginDx11::BindPixelShaderResources(int startSlot, + int numSRVs, GPUShaderResource** ppSRVs) +{ + RenderInterfaceD3D11::BindPixelShaderResources(startSlot, numSRVs, ppSRVs); +} + +void RenderPluginDx11::ClearVertexShaderResources(int startSlot, int numSRVs) +{ + RenderInterfaceD3D11::ClearVertexShaderResources(startSlot, numSRVs); +} + +void RenderPluginDx11::ClearPixelShaderResources(int startSlot, int numSRVs) +{ + RenderInterfaceD3D11::ClearPixelShaderResources(startSlot, numSRVs); +} + +void RenderPluginDx11::ClearInputLayout() +{ + RenderInterfaceD3D11::ClearInputLayout(); +} + +void RenderPluginDx11::SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset) +{ + RenderInterfaceD3D11::SetVertexBuffer(pBuffer, stride, offset); +} + +void RenderPluginDx11::SetPrimitiveTopologyTriangleStrip() +{ + RenderInterfaceD3D11::SetPrimitiveTopologyTriangleStrip(); +} + +void RenderPluginDx11::SetPrimitiveTopologyTriangleList() +{ + RenderInterfaceD3D11::SetPrimitiveTopologyTriangleList(); +} + +void RenderPluginDx11::SetPrimitiveTopologyLineList() +{ + RenderInterfaceD3D11::SetPrimitiveTopologyLineList(); +} + +void RenderPluginDx11::Draw(unsigned int vertexCount, unsigned int startCount) +{ + RenderInterfaceD3D11::Draw(vertexCount, startCount); +} + +GPUBufferResource* RenderPluginDx11::CreateVertexBuffer(unsigned int ByteWidth, void* pSysMem) +{ + return RenderInterfaceD3D11::CreateVertexBuffer(ByteWidth, pSysMem); +} + +GPUShaderResource* RenderPluginDx11::CreateShaderResource(unsigned int stride, + unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer) +{ + return RenderInterfaceD3D11::CreateShaderResource(stride, numElements, pSysMem); +} + +void RenderPluginDx11::ApplyForShadow(int ForShadow) +{ +} + +void RenderPluginDx11::SwitchToDX11() +{ +} + +void RenderPluginDx11::FlushDX11() +{ +} + +void RenderPluginDx11::FlushDX12() +{ +} + +void RenderPluginDx11::ApplyPrimitiveTopologyLine() +{ +} + +void RenderPluginDx11::ApplyPrimitiveTopologyTriangle() +{ +} + +void RenderPluginDx11::SubmitGpuWork() +{ +} + +void RenderPluginDx11::WaitForGpu() +{ +} + +// util +bool RenderPluginDx11::CreateRenderWindow(HWND hWnd, int nSamples) +{ + return D3D11Util::CreateRenderWindow(hWnd, nSamples); +} + +bool RenderPluginDx11::ResizeRenderWindow(int w, int h) +{ + return D3D11Util::ResizeRenderWindow(w, h); +} + +void RenderPluginDx11::PresentRenderWindow() +{ + D3D11Util::PresentRenderWindow(); +} + +void RenderPluginDx11::ClearRenderWindow(float r, float g, float b) +{ + D3D11Util::ClearRenderWindow(r, g, b); +} + +bool RenderPluginDx11::GetDeviceInfoString(wchar_t *str) +{ + return D3D11Util::GetDeviceInfoString(str); +} + +GPUShaderResource* RenderPluginDx11::CreateTextureSRV(const char* texturename) +{ + return D3D11Util::CreateTextureSRV(texturename); +} + +void RenderPluginDx11::TxtHelperBegin() +{ + D3D11Util::TxtHelperBegin(); +} + +void RenderPluginDx11::TxtHelperEnd() +{ + D3D11Util::TxtHelperEnd(); +} + +void RenderPluginDx11::TxtHelperSetInsertionPos(int x, int y) +{ + D3D11Util::TxtHelperSetInsertionPos(x, y); +} + +void RenderPluginDx11::TxtHelperSetForegroundColor(float r, float g, float b, float a) +{ + D3D11Util::TxtHelperSetForegroundColor(r, g, b, a); +} + +void RenderPluginDx11::TxtHelperDrawTextLine(wchar_t* str) +{ + D3D11Util::TxtHelperDrawTextLine(str); +} + +// shader +bool RenderPluginDx11::InitializeShaders() +{ + return InitializeShadersD3D11(); +} + +void RenderPluginDx11::DestroyShaders() +{ + DestroyShadersD3D11(); +} + +void RenderPluginDx11::ApplyShader(SHADER_TYPE st) +{ + ApplyShaderD3D11(st); +} + +void RenderPluginDx11::DisableShader(SHADER_TYPE st) +{ + DisableShaderD3D11(st); +} + +void RenderPluginDx11::BindShaderResources(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs) +{ +} + +void RenderPluginDx11::CopyShaderParam(SHADER_TYPE st, + void* pSysMem, unsigned int bytes, unsigned int slot) +{ + CopyShaderParamD3D11(st, pSysMem, bytes, slot); +} + +// GPUProfiler +GPUProfiler* RenderPluginDx11::CreateGPUProfiler() +{ + GPUProfiler* pProfiler = new D3D11GPUProfiler; + pProfiler->Initialize(); + return pProfiler; +} + +// ShadowMap +ShadowMap* RenderPluginDx11::CreateShadowMap(int resolution) +{ + return new D3D11ShadowMap(resolution); +} + +// D3D12RenderContext +void RenderPluginDx11::PreRender() +{ +} + +void RenderPluginDx11::PostRender() +{ +} + +// GPUMeshResources + +#include "MeshData.h" +#include "AnimUtil.h" + +GPUMeshResources* RenderPluginDx11::GPUMeshResourcesCreate(MeshData* pMeshData, const SkinData& skinData) +{ + GPUMeshResources* resources = new GPUMeshResources; + + int numIndices = pMeshData->m_NumIndices; + int numVertices = pMeshData->m_NumVertices; + + resources->m_pVertexBuffer = CreateVertexBuffer( + sizeof(MeshData::MeshVertex) * numIndices, pMeshData->m_pMeshVertices); + + resources->m_pBoneIndicesSRV = CreateShaderResource( + sizeof(atcore_float4), numVertices, skinData.m_pBoneIndices); + + resources->m_pBoneWeightsSRV = CreateShaderResource( + sizeof(atcore_float4), numVertices, skinData.m_pBoneWeights); + + return resources; +} + +void RenderPluginDx11::GPUMeshResourcesRelease(GPUMeshResources* pResource) +{ + SAFE_RELEASE(pResource->m_pVertexBuffer); + SAFE_RELEASE(pResource->m_pBoneIndicesSRV); + SAFE_RELEASE(pResource->m_pBoneWeightsSRV); +} + +D3DHandles& RenderPluginDx11::GetDeviceHandles(D3DHandles& deviceHandles) +{ + return D3D11Util::GetDeviceHandles(deviceHandles); +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.h new file mode 100644 index 0000000..a43eb94 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D11/RenderPluginDx11.h @@ -0,0 +1,83 @@ +#pragma once + +#include "RenderPlugin.h" + +extern "C" CORERENDER_EXPORT RenderPlugin* CreateRenderPlugin(void); + +class CORERENDER_EXPORT RenderPluginDx11 : public RenderPlugin +{ +public: + RenderPluginDx11(); + ~RenderPluginDx11(); + + // interface + virtual bool InitDevice(int deviceID); + virtual bool Initialize(); + virtual void Shutdown(); + virtual void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth); + virtual void ApplyDepthStencilState(DEPTH_STENCIL_STATE state); + virtual void ApplyRasterizerState(RASTERIZER_STATE state); + virtual void ApplySampler(int slot, SAMPLER_TYPE st); + virtual void ApplyBlendState(BLEND_STATE st); + virtual void GetViewport(Viewport& vp); + virtual void SetViewport(const Viewport& vp); + virtual void BindVertexShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs); + virtual void BindPixelShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs); + virtual void ClearVertexShaderResources(int startSlot, int numSRVs); + virtual void ClearPixelShaderResources(int startSlot, int numSRVs); + virtual void ClearInputLayout(); + virtual void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset = 0); + virtual void SetPrimitiveTopologyTriangleStrip(); + virtual void SetPrimitiveTopologyTriangleList(); + virtual void SetPrimitiveTopologyLineList(); + virtual void Draw(unsigned int vertexCount, unsigned int startCount = 0); + virtual GPUBufferResource* CreateVertexBuffer(unsigned int ByteWidth, void* pSysMem = 0); + virtual GPUShaderResource* CreateShaderResource(unsigned int stride, unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer = NULL); + virtual void ApplyForShadow(int ForShadow); + virtual void SwitchToDX11(); + virtual void FlushDX11(); + virtual void FlushDX12(); + virtual void ApplyPrimitiveTopologyLine(); + virtual void ApplyPrimitiveTopologyTriangle(); + virtual void SubmitGpuWork(); + virtual void WaitForGpu(); + + // util + virtual bool CreateRenderWindow(HWND hWnd, int nSamples); + virtual bool ResizeRenderWindow(int w, int h); + virtual void PresentRenderWindow(); + virtual void ClearRenderWindow(float r, float g, float b); + virtual bool GetDeviceInfoString(wchar_t *str); + virtual GPUShaderResource* CreateTextureSRV(const char* texturename); + virtual void TxtHelperBegin(); + virtual void TxtHelperEnd(); + virtual void TxtHelperSetInsertionPos(int x, int y); + virtual void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f); + virtual void TxtHelperDrawTextLine(wchar_t* str); + + // shader + virtual bool InitializeShaders(); + virtual void DestroyShaders(); + virtual void ApplyShader(SHADER_TYPE st); + virtual void DisableShader(SHADER_TYPE st); + virtual void BindShaderResources(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs); + virtual void CopyShaderParam(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0); + + // GPUProfiler + virtual GPUProfiler* CreateGPUProfiler(); + + // ShadowMap + virtual ShadowMap* CreateShadowMap(int resolution); + + // D3D12RenderContext + virtual void PreRender(); + virtual void PostRender(); + + // GPUMeshResources + virtual GPUMeshResources* GPUMeshResourcesCreate(MeshData* pMeshData, const SkinData& skinData); + virtual void GPUMeshResourcesRelease(GPUMeshResources* pResource); + + // Get devices related + virtual D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles); +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.cpp new file mode 100644 index 0000000..0421792 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.cpp @@ -0,0 +1,31 @@ +// 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. +// +#include "D3D12Buffer.h" + +// shared path + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.h new file mode 100644 index 0000000..ccf636b --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Buffer.h @@ -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-2015 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. +// + +#pragma once + +#include "RenderResources.h" + +#include <d3d12.h> + +// GPU resources for texture +struct GPUBufferD3D12 : public GPUBufferResource +{ + ID3D12Resource* m_pBuffer; + UINT m_pBufferSize; + + D3D12_VERTEX_BUFFER_VIEW m_vertexBufferView; + +public: + static GPUBufferResource* Create(ID3D12Resource* pResource, int nSize) { + GPUBufferD3D12* pBuffer = new GPUBufferD3D12; + pBuffer->m_pBuffer = pResource; + pBuffer->m_pBufferSize = nSize; + return pBuffer; + } + + static ID3D12Resource* GetResource(GPUBufferResource* pBuffer) + { + GPUBufferD3D12* pD3D12Buffer = dynamic_cast<GPUBufferD3D12*>(pBuffer); + if (!pD3D12Buffer) + return 0; + return pD3D12Buffer->m_pBuffer; + } + + static D3D12_VERTEX_BUFFER_VIEW* GetVertexView(GPUBufferResource* pBuffer) + { + GPUBufferD3D12* pD3D12Buffer = dynamic_cast<GPUBufferD3D12*>(pBuffer); + if (!pD3D12Buffer) + return 0; + + pD3D12Buffer->m_vertexBufferView.BufferLocation = pD3D12Buffer->m_pBuffer->GetGPUVirtualAddress(); + pD3D12Buffer->m_vertexBufferView.StrideInBytes = 0; + pD3D12Buffer->m_vertexBufferView.SizeInBytes = pD3D12Buffer->m_pBufferSize; + return &pD3D12Buffer->m_vertexBufferView; + } + + ~GPUBufferD3D12() + { + Release(); + } + + void Release() + { + SAFE_RELEASE(m_pBuffer); + } +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.cpp new file mode 100644 index 0000000..b434c3c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.cpp @@ -0,0 +1,222 @@ +// 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-2015 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. +// +#include "D3D12GPUProfiler.h" + +#include "D3D12RenderInterface.h" +#include "D3D12RenderContext.h" +/////////////////////////////////////////////////////////////// +// factory function to create D3D12 GPU profiler +/* +GPUProfiler* GPUProfiler::CreateD3D12() +{ + GPUProfiler* pProfiler = new D3D12GPUProfiler; + pProfiler->Initialize(); + return pProfiler; +} +*/ + +/////////////////////////////////////////////////////////////// +D3D12GPUProfiler::~D3D12GPUProfiler() +{ + Release(); +} + +/////////////////////////////////////////////////////////////// +void D3D12GPUProfiler::Initialize() +{ + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + + /* + ID3D12Device* pDevice12 = pContext->GetDevice(); + + D3D12_QUERY_HEAP_DESC queryHeapDesc = {}; + queryHeapDesc.Count = MAX_QUERY_COUNT * 2; + queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP; + ThrowIfFailed(pDevice12->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&query_heap))); + + D3D12_HEAP_PROPERTIES heap_prop; + heap_prop.Type = D3D12_HEAP_TYPE_DEFAULT; + heap_prop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + heap_prop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + heap_prop.CreationNodeMask = 0; + heap_prop.VisibleNodeMask = 0; + + D3D12_RESOURCE_DESC res_desc; + res_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + res_desc.Alignment = 0; + res_desc.Width = sizeof(UINT64) * 2; + res_desc.Height = 1; + res_desc.DepthOrArraySize = 1; + res_desc.MipLevels = 1; + res_desc.Format = DXGI_FORMAT_UNKNOWN; + res_desc.SampleDesc.Count = 1; + res_desc.SampleDesc.Quality = 0; + res_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + res_desc.Flags = D3D12_RESOURCE_FLAG_NONE; + + ThrowIfFailed(pDevice12->CreateCommittedResource(&heap_prop, D3D12_HEAP_FLAG_NONE, + &res_desc, D3D12_RESOURCE_STATE_COMMON, nullptr, + IID_ID3D12Resource, reinterpret_cast<void**>(&query_result))); + + heap_prop.Type = D3D12_HEAP_TYPE_READBACK; + ThrowIfFailed(pDevice12->CreateCommittedResource(&heap_prop, D3D12_HEAP_FLAG_NONE, + &res_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, + IID_ID3D12Resource, reinterpret_cast<void**>(&query_result_readback))); + */ + + m_pContext = pContext->GetDeviceContext(); + + D3D11_QUERY_DESC desc; + memset(&desc, 0, sizeof(D3D11_QUERY_DESC)); + desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT; + desc.MiscFlags = 0; + + ID3D11Device* pDevice = pContext->GetDevice11(); + pDevice->CreateQuery(&desc, &m_pQueryDisjoint); + + desc.Query = D3D11_QUERY_TIMESTAMP; + + for (int i = 0; i < MAX_QUERY_COUNT; i++) + { + pDevice->CreateQuery(&desc, &m_pQueryStart[i]); + pDevice->CreateQuery(&desc, &m_pQueryEnd[i]); + } + m_enable = true; +} + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; } +#endif + +/////////////////////////////////////////////////////////////// +void D3D12GPUProfiler::Release() +{ + for (int i = 0; i < MAX_QUERY_COUNT; i++) + { + SAFE_RELEASE(m_pQueryStart[i]); + SAFE_RELEASE(m_pQueryEnd[i]); + } + + SAFE_RELEASE(m_pQueryDisjoint); +} + +/////////////////////////////////////////////////////////////// +void D3D12GPUProfiler::StartProfile(int id) +{ + if (!m_enable) return; + + /* + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList(); + pCommandList->EndQuery(query_heap, D3D12_QUERY_TYPE_TIMESTAMP, id * 2); + */ + + ID3D11Query* pQuery = m_pQueryStart[id]; + m_pContext->End(pQuery); +} + +/////////////////////////////////////////////////////////////// +void D3D12GPUProfiler::EndProfile(int id) +{ + if (!m_enable) return; + + /* + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList(); + pCommandList->EndQuery(query_heap, D3D12_QUERY_TYPE_TIMESTAMP, id * 2 + 1); + */ + + ID3D11Query* pQuery = m_pQueryEnd[id]; + m_pContext->End(pQuery); +} + +/////////////////////////////////////////////////////////////// +void D3D12GPUProfiler::StartFrame() +{ + if (!m_enable) return; + + m_pContext->Begin(m_pQueryDisjoint); +} + +/////////////////////////////////////////////////////////////// +void D3D12GPUProfiler::EndFrame() +{ + if (!m_enable) return; + + m_pContext->End(m_pQueryDisjoint); + + while(m_pContext->GetData(m_pQueryDisjoint, &m_disjointData, sizeof(D3D11_QUERY_DATA_TIMESTAMP_DISJOINT), 0) != S_OK); +} + +/////////////////////////////////////////////////////////////// +float D3D12GPUProfiler::GetProfileData(int id) +{ + if (!m_enable) + return 0.0f; + + /* + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList(); + + UINT64 times[2]; + D3D12_RESOURCE_BARRIER barrier; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = query_result; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.Subresource = 0; + pCommandList->ResourceBarrier(1, &barrier); + + pCommandList->ResolveQueryData(query_heap, D3D12_QUERY_TYPE_TIMESTAMP, id * 2, 2, query_result, 0); + + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; + pCommandList->ResourceBarrier(1, &barrier); + + pCommandList->CopyResource(query_result_readback, query_result); + + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON; + pCommandList->ResourceBarrier(1, &barrier); + + void* pData; + ThrowIfFailed(query_result_readback->Map(0, 0, &pData)); + memcpy(times, pData, sizeof(UINT64) * 2); + query_result_readback->Unmap(0, 0); + */ + + UINT64 startTime = 0; + while(m_pContext->GetData(m_pQueryStart[id], &startTime, sizeof(UINT64), 0) != S_OK); + + UINT64 endTime = 0; + while(m_pContext->GetData(m_pQueryEnd[id], &endTime, sizeof(UINT64), 0) != S_OK); + + float frequency = static_cast<float>(m_disjointData.Frequency); + return (endTime - startTime) / frequency * 1000.0f; +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.h new file mode 100644 index 0000000..721b8a9 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12GPUProfiler.h @@ -0,0 +1,63 @@ +// 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-2015 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. +// + +#pragma once + +#include <d3d11.h> +/* +#include <d3d12.h> +*/ +#include "GPUProfiler.h" + +#define MAX_QUERY_COUNT 64 +struct D3D12GPUProfiler : public GPUProfiler +{ +public: + ~D3D12GPUProfiler(); + + void Initialize(); + void Release(); + void StartProfile(int id); + void EndProfile(int id); + void StartFrame(); + void EndFrame(); + float GetProfileData(int id); + +protected: + ID3D11Query* m_pQueryDisjoint; + ID3D11Query* m_pQueryStart[MAX_QUERY_COUNT]; + ID3D11Query* m_pQueryEnd[MAX_QUERY_COUNT]; + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT m_disjointData; + ID3D11DeviceContext* m_pContext; + /* + ID3D12QueryHeap* query_heap; + ID3D12Resource* query_result; + ID3D12Resource* query_result_readback; + */ +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.cpp new file mode 100644 index 0000000..8202139 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.cpp @@ -0,0 +1,564 @@ +#include "D3D12RenderContext.h" + +const int nBufferCount = 2; +//const int nBufferCount = 5; + +int nRenderTargetIndex = 1; +//int nRenderTargetIndex = 4; + +D3D12RenderContext::D3D12RenderContext() +{ + m_sampleCount = 1; +} + +D3D12RenderContext::~D3D12RenderContext() +{ +} + +D3D12RenderContext* D3D12RenderContext::Instance() +{ + static D3D12RenderContext ri; + return &ri; +} + +void GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) +{ + IDXGIAdapter1* pAdapter = nullptr; + *ppAdapter = nullptr; + + for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &pAdapter); ++adapterIndex) + { + DXGI_ADAPTER_DESC1 desc; + pAdapter->GetDesc1(&desc); + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + // Don't select the Basic Render Driver adapter. + // If you want a software adapter, pass in "/warp" on the command line. + continue; + } + + // Check to see if the adapter supports Direct3D 12, but don't create the + // actual device yet. + if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) + { + break; + } + } + + *ppAdapter = pAdapter; +} + +void D3D12RenderContext::InitDevice() +{ + UINT d3d11DeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; +#if defined(_DEBUG) + // Enable the D3D11 debug layer. + d3d11DeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; + // Enable the D3D12 debug layer. + { + ComPtr<ID3D12Debug> debugController; + if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) + { + debugController->EnableDebugLayer(); + } + } +#endif + + ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&m_factory))); + + GetHardwareAdapter(m_factory.Get(), &m_adapter); + + auto adapterDescription = DXGI_ADAPTER_DESC(); + m_adapter->GetDesc(&adapterDescription); + + D3D12CreateDevice(m_adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)); + if (nullptr == m_device) + { + ComPtr<IDXGIAdapter> warpAdapter; + ThrowIfFailed(m_factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter))); + ThrowIfFailed(D3D12CreateDevice(warpAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device))); + } + + // Describe and create the command queue. + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + + ThrowIfFailed(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue))); + + ThrowIfFailed(D3D11On12CreateDevice( + m_device.Get(), + d3d11DeviceFlags, nullptr, 0, + reinterpret_cast<IUnknown**>(m_commandQueue.GetAddressOf()), 1, 0, + &m_d3d11Device, + &m_d3d11DeviceContext, + nullptr )); + + ThrowIfFailed(m_d3d11Device.As(&m_d3d11On12Device)); +} + +void D3D12RenderContext::InitSwapchain(int nWidth, int nHeight, HWND hWnd) +{ + // Describe and create the swap chain. + DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; + swapChainDesc.BufferCount = nBufferCount; + swapChainDesc.BufferDesc.Width = nWidth; + swapChainDesc.BufferDesc.Height = nHeight; + swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapChainDesc.OutputWindow = hWnd; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.Windowed = TRUE; + + ComPtr<IDXGISwapChain> swapChain; + ThrowIfFailed(m_factory->CreateSwapChain( + m_commandQueue.Get(), // Swap chain needs the queue so that it can force a flush on it. + &swapChainDesc, + &swapChain + )); + + ThrowIfFailed(swapChain.As(&m_swapChain)); + + // This sample does not support fullscreen transitions. + // ThrowIfFailed(m_factory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER)); + + m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); + + ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocator))); + + // Create the command list. + ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), nullptr, IID_PPV_ARGS(&m_commandList))); + + m_pCurrentRenderTarget = new D3D12RenderTarget(0, nBufferCount); + m_pCurrentRenderTarget->OnCreate(nWidth, nHeight); + m_pCurrentRenderTarget->SetClearColor(0.5, 0.5, 0.5); + m_RenderTargetMap[0] = m_pCurrentRenderTarget; + + m_pD3D11RenderTargetView = new ID3D11RenderTargetView*[nBufferCount]; + m_wrappedBackBuffers = new ID3D11Resource*[nBufferCount]; + for (int n = 0; n < nBufferCount; n++) + { + m_pD3D11RenderTargetView[n] = nullptr; + m_wrappedBackBuffers[n] = nullptr; + } + + PostCreate(); +} + +#ifndef Safe_Release +#define Safe_Release(p) { if (p) { p->Release(); (p) = nullptr; } } +#endif // !Safe_Delete + +void D3D12RenderContext::ResizeSwapchain(int width, int height) +{ + D3D12RenderTarget* rt = m_RenderTargetMap[0]; + + for (int n = 0; n < nBufferCount; n++) + { + Safe_Release(m_pD3D11RenderTargetView[n]); + Safe_Release(m_wrappedBackBuffers[n]); + } + m_d3d11DeviceContext->Flush(); + + rt->OnDestroy(); + + ThrowIfFailed(m_swapChain->ResizeBuffers(nBufferCount, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, 0)); + + m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); + + rt->OnResize(width, height); + + for (int n = 0; n < nBufferCount; n++) + { + ID3D11On12Device* pDevice11On12 = GetDevice11On12(); + + D3D11_RESOURCE_FLAGS d3d11Flags = { D3D11_BIND_RENDER_TARGET }; + ThrowIfFailed(pDevice11On12->CreateWrappedResource( + rt->GetTexture(n, false), + &d3d11Flags, + D3D12_RESOURCE_STATE_RENDER_TARGET, + D3D12_RESOURCE_STATE_PRESENT, + IID_PPV_ARGS(&m_wrappedBackBuffers[n]))); + + ThrowIfFailed(m_d3d11Device->CreateRenderTargetView(m_wrappedBackBuffers[n], + NULL, &m_pD3D11RenderTargetView[n])); + } +} + +void D3D12RenderContext::PostCreate() +{ + m_srvUavHeap.Init(m_device.Get(), 256, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_FLAG_NONE); + + { + ThrowIfFailed(m_commandList->Close()); + ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() }; + m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); + } + + { + ThrowIfFailed(m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence))); + m_fenceValue = 1; + + // Create an event handle to use for frame synchronization. + m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + if (m_fenceEvent == nullptr) + { + ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); + } + + WaitForGpu(); + } +} + +void D3D12RenderContext::OnDestroy() +{ + WaitForGpu(); + if (nullptr != m_fenceEvent) + { + CloseHandle(m_fenceEvent); + m_fenceEvent = nullptr; + } + +#if 0 + ID3D12DebugDevice* debugInterface; + if (SUCCEEDED(m_device.Get()->QueryInterface(&debugInterface))) + { + debugInterface->ReportLiveDeviceObjects(D3D12_RLDO_DETAIL | D3D12_RLDO_IGNORE_INTERNAL); + debugInterface->Release(); + } +#endif // 0 +} + +void D3D12RenderContext::PreRender() +{ + ThrowIfFailed(m_commandAllocator->Reset()); + ThrowIfFailed(m_commandList->Reset(m_commandAllocator.Get(), nullptr)); +} + +void D3D12RenderContext::PostRender() +{ + ThrowIfFailed(m_commandList->Close()); + ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() }; + m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); + + OnGpuWorkSubmitted(m_commandQueue.Get()); + + WaitForGpu(); +} + +void D3D12RenderContext::SubmitGpuWork() +{ + ThrowIfFailed(m_commandList->Close()); + ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() }; + m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); + + ThrowIfFailed(m_commandList->Reset(m_commandAllocator.Get(), nullptr)); + + OnGpuWorkSubmitted(m_commandQueue.Get()); +} + + +void D3D12RenderContext::Flush() +{ + m_pCurrentRenderTarget->PostRender(); + PostRender(); + PreRender(); + m_pCurrentRenderTarget->PreRender(); +} + +void D3D12RenderContext::Present() +{ + ThrowIfFailed(m_swapChain->Present(1, 0)); + //ThrowIfFailed(m_swapChain->Present(0, 0)); + m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); + + //OnGpuWorkSubmitted(m_commandQueue.Get(), true); + //WaitForGpu(); +} + +int D3D12RenderContext::AllocRenderTargetIndex() +{ + return nRenderTargetIndex++; +} + + +void D3D12RenderContext::AddGpuInterface(GpuInterface* gpuIntf) +{ + m_gpuInterfaces.push_back(gpuIntf); +} + + +void D3D12RenderContext::OnGpuWorkSubmitted(ID3D12CommandQueue* queue) +{ + std::vector<GpuInterface*>::const_iterator cur = m_gpuInterfaces.begin(); + std::vector<GpuInterface*>::const_iterator end = m_gpuInterfaces.end(); + + for (; cur != end; cur++) + { + (*cur)->onGpuWorkSubmitted(queue); + } +} + +void D3D12RenderContext::UpdateGpuWorkCompleted() +{ + std::vector<GpuInterface*>::const_iterator cur = m_gpuInterfaces.begin(); + std::vector<GpuInterface*>::const_iterator end = m_gpuInterfaces.end(); + + for (; cur != end; cur++) + { + (*cur)->updateGpuWorkCompleted(); + } +} + +D3D12RenderTarget* D3D12RenderContext::CreateRenderTarget(int renderTargetIndex, int nWidth, int nHeight) +{ + D3D12RenderTarget* pRenderTarget = new D3D12RenderTarget(renderTargetIndex); + pRenderTarget->OnCreate(nWidth, nHeight); + m_RenderTargetMap[renderTargetIndex] = pRenderTarget; + return pRenderTarget; +} + +ID3D12Resource* D3D12RenderContext::GetTexture(int renderTargetIndex, int index) +{ + D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[renderTargetIndex]; + ID3D12Resource* pTexture = pRenderTarget->GetTexture(index); + return pTexture; +} + +void D3D12RenderContext::SetViewport(D3D12_VIEWPORT& vp) +{ + m_pCurrentRenderTarget->m_viewport = vp; + m_commandList->RSSetViewports(1, &vp); +} + +void D3D12RenderContext::GetViewport(D3D12_VIEWPORT& vp) +{ + vp = m_pCurrentRenderTarget->m_viewport; +} + +D3D12_RESOURCE_DESC D3D12RenderContext::GetBackBufferDesc() +{ + D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[0]; + ID3D12Resource* pResource = pRenderTarget->GetTexture(); + return pResource->GetDesc(); +} + +void D3D12RenderContext::SwitchToDX11() +{ + ReleaseRenderTarget(); + PostRender(); + + if (nullptr == m_wrappedBackBuffers[m_frameIndex]) + { + return; + } + + m_d3d11On12Device->AcquireWrappedResources(&m_wrappedBackBuffers[m_frameIndex], 1); + + m_d3d11DeviceContext->OMSetRenderTargets(1, &m_pD3D11RenderTargetView[m_frameIndex], nullptr); + D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[0]; + D3D11_VIEWPORT vp; + { + vp.TopLeftX = 0; + vp.TopLeftY = 0; + vp.Width = (float)pRenderTarget->m_viewport.Width; + vp.Height = (float)pRenderTarget->m_viewport.Height; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + } + m_d3d11DeviceContext->RSSetViewports(1, &vp); +} + +void D3D12RenderContext::FlushDX11() +{ + if (nullptr == m_wrappedBackBuffers[m_frameIndex]) + { + return; + } + + m_d3d11On12Device->ReleaseWrappedResources(&m_wrappedBackBuffers[m_frameIndex], 1); + m_d3d11DeviceContext->Flush(); +} + +ID3D12Resource* D3D12RenderContext::GetDepthStencilResource() +{ + D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[0]; + return pRenderTarget->GetDepthStencilResource(); +} + +D3D12_CPU_DESCRIPTOR_HANDLE D3D12RenderContext::GetRenderTargetViewHandle() +{ + D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[0]; + return pRenderTarget->GetRenderTargetViewHandle(); +} + +D3D12_CPU_DESCRIPTOR_HANDLE D3D12RenderContext::GetDepthStencilViewHandle() +{ + D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[0]; + return pRenderTarget->GetDepthStencilViewHandle(); +} + +void D3D12RenderContext::AcquireRenderTarget(bool doClear, int renderTargetIndex) +{ + m_pCurrentRenderTarget = m_RenderTargetMap[renderTargetIndex]; + m_pCurrentRenderTarget->PreRender(doClear); +} + +void D3D12RenderContext::ReleaseRenderTarget(int renderTargetIndex) +{ + D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[renderTargetIndex]; + pRenderTarget->PostRender(); +} + +void D3D12RenderContext::SetClearColor(int renderTargetIndex, float r, float g, float b, float a, float depth, float stencil) +{ + D3D12RenderTarget* pRenderTarget = m_RenderTargetMap[renderTargetIndex]; + pRenderTarget->SetClearColor(r, g, b, a, depth, stencil); +} + +void D3D12RenderContext::WaitForGpu() +{ + const UINT64 fence = m_fenceValue; + ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), fence)); + m_fenceValue++; + + // Wait until the previous frame is finished. + if (m_fence->GetCompletedValue() < fence) + { + ThrowIfFailed(m_fence->SetEventOnCompletion(fence, m_fenceEvent)); + WaitForSingleObject(m_fenceEvent, INFINITE); + } +} + +void D3D12RenderContext::InitBuffer(NVHairReadOnlyBuffer& buffer) +{ + buffer.Init(&m_srvUavHeap); +} + +void D3D12RenderContext::DestroyBuffer(NVHairReadOnlyBuffer& buffer) +{ + buffer.Release(); +} + +CD3DX12_CPU_DESCRIPTOR_HANDLE D3D12RenderContext::NVHairINT_CreateD3D12ReadOnlyBuffer( + UINT stride, + UINT numElements, + NVHairReadOnlyBuffer* pReadOnlyBuffer, + void* pSysMem) +{ + ID3D12Device* pd3dDevice = m_device.Get(); + ID3D12GraphicsCommandList* pCommandList = m_commandList.Get(); + + UINT bufferSize = numElements * stride; + + HRESULT hr; + hr = pd3dDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(bufferSize), + D3D12_RESOURCE_STATE_COPY_DEST, + nullptr, + IID_PPV_ARGS(pReadOnlyBuffer->m_pBuffer.ReleaseAndGetAddressOf())); + + hr = pd3dDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(bufferSize), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(pReadOnlyBuffer->m_pBufferUpload.ReleaseAndGetAddressOf())); + + D3D12_SUBRESOURCE_DATA data = {}; + data.pData = reinterpret_cast<UINT8*>(pSysMem); + data.RowPitch = bufferSize; + data.SlicePitch = data.RowPitch; + + PreRender(); + UpdateSubresources<1>(pCommandList, pReadOnlyBuffer->m_pBuffer.Get(), pReadOnlyBuffer->m_pBufferUpload.Get(), 0, 0, 1, &data); + pCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pReadOnlyBuffer->m_pBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)); + PostRender(); + + CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(pReadOnlyBuffer->m_pSrvUavHeap->m_pHeap.Get()->GetCPUDescriptorHandleForHeapStart(), pReadOnlyBuffer->m_srvIndex, pReadOnlyBuffer->m_pSrvUavHeap->m_sizeDescriptor); + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srvDesc.Format = DXGI_FORMAT_UNKNOWN; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + srvDesc.Buffer.FirstElement = 0; + srvDesc.Buffer.NumElements = numElements; + srvDesc.Buffer.StructureByteStride = stride; + srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; + pd3dDevice->CreateShaderResourceView(pReadOnlyBuffer->m_pBuffer.Get(), &srvDesc, srvHandle); + + return srvHandle; +} + +CD3DX12_CPU_DESCRIPTOR_HANDLE D3D12RenderContext::NVHairINT_CreateD3D12Texture(ID3D12Resource* pTexture, int& nIndexInHeap) +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE handle = {}; + + if (!pTexture) + return handle; + + ID3D12Device* pDevice = m_device.Get(); + if (!pDevice) + return handle; + + nIndexInHeap = m_srvUavHeap.allocate(); + if(nIndexInHeap == -1) + return handle; + + CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(m_srvUavHeap.m_pHeap.Get()->GetCPUDescriptorHandleForHeapStart(), + nIndexInHeap, m_srvUavHeap.m_sizeDescriptor); + + D3D12_RESOURCE_DESC desc = pTexture->GetDesc(); + + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srvDesc.Format = desc.Format; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = 1; + + pDevice->CreateShaderResourceView(pTexture, &srvDesc, srvHandle); + + return srvHandle; +} + +void D3D12RenderContext::NVHairINT_DestroyD3D12Texture(int& nIndexInHeap) +{ + if (nIndexInHeap != -1) + { + m_srvUavHeap.deallocate(nIndexInHeap); + } +} + +void D3D12RenderContext::SetSampleCount(int nSampleCount) +{ + m_sampleCount = 1; + + if (nSampleCount > D3D12_MAX_MULTISAMPLE_SAMPLE_COUNT) + nSampleCount = D3D12_MAX_MULTISAMPLE_SAMPLE_COUNT; + + if (nSampleCount > 1) + { + D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS qualityLevels; + qualityLevels.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + qualityLevels.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE; + qualityLevels.NumQualityLevels = 0; + qualityLevels.SampleCount = nSampleCount; + + ID3D12Device *pDevice = GetDevice(); + pDevice->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &qualityLevels, sizeof(qualityLevels)); + + if (qualityLevels.NumQualityLevels > 0) + { + m_sampleCount = qualityLevels.SampleCount; + } + } +} + +int D3D12RenderContext::GetSampleCount() +{ + return m_sampleCount; +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.h new file mode 100644 index 0000000..2e0b393 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderContext.h @@ -0,0 +1,254 @@ +#pragma once + +#include "D3D12RenderTarget.h" +#include "RenderPlugin.h" + +#include "d3dx12.h" +#include <wrl.h> +using namespace Microsoft::WRL; + +struct NVHairHeap +{ + ComPtr<ID3D12DescriptorHeap> m_pHeap; + UINT m_sizeHeap; + UINT m_currentIndex; + UINT m_sizeDescriptor; + std::vector<UINT> m_availableIndexes; + + void Init(ID3D12Device* pd3dDevice, UINT size, D3D12_DESCRIPTOR_HEAP_TYPE type, D3D12_DESCRIPTOR_HEAP_FLAGS flags) + { + HRESULT hr; + + D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {}; + srvHeapDesc.NumDescriptors = size; + srvHeapDesc.Flags = flags; + srvHeapDesc.Type = type; + hr = pd3dDevice->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(m_pHeap.ReleaseAndGetAddressOf())); + + if (SUCCEEDED(hr)) + { + m_sizeHeap = size; + m_sizeDescriptor = pd3dDevice->GetDescriptorHandleIncrementSize(type); + } + else + { + m_sizeHeap = 0; + m_sizeDescriptor = 0; + } + m_currentIndex = 0; + m_availableIndexes.clear(); + } + + UINT allocate() + { + int availables = m_availableIndexes.size(); + if (availables > 0) + { + UINT index = m_availableIndexes[availables - 1]; + m_availableIndexes.pop_back(); + return index; + } + UINT index = m_currentIndex++; + if (m_sizeHeap > m_currentIndex) + return index; + return (UINT)-1; + } + + void deallocate(UINT availableIndex) + { + m_availableIndexes.push_back(availableIndex); + } + + void Release() + { + if (m_pHeap) m_pHeap = nullptr; + m_sizeHeap = 0; + m_currentIndex = 0; + m_sizeDescriptor = 0; + m_availableIndexes.clear(); + } +}; + +struct NVHairVertexBuffer +{ + ComPtr<ID3D12Resource> m_pBuffer; + ComPtr<ID3D12Resource> m_pBufferUpload; + D3D12_VERTEX_BUFFER_VIEW m_vertexBufferView; + NVHairHeap* m_pSrvUavHeap; + UINT m_uavIndex; + + void Init(NVHairHeap* pHeap) + { + m_pBuffer = nullptr; + m_pBufferUpload = nullptr; + memset(&m_vertexBufferView, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW)); + m_pSrvUavHeap = pHeap; + + m_uavIndex = m_pSrvUavHeap->allocate(); + } + + D3D12_CPU_DESCRIPTOR_HANDLE getUavCpuHandle() + { + CD3DX12_CPU_DESCRIPTOR_HANDLE uavHandle(m_pSrvUavHeap->m_pHeap.Get()->GetCPUDescriptorHandleForHeapStart(), m_uavIndex, m_pSrvUavHeap->m_sizeDescriptor); + return uavHandle; + } + + void Release() + { + if (m_pBuffer) m_pBuffer = nullptr; + if (m_pBufferUpload) m_pBufferUpload = nullptr; + memset(&m_vertexBufferView, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW)); + if (m_pSrvUavHeap) m_pSrvUavHeap = nullptr; + m_uavIndex = (UINT)-1; + } +}; + +struct NVHairReadOnlyBuffer +{ + ComPtr<ID3D12Resource> m_pBuffer; + ComPtr<ID3D12Resource> m_pBufferUpload; + NVHairHeap* m_pSrvUavHeap; + UINT m_srvIndex; + + void Init(NVHairHeap* pHeap) + { + m_pBuffer = nullptr; + m_pBufferUpload = nullptr; + m_pSrvUavHeap = pHeap; + + m_srvIndex = m_pSrvUavHeap->allocate(); + } + + CD3DX12_CPU_DESCRIPTOR_HANDLE getSrvCpuHandle() + { + CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(m_pSrvUavHeap->m_pHeap.Get()->GetCPUDescriptorHandleForHeapStart(), m_srvIndex, m_pSrvUavHeap->m_sizeDescriptor); + return srvHandle; + } + + void Release() + { + m_pSrvUavHeap->deallocate(m_srvIndex); + + if (m_pBuffer) m_pBuffer = nullptr; + if (m_pBufferUpload) m_pBufferUpload = nullptr; + if (m_pSrvUavHeap) m_pSrvUavHeap = nullptr; + m_srvIndex = (UINT)-1; + } +}; + +class CORERENDER_EXPORT D3D12RenderContext +{ +public: + ~D3D12RenderContext(); + static D3D12RenderContext* Instance(); + + class GpuInterface + { + public: + virtual void onGpuWorkSubmitted(ID3D12CommandQueue* queue) = 0; + virtual void updateGpuWorkCompleted() = 0; + virtual ~GpuInterface() {} + }; + + typedef void (*GpuWorkSubmitFunc)(ID3D12CommandQueue* queue, void* data); + typedef void (*GpuUpdateCompletedFunc)(void* data); + + void InitDevice(); + void InitSwapchain(int width, int height, HWND hWnd); + void ResizeSwapchain(int width, int height); + void PostCreate(); + + void OnDestroy(); + + void PreRender(); + void PostRender(); + void Flush(); + + void SubmitGpuWork(); + void WaitForGpu(); + + void UpdateGpuWorkCompleted(); + + void Present(); + + int AllocRenderTargetIndex(); + D3D12RenderTarget* CreateRenderTarget(int renderTargetIndex, int nWidth, int nHeight); + void SetClearColor(int renderTargetIndex, float r, float g, float b, float a = 1.0, float depth = 1.0, float stencil = 0.0); + void AcquireRenderTarget(bool doClear = false, int renderTargetIndex = 0); + void ReleaseRenderTarget(int renderTargetIndex = 0); + ID3D12Resource* GetTexture(int renderTargetIndex, int index = 0); + void SetViewport(D3D12_VIEWPORT& vp); + void GetViewport(D3D12_VIEWPORT& vp); + + ID3D12Device* GetDevice() { return m_device.Get(); } + ID3D12GraphicsCommandList* GetGraphicsCommandList() { return m_commandList.Get(); } + ID3D12CommandQueue* GetCommandQueue() const { return m_commandQueue.Get(); } + + IDXGISwapChain3* GetSwapChain() { return m_swapChain.Get(); } + UINT GetFrameIndex() { return m_frameIndex; } + + ID3D11Device* GetDevice11() { return m_d3d11Device.Get(); } + ID3D11On12Device* GetDevice11On12() { return m_d3d11On12Device.Get(); } + ID3D11DeviceContext* GetDeviceContext() { return m_d3d11DeviceContext.Get(); } + + D3D12_RESOURCE_DESC GetBackBufferDesc(); + void SwitchToDX11(); + void FlushDX11(); + + ID3D12Resource* GetDepthStencilResource(); + D3D12_CPU_DESCRIPTOR_HANDLE GetRenderTargetViewHandle(); + D3D12_CPU_DESCRIPTOR_HANDLE GetDepthStencilViewHandle(); + + void InitBuffer(NVHairReadOnlyBuffer& buffer); + void DestroyBuffer(NVHairReadOnlyBuffer& buffer); + + CD3DX12_CPU_DESCRIPTOR_HANDLE NVHairINT_CreateD3D12ReadOnlyBuffer( + UINT stride, + UINT numElements, + NVHairReadOnlyBuffer* pReadOnlyBuffer, + void* pSysMem); + + CD3DX12_CPU_DESCRIPTOR_HANDLE NVHairINT_CreateD3D12Texture(ID3D12Resource* pTexture, int& nIndexInHeap); + void NVHairINT_DestroyD3D12Texture(int& nIndexInHeap); + + void SetSampleCount(int nSampleCount); + int GetSampleCount(); + + void AddGpuInterface(GpuInterface* intf); + +private: + void OnGpuWorkSubmitted(ID3D12CommandQueue* queue); + + D3D12RenderContext(); + + ComPtr<IDXGIFactory4> m_factory; + ComPtr<IDXGIAdapter1> m_adapter; + + ComPtr<ID3D12Device> m_device; + ComPtr<ID3D12CommandQueue> m_commandQueue; + ComPtr<ID3D12CommandAllocator> m_commandAllocator; + ComPtr<ID3D12GraphicsCommandList> m_commandList; + ComPtr<IDXGISwapChain3> m_swapChain; + + ComPtr<ID3D11Device> m_d3d11Device; + ComPtr<ID3D11On12Device> m_d3d11On12Device; + ComPtr<ID3D11DeviceContext> m_d3d11DeviceContext; + ID3D11Resource** m_wrappedBackBuffers; + ID3D11RenderTargetView** m_pD3D11RenderTargetView; + + UINT m_frameIndex; + HANDLE m_fenceEvent; + ComPtr<ID3D12Fence> m_fence; + UINT64 m_fenceValue; + + D3D12RenderTarget* m_pCurrentRenderTarget; + map<int, D3D12RenderTarget*> m_RenderTargetMap; + + std::vector<GpuInterface*> m_gpuInterfaces; + + NVHairHeap m_srvUavHeap; + + // sample desc + UINT m_sampleCount; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.cpp new file mode 100644 index 0000000..2346683 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.cpp @@ -0,0 +1,467 @@ +// 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. +// +#include "D3D12RenderInterface.h" + +#include "D3D12TextureResource.h" +#include "D3D12Shaders.h" +#include "D3D12Buffer.h" + +#include "D3D12RenderContext.h" + +namespace RenderInterfaceD3D12 +{ + using namespace RenderInterface; + + D3D12_BLEND_DESC m_BlendStates[BLEND_STATE_END]; + D3D12_DEPTH_STENCIL_DESC m_DepthStencilStates[DEPTH_STENCIL_STATE_END]; + D3D12_RASTERIZER_DESC m_RasterizerStates[RASTERIZER_STATE_END]; + + D3D12RenderContext *pRenderContext = D3D12RenderContext::Instance(); + + SHADER_TYPE m_ShaderType; + RenderShaderStateKey m_ShaderStateKey; + + map<RenderShaderStateKey, RenderShaderState*> m_RenderShaderStates; + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +bool InitDevice(int deviceID) +{ + pRenderContext->InitDevice(); + return true; +} + +////////////////////////////////////////////////////////////////////////// +bool Initialize() +{ + if (!pRenderContext) + return false; + + InitializeShadersD3D12(); + InitializeRenderStates(); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +void Shutdown() +{ + DestroyShadersD3D12(); +} + +RenderShaderState* GetShaderState() +{ + RenderShaderState* pShaderState = nullptr; + map<RenderShaderStateKey, RenderShaderState*>::iterator it = m_RenderShaderStates.find(m_ShaderStateKey); + if (it != m_RenderShaderStates.end()) + { + pShaderState = it->second; + } + else + { + pShaderState = new RenderShaderState; + pShaderState->BlendState = m_BlendStates[m_ShaderStateKey.BlendState]; + pShaderState->DepthStencilState = m_DepthStencilStates[m_ShaderStateKey.DepthStencilState]; + pShaderState->RasterizerState = m_RasterizerStates[m_ShaderStateKey.RasterizerState]; + pShaderState->PrimitiveTopologyType = m_ShaderStateKey.PrimitiveTopologyType; + if (m_ShaderStateKey.ForShadow) + { + pShaderState->RTVFormat = DXGI_FORMAT_R32_FLOAT; + pShaderState->DSVFormat = DXGI_FORMAT_D32_FLOAT; + } + else + { + pShaderState->RTVFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + pShaderState->DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; + pShaderState->SampleCount = D3D12RenderContext::Instance()->GetSampleCount(); + } + + m_RenderShaderStates[m_ShaderStateKey] = pShaderState; + } + return pShaderState; +} +////////////////////////////////////////////////////////////////////////////////////// +void InitializeRenderStates() +{ + ///////////////////////////////////////////////////////////////////////////////////////// + // alpha blending state descriptors + ///////////////////////////////////////////////////////////////////////////////////////// + + // alpha blending enabled + { + D3D12_BLEND_DESC desc = CD3DX12_BLEND_DESC(D3D12_DEFAULT); + desc.AlphaToCoverageEnable = false; + desc.IndependentBlendEnable = false; + + D3D12_RENDER_TARGET_BLEND_DESC &rtDesc = desc.RenderTarget[0]; + { + rtDesc.BlendEnable = true; + rtDesc.SrcBlend = D3D12_BLEND_SRC_ALPHA; + rtDesc.DestBlend = D3D12_BLEND_INV_SRC_ALPHA; + rtDesc.BlendOp = D3D12_BLEND_OP_ADD; + rtDesc.SrcBlendAlpha = D3D12_BLEND_ZERO; + rtDesc.DestBlendAlpha = D3D12_BLEND_ONE; + rtDesc.BlendOpAlpha = D3D12_BLEND_OP_ADD; + rtDesc.RenderTargetWriteMask = 0x0f; + } + m_BlendStates[BLEND_STATE_ALPHA] = desc; + } + + // no alpha blending + { + D3D12_BLEND_DESC desc = CD3DX12_BLEND_DESC(D3D12_DEFAULT); + desc.AlphaToCoverageEnable = false; + desc.IndependentBlendEnable = false; + + D3D12_RENDER_TARGET_BLEND_DESC &rtDesc = desc.RenderTarget[0]; + { + rtDesc.BlendEnable = false; + rtDesc.SrcBlend = D3D12_BLEND_SRC_ALPHA; + rtDesc.DestBlend = D3D12_BLEND_INV_SRC_ALPHA; + rtDesc.BlendOp = D3D12_BLEND_OP_ADD; + rtDesc.SrcBlendAlpha = D3D12_BLEND_ZERO; + rtDesc.DestBlendAlpha = D3D12_BLEND_ONE; + rtDesc.BlendOpAlpha = D3D12_BLEND_OP_ADD; + rtDesc.RenderTargetWriteMask = 0x0f; + } + m_BlendStates[BLEND_STATE_NONE] = desc; + } + + ////////////////////////////////////////////////////////////////////////////////////////////// + // depth and stencil + /////////////////////////////////////////////////////////////////////////////////////////////// + D3D12_DEPTH_STENCIL_DESC depthTestDesc = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); + { + depthTestDesc.DepthEnable = true; + depthTestDesc.DepthFunc = D3D12_COMPARISON_FUNC_LESS; + depthTestDesc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + depthTestDesc.StencilEnable = false; + depthTestDesc.StencilReadMask = 0xff; + depthTestDesc.StencilWriteMask = 0xff; + } + + m_DepthStencilStates[DEPTH_STENCIL_DEPTH_TEST] = depthTestDesc; + + D3D12_DEPTH_STENCIL_DESC depthNone = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); + { + depthNone.DepthEnable = false; + depthNone.DepthFunc = D3D12_COMPARISON_FUNC_LESS; + depthNone.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO; + depthNone.StencilEnable = false; + depthNone.StencilReadMask = 0xff; + depthNone.StencilWriteMask = 0xff; + } + + m_DepthStencilStates[DEPTH_STENCIL_DEPTH_NONE] = depthNone; + + ////////////////////////////////////////////////////////////////////////////////////////////// + // rasterizer + /////////////////////////////////////////////////////////////////////////////////////////////// + D3D12_RASTERIZER_DESC rsDesc = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); + + // solid cull front + { + rsDesc.FillMode = D3D12_FILL_MODE_SOLID; + rsDesc.CullMode = D3D12_CULL_MODE_FRONT; + rsDesc.AntialiasedLineEnable = false; + rsDesc.MultisampleEnable = true; + rsDesc.FrontCounterClockwise = true; + rsDesc.DepthBias = 10; + rsDesc.DepthBiasClamp = 0; + rsDesc.SlopeScaledDepthBias = 0; + rsDesc.DepthClipEnable = true; + rsDesc.ForcedSampleCount = 0; + + m_RasterizerStates[RASTERIZER_STATE_FILL_CULL_FRONT] = rsDesc; + }; + + // solid cull back + { + rsDesc.FillMode = D3D12_FILL_MODE_SOLID; + rsDesc.CullMode = D3D12_CULL_MODE_BACK; + rsDesc.AntialiasedLineEnable = false; + rsDesc.MultisampleEnable = true; + rsDesc.FrontCounterClockwise = true; + rsDesc.DepthBias = 10; + rsDesc.DepthBiasClamp = 0; + rsDesc.SlopeScaledDepthBias = 0; + rsDesc.DepthClipEnable = true; + rsDesc.ForcedSampleCount = 0; + + m_RasterizerStates[RASTERIZER_STATE_FILL_CULL_BACK] = rsDesc; + } + + // solid cull none + { + rsDesc.FillMode = D3D12_FILL_MODE_SOLID; + rsDesc.CullMode = D3D12_CULL_MODE_NONE; + rsDesc.AntialiasedLineEnable = false; + rsDesc.MultisampleEnable = true; + rsDesc.FrontCounterClockwise = true; + rsDesc.DepthBias = 10; + rsDesc.DepthBiasClamp = 0; + rsDesc.SlopeScaledDepthBias = 0; + rsDesc.DepthClipEnable = true; + rsDesc.ForcedSampleCount = 0; + + m_RasterizerStates[RASTERIZER_STATE_FILL_CULL_NONE] = rsDesc; + } + + // wireframe cull none + { + rsDesc.FillMode = D3D12_FILL_MODE_WIREFRAME; + rsDesc.CullMode = D3D12_CULL_MODE_NONE; + rsDesc.AntialiasedLineEnable = false; + rsDesc.MultisampleEnable = true; + rsDesc.FrontCounterClockwise = 0; + rsDesc.DepthBias = 0; + rsDesc.DepthBiasClamp = 0; + rsDesc.SlopeScaledDepthBias = 0; + rsDesc.DepthClipEnable = true; + rsDesc.ForcedSampleCount = 0; + }; + + m_RasterizerStates[RASTERIZER_STATE_WIRE] = rsDesc; +} + +////////////////////////////////////////////////////////////////////////////////////// +void SetPrimitiveTopologyTriangleStrip() +{ + ID3D12GraphicsCommandList* pCommandList = pRenderContext->GetGraphicsCommandList(); + pCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); +} + +////////////////////////////////////////////////////////////////////////////////////// +void SetPrimitiveTopologyTriangleList() +{ + ID3D12GraphicsCommandList* pCommandList = pRenderContext->GetGraphicsCommandList(); + pCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); +} + +////////////////////////////////////////////////////////////////////////////////////// +void SetPrimitiveTopologyLineList() +{ + ID3D12GraphicsCommandList* pCommandList = pRenderContext->GetGraphicsCommandList(); + pCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_LINELIST); +} + +////////////////////////////////////////////////////////////////////////////////////// +void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset) +{ + D3D12_VERTEX_BUFFER_VIEW* vertexView = GPUBufferD3D12::GetVertexView(pBuffer); + if (!vertexView) + return; + + vertexView->StrideInBytes = stride; + ID3D12GraphicsCommandList* m_commandList = pRenderContext->GetGraphicsCommandList(); + m_commandList->IASetVertexBuffers(0, 1, vertexView); +} + +/////////////////////////////////////////////////////////////////////////////// +void ApplyDepthStencilState(DEPTH_STENCIL_STATE state) +{ + m_ShaderStateKey.DepthStencilState = state; +} + +/////////////////////////////////////////////////////////////////////////////// +void ApplyRasterizerState(RASTERIZER_STATE state) +{ + m_ShaderStateKey.RasterizerState = state; +} + +/////////////////////////////////////////////////////////////////////////////// +void ApplyBlendState(BLEND_STATE state) +{ + m_ShaderStateKey.BlendState = state; +} + +void ApplyPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType) +{ + m_ShaderStateKey.PrimitiveTopologyType = PrimitiveTopologyType; +} + +void ApplyForShadow(int ForShadow) +{ + m_ShaderStateKey.ForShadow = ForShadow; +} + +void SwitchToDX11() +{ + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + pContext->SwitchToDX11(); +} + +void FlushDX11() +{ + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + pContext->FlushDX11(); +} + +void FlushDX12() +{ + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + pContext->Flush(); +} + +void SubmitGpuWork() +{ + D3D12RenderContext::Instance()->SubmitGpuWork(); +} + +void WaitForGpu() +{ + D3D12RenderContext* context = D3D12RenderContext::Instance(); + context->WaitForGpu(); + context->UpdateGpuWorkCompleted(); +} + +///////////////////////////////////////////////////////////////////////////////////////// +void SetViewport(const RenderInterface::Viewport& vp) +{ + ID3D12GraphicsCommandList* pCommandList = pRenderContext->GetGraphicsCommandList(); + + D3D12_VIEWPORT d3dViewport; + + d3dViewport.TopLeftX = vp.TopLeftX; + d3dViewport.TopLeftY = vp.TopLeftY; + + d3dViewport.Width = vp.Width; + d3dViewport.Height = vp.Height; + + d3dViewport.MinDepth = vp.MinDepth; + d3dViewport.MaxDepth = vp.MaxDepth; + + pRenderContext->SetViewport(d3dViewport); +} + +///////////////////////////////////////////////////////////////////////////////////////// +void GetViewport(RenderInterface::Viewport& vp) +{ + D3D12_VIEWPORT d3dViewport; + pRenderContext->GetViewport(d3dViewport); + + vp.TopLeftX = d3dViewport.TopLeftX; + vp.TopLeftY = d3dViewport.TopLeftY; + + vp.Width = d3dViewport.Width; + vp.Height = d3dViewport.Height; + + vp.MinDepth = d3dViewport.MinDepth; + vp.MaxDepth = d3dViewport.MaxDepth; +} + +/////////////////////////////////////////////////////////////////////////////// +void Draw(unsigned int vertexCount, unsigned int startCount) +{ + ID3D12GraphicsCommandList* pCommandList = pRenderContext->GetGraphicsCommandList(); + pCommandList->DrawInstanced(vertexCount, 1, startCount, 0); +} + +/////////////////////////////////////////////////////////////////////////////// +GPUBufferResource* CreateVertexBuffer( + unsigned int ByteWidth, void* pSysMem) +{ + ID3D12Device* pDevice = D3D12RenderContext::Instance()->GetDevice(); + if (!pDevice) + return false; + + ID3D12Resource* pBuffer = nullptr; + ThrowIfFailed(pDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(ByteWidth), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&pBuffer))); + if (nullptr == pBuffer) + { + return false; + } + + void* pData; + ThrowIfFailed(pBuffer->Map(0, nullptr, &pData)); + memcpy(pData, pSysMem, ByteWidth); + pBuffer->Unmap(0, nullptr); + + return GPUBufferD3D12::Create(pBuffer, ByteWidth); +} + +/////////////////////////////////////////////////////////////////////////////// +GPUShaderResource* CreateShaderResource(unsigned int stride, + unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer) +{ + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + if (!pContext) + return false; + + ID3D12Device* pDevice = pContext->GetDevice(); + ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList(); + + pContext->NVHairINT_CreateD3D12ReadOnlyBuffer(stride, numElements, pReadOnlyBuffer, pSysMem); + + int nIndexInHeap = -1; + return D3D12TextureResource::Create(pReadOnlyBuffer->m_pBuffer.Get(), pReadOnlyBuffer->getSrvCpuHandle(), nIndexInHeap); +} + +/////////////////////////////////////////////////////////////////////////////// +// create read only shader resource buffer +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +void CopyToDevice( + GPUBufferResource *pGPUBuffer, void* pSysMem, unsigned int ByteWidth) +{ + ID3D12Resource* pBuffer = GPUBufferD3D12::GetResource(pGPUBuffer); + if (!pBuffer) + return; + + void* pData; + ThrowIfFailed(pBuffer->Map(0, nullptr, &pData)); + memcpy(pData, pSysMem, ByteWidth); + pBuffer->Unmap(0, nullptr); + + /* + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + if (!pContext) + return; + + ID3D12Device* pDevice = pContext->GetDevice(); + ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList(); + + D3D12_SUBRESOURCE_DATA data = {}; + data.pData = reinterpret_cast<UINT8*>(pSysMem); + data.RowPitch = ByteWidth; + data.SlicePitch = data.RowPitch; + + ID3D12Resource* m_pBufferUpload = GPUBufferD3D12::GetResourceUpload(pGPUBuffer, pDevice, ByteWidth); + + UpdateSubresources<1>(pCommandList, pBuffer, m_pBufferUpload, 0, 0, 1, &data); + pCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pBuffer, + D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)); + */ +} +} // end namespace diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.h new file mode 100644 index 0000000..8168936 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderInterface.h @@ -0,0 +1,74 @@ +// 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. +// + +#pragma once +#include <d3d11.h> +#include <d3d12.h> +#include <dxgi1_4.h> +#include "RenderInterface.h" +#include "RenderPlugin.h" +class RenderShaderState; +// abstract interface to D3D calls +namespace RenderInterfaceD3D12 +{ + CORERENDER_EXPORT bool InitDevice(int deviceID); + CORERENDER_EXPORT bool Initialize(); + CORERENDER_EXPORT void Shutdown(); + + RenderShaderState* GetShaderState(); + void InitializeRenderStates(); + + CORERENDER_EXPORT void ApplyDepthStencilState(RenderInterface::DEPTH_STENCIL_STATE st); + CORERENDER_EXPORT void ApplyRasterizerState(RenderInterface::RASTERIZER_STATE st); + CORERENDER_EXPORT void ApplyBlendState(RenderInterface::BLEND_STATE st); + CORERENDER_EXPORT void ApplyPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType); + CORERENDER_EXPORT void ApplyForShadow(int ForShadow); + CORERENDER_EXPORT void SwitchToDX11(); + CORERENDER_EXPORT void FlushDX11(); + CORERENDER_EXPORT void FlushDX12(); + CORERENDER_EXPORT void SubmitGpuWork(); + CORERENDER_EXPORT void WaitForGpu(); + + CORERENDER_EXPORT void GetViewport(RenderInterface::Viewport& vp); + CORERENDER_EXPORT void SetViewport(const RenderInterface::Viewport& vp); + + CORERENDER_EXPORT GPUBufferResource* CreateVertexBuffer( unsigned int ByteWidth, void* pSysMem); + CORERENDER_EXPORT GPUShaderResource* CreateShaderResource( unsigned int stride, unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer); + + CORERENDER_EXPORT void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth); + + CORERENDER_EXPORT void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset = 0); + + CORERENDER_EXPORT void SetPrimitiveTopologyTriangleStrip(); + CORERENDER_EXPORT void SetPrimitiveTopologyTriangleList(); + CORERENDER_EXPORT void SetPrimitiveTopologyLineList(); + + + CORERENDER_EXPORT void Draw(unsigned int vertexCount, unsigned int startCount = 0); +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.cpp new file mode 100644 index 0000000..f115349 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.cpp @@ -0,0 +1,384 @@ +// 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-2015 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. +// + +#include "D3D12RenderShader.h" + +#include "D3D12RenderInterface.h" +#include "D3D12Wrapper.h" +#include "D3D12RenderContext.h" +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(x) { if (x) x->Release(); } +#endif + +/////////////////////////////////////////////////////////////////////////////// +D3D12RenderShader::D3D12RenderShader() +{ + m_vertexShader = 0; + m_vertexShaderSize = 0; + m_pixelShader = 0; + m_pixelShaderSize = 0; + + m_inputElementDescs = 0; + m_inputElementDescsNum = 0; + + m_pRootSignature = 0; + + m_scuHeap = 0; + m_scuDescriptorSize = 0; + + m_samplerHeap = 0; + m_samplerDescriptorSize = 0; + + m_PipelineStates.clear(); + + for (int i = 0; i < 2; i++) + { + m_ConstantBuffer[i] = nullptr; + } +} + +/////////////////////////////////////////////////////////////////////////////// +D3D12RenderShader::~D3D12RenderShader() +{ + for (int i = 0; i < 1; i++) + { + SAFE_RELEASE(m_ConstantBuffer[i]); + } +} + +/////////////////////////////////////////////////////////////////////////////// +D3D12RenderShader* D3D12RenderShader::Create( + const char *name, + void* vertexShader, size_t vertexShaderSize, void* pixelShader, size_t pixelShaderSize, + UINT cbufferSize0, UINT cbufferSize1, + D3D12_INPUT_ELEMENT_DESC* pElemDesc, UINT numElements, + int ShaderResourceNum, int UnorderedAccessNum, int SamplerNum) +{ + D3D12RenderContext* pAdapter = D3D12RenderContext::Instance(); + ID3D12Device* m_device = pAdapter->GetDevice(); + + D3D12RenderShader* pShader = new D3D12RenderShader; + + int sizeofuint = sizeof(UINT8); + pShader->m_vertexShaderSize = vertexShaderSize; + if (vertexShaderSize > 0) + { + pShader->m_vertexShader = new UINT8[vertexShaderSize / sizeofuint]; + memcpy(pShader->m_vertexShader, vertexShader, vertexShaderSize); + } + pShader->m_pixelShaderSize = pixelShaderSize; + if (pixelShaderSize > 0) + { + pShader->m_pixelShader = new UINT8[pixelShaderSize / sizeofuint]; + memcpy(pShader->m_pixelShader, pixelShader, pixelShaderSize); + } + + pShader->m_inputElementDescsNum = numElements; + pShader->m_inputElementDescs = pElemDesc; + + CD3DX12_DESCRIPTOR_RANGE ranges[3]; + CD3DX12_ROOT_PARAMETER rootParameters[2]; + + int rangesindex = 0; + int rootParametersindex = 0; + + if (ShaderResourceNum > 0) + { + ranges[rangesindex++].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, ShaderResourceNum, 0); + } + int ConstantBufferNum = 0; + if (cbufferSize0 > 0) + { + ConstantBufferNum++; + } + if (cbufferSize1 > 0) + { + ConstantBufferNum++; + } + if (ConstantBufferNum > 0) + { + ranges[rangesindex++].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, ConstantBufferNum, 0); + } + if (UnorderedAccessNum > 0) + { + ranges[rangesindex++].Init(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, UnorderedAccessNum, 0); + } + if (rangesindex > 0) + { + rootParameters[rootParametersindex++].InitAsDescriptorTable(rangesindex, &ranges[0], D3D12_SHADER_VISIBILITY_ALL); + } + + if (SamplerNum > 0) + { + ranges[rangesindex].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, SamplerNum, 0); + rootParameters[rootParametersindex++].InitAsDescriptorTable(1, &ranges[rangesindex], D3D12_SHADER_VISIBILITY_ALL); + } + + D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags = + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | + D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS; + CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; + rootSignatureDesc.Init(rootParametersindex, rootParameters, 0, nullptr, rootSignatureFlags); + + ComPtr<ID3DBlob> signature; + ComPtr<ID3DBlob> error; + ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); + ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&pShader->m_pRootSignature))); + + int numSCU = ShaderResourceNum + ConstantBufferNum + UnorderedAccessNum; + if (numSCU > 0) + { + D3D12_DESCRIPTOR_HEAP_DESC scuHeapDesc = {}; + scuHeapDesc.NumDescriptors = numSCU; + scuHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + scuHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + ThrowIfFailed(m_device->CreateDescriptorHeap(&scuHeapDesc, IID_PPV_ARGS(&pShader->m_scuHeap))); + pShader->m_scuDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + if (ConstantBufferNum > 0) + { + CD3DX12_CPU_DESCRIPTOR_HANDLE scuHandle(pShader->m_scuHeap->GetCPUDescriptorHandleForHeapStart(), + ShaderResourceNum, pShader->m_scuDescriptorSize); + + if (cbufferSize0 > 0) + { + pShader->CreateParamBuffer(cbufferSize0, 0); + + // Describe and create a constant buffer view. + D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {}; + // CB size is required to be 256-byte aligned. + cbvDesc.SizeInBytes = (cbufferSize0 + 255) & ~255; + cbvDesc.BufferLocation = pShader->m_ConstantBuffer[0]->GetGPUVirtualAddress(); + m_device->CreateConstantBufferView(&cbvDesc, scuHandle); + scuHandle.Offset(pShader->m_scuDescriptorSize); + } + if (cbufferSize1 > 0) + { + pShader->CreateParamBuffer(cbufferSize1, 1); + + // Describe and create a constant buffer view. + D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {}; + // CB size is required to be 256-byte aligned. + cbvDesc.SizeInBytes = (cbufferSize1 + 255) & ~255; + cbvDesc.BufferLocation = pShader->m_ConstantBuffer[1]->GetGPUVirtualAddress(); + m_device->CreateConstantBufferView(&cbvDesc, scuHandle); + } + } + } + + if (SamplerNum > 0) + { + D3D12_DESCRIPTOR_HEAP_DESC samplerHeapDesc = {}; + samplerHeapDesc.NumDescriptors = SamplerNum; + samplerHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; + samplerHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + ThrowIfFailed(m_device->CreateDescriptorHeap(&samplerHeapDesc, IID_PPV_ARGS(&pShader->m_samplerHeap))); + pShader->m_samplerDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + + CD3DX12_CPU_DESCRIPTOR_HANDLE samplerHandle(pShader->m_samplerHeap->GetCPUDescriptorHandleForHeapStart()); + + if(SamplerNum == 1) + { + D3D12_SAMPLER_DESC pointClampSamplerDesc[1] = { + D3D12_FILTER_MIN_MAG_MIP_POINT, + D3D12_TEXTURE_ADDRESS_MODE_CLAMP, + D3D12_TEXTURE_ADDRESS_MODE_CLAMP, + D3D12_TEXTURE_ADDRESS_MODE_CLAMP, + 0.0, 0, D3D12_COMPARISON_FUNC_NEVER, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, D3D12_FLOAT32_MAX, + }; + m_device->CreateSampler(pointClampSamplerDesc, samplerHandle); + } + else if(SamplerNum == 2) + { + D3D12_SAMPLER_DESC linearSamplerDesc[1] = { + D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT, + D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE_WRAP, + 0.0, 0, D3D12_COMPARISON_FUNC_NEVER, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, D3D12_FLOAT32_MAX, + }; + m_device->CreateSampler(linearSamplerDesc, samplerHandle); + samplerHandle.Offset(pShader->m_samplerDescriptorSize); + + D3D12_SAMPLER_DESC pointClampSamplerDesc[1] = { + D3D12_FILTER_MIN_MAG_MIP_POINT, + D3D12_TEXTURE_ADDRESS_MODE_CLAMP, + D3D12_TEXTURE_ADDRESS_MODE_CLAMP, + D3D12_TEXTURE_ADDRESS_MODE_CLAMP, + 0.0, 0, D3D12_COMPARISON_FUNC_NEVER, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, D3D12_FLOAT32_MAX, + }; + m_device->CreateSampler(pointClampSamplerDesc, samplerHandle); + } + } + + return pShader; +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D12RenderShader::SetConstantBuffer() +{ + return; +} + +ID3D12PipelineState* D3D12RenderShader::GetPipelineState(RenderShaderState* pShaderState) +{ + ID3D12PipelineState* pPipelineState = nullptr; + map<RenderShaderState*, ID3D12PipelineState*>::iterator it = m_PipelineStates.find(pShaderState); + if (it == m_PipelineStates.end()) + { + D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; + psoDesc.InputLayout = { m_inputElementDescs, m_inputElementDescsNum }; + psoDesc.pRootSignature = m_pRootSignature; + psoDesc.VS = { reinterpret_cast<UINT8*>(m_vertexShader), m_vertexShaderSize }; + psoDesc.PS = { reinterpret_cast<UINT8*>(m_pixelShader), m_pixelShaderSize }; + psoDesc.BlendState = pShaderState->BlendState; + psoDesc.RasterizerState = pShaderState->RasterizerState; + psoDesc.DepthStencilState = pShaderState->DepthStencilState; + psoDesc.SampleMask = UINT_MAX; + psoDesc.PrimitiveTopologyType = pShaderState->PrimitiveTopologyType; + psoDesc.NumRenderTargets = 1; + psoDesc.RTVFormats[0] = pShaderState->RTVFormat; + psoDesc.DSVFormat = pShaderState->DSVFormat; + psoDesc.SampleDesc.Count = pShaderState->SampleCount; + + ID3D12Device* pDevice = D3D12RenderContext::Instance()->GetDevice(); + ThrowIfFailed(pDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pPipelineState))); + + m_PipelineStates[pShaderState] = pPipelineState; + } + else + { + pPipelineState = it->second; + } + return pPipelineState; +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D12RenderShader::MakeCurrent() +{ + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + ID3D12GraphicsCommandList* m_commandList = pContext->GetGraphicsCommandList(); + + RenderShaderState* pShaderState = RenderInterfaceD3D12::GetShaderState(); + if (nullptr == pShaderState) + { + return; + } + + ID3D12PipelineState* pPipelineState = GetPipelineState(pShaderState); + + m_commandList->SetGraphicsRootSignature(m_pRootSignature); + m_commandList->SetPipelineState(pPipelineState); + + vector<ID3D12DescriptorHeap*> heaps; + if (nullptr != m_scuHeap) + { + heaps.push_back(m_scuHeap); + } + if (nullptr != m_samplerHeap) + { + heaps.push_back(m_samplerHeap); + } + if (heaps.size() > 0) + { + m_commandList->SetDescriptorHeaps(heaps.size(), heaps.data()); + } + int heapindex = 0; + if (nullptr != m_scuHeap) + { + m_commandList->SetGraphicsRootDescriptorTable(heapindex++, m_scuHeap->GetGPUDescriptorHandleForHeapStart()); + } + if (nullptr != m_samplerHeap) + { + m_commandList->SetGraphicsRootDescriptorTable(heapindex++, m_samplerHeap->GetGPUDescriptorHandleForHeapStart()); + } +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D12RenderShader::Disable() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +bool D3D12RenderShader::CreateParamBuffer( UINT sizeBuffer, UINT slot ) +{ + ID3D12Device* pDevice = D3D12RenderContext::Instance()->GetDevice(); + if (!pDevice) + return false; + + SAFE_RELEASE(m_ConstantBuffer[slot]); + + ThrowIfFailed(pDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(sizeBuffer), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&m_ConstantBuffer[slot]))); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +void* D3D12RenderShader::MapParam(UINT slot) +{ + if (!m_ConstantBuffer[slot]) + return 0; + + void* pData; + ThrowIfFailed(m_ConstantBuffer[slot]->Map(0, nullptr, &pData)); + return pData; +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D12RenderShader::UnmapParam( UINT slot ) +{ + if (!m_ConstantBuffer[slot]) + return; + + m_ConstantBuffer[slot]->Unmap(0, nullptr); +} + +void D3D12RenderShader::BindShaderResource(UINT slot, CD3DX12_CPU_DESCRIPTOR_HANDLE& handle) +{ + ID3D12Device* pDevice = D3D12RenderContext::Instance()->GetDevice(); + if (!pDevice) + return; + + CD3DX12_CPU_DESCRIPTOR_HANDLE destHandle(m_scuHeap->GetCPUDescriptorHandleForHeapStart(), slot, m_scuDescriptorSize); + if (handle.ptr != 0) + { + pDevice->CopyDescriptorsSimple(1, destHandle, handle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.h new file mode 100644 index 0000000..d43783c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderShader.h @@ -0,0 +1,85 @@ +// 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-2015 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. +// + +#pragma once + +#include <d3d11.h> +#include <d3d12.h> + +#include "D3D12RenderTarget.h" + +class D3D12RenderShader +{ +public: + D3D12RenderShader(); + ~D3D12RenderShader(); + + static D3D12RenderShader* Create( + const char *name, + void* pVSBlob, size_t vsBlobSize, + void* pPSBlob, size_t psBlobSize, + UINT cbufferSize0 = 0, UINT cbufferSize1 = 0, + D3D12_INPUT_ELEMENT_DESC* pElemDesc = 0, UINT numElements = 0, + int ShaderResourceNum = 0, int UnorderedAccessNum = 0, int SamplerNum = 0); + + void MakeCurrent(); + void Disable(); + void SetConstantBuffer(); + + void* MapParam(UINT slot = 0); + void UnmapParam(UINT slot = 0); + + void BindShaderResource(UINT slot, CD3DX12_CPU_DESCRIPTOR_HANDLE& handle); + +protected: + bool CreateParamBuffer(UINT sizeBuffer, UINT slot = 0); + +private: + ID3D12PipelineState* GetPipelineState(RenderShaderState* pShaderState); + + void* m_vertexShader; + SIZE_T m_vertexShaderSize; + void* m_pixelShader; + SIZE_T m_pixelShaderSize; + + D3D12_INPUT_ELEMENT_DESC* m_inputElementDescs; + UINT m_inputElementDescsNum; + + ID3D12RootSignature* m_pRootSignature; + + ID3D12DescriptorHeap* m_scuHeap; + int m_scuDescriptorSize; + + ID3D12Resource* m_ConstantBuffer[2]; + + ID3D12DescriptorHeap* m_samplerHeap; + int m_samplerDescriptorSize; + + map<RenderShaderState*, ID3D12PipelineState*> m_PipelineStates; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.cpp new file mode 100644 index 0000000..301cad6 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.cpp @@ -0,0 +1,371 @@ +#include "D3D12RenderTarget.h" +#include "D3D12RenderContext.h" + +D3D12RenderTarget::D3D12RenderTarget(int renderTargetIndex, int nRenderTargetCount) +{ + m_RenderTargetIndex = renderTargetIndex; + + m_RenderTargetCount = nRenderTargetCount; + + m_BackBuffers = nullptr; + m_RenderTargets = nullptr; + m_DepthStencil = nullptr; + + m_pRenderContext = D3D12RenderContext::Instance(); + + if (m_RenderTargetCount > 0) + { + m_BackBuffers = new ID3D12Resource*[m_RenderTargetCount]; + + for (int n = 0; n < m_RenderTargetCount; n++) + { + m_BackBuffers[n] = nullptr; + } + + m_RenderTargets = new ID3D12Resource*[m_RenderTargetCount]; + + for (int n = 0; n < m_RenderTargetCount; n++) + { + m_RenderTargets[n] = nullptr; + } + } + + if (renderTargetIndex == 0) + { + m_rtvClearValue.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + m_rtvClearValue.Color[0] = 0.0; + m_rtvClearValue.Color[1] = 0.0; + m_rtvClearValue.Color[2] = 0.0; + m_rtvClearValue.Color[3] = 1.0; + } + else + { + m_rtvClearValue.Format = DXGI_FORMAT_R32_FLOAT; + m_rtvClearValue.Color[0] = FLT_MAX; + m_rtvClearValue.Color[1] = FLT_MAX; + m_rtvClearValue.Color[2] = FLT_MAX; + m_rtvClearValue.Color[3] = FLT_MAX; + } + + if (renderTargetIndex == 0) + { + m_dsvClearValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + } + else + { + m_dsvClearValue.Format = DXGI_FORMAT_D32_FLOAT; + } + m_dsvClearValue.DepthStencil.Depth = 1.0f; + m_dsvClearValue.DepthStencil.Stencil = 0; +} + +D3D12RenderTarget::~D3D12RenderTarget() +{ + if (nullptr != m_BackBuffers) + { + delete[] m_BackBuffers; + m_BackBuffers = nullptr; + } + + if (nullptr != m_RenderTargets) + { + delete[] m_RenderTargets; + m_RenderTargets = nullptr; + } +} + +ID3D12Resource* D3D12RenderTarget::GetDepthStencilResource() +{ + return m_DepthStencil; +} + +D3D12_CPU_DESCRIPTOR_HANDLE D3D12RenderTarget::GetRenderTargetViewHandle() +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); + return rtvHandle; +} + +D3D12_CPU_DESCRIPTOR_HANDLE D3D12RenderTarget::GetDepthStencilViewHandle() +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); + return dsvHandle; +} + +void D3D12RenderTarget::CreateResource(int nWidth, int nHeight) +{ + ID3D12Device* m_device = m_pRenderContext->GetDevice(); + int nSampleCount = m_pRenderContext->GetSampleCount(); + + CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); + + if (m_RenderTargetIndex == 0) + { + IDXGISwapChain3* m_swapChain = m_pRenderContext->GetSwapChain(); + + // Create a RTV for each frame. + for (int n = 0; n < m_RenderTargetCount; n++) + { + ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_BackBuffers[n]))); + + if (nSampleCount > 1) + { + // If we are multi-sampling - create a render target separate from the back buffer + CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_DEFAULT); + D3D12_RESOURCE_DESC desc = m_BackBuffers[n]->GetDesc(); + + desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + desc.SampleDesc.Count = nSampleCount; + desc.SampleDesc.Quality = 0; + desc.Alignment = 0; + + ThrowIfFailed(m_device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_RENDER_TARGET, + &m_rtvClearValue, IID_PPV_ARGS(&m_RenderTargets[n]))); + } + else + { + // The render targets and back buffers are the same thing + m_RenderTargets[n] = m_BackBuffers[n]; + } + + m_device->CreateRenderTargetView(m_RenderTargets[n], nullptr, rtvHandle); + rtvHandle.Offset(1, m_rtvDescriptorSize); + } + + { + auto resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(m_dsvClearValue.Format, + nWidth, nHeight, 1, 1, nSampleCount, 0, + D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); + + ThrowIfFailed(m_device->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), // No need to read/write by CPU + D3D12_HEAP_FLAG_NONE, + &resourceDesc, + D3D12_RESOURCE_STATE_DEPTH_WRITE, + &m_dsvClearValue, + IID_PPV_ARGS(&m_DepthStencil))); + + D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; + dsvDesc.ViewDimension = nSampleCount <= 1 ? D3D12_DSV_DIMENSION_TEXTURE2D : D3D12_DSV_DIMENSION_TEXTURE2DMS; + dsvDesc.Format = m_dsvClearValue.Format; + dsvDesc.Texture2D.MipSlice = 0; + dsvDesc.Flags = D3D12_DSV_FLAG_NONE; + m_device->CreateDepthStencilView(m_DepthStencil, &dsvDesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); + } + } + else + { + { + auto resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(m_rtvClearValue.Format, + nWidth, nHeight, 1, 1, 1, 0, + D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET); + + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {}; + rtvDesc.Format = m_rtvClearValue.Format; + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = 0; + rtvDesc.Texture2D.PlaneSlice = 0; + + for (int n = 0; n < m_RenderTargetCount; n++) + { + m_device->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &resourceDesc, + D3D12_RESOURCE_STATE_RENDER_TARGET, + &m_rtvClearValue, + IID_PPV_ARGS(&m_RenderTargets[n])); + m_device->CreateRenderTargetView(m_RenderTargets[n], &rtvDesc, rtvHandle); + rtvHandle.Offset(1, m_rtvDescriptorSize); + } + } + + { + auto resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(m_dsvClearValue.Format, + nWidth, nHeight, 1, 1, 1, 0, + D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); + + m_device->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &resourceDesc, + D3D12_RESOURCE_STATE_DEPTH_WRITE, + &m_dsvClearValue, + IID_PPV_ARGS(&m_DepthStencil)); + + D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Format = m_dsvClearValue.Format; + dsvDesc.Texture2D.MipSlice = 0; + dsvDesc.Flags = D3D12_DSV_FLAG_NONE; + m_device->CreateDepthStencilView(m_DepthStencil, &dsvDesc, m_dsvHeap.Get()->GetCPUDescriptorHandleForHeapStart()); + } + } +} + +void D3D12RenderTarget::OnCreate(int nWidth, int nHeight) +{ + ID3D12Device* m_device = m_pRenderContext->GetDevice(); + + // Create descriptor heaps. + { + // Describe and create a render target view (RTV) descriptor heap. + D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {}; + rtvHeapDesc.NumDescriptors = m_RenderTargetCount; + rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + ThrowIfFailed(m_device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap))); + + m_rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + + // Describe and create a render target view (RTV) descriptor heap. + D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {}; + dsvHeapDesc.NumDescriptors = 1; + dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; + dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + ThrowIfFailed(m_device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap))); + + m_dsvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + } + + OnResize(nWidth, nHeight); +} + +void D3D12RenderTarget::OnResize(int nWidth, int nHeight) +{ + CreateResource(nWidth, nHeight); + + // viewport and scissor rect + { + memset(&m_viewport, 0, sizeof(m_viewport)); + m_viewport.Width = nWidth; + m_viewport.Height = nHeight; + m_viewport.MaxDepth = 1.0; + + memset(&m_scissorRect, 0, sizeof(m_scissorRect)); + m_scissorRect.right = nWidth; + m_scissorRect.bottom = nHeight; + } +} + +void D3D12RenderTarget::OnDestroy() +{ + for (int n = 0; n < m_RenderTargetCount; n++) + { + Safe_Release(m_RenderTargets[n]); + + if (m_pRenderContext->GetSampleCount() > 1) + { + Safe_Release(m_BackBuffers[n]); + } + } + Safe_Release(m_DepthStencil); +} + +void D3D12RenderTarget::PreRender(bool doClear) +{ + ID3D12GraphicsCommandList* m_commandList = m_pRenderContext->GetGraphicsCommandList(); + m_commandList->RSSetViewports(1, &m_viewport); + m_commandList->RSSetScissorRects(1, &m_scissorRect); + + int numSamples = 1; + UINT m_frameIndex = 0; + D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + if (m_RenderTargetIndex == 0) + { + numSamples = m_pRenderContext->GetSampleCount(); + m_frameIndex = m_pRenderContext->GetFrameIndex(); + if (numSamples <= 1) + { + state = D3D12_RESOURCE_STATE_PRESENT; + } + else + { + state = D3D12_RESOURCE_STATE_RESOLVE_SOURCE; + } + } + + ID3D12Resource* pRenderTarget = m_RenderTargets[m_frameIndex]; + + m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pRenderTarget, state, D3D12_RESOURCE_STATE_RENDER_TARGET)); + + CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_rtvDescriptorSize); + CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); + m_commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle); + + if (doClear) + { + m_commandList->ClearRenderTargetView(rtvHandle, m_rtvClearValue.Color, 0, nullptr); + m_commandList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, + m_dsvClearValue.DepthStencil.Depth, m_dsvClearValue.DepthStencil.Stencil, 0, nullptr); + } +} + +void D3D12RenderTarget::PostRender() +{ + ID3D12GraphicsCommandList* m_commandList = m_pRenderContext->GetGraphicsCommandList(); + + int numSamples = 1; + UINT m_frameIndex = 0; + D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + if (m_RenderTargetIndex == 0) + { + numSamples = m_pRenderContext->GetSampleCount(); + m_frameIndex = m_pRenderContext->GetFrameIndex(); + state = D3D12_RESOURCE_STATE_PRESENT; + } + + if (numSamples <= 1) + { + ID3D12Resource* renderTarget = m_RenderTargets[m_frameIndex]; + CD3DX12_RESOURCE_BARRIER barrier(CD3DX12_RESOURCE_BARRIER::Transition(renderTarget, D3D12_RESOURCE_STATE_RENDER_TARGET, state)); + m_commandList->ResourceBarrier(1, &barrier); + } + else + { + ID3D12Resource* backBuffer = m_BackBuffers[m_frameIndex]; + ID3D12Resource* renderTarget = m_RenderTargets[m_frameIndex]; + + // Barriers to wait for the render target, and the backbuffer to be in correct state + { + D3D12_RESOURCE_BARRIER barriers[] = + { + CD3DX12_RESOURCE_BARRIER::Transition(renderTarget, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE), + CD3DX12_RESOURCE_BARRIER::Transition(backBuffer, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RESOLVE_DEST), + }; + m_commandList->ResourceBarrier(2, barriers); + } + // Do the resolve... + m_commandList->ResolveSubresource(backBuffer, 0, renderTarget, 0, m_rtvClearValue.Format); + // Barrier until can present + { + CD3DX12_RESOURCE_BARRIER barrier(CD3DX12_RESOURCE_BARRIER::Transition(backBuffer, D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_PRESENT)); + m_commandList->ResourceBarrier(1, &barrier); + } + } +} + +void D3D12RenderTarget::SetClearColor(float r, float g, float b, float a, float depth, float stencil) +{ + m_rtvClearValue.Color[0] = r; + m_rtvClearValue.Color[1] = g; + m_rtvClearValue.Color[2] = b; + m_rtvClearValue.Color[3] = a; + + m_dsvClearValue.DepthStencil.Depth = depth; + m_dsvClearValue.DepthStencil.Stencil = stencil; +} + +ID3D12Resource* D3D12RenderTarget::GetTexture(int nIndex, bool bRenderTarget) +{ + if (nIndex < 0 || nIndex > m_RenderTargetCount) + return nullptr; + + if (bRenderTarget) + { + return m_RenderTargets[nIndex]; + } + else + { + return m_BackBuffers[nIndex]; + } +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.h new file mode 100644 index 0000000..8ae0b7d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RenderTarget.h @@ -0,0 +1,110 @@ +#pragma once + +class D3D12RenderContext; + +#include "RenderInterface.h" +using namespace RenderInterface; + +#include <d3d12.h> +#include <d3d11on12.h> +#include <dxgi1_4.h> +#include <D3Dcompiler.h> +#include <DirectXMath.h> +#include "d3dx12.h" +#include <string> +#include <vector> +#include <map> +#include <wrl.h> +#include <shellapi.h> +using namespace std; +using namespace DirectX; +using namespace Microsoft::WRL; + +#ifndef Safe_Delete +#define Safe_Delete(p) { if (p) { delete (p); (p) = nullptr; } } +#endif // !Safe_Delete +#ifndef Safe_Release +#define Safe_Release(p) { if (p) { p->Release(); (p) = nullptr; } } +#endif // !Safe_Delete + +inline void ThrowIfFailed(HRESULT hr) +{ + if (FAILED(hr)) + { + throw; + } +} + +typedef struct RenderShaderStateKey +{ + BLEND_STATE BlendState = BLEND_STATE_NONE; + RASTERIZER_STATE RasterizerState = RASTERIZER_STATE_FILL_CULL_NONE; + DEPTH_STENCIL_STATE DepthStencilState = DEPTH_STENCIL_DEPTH_TEST; + D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + int ForShadow = 0; + + bool operator <(const RenderShaderStateKey &other) const + { + int key = (((BlendState * 10 + RasterizerState) * 10 + DepthStencilState) * 10 + PrimitiveTopologyType) * 10 + ForShadow; + int otherkey = (((other.BlendState * 10 + other.RasterizerState) * 10 + other.DepthStencilState) * 10 + other.PrimitiveTopologyType) * 10 + other.ForShadow; + return key < otherkey; + } +} RenderShaderStateKey; + +typedef struct RenderShaderState +{ + D3D12_BLEND_DESC BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); + D3D12_RASTERIZER_DESC RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); + D3D12_DEPTH_STENCIL_DESC DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); + D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + DXGI_FORMAT RTVFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + DXGI_FORMAT DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; + int SampleCount = 1; +} RenderShaderState; + +class D3D12RenderTarget +{ +public: + D3D12RenderTarget(int renderTargetIndex, int nRenderTargetCount = 1); + ~D3D12RenderTarget(); + + void OnCreate(int nWidth, int nHeight); + void OnResize(int nWidth, int nHeight); + void OnDestroy(); + + void PreRender(bool doClear = false); + void PostRender(); + + void SetClearColor(float r, float g, float b, float a = 1.0, float depth = 1.0, float stencil = 0.0); + + ID3D12Resource* GetTexture(int nIndex = 0, bool bRenderTarget = true); + + D3D12_VIEWPORT m_viewport; + + ID3D12Resource* GetDepthStencilResource(); + D3D12_CPU_DESCRIPTOR_HANDLE GetRenderTargetViewHandle(); + D3D12_CPU_DESCRIPTOR_HANDLE GetDepthStencilViewHandle(); + +private: + void CreateResource(int nWidth, int nHeight); + + int m_RenderTargetIndex; + int m_RenderTargetCount; + + ID3D12Resource** m_BackBuffers; + ID3D12Resource** m_RenderTargets; + ID3D12Resource* m_DepthStencil; + + ComPtr<ID3D12DescriptorHeap> m_rtvHeap; + UINT m_rtvDescriptorSize; + ComPtr<ID3D12DescriptorHeap> m_dsvHeap; + UINT m_dsvDescriptorSize; + + D3D12_RECT m_scissorRect; + + D3D12RenderContext* m_pRenderContext; + + D3D12_CLEAR_VALUE m_rtvClearValue; + D3D12_CLEAR_VALUE m_dsvClearValue; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.cpp new file mode 100644 index 0000000..b640ebd --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.cpp @@ -0,0 +1,141 @@ +// 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. +// +#include "D3D12RendererWindow.h" + +#include "DXUT.h" +#include "DXUTgui.h" +#include "sdkmisc.h" + +#include "D3D12RenderInterface.h" +#include "D3D12RenderContext.h" +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; } +#endif + +/////////////////////////////////////////////////////////////////////////////// +D3D12RenderWindow::D3D12RenderWindow() +{ + m_pRenderContext = D3D12RenderContext::Instance(); + + m_pDialogResourceManager = 0; + m_pTextHelper = 0; +} + +/////////////////////////////////////////////////////////////////////////////// +D3D12RenderWindow::~D3D12RenderWindow() +{ + Free(); +} + +/////////////////////////////////////////////////////////////////////////////// +bool D3D12RenderWindow::Create( HWND hWnd, unsigned int nSamples ) +{ + m_pRenderContext->SetSampleCount(nSamples); + + RECT rc; + GetClientRect((HWND)hWnd, &rc); + int wBuf = rc.right - rc.left; + int hBuf = rc.bottom- rc.top; + + ID3D11Device *pDevice = m_pRenderContext->GetDevice11(); + ID3D11DeviceContext* pDeviceContext = m_pRenderContext->GetDeviceContext(); + if (nullptr != pDevice && nullptr != pDeviceContext) + { + m_pDialogResourceManager = new CDXUTDialogResourceManager; + m_pDialogResourceManager->OnD3D11CreateDevice(pDevice, pDeviceContext); + m_pTextHelper = new CDXUTTextHelper(pDevice, pDeviceContext, m_pDialogResourceManager, 15); + } + + m_pRenderContext->InitSwapchain(wBuf, hBuf, hWnd); + Resize(wBuf, hBuf); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D12RenderWindow::Free() +{ + FreeBuffer(); + + SAFE_DELETE(m_pTextHelper); + + if (m_pDialogResourceManager) + { + m_pDialogResourceManager->OnD3D11DestroyDevice(); + SAFE_DELETE(m_pDialogResourceManager); + } +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D12RenderWindow::FreeBuffer() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D12RenderWindow::Present() +{ +// m_pRenderContext->ReleaseRenderTarget(); + +// m_pRenderContext->PostRender(); + + m_pRenderContext->Present(); +} + +/////////////////////////////////////////////////////////////////////////////// +void D3D12RenderWindow::Clear(float r, float g, float b) +{ + m_pRenderContext->PreRender(); + + m_pRenderContext->SetClearColor(0, r, g, b); + m_pRenderContext->AcquireRenderTarget(true); +} + +/////////////////////////////////////////////////////////////////////////////// +bool D3D12RenderWindow::Resize( int w, int h ) +{ + assert(w > 0 && h > 0); + + m_pRenderContext->ResizeSwapchain(w, h); + + if (m_pDialogResourceManager) + { + ID3D11Device *pDevice = m_pRenderContext->GetDevice11(); + D3D12_RESOURCE_DESC descTex2D = m_pRenderContext->GetBackBufferDesc(); + + DXGI_SURFACE_DESC backbufferDesc; + backbufferDesc.Width = descTex2D.Width; + backbufferDesc.Height = descTex2D.Height; + backbufferDesc.Format = descTex2D.Format; + backbufferDesc.SampleDesc = descTex2D.SampleDesc; + + m_pDialogResourceManager->OnD3D11ResizedSwapChain(pDevice, &backbufferDesc); + } + + return true; +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.h new file mode 100644 index 0000000..abd5d9b --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12RendererWindow.h @@ -0,0 +1,29 @@ +#pragma once + +#include <d3d12.h> +class D3D12RenderContext; +// DXUT stuffs for text rendering +class CDXUTDialogResourceManager; +class CDXUTTextHelper; + +struct D3D12RenderWindow +{ +public: + D3D12RenderWindow(); + ~D3D12RenderWindow(); + + bool Create(HWND hWnd, unsigned int nSamples = 1); + bool Resize(int w, int h); + void Present(); + void Clear(float r, float g, float b); + + CDXUTDialogResourceManager* m_pDialogResourceManager; + CDXUTTextHelper* m_pTextHelper; + +private: + void Free(); + void FreeBuffer(); + + D3D12RenderContext* m_pRenderContext; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.cpp new file mode 100644 index 0000000..0c07409 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.cpp @@ -0,0 +1,231 @@ +// 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. +// +#include "D3D12Shaders.h" + +#include "MeshShaderParam.h" +#include "LightShaderParam.h" + +//#include <Nv/Blast/NvHairSdk.h> +#include "D3D12RenderShader.h" +#include "D3D12RenderContext.h" +#include "D3D12TextureResource.h" +using namespace RenderInterface; + +D3D12_INPUT_ELEMENT_DESC layoutBodyRender[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "VERTEX_NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "FACE_NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 36, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 48, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "VERTEX_ID", 0, DXGI_FORMAT_R32_FLOAT, 0, 56, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, +}; + +D3D12_INPUT_ELEMENT_DESC layout_Position_And_Color[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, +}; + +///////////////////////////////////////////////////////////////////////////////////// +// Common shader settings +//static D3D12RenderShader* g_pShaders[SHADER_TYPE_END]; +static std::map<int, D3D12RenderShader*> g_pShaders; +/* +namespace BodyShaderBlobs +{ + #include "Shaders/BodyShader_VS.h" + #include "Shaders/BodyShader_PS.h" +} + +namespace BodyShadowBlobs +{ + #include "Shaders/BodyShadow_VS.h" + #include "Shaders/BodyShadow_PS.h" +} + +namespace ScreenQuadBlobs +{ + #include "Shaders/ScreenQuad_VS.h" + #include "Shaders/ScreenQuad_PS.h" +} + +namespace ScreenQuadColorBlobs +{ + #include "Shaders/ScreenQuadColor_VS.h" + #include "Shaders/ScreenQuadColor_PS.h" +} + +namespace VisualizeShadowBlobs +{ + #include "Shaders/VisualizeShadow_VS.h" + #include "Shaders/VisualizeShadow_PS.h" +} + +namespace ColorBlobs +{ + #include "Shaders/Color_VS.h" + #include "Shaders/Color_PS.h" +} +*/ +////////////////////////////////////////////////////////////////////////// +bool InitializeShadersD3D12() +{ + /* + UINT numElements = sizeof(layoutBodyRender) / sizeof(D3D11_INPUT_ELEMENT_DESC); + + g_pShaders[SHADER_TYPE_MESH_RENDERING] = D3D12RenderShader::Create("MeshRenderShader", + (void*)BodyShaderBlobs::g_vs_main, sizeof(BodyShaderBlobs::g_vs_main), + (void*)BodyShaderBlobs::g_ps_main, sizeof(BodyShaderBlobs::g_ps_main), + sizeof(MeshShaderParam), 0, + &layoutBodyRender[0], numElements, + 10, 0, 2); + + g_pShaders[SHADER_TYPE_MESH_SHADOW] = D3D12RenderShader::Create("MeshShadowShader", + (void*)BodyShadowBlobs::g_vs_main, sizeof(BodyShadowBlobs::g_vs_main), + (void*)BodyShadowBlobs::g_ps_main, sizeof(BodyShadowBlobs::g_ps_main), + sizeof(MeshShadowShaderParam), 0, + &layoutBodyRender[0], numElements, + 2); + + g_pShaders[SHADER_TYPE_SCREEN_QUAD] = D3D12RenderShader::Create("ScreenQuadShader", + (void*)ScreenQuadBlobs::g_vs_main, sizeof(ScreenQuadBlobs::g_vs_main), + (void*)ScreenQuadBlobs::g_ps_main, sizeof(ScreenQuadBlobs::g_ps_main), + 0, 0, + 0, 0, + 1, 0, 1); + + g_pShaders[SHADER_TYPE_SCREEN_QUAD_COLOR] = D3D12RenderShader::Create("ScreenQuadColorShader", + (void*)ScreenQuadColorBlobs::g_vs_main, sizeof(ScreenQuadColorBlobs::g_vs_main), + (void*)ScreenQuadColorBlobs::g_ps_main, sizeof(ScreenQuadColorBlobs::g_ps_main)); + + g_pShaders[SHADER_TYPE_VISUALIZE_SHADOW] = D3D12RenderShader::Create("VisualizeShadowShader", + (void*)VisualizeShadowBlobs::g_vs_main, sizeof(VisualizeShadowBlobs::g_vs_main), + (void*)VisualizeShadowBlobs::g_ps_main, sizeof(VisualizeShadowBlobs::g_ps_main), + sizeof(ShadowVizParam), 0, + 0, 0, + 1, 0, 1); + + UINT numElements2 = sizeof(layout_Position_And_Color) / sizeof(D3D11_INPUT_ELEMENT_DESC); + + g_pShaders[SHADER_TYPE_SIMPLE_COLOR] = D3D12RenderShader::Create("Color", + (void*)ColorBlobs::g_vs_main, sizeof(ColorBlobs::g_vs_main), + (void*)ColorBlobs::g_ps_main, sizeof(ColorBlobs::g_ps_main), + sizeof(SimpleShaderParam), 0, + &layout_Position_And_Color[0], numElements2); + + g_pShaders[SHADER_TYPE_HAIR_SHADER_DEFAULT] = D3D12RenderShader::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] = D3D12RenderShader::Create( + "hairShadow", 0, 0, + (void*)BlastShadowBlobs::g_ps_main, sizeof(BlastShadowBlobs::g_ps_main), + sizeof(NvHair::ShaderConstantBuffer), + 0); + */ + return true; +} + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; } +#endif + +#ifndef SAFE_DELETE +#define SAFE_DELETE(x) { if (x) delete x; x = 0; } +#endif + +/////////////////////////////////////////////////////////////////////////////// +void DestroyShadersD3D12() +{ + for (int i = 0; i < g_pShaders.size(); i++) + { + D3D12RenderShader*& pShader = g_pShaders[i]; + if (pShader) + { + delete pShader; + pShader = 0; + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +D3D12RenderShader* GetShaderD3D12(SHADER_TYPE st) +{ + return g_pShaders[st]; +} + +/////////////////////////////////////////////////////////////////////////////// +void ApplyShaderD3D12(SHADER_TYPE st) +{ + D3D12RenderShader* pD3D12Shader = GetShaderD3D12(st); + if (!pD3D12Shader) + return; + + pD3D12Shader->MakeCurrent(); +} + +void BindShaderResourcesD3D12(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs) +{ + D3D12RenderShader* pD3D12Shader = GetShaderD3D12(st); + if (!pD3D12Shader) + return; + + for (int i = 0; i < numSRVs; i++) + { + CD3DX12_CPU_DESCRIPTOR_HANDLE handle = D3D12TextureResource::GetHandle(ppSRVs[i]); + pD3D12Shader->BindShaderResource(i, handle); + } +} + +/////////////////////////////////////////////////////////////////////////////// +void DisableShaderD3D12(RenderInterface::SHADER_TYPE st) +{ + D3D12RenderShader* pD3D12Shader = GetShaderD3D12(st); + if (!pD3D12Shader) + return; + + pD3D12Shader->Disable(); +} + +/////////////////////////////////////////////////////////////////////////////// +void CopyShaderParamD3D12(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot) +{ + D3D12RenderShader* pD3D12Shader = GetShaderD3D12(st); + if (!pD3D12Shader) + return; + + void* mappedParam = pD3D12Shader->MapParam(slot); + + memcpy(mappedParam, pSysMem, bytes); + + pD3D12Shader->UnmapParam(slot); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.h new file mode 100644 index 0000000..29b0e1b --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Shaders.h @@ -0,0 +1,42 @@ +// 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. +// + +#pragma once + +#include "RenderInterface.h" +#include "RenderPlugin.h" +/////////////////////////////////////////////////////////////////// +// default shaders +/////////////////////////////////////////////////////////////////// +CORERENDER_EXPORT bool InitializeShadersD3D12(); +CORERENDER_EXPORT void DestroyShadersD3D12(); + +CORERENDER_EXPORT void ApplyShaderD3D12(RenderInterface::SHADER_TYPE st); +CORERENDER_EXPORT void DisableShaderD3D12(RenderInterface::SHADER_TYPE st); +CORERENDER_EXPORT void BindShaderResourcesD3D12(RenderInterface::SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs); +CORERENDER_EXPORT void CopyShaderParamD3D12(RenderInterface::SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0); diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.cpp new file mode 100644 index 0000000..342c6f3 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.cpp @@ -0,0 +1,99 @@ +// 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-2015 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. +// +#include "D3D12ShadowMap.h" + +#include "RenderResources.h" + +#include "D3D12RenderInterface.h" +#include "D3D12TextureResource.h" +#include "D3D12RenderContext.h" + +////////////////////////////////////////////////////////////////////////////// +D3D12ShadowMap::D3D12ShadowMap(int resolution) +{ + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + m_nIndex = pContext->AllocRenderTargetIndex(); + m_pRenderTarget = pContext->CreateRenderTarget(m_nIndex, resolution, resolution); + ID3D12Resource* pTexture = pContext->GetTexture(m_nIndex); + int nIndexInHeap = -1; + CD3DX12_CPU_DESCRIPTOR_HANDLE handle = pContext->NVHairINT_CreateD3D12Texture(pTexture, nIndexInHeap); + m_ShadowResource.m_pResource = pTexture; + m_ShadowResource.m_Handle = handle; + m_ShadowResource.m_nIndexInHeap = nIndexInHeap; +} + +////////////////////////////////////////////////////////////////////////////// +D3D12ShadowMap::~D3D12ShadowMap() +{ + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + pContext->NVHairINT_DestroyD3D12Texture(m_ShadowResource.m_nIndexInHeap); + + Release(); +} + +////////////////////////////////////////////////////////////////////////////// +void D3D12ShadowMap::Release() +{ +} + +////////////////////////////////////////////////////////////////////////////// +GPUShaderResource* D3D12ShadowMap::GetShadowSRV() +{ + return &m_ShadowResource; +} + +////////////////////////////////////////////////////////////////////////////// +bool D3D12ShadowMap::isValid() +{ + return m_pRenderTarget != nullptr; +} + +////////////////////////////////////////////////////////////////////////////// +void D3D12ShadowMap::BeginRendering(float clearDepth) +{ + if (!isValid()) + return; + + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + pContext->ReleaseRenderTarget(); + + pContext->AcquireRenderTarget(true, m_nIndex); +} + +////////////////////////////////////////////////////////////////////////////// +void D3D12ShadowMap::EndRendering() +{ + if (!isValid()) + return; + + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + pContext->ReleaseRenderTarget(m_nIndex); + + pContext->AcquireRenderTarget(); +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.h new file mode 100644 index 0000000..dabf9a1 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12ShadowMap.h @@ -0,0 +1,68 @@ +// 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-2015 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. +// + +#pragma once + +#include "ShadowMap.h" + +#include <d3d11.h> +#include <d3d12.h> +#include "D3D12TextureResource.h" + +#include "DXUT.h" // DXUT header +#include "d3dx12.h" + +#include "D3D12RenderTarget.h" + +using namespace Microsoft::WRL; + +class GPUShaderResource; +class D3D12TextureResource; + +struct D3D12ShadowMap : public ShadowMap +{ + D3D12TextureResource m_ShadowResource; + + D3D12RenderTarget* m_pRenderTarget; + +public: + D3D12ShadowMap(int resolution ); + ~D3D12ShadowMap(); + + void Release(); + void BeginRendering(float clearDepth); + void EndRendering(); + + GPUShaderResource* GetShadowSRV(); + +protected: + + bool isValid(); + int m_nIndex; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.cpp new file mode 100644 index 0000000..0247895 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.cpp @@ -0,0 +1,29 @@ +// 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. +// +#include "D3D12TextureResource.h" + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.h new file mode 100644 index 0000000..b6c7584 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12TextureResource.h @@ -0,0 +1,89 @@ +// 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-2015 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. +// + +#pragma once + +#include "RenderResources.h" + +#include "d3d12.h" +#include "d3dx12.h" + +// GPU resources for texture +struct D3D12TextureResource : public GPUShaderResource +{ + ID3D12Resource* m_pResource; + CD3DX12_CPU_DESCRIPTOR_HANDLE m_Handle; + int m_nIndexInHeap; + +public: + static GPUShaderResource* Create( + ID3D12Resource* pResource, + CD3DX12_CPU_DESCRIPTOR_HANDLE handle, + int nIndexInHeap) { + D3D12TextureResource* pBuffer = new D3D12TextureResource; + pBuffer->m_pResource = pResource; + pBuffer->m_Handle = handle; + pBuffer->m_nIndexInHeap = nIndexInHeap; + return pBuffer; + } + + static ID3D12Resource* GetResource(GPUShaderResource* pBuffer) + { + D3D12TextureResource* pD3D12Buffer = dynamic_cast<D3D12TextureResource*>(pBuffer); + if (!pD3D12Buffer) + return 0; + return pD3D12Buffer->m_pResource; + } + + static CD3DX12_CPU_DESCRIPTOR_HANDLE GetHandle(GPUShaderResource* pBuffer) + { + CD3DX12_CPU_DESCRIPTOR_HANDLE handle = {}; + D3D12TextureResource* pD3D12Buffer = dynamic_cast<D3D12TextureResource*>(pBuffer); + if (pD3D12Buffer) + handle = pD3D12Buffer->m_Handle; + else + handle.ptr = 0; + return handle; + } + + D3D12TextureResource() + { + m_pResource = 0; + } + + void Release() + { + SAFE_RELEASE(m_pResource); + } + + ~D3D12TextureResource() + { + Release(); + } +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.cpp new file mode 100644 index 0000000..695bb41 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.cpp @@ -0,0 +1,386 @@ +// 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. +// +#include <DirectXTex.h> +#include "D3D12Util.h" + +#include "D3D12Shaders.h" +#include "D3D12RenderShader.h" + +#include "D3DX10tex.h" +#include "D3DX11tex.h" + +#include "D3D12Wrapper.h" +#include "DXUT.h" +#include "DXUTgui.h" +#include "sdkmisc.h" +#include "D3D12RendererWindow.h" +#include "SimpleRenderable.h" +//#include "MeshShaderParam.h" +#include "D3D12RenderInterface.h" +#include "D3D12TextureResource.h" +#include "D3D12RenderContext.h" +namespace D3D12Util +{ + using namespace RenderInterface; + + // D3D hook to render window + D3D12RenderWindow* g_pRenderWindow = 0; + +/////////////////////////////////////////////////////////////////////////////// +GPUShaderResource* + CreateTextureSRV(const char* texturename) +{ + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + if (!pContext) + return 0; + ID3D12Device* pDevice = pContext->GetDevice(); + if (!pDevice) + return 0; + ID3D12GraphicsCommandList* pCommandList = pContext->GetGraphicsCommandList(); + if (!pCommandList) + return 0; + + unsigned char *pSTBIRes = 0; + int width = 0; + int height = 0; + + size_t nu = strlen(texturename); + size_t n = (size_t)MultiByteToWideChar(CP_ACP, 0, (const char *)texturename, (int)nu, NULL, 0); + wchar_t* pwstr = new wchar_t[n]; + MultiByteToWideChar(CP_ACP, 0, (const char *)texturename, (int)nu, pwstr, (int)n); + pwstr[n] = 0; + + TexMetadata texMetadata; + ScratchImage scratchImage; + HRESULT loaded = LoadFromTGAFile(pwstr, &texMetadata, scratchImage); + + if (loaded != S_OK) + { + loaded = LoadFromWICFile(pwstr, TEX_FILTER_DEFAULT | WIC_FLAGS_ALL_FRAMES, &texMetadata, scratchImage); + } + + if (loaded != S_OK) + { + loaded = LoadFromDDSFile(pwstr, DDS_FLAGS_NONE, &texMetadata, scratchImage); + } + + if (loaded == S_OK) + { + pSTBIRes = scratchImage.GetPixels(); + width = texMetadata.width; + height = texMetadata.height; + } + + if (!pSTBIRes) + return 0; + + int numMipMaps = 0; + { + int mipWidth = width; + int mipHeight = height; + while (mipWidth > 1 || mipHeight > 1) + { + numMipMaps++; + mipWidth >>= 1; + mipHeight >>= 1; + + if ((mipWidth * sizeof(uint32_t)) < D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) + break; + } + } + + std::vector<D3D12_PLACED_SUBRESOURCE_FOOTPRINT> layouts(numMipMaps); + std::vector<uint64_t> row_sizes_in_bytes(numMipMaps); + std::vector<uint32_t> num_rows(numMipMaps); + + auto resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D( + DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, (UINT16)numMipMaps, 1, 0, D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT_UNKNOWN, 0); + + uint64_t required_size = 0; + pDevice->GetCopyableFootprints(&resourceDesc, 0, numMipMaps, 0, &layouts[0], &num_rows[0], &row_sizes_in_bytes[0], &required_size); + + HRESULT hr; + ID3D12Resource* mTextureUpload; + ID3D12Resource* mTexture; + + hr = pDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &resourceDesc, + D3D12_RESOURCE_STATE_COPY_DEST, + nullptr, + IID_PPV_ARGS(&mTexture)); + mTexture->SetName(L"Texture"); + hr = pDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(required_size), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&mTextureUpload)); + mTextureUpload->SetName(L"TextureUpload"); + + const int requestedMipLevels = numMipMaps; + D3D12_SUBRESOURCE_DATA* initData = new D3D12_SUBRESOURCE_DATA[requestedMipLevels]; + ZeroMemory(initData, sizeof(D3D12_SUBRESOURCE_DATA)*requestedMipLevels); + + struct Pixel + { + unsigned char rgba[4]; + }; + + // prepare target buffer just large enough to include all the mip levels + Pixel* targets = new Pixel[width*height * 2]; + + // copy the first mip level + memcpy(targets, pSTBIRes, width*height * 4); + + // current mip level width and height + int mipWidth = width; + int mipHeight = height; + + // actual mip levels + int mipLevels = 0; + + // current data + Pixel* source = targets; + Pixel* target = nullptr; + + for (int idx = 0; idx < requestedMipLevels; ++idx) + { + // set initData + initData[idx].pData = source; + initData[idx].RowPitch = mipWidth * 4; + mipLevels++; + + // skip generating mip for 1x1 + if ((mipWidth == 1) && (mipHeight == 1)) + break; + + // skip generating mip for the last level + if (idx == (requestedMipLevels - 1)) + break; + + // buffer for the next mip level + target = &source[mipWidth*mipHeight]; + + const int prevWidth = mipWidth; // previous mip's width + + // generate the next mip level + mipWidth = max(1, mipWidth >> 1); + mipHeight = max(1, mipHeight >> 1); + + Pixel samples[4]; + + for (int y = 0; y < mipHeight; ++y) + { + for (int x = 0; x < mipWidth; ++x) + { + const int px = x * 2; // x in previous mip + const int py = y * 2; // y in previous mip + + samples[0] = source[py*prevWidth + px]; // left top + samples[1] = source[py*prevWidth + px + 1]; // right top + samples[2] = source[(py + 1)*prevWidth + px]; // left bottom + samples[3] = source[(py + 1)*prevWidth + px + 1]; // right bottom + + // for each component + for (int comp = 0; comp < 4; ++comp) + { + // do the linear box filter for lower mip level + target[y*mipWidth + x].rgba[comp] = (samples[0].rgba[comp] + samples[1].rgba[comp] + samples[2].rgba[comp] + samples[3].rgba[comp]) / 4; + } + } + } + + // update source + source = target; + } + + uint8_t* p; + mTextureUpload->Map(0, nullptr, reinterpret_cast<void**>(&p)); + for (uint32_t i = 0; i < numMipMaps; ++i) + { + memcpy(p + layouts[i].Offset, initData[i].pData, layouts[i].Footprint.RowPitch * num_rows[i]); + } + mTextureUpload->Unmap(0, nullptr); + + for (uint32_t i = 0; i < numMipMaps; ++i) + { + D3D12_TEXTURE_COPY_LOCATION src; + src.pResource = mTextureUpload; + src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + src.PlacedFootprint = layouts[i]; + + D3D12_TEXTURE_COPY_LOCATION dst; + dst.pResource = mTexture; + dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dst.SubresourceIndex = i; + pCommandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); + } + pCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(mTexture, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)); + + delete initData; + delete targets; + + int nIndexInHeap = -1; + CD3DX12_CPU_DESCRIPTOR_HANDLE handle = pContext->NVHairINT_CreateD3D12Texture(mTexture, nIndexInHeap); + return D3D12TextureResource::Create(mTexture, handle, nIndexInHeap); +} + + +/////////////////////////////////////////////////////////////////////////////// +bool GetDeviceInfoString(wchar_t *str) +{ + ID3D11Device* pDevice = nullptr;// RenderInterfaceD3D12::GetDevice(); + if (!pDevice) + return false; + + { + IDXGIDevice1 *pDXGIDevice1 = NULL; + pDevice->QueryInterface(__uuidof(IDXGIDevice1), reinterpret_cast<void **>(&pDXGIDevice1)); + + IDXGIAdapter1 *pDXGIAdapter1 = NULL; + pDXGIDevice1->GetParent(__uuidof(IDXGIAdapter1), reinterpret_cast<void **>(&pDXGIAdapter1)); + + if (pDXGIAdapter1) + { + auto adapterDescription = DXGI_ADAPTER_DESC1(); + pDXGIAdapter1->GetDesc1(&adapterDescription); + + WCHAR* pDescStr = adapterDescription.Description; + float memInGB = float(adapterDescription.DedicatedVideoMemory) / 1e9f; + swprintf_s(str, 1000, L"%s(%.1fGb)\n", pDescStr, memInGB); + } + } + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Render window interafce +///////////////////////////////////////////////////////////////////////////////////////// +bool CreateRenderWindow(HWND hWnd, int nSamples) +{ + SAFE_DELETE(g_pRenderWindow); + + g_pRenderWindow = new D3D12RenderWindow; + return g_pRenderWindow->Create(hWnd, nSamples); +} + +D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles) +{ + /* + deviceHandles.pAdapter = RenderInterfaceD3D11::GetAdapter(); + deviceHandles.pFactory = RenderInterfaceD3D11::GetDXGIFactory(); + deviceHandles.pDevice = RenderInterfaceD3D11::GetDevice(); + deviceHandles.pDeviceContext = RenderInterfaceD3D11::GetDeviceContext(); + + deviceHandles.pDXGISwapChain = g_pRenderWindow->m_pDXGISwapChain; + deviceHandles.pD3D11BackBuffer = g_pRenderWindow->m_pD3D11BackBuffer; + deviceHandles.pD3D11RenderTargetView = g_pRenderWindow->m_pD3D11RenderTargetView; + deviceHandles.pD3D11DepthBuffer = g_pRenderWindow->m_pD3D11DepthBuffer; + deviceHandles.pD3D11DepthStencilView = g_pRenderWindow->m_pD3D11DepthStencilView; + */ + return deviceHandles; +} + +void DestroyRenderWindow() +{ + SAFE_DELETE(g_pRenderWindow); +} + +bool ResizeRenderWindow(int w, int h) +{ + if (!g_pRenderWindow) + return false; + + return g_pRenderWindow->Resize(w,h); +} + +void PresentRenderWindow() +{ + if (!g_pRenderWindow) + return; + + g_pRenderWindow->Present(); +} + +void ClearRenderWindow(float r, float g, float b) +{ + if (!g_pRenderWindow) + return; + + g_pRenderWindow->Clear(r,g,b); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Text draw helper functions (using DXUT) +///////////////////////////////////////////////////////////////////////////////////////// +void TxtHelperBegin() +{ + if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper) + return; + + g_pRenderWindow->m_pTextHelper->Begin(); +} + +void TxtHelperEnd() +{ + if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper) + return; + + g_pRenderWindow->m_pTextHelper->End(); +} + +void TxtHelperSetInsertionPos(int x, int y) +{ + if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper) + return; + + g_pRenderWindow->m_pTextHelper->SetInsertionPos(x, y); +} + +void TxtHelperSetForegroundColor(float r, float g, float b, float a) +{ + if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper) + return; + + g_pRenderWindow->m_pTextHelper->SetForegroundColor(DirectX::XMFLOAT4(r,g,b,a)); +} + +void TxtHelperDrawTextLine(wchar_t* str) +{ + if (!g_pRenderWindow || !g_pRenderWindow->m_pTextHelper) + return; + + g_pRenderWindow->m_pTextHelper->DrawTextLine(str); +} + +} // end namespace
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.h new file mode 100644 index 0000000..f83b063 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Util.h @@ -0,0 +1,68 @@ +// 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. +// + +#pragma once + +#include <d3d12.h> + +#include "RenderPlugin.h" + +class GPUShaderResource; + +namespace D3D12Util +{ + /////////////////////////////////////////////////////////////////// + // render window management + /////////////////////////////////////////////////////////////////// + D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles); + bool CreateRenderWindow(HWND hWnd, int nSamples); + void DestroyRenderWindow(); + bool ResizeRenderWindow(int w, int h); + void PresentRenderWindow(); + void ClearRenderWindow(float r, float g, float b); + + /////////////////////////////////////////////////////////////////// + // background textures + bool LoadBackgroundTexture(const char* filePath); + void RenderBackgroundTexture(); + void ClearBackgroundTexture(); + GPUShaderResource* CreateTextureSRV(const char* texturename); + + /////////////////////////////////////////////////////////////////// + bool GetDeviceInfoString(wchar_t *str); + + /////////////////////////////////////////////////////////////////// + // text helpers + void TxtHelperBegin(); + void TxtHelperEnd(); + void TxtHelperSetInsertionPos(int x, int y); + void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f); + void TxtHelperDrawTextLine(wchar_t* str); + + +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.cpp new file mode 100644 index 0000000..b534a36 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.cpp @@ -0,0 +1,33 @@ +// 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. +// +#include "D3D12Wrapper.h" + +namespace D3DWrapper +{ + +} // end namespace
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.h new file mode 100644 index 0000000..dc81e34 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/D3D12Wrapper.h @@ -0,0 +1,14 @@ +#pragma once + +#include <d3d11.h> + +namespace D3DWrapper +{ + inline void SetDebugName(ID3D11DeviceChild* pResource, const char *name) + { + if (pResource) pResource->SetPrivateData( WKPDID_D3DDebugObjectName, strlen(name), name); + } +} + +#define SET_D3D_DEBUG_NAME(x, name) D3DWrapper::SetDebugName(x, name); +#define SET_D3D_DEBUG_NAME_VAR(x) D3DWrapper::SetDebugName(x, #x); diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.cpp new file mode 100644 index 0000000..9945d7c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.cpp @@ -0,0 +1,343 @@ +#include "RenderPluginDx12.h" + +#include "D3D12RenderInterface.h" +#include "D3D12Util.h" +#include "D3D12Shaders.h" +#include "D3D12GPUProfiler.h" +#include "D3D12ShadowMap.h" +#include "D3D12RenderContext.h" + +RenderPlugin* CreateRenderPlugin(void) +{ + return new RenderPluginDx12; +} + +RenderPluginDx12::RenderPluginDx12() +{ + m_RenderApi = "Dx12"; +} + +RenderPluginDx12::~RenderPluginDx12() +{ +} + +// interface +bool RenderPluginDx12::InitDevice(int deviceID) +{ + return RenderInterfaceD3D12::InitDevice(deviceID); +} + +bool RenderPluginDx12::Initialize() +{ + return RenderInterfaceD3D12::Initialize(); +} + +void RenderPluginDx12::Shutdown() +{ + D3D12Util::DestroyRenderWindow(); + RenderInterfaceD3D12::Shutdown(); +} + +void RenderPluginDx12::CopyToDevice(GPUBufferResource *pDevicePtr, + void* pSysMem, unsigned int ByteWidth) +{ + RenderInterfaceD3D12::CopyToDevice(pDevicePtr, pSysMem, ByteWidth); +} + +void RenderPluginDx12::ApplyDepthStencilState(DEPTH_STENCIL_STATE state) +{ + RenderInterfaceD3D12::ApplyDepthStencilState(state); +} + +void RenderPluginDx12::ApplyRasterizerState(RASTERIZER_STATE state) +{ + RenderInterfaceD3D12::ApplyRasterizerState(state); +} + +void RenderPluginDx12::ApplySampler(int slot, SAMPLER_TYPE state) +{ +} + +void RenderPluginDx12::ApplyBlendState(BLEND_STATE state) +{ + RenderInterfaceD3D12::ApplyBlendState(state); +} + +void RenderPluginDx12::GetViewport(Viewport& vp) +{ + RenderInterfaceD3D12::GetViewport(vp); +} + +void RenderPluginDx12::SetViewport(const Viewport& vp) +{ + RenderInterfaceD3D12::SetViewport(vp); +} + +void RenderPluginDx12::BindVertexShaderResources(int startSlot, + int numSRVs, GPUShaderResource** ppSRVs) +{ +} + +void RenderPluginDx12::BindPixelShaderResources(int startSlot, + int numSRVs, GPUShaderResource** ppSRVs) +{ +} + +void RenderPluginDx12::ClearVertexShaderResources(int startSlot, int numSRVs) +{ +} + +void RenderPluginDx12::ClearPixelShaderResources(int startSlot, int numSRVs) +{ +} + +void RenderPluginDx12::ClearInputLayout() +{ +} + +void RenderPluginDx12::SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset) +{ + RenderInterfaceD3D12::SetVertexBuffer(pBuffer, stride, offset); +} + +void RenderPluginDx12::SetPrimitiveTopologyTriangleStrip() +{ + RenderInterfaceD3D12::SetPrimitiveTopologyTriangleStrip(); +} + +void RenderPluginDx12::SetPrimitiveTopologyTriangleList() +{ + RenderInterfaceD3D12::SetPrimitiveTopologyTriangleList(); +} + +void RenderPluginDx12::SetPrimitiveTopologyLineList() +{ + RenderInterfaceD3D12::SetPrimitiveTopologyLineList(); +} + +void RenderPluginDx12::Draw(unsigned int vertexCount, unsigned int startCount) +{ + RenderInterfaceD3D12::Draw(vertexCount, startCount); +} + +GPUBufferResource* RenderPluginDx12::CreateVertexBuffer(unsigned int ByteWidth, void* pSysMem) +{ + return RenderInterfaceD3D12::CreateVertexBuffer(ByteWidth, pSysMem); +} + +GPUShaderResource* RenderPluginDx12::CreateShaderResource(unsigned int stride, + unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer) +{ + return RenderInterfaceD3D12::CreateShaderResource(stride, numElements, pSysMem, pReadOnlyBuffer); +} + +void RenderPluginDx12::ApplyForShadow(int ForShadow) +{ + RenderInterfaceD3D12::ApplyForShadow(ForShadow); +} + +void RenderPluginDx12::SwitchToDX11() +{ + RenderInterfaceD3D12::SwitchToDX11(); +} + +void RenderPluginDx12::FlushDX11() +{ + RenderInterfaceD3D12::FlushDX11(); +} + +void RenderPluginDx12::FlushDX12() +{ + RenderInterfaceD3D12::FlushDX12(); +} + +void RenderPluginDx12::ApplyPrimitiveTopologyLine() +{ + RenderInterfaceD3D12::ApplyPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE); +} + +void RenderPluginDx12::ApplyPrimitiveTopologyTriangle() +{ + RenderInterfaceD3D12::ApplyPrimitiveTopologyType(D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE); +} + +void RenderPluginDx12::SubmitGpuWork() +{ + RenderInterfaceD3D12::SubmitGpuWork(); +} + +void RenderPluginDx12::WaitForGpu() +{ + RenderInterfaceD3D12::WaitForGpu(); +} + +// util +bool RenderPluginDx12::CreateRenderWindow(HWND hWnd, int nSamples) +{ + return D3D12Util::CreateRenderWindow(hWnd, nSamples); +} + +bool RenderPluginDx12::ResizeRenderWindow(int w, int h) +{ + return D3D12Util::ResizeRenderWindow(w, h); +} + +void RenderPluginDx12::PresentRenderWindow() +{ + D3D12Util::PresentRenderWindow(); +} + +void RenderPluginDx12::ClearRenderWindow(float r, float g, float b) +{ + D3D12Util::ClearRenderWindow(r, g, b); +} + +bool RenderPluginDx12::GetDeviceInfoString(wchar_t *str) +{ + return D3D12Util::GetDeviceInfoString(str); +} + +GPUShaderResource* RenderPluginDx12::CreateTextureSRV(const char* texturename) +{ + return D3D12Util::CreateTextureSRV(texturename); +} + +void RenderPluginDx12::TxtHelperBegin() +{ + D3D12Util::TxtHelperBegin(); +} + +void RenderPluginDx12::TxtHelperEnd() +{ + D3D12Util::TxtHelperEnd(); +} + +void RenderPluginDx12::TxtHelperSetInsertionPos(int x, int y) +{ + D3D12Util::TxtHelperSetInsertionPos(x, y); +} + +void RenderPluginDx12::TxtHelperSetForegroundColor(float r, float g, float b, float a) +{ + D3D12Util::TxtHelperSetForegroundColor(r, g, b, a); +} + +void RenderPluginDx12::TxtHelperDrawTextLine(wchar_t* str) +{ + D3D12Util::TxtHelperDrawTextLine(str); +} + +// shader +bool RenderPluginDx12::InitializeShaders() +{ + return InitializeShadersD3D12(); +} + +void RenderPluginDx12::DestroyShaders() +{ + DestroyShadersD3D12(); +} + +void RenderPluginDx12::ApplyShader(SHADER_TYPE st) +{ + ApplyShaderD3D12(st); +} + +void RenderPluginDx12::DisableShader(SHADER_TYPE st) +{ + DisableShaderD3D12(st); +} + +void RenderPluginDx12::BindShaderResources(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs) +{ + BindShaderResourcesD3D12(st, numSRVs, ppSRVs); +} + +void RenderPluginDx12::CopyShaderParam(SHADER_TYPE st, + void* pSysMem, unsigned int bytes, unsigned int slot) +{ + CopyShaderParamD3D12(st, pSysMem, bytes, slot); +} + +// GPUProfiler +GPUProfiler* RenderPluginDx12::CreateGPUProfiler() +{ + GPUProfiler* pProfiler = new D3D12GPUProfiler; + pProfiler->Initialize(); + return pProfiler; +} + +// ShadowMap +ShadowMap* RenderPluginDx12::CreateShadowMap(int resolution) +{ + return new D3D12ShadowMap(resolution); +} + +// D3D12RenderContext +void RenderPluginDx12::PreRender() +{ + D3D12RenderContext::Instance()->PreRender(); +} + +void RenderPluginDx12::PostRender() +{ + D3D12RenderContext::Instance()->PostRender(); +} + +// GPUMeshResources +#include "MeshData.h" +#include "AnimUtil.h" + +class GPUMeshResourcesDx12 : public GPUMeshResources +{ +public: + NVHairReadOnlyBuffer m_BoneIndicesBuffer; + NVHairReadOnlyBuffer m_BoneWeightsBuffer; +}; + +GPUMeshResources* RenderPluginDx12::GPUMeshResourcesCreate(MeshData* pMeshData, const SkinData& skinData) +{ + GPUMeshResources* resources = new GPUMeshResourcesDx12; + + int numIndices = pMeshData->m_NumIndices; + int numVertices = pMeshData->m_NumVertices; + + resources->m_pVertexBuffer = CreateVertexBuffer( + sizeof(MeshData::MeshVertex) * numIndices, pMeshData->m_pMeshVertices); + + GPUMeshResourcesDx12* resourceDx12 = (GPUMeshResourcesDx12*)resources; + if (NULL != resourceDx12) + { + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + pContext->InitBuffer(resourceDx12->m_BoneIndicesBuffer); + pContext->InitBuffer(resourceDx12->m_BoneWeightsBuffer); + resources->m_pBoneIndicesSRV = CreateShaderResource( + sizeof(atcore_float4), numVertices, skinData.m_pBoneIndices, &resourceDx12->m_BoneIndicesBuffer); + resources->m_pBoneWeightsSRV = CreateShaderResource( + sizeof(atcore_float4), numVertices, skinData.m_pBoneWeights, &resourceDx12->m_BoneWeightsBuffer); + } + + return resources; +} + +void RenderPluginDx12::GPUMeshResourcesRelease(GPUMeshResources* pResource) +{ + SAFE_RELEASE(pResource->m_pVertexBuffer); + SAFE_RELEASE(pResource->m_pBoneIndicesSRV); + SAFE_RELEASE(pResource->m_pBoneWeightsSRV); + + GPUMeshResourcesDx12* pResourceDx12 = (GPUMeshResourcesDx12*)pResource; + if (NULL == pResourceDx12) + { + return; + } + + D3D12RenderContext* pContext = D3D12RenderContext::Instance(); + pContext->DestroyBuffer(pResourceDx12->m_BoneIndicesBuffer); + pContext->DestroyBuffer(pResourceDx12->m_BoneWeightsBuffer); +} + +D3DHandles& RenderPluginDx12::GetDeviceHandles(D3DHandles& deviceHandles) +{ + return D3D12Util::GetDeviceHandles(deviceHandles); +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.h new file mode 100644 index 0000000..a88dfbf --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/D3D12/RenderPluginDx12.h @@ -0,0 +1,83 @@ +#pragma once + +#include "RenderPlugin.h" + +extern "C" CORERENDER_EXPORT RenderPlugin* CreateRenderPlugin(void); + +class CORERENDER_EXPORT RenderPluginDx12 : public RenderPlugin +{ +public: + RenderPluginDx12(); + ~RenderPluginDx12(); + + // interface + virtual bool InitDevice(int deviceID); + virtual bool Initialize(); + virtual void Shutdown(); + virtual void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth); + virtual void ApplyDepthStencilState(DEPTH_STENCIL_STATE state); + virtual void ApplyRasterizerState(RASTERIZER_STATE state); + virtual void ApplySampler(int slot, SAMPLER_TYPE st); + virtual void ApplyBlendState(BLEND_STATE st); + virtual void GetViewport(Viewport& vp); + virtual void SetViewport(const Viewport& vp); + virtual void BindVertexShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs); + virtual void BindPixelShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs); + virtual void ClearVertexShaderResources(int startSlot, int numSRVs); + virtual void ClearPixelShaderResources(int startSlot, int numSRVs); + virtual void ClearInputLayout(); + virtual void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset = 0); + virtual void SetPrimitiveTopologyTriangleStrip(); + virtual void SetPrimitiveTopologyTriangleList(); + virtual void SetPrimitiveTopologyLineList(); + virtual void Draw(unsigned int vertexCount, unsigned int startCount = 0); + virtual GPUBufferResource* CreateVertexBuffer(unsigned int ByteWidth, void* pSysMem = 0); + virtual GPUShaderResource* CreateShaderResource(unsigned int stride, unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer = NULL); + virtual void ApplyForShadow(int ForShadow); + virtual void SwitchToDX11(); + virtual void FlushDX11(); + virtual void FlushDX12(); + virtual void ApplyPrimitiveTopologyLine(); + virtual void ApplyPrimitiveTopologyTriangle(); + virtual void SubmitGpuWork(); + virtual void WaitForGpu(); + + // util + virtual bool CreateRenderWindow(HWND hWnd, int nSamples); + virtual bool ResizeRenderWindow(int w, int h); + virtual void PresentRenderWindow(); + virtual void ClearRenderWindow(float r, float g, float b); + virtual bool GetDeviceInfoString(wchar_t *str); + virtual GPUShaderResource* CreateTextureSRV(const char* texturename); + virtual void TxtHelperBegin(); + virtual void TxtHelperEnd(); + virtual void TxtHelperSetInsertionPos(int x, int y); + virtual void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f); + virtual void TxtHelperDrawTextLine(wchar_t* str); + + // shader + virtual bool InitializeShaders(); + virtual void DestroyShaders(); + virtual void ApplyShader(SHADER_TYPE st); + virtual void DisableShader(SHADER_TYPE st); + virtual void BindShaderResources(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs); + virtual void CopyShaderParam(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0); + + // GPUProfiler + virtual GPUProfiler* CreateGPUProfiler(); + + // ShadowMap + virtual ShadowMap* CreateShadowMap(int resolution); + + // D3D12RenderContext + virtual void PreRender(); + virtual void PostRender(); + + // GPUMeshResources + virtual GPUMeshResources* GPUMeshResourcesCreate(MeshData* pMeshData, const SkinData& skinData); + virtual void GPUMeshResourcesRelease(GPUMeshResources* pResource); + + // Get devices related + virtual D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles); +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.cpp new file mode 100644 index 0000000..08a3497 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.cpp @@ -0,0 +1,87 @@ +// 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-2015 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. +// +#include "GPUProfiler.h" + +#include "RenderPlugin.h" + +#ifndef SAFE_DELETE +#define SAFE_DELETE(x) {if(x){delete x; x=nullptr;}} +#endif + +GPUProfiler* g_pGPUProfiler = 0; + +void GPUProfiler_Initialize() +{ + g_pGPUProfiler = RenderPlugin::Instance()->CreateGPUProfiler(); +} + +void GPUProfiler_Shutdown() +{ + SAFE_DELETE(g_pGPUProfiler); +} + +void GPUProfiler_Enable(bool b) +{ + if (g_pGPUProfiler) + g_pGPUProfiler->Enable(b); +} + +void GPUProfiler_StartFrame() +{ + if (g_pGPUProfiler) + g_pGPUProfiler->StartFrame(); +} + +void GPUProfiler_EndFrame() +{ + if (g_pGPUProfiler) + g_pGPUProfiler->EndFrame(); +} + +void GPUProfiler_StartProfile(int id) +{ + if (g_pGPUProfiler) + g_pGPUProfiler->StartProfile(id); +} + +void GPUProfiler_EndProfile(int id) +{ + if (g_pGPUProfiler) + g_pGPUProfiler->EndProfile(id); +} + +float GPUProfiler_GetProfileData(int id) +{ + if (!g_pGPUProfiler) + return 0; + + return g_pGPUProfiler->GetProfileData(id); +} + + + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.h new file mode 100644 index 0000000..65bb602 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/GPUProfiler.h @@ -0,0 +1,61 @@ +// 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-2015 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. +// + +#pragma once + +#include "corelib_global.h" + +struct CORELIB_EXPORT GPUProfiler +{ + bool m_enable; + +public: + // define base class virtual destructor to make sure child classes call destructor right. + virtual ~GPUProfiler() {} + + void Enable(bool b) { m_enable = b; } + + virtual void Initialize() = 0; + virtual void Release() = 0; + virtual void StartFrame() = 0; + virtual void EndFrame() = 0; + virtual void StartProfile(int id) = 0; + virtual void EndProfile(int id) = 0; + virtual float GetProfileData(int id) = 0; +}; + +// helper functions +CORELIB_EXPORT void GPUProfiler_Initialize(); +CORELIB_EXPORT void GPUProfiler_Enable(bool); +CORELIB_EXPORT void GPUProfiler_Shutdown(); +CORELIB_EXPORT void GPUProfiler_StartFrame(); +CORELIB_EXPORT void GPUProfiler_EndFrame(); +CORELIB_EXPORT void GPUProfiler_StartProfile(int id); +CORELIB_EXPORT void GPUProfiler_EndProfile(int id); +CORELIB_EXPORT float GPUProfiler_GetProfileData(int id); + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/GeometryData/BoneGeometryData.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/GeometryData/BoneGeometryData.h new file mode 100644 index 0000000..4a6ea37 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/GeometryData/BoneGeometryData.h @@ -0,0 +1,305 @@ +const int num_faces = 100; + +// pos.xyz, uv.uv, normal.xyz +float vertices[100*3*8] = { +0.250000, -0.951057, -0.181636, 0.000000, 0.900000, 0.277578, -0.881468, -0.382053, +0.095491, -0.951057, -0.293893, 0.100000, 0.900000, 0.277578, -0.881468, -0.382053, +0.181636, -0.809017, -0.559017, 0.100000, 0.800000, 0.277578, -0.881468, -0.382053, +0.095491, -0.951057, -0.293893, 0.100000, 0.900000, -0.000000, -0.881468, -0.472244, +-0.095492, -0.951057, -0.293893, 0.200000, 0.900000, -0.000000, -0.881468, -0.472244, +-0.181636, -0.809017, -0.559017, 0.200000, 0.800000, -0.000000, -0.881468, -0.472244, +-0.095492, -0.951057, -0.293893, 0.200000, 0.900000, -0.277578, -0.881468, -0.382053, +-0.250000, -0.951057, -0.181636, 0.300000, 0.900000, -0.277578, -0.881468, -0.382053, +-0.475528, -0.809017, -0.345491, 0.300000, 0.800000, -0.277578, -0.881468, -0.382053, +-0.250000, -0.951057, -0.181636, 0.300000, 0.900000, -0.449130, -0.881468, -0.145931, +-0.309017, -0.951057, 0.000000, 0.400000, 0.900000, -0.449130, -0.881468, -0.145931, +-0.587785, -0.809017, 0.000000, 0.400000, 0.800000, -0.449130, -0.881468, -0.145931, +-0.309017, -0.951057, 0.000000, 0.400000, 0.900000, -0.449130, -0.881468, 0.145931, +-0.250000, -0.951057, 0.181636, 0.500000, 0.900000, -0.449130, -0.881468, 0.145931, +-0.475528, -0.809017, 0.345492, 0.500000, 0.800000, -0.449130, -0.881468, 0.145931, +-0.250000, -0.951057, 0.181636, 0.500000, 0.900000, -0.277578, -0.881468, 0.382053, +-0.095491, -0.951057, 0.293893, 0.600000, 0.900000, -0.277578, -0.881468, 0.382053, +-0.181636, -0.809017, 0.559017, 0.600000, 0.800000, -0.277578, -0.881468, 0.382053, +-0.095491, -0.951057, 0.293893, 0.600000, 0.900000, 0.000000, -0.881468, 0.472244, +0.095492, -0.951057, 0.293893, 0.700000, 0.900000, 0.000000, -0.881468, 0.472244, +0.181636, -0.809017, 0.559017, 0.700000, 0.800000, 0.000000, -0.881468, 0.472244, +0.095492, -0.951057, 0.293893, 0.700000, 0.900000, 0.277578, -0.881468, 0.382053, +0.250000, -0.951057, 0.181636, 0.800000, 0.900000, 0.277578, -0.881468, 0.382053, +0.475528, -0.809017, 0.345491, 0.800000, 0.800000, 0.277578, -0.881468, 0.382053, +0.250000, -0.951057, 0.181636, 0.800000, 0.900000, 0.449130, -0.881468, 0.145931, +0.309017, -0.951057, 0.000000, 0.900000, 0.900000, 0.449130, -0.881468, 0.145931, +0.587785, -0.809017, 0.000000, 0.900000, 0.800000, 0.449131, -0.881468, 0.145931, +0.309017, -0.951057, 0.000000, 0.900000, 0.900000, 0.449131, -0.881468, -0.145931, +0.250000, -0.951057, -0.181636, 1.000000, 0.900000, 0.449131, -0.881468, -0.145931, +0.475528, -0.809017, -0.345492, 1.000000, 0.800000, 0.449131, -0.881468, -0.145931, +0.475528, -0.809017, -0.345492, 0.000000, 0.800000, 0.425919, -0.689152, -0.586227, +0.181636, -0.809017, -0.559017, 0.100000, 0.800000, 0.425919, -0.689152, -0.586227, +0.250000, -0.587785, -0.769421, 0.100000, 0.700000, 0.425919, -0.689152, -0.586227, +0.181636, -0.809017, -0.559017, 0.100000, 0.800000, -0.000000, -0.689152, -0.724617, +-0.181636, -0.809017, -0.559017, 0.200000, 0.800000, -0.000000, -0.689152, -0.724617, +-0.250000, -0.587785, -0.769421, 0.200000, 0.700000, -0.000000, -0.689152, -0.724617, +-0.181636, -0.809017, -0.559017, 0.200000, 0.800000, -0.425919, -0.689152, -0.586228, +-0.475528, -0.809017, -0.345491, 0.300000, 0.800000, -0.425919, -0.689152, -0.586228, +-0.654509, -0.587785, -0.475528, 0.300000, 0.700000, -0.425919, -0.689152, -0.586228, +-0.475528, -0.809017, -0.345491, 0.300000, 0.800000, -0.689152, -0.689152, -0.223919, +-0.587785, -0.809017, 0.000000, 0.400000, 0.800000, -0.689152, -0.689152, -0.223919, +-0.809017, -0.587785, 0.000000, 0.400000, 0.700000, -0.689152, -0.689152, -0.223919, +-0.587785, -0.809017, 0.000000, 0.400000, 0.800000, -0.689152, -0.689152, 0.223919, +-0.475528, -0.809017, 0.345492, 0.500000, 0.800000, -0.689152, -0.689152, 0.223919, +-0.654509, -0.587785, 0.475528, 0.500000, 0.700000, -0.689152, -0.689152, 0.223919, +-0.475528, -0.809017, 0.345492, 0.500000, 0.800000, -0.425919, -0.689152, 0.586228, +-0.181636, -0.809017, 0.559017, 0.600000, 0.800000, -0.425919, -0.689152, 0.586228, +-0.250000, -0.587785, 0.769421, 0.600000, 0.700000, -0.425919, -0.689152, 0.586228, +-0.181636, -0.809017, 0.559017, 0.600000, 0.800000, 0.000000, -0.689152, 0.724617, +0.181636, -0.809017, 0.559017, 0.700000, 0.800000, 0.000000, -0.689152, 0.724617, +0.250000, -0.587785, 0.769421, 0.700000, 0.700000, 0.000000, -0.689152, 0.724617, +0.181636, -0.809017, 0.559017, 0.700000, 0.800000, 0.425919, -0.689152, 0.586227, +0.475528, -0.809017, 0.345491, 0.800000, 0.800000, 0.425919, -0.689152, 0.586227, +0.654509, -0.587785, 0.475528, 0.800000, 0.700000, 0.425919, -0.689152, 0.586227, +0.475528, -0.809017, 0.345491, 0.800000, 0.800000, 0.689152, -0.689152, 0.223919, +0.587785, -0.809017, 0.000000, 0.900000, 0.800000, 0.689152, -0.689152, 0.223919, +0.809017, -0.587785, 0.000000, 0.900000, 0.700000, 0.689152, -0.689152, 0.223919, +0.587785, -0.809017, 0.000000, 0.900000, 0.800000, 0.689152, -0.689152, -0.223919, +0.475528, -0.809017, -0.345492, 1.000000, 0.800000, 0.689152, -0.689152, -0.223919, +0.654509, -0.587785, -0.475528, 1.000000, 0.700000, 0.689152, -0.689152, -0.223919, +0.654509, -0.587785, -0.475528, 0.000000, 0.700000, 0.528952, -0.436083, -0.728040, +0.250000, -0.587785, -0.769421, 0.100000, 0.700000, 0.528952, -0.436083, -0.728040, +0.293893, -0.309017, -0.904509, 0.100000, 0.600000, 0.528952, -0.436083, -0.728040, +0.250000, -0.587785, -0.769421, 0.100000, 0.700000, -0.000000, -0.436083, -0.899906, +-0.250000, -0.587785, -0.769421, 0.200000, 0.700000, -0.000000, -0.436083, -0.899906, +-0.293893, -0.309017, -0.904509, 0.200000, 0.600000, -0.000000, -0.436083, -0.899906, +-0.250000, -0.587785, -0.769421, 0.200000, 0.700000, -0.528952, -0.436083, -0.728040, +-0.654509, -0.587785, -0.475528, 0.300000, 0.700000, -0.528952, -0.436083, -0.728040, +-0.769421, -0.309017, -0.559017, 0.300000, 0.600000, -0.528952, -0.436083, -0.728040, +-0.654509, -0.587785, -0.475528, 0.300000, 0.700000, -0.855862, -0.436083, -0.278086, +-0.809017, -0.587785, 0.000000, 0.400000, 0.700000, -0.855862, -0.436083, -0.278086, +-0.951057, -0.309017, 0.000000, 0.400000, 0.600000, -0.855862, -0.436083, -0.278086, +-0.809017, -0.587785, 0.000000, 0.400000, 0.700000, -0.855862, -0.436083, 0.278086, +-0.654509, -0.587785, 0.475528, 0.500000, 0.700000, -0.855862, -0.436083, 0.278086, +-0.769421, -0.309017, 0.559017, 0.500000, 0.600000, -0.855862, -0.436083, 0.278086, +-0.654509, -0.587785, 0.475528, 0.500000, 0.700000, -0.528952, -0.436083, 0.728040, +-0.250000, -0.587785, 0.769421, 0.600000, 0.700000, -0.528952, -0.436083, 0.728039, +-0.293893, -0.309017, 0.904509, 0.600000, 0.600000, -0.528952, -0.436083, 0.728039, +-0.250000, -0.587785, 0.769421, 0.600000, 0.700000, 0.000000, -0.436083, 0.899906, +0.250000, -0.587785, 0.769421, 0.700000, 0.700000, 0.000000, -0.436083, 0.899906, +0.293893, -0.309017, 0.904509, 0.700000, 0.600000, 0.000000, -0.436083, 0.899906, +0.250000, -0.587785, 0.769421, 0.700000, 0.700000, 0.528952, -0.436083, 0.728039, +0.654509, -0.587785, 0.475528, 0.800000, 0.700000, 0.528952, -0.436083, 0.728040, +0.769421, -0.309017, 0.559017, 0.800000, 0.600000, 0.528952, -0.436083, 0.728040, +0.654509, -0.587785, 0.475528, 0.800000, 0.700000, 0.855862, -0.436083, 0.278086, +0.809017, -0.587785, 0.000000, 0.900000, 0.700000, 0.855862, -0.436083, 0.278086, +0.951057, -0.309017, 0.000000, 0.900000, 0.600000, 0.855862, -0.436083, 0.278086, +0.809017, -0.587785, 0.000000, 0.900000, 0.700000, 0.855862, -0.436084, -0.278086, +0.654509, -0.587785, -0.475528, 1.000000, 0.700000, 0.855862, -0.436084, -0.278086, +0.769421, -0.309017, -0.559017, 1.000000, 0.600000, 0.855862, -0.436084, -0.278086, +0.769421, -0.309017, -0.559017, 0.000000, 0.600000, 0.581228, -0.148952, -0.799992, +0.293893, -0.309017, -0.904509, 0.100000, 0.600000, 0.581228, -0.148952, -0.799992, +0.309017, 0.000000, -0.951057, 0.100000, 0.500000, 0.581228, -0.148952, -0.799992, +0.293893, -0.309017, -0.904509, 0.100000, 0.600000, -0.000000, -0.148952, -0.988844, +-0.293893, -0.309017, -0.904509, 0.200000, 0.600000, -0.000000, -0.148952, -0.988844, +-0.309017, 0.000000, -0.951057, 0.200000, 0.500000, -0.000000, -0.148952, -0.988844, +-0.293893, -0.309017, -0.904509, 0.200000, 0.600000, -0.581228, -0.148952, -0.799992, +-0.769421, -0.309017, -0.559017, 0.300000, 0.600000, -0.581228, -0.148952, -0.799992, +-0.809017, 0.000000, -0.587785, 0.300000, 0.500000, -0.581228, -0.148952, -0.799992, +-0.769421, -0.309017, -0.559017, 0.300000, 0.600000, -0.940447, -0.148952, -0.305570, +-0.951057, -0.309017, 0.000000, 0.400000, 0.600000, -0.940447, -0.148952, -0.305570, +-1.000000, 0.000000, 0.000000, 0.400000, 0.500000, -0.940447, -0.148952, -0.305570, +-0.951057, -0.309017, 0.000000, 0.400000, 0.600000, -0.940447, -0.148952, 0.305570, +-0.769421, -0.309017, 0.559017, 0.500000, 0.600000, -0.940447, -0.148952, 0.305570, +-0.809017, 0.000000, 0.587785, 0.500000, 0.500000, -0.940447, -0.148952, 0.305570, +-0.769421, -0.309017, 0.559017, 0.500000, 0.600000, -0.581228, -0.148952, 0.799992, +-0.293893, -0.309017, 0.904509, 0.600000, 0.600000, -0.581228, -0.148952, 0.799992, +-0.309017, 0.000000, 0.951057, 0.600000, 0.500000, -0.581228, -0.148952, 0.799992, +-0.293893, -0.309017, 0.904509, 0.600000, 0.600000, 0.000000, -0.148952, 0.988844, +0.293893, -0.309017, 0.904509, 0.700000, 0.600000, 0.000000, -0.148952, 0.988844, +0.309017, 0.000000, 0.951057, 0.700000, 0.500000, 0.000000, -0.148952, 0.988844, +0.293893, -0.309017, 0.904509, 0.700000, 0.600000, 0.581228, -0.148952, 0.799992, +0.769421, -0.309017, 0.559017, 0.800000, 0.600000, 0.581228, -0.148952, 0.799992, +0.809017, 0.000000, 0.587785, 0.800000, 0.500000, 0.581228, -0.148952, 0.799992, +0.769421, -0.309017, 0.559017, 0.800000, 0.600000, 0.940447, -0.148952, 0.305570, +0.951057, -0.309017, 0.000000, 0.900000, 0.600000, 0.940447, -0.148952, 0.305570, +1.000000, 0.000000, 0.000000, 0.900000, 0.500000, 0.940447, -0.148952, 0.305570, +0.951057, -0.309017, 0.000000, 0.900000, 0.600000, 0.940447, -0.148952, -0.305570, +0.769421, -0.309017, -0.559017, 1.000000, 0.600000, 0.940447, -0.148952, -0.305570, +0.809017, 0.000000, -0.587785, 1.000000, 0.500000, 0.940447, -0.148952, -0.305570, +0.809017, 0.000000, -0.587785, 0.000000, 0.500000, 0.581228, 0.148952, -0.799992, +0.309017, 0.000000, -0.951057, 0.100000, 0.500000, 0.581228, 0.148952, -0.799992, +0.293893, 0.309017, -0.904509, 0.100000, 0.400000, 0.581228, 0.148952, -0.799992, +0.309017, 0.000000, -0.951057, 0.100000, 0.500000, -0.000000, 0.148952, -0.988844, +-0.309017, 0.000000, -0.951057, 0.200000, 0.500000, -0.000000, 0.148952, -0.988844, +-0.293893, 0.309017, -0.904509, 0.200000, 0.400000, -0.000000, 0.148952, -0.988844, +-0.309017, 0.000000, -0.951057, 0.200000, 0.500000, -0.581228, 0.148952, -0.799992, +-0.809017, 0.000000, -0.587785, 0.300000, 0.500000, -0.581228, 0.148952, -0.799992, +-0.769421, 0.309017, -0.559017, 0.300000, 0.400000, -0.581228, 0.148952, -0.799992, +-0.809017, 0.000000, -0.587785, 0.300000, 0.500000, -0.940447, 0.148952, -0.305570, +-1.000000, 0.000000, 0.000000, 0.400000, 0.500000, -0.940447, 0.148952, -0.305570, +-0.951057, 0.309017, 0.000000, 0.400000, 0.400000, -0.940447, 0.148952, -0.305570, +-1.000000, 0.000000, 0.000000, 0.400000, 0.500000, -0.940447, 0.148952, 0.305570, +-0.809017, 0.000000, 0.587785, 0.500000, 0.500000, -0.940447, 0.148952, 0.305570, +-0.769421, 0.309017, 0.559017, 0.500000, 0.400000, -0.940447, 0.148952, 0.305570, +-0.809017, 0.000000, 0.587785, 0.500000, 0.500000, -0.581228, 0.148952, 0.799992, +-0.309017, 0.000000, 0.951057, 0.600000, 0.500000, -0.581228, 0.148952, 0.799992, +-0.293893, 0.309017, 0.904509, 0.600000, 0.400000, -0.581228, 0.148952, 0.799992, +-0.309017, 0.000000, 0.951057, 0.600000, 0.500000, 0.000000, 0.148952, 0.988844, +0.309017, 0.000000, 0.951057, 0.700000, 0.500000, 0.000000, 0.148952, 0.988844, +0.293893, 0.309017, 0.904509, 0.700000, 0.400000, 0.000000, 0.148952, 0.988844, +0.309017, 0.000000, 0.951057, 0.700000, 0.500000, 0.581228, 0.148952, 0.799992, +0.809017, 0.000000, 0.587785, 0.800000, 0.500000, 0.581228, 0.148952, 0.799992, +0.769421, 0.309017, 0.559017, 0.800000, 0.400000, 0.581228, 0.148952, 0.799992, +0.809017, 0.000000, 0.587785, 0.800000, 0.500000, 0.940447, 0.148952, 0.305570, +1.000000, 0.000000, 0.000000, 0.900000, 0.500000, 0.940447, 0.148952, 0.305570, +0.951057, 0.309017, 0.000000, 0.900000, 0.400000, 0.940447, 0.148952, 0.305570, +1.000000, 0.000000, 0.000000, 0.900000, 0.500000, 0.940447, 0.148952, -0.305570, +0.809017, 0.000000, -0.587785, 1.000000, 0.500000, 0.940447, 0.148952, -0.305570, +0.769421, 0.309017, -0.559017, 1.000000, 0.400000, 0.940447, 0.148952, -0.305569, +0.769421, 0.309017, -0.559017, 0.000000, 0.400000, 0.528952, 0.436083, -0.728040, +0.293893, 0.309017, -0.904509, 0.100000, 0.400000, 0.528952, 0.436083, -0.728040, +0.250000, 0.587785, -0.769421, 0.100000, 0.300000, 0.528952, 0.436083, -0.728040, +0.293893, 0.309017, -0.904509, 0.100000, 0.400000, -0.000000, 0.436083, -0.899906, +-0.293893, 0.309017, -0.904509, 0.200000, 0.400000, -0.000000, 0.436083, -0.899906, +-0.250000, 0.587785, -0.769421, 0.200000, 0.300000, -0.000000, 0.436083, -0.899906, +-0.293893, 0.309017, -0.904509, 0.200000, 0.400000, -0.528952, 0.436083, -0.728039, +-0.769421, 0.309017, -0.559017, 0.300000, 0.400000, -0.528952, 0.436083, -0.728039, +-0.654509, 0.587785, -0.475528, 0.300000, 0.300000, -0.528952, 0.436083, -0.728039, +-0.769421, 0.309017, -0.559017, 0.300000, 0.400000, -0.855862, 0.436083, -0.278086, +-0.951057, 0.309017, 0.000000, 0.400000, 0.400000, -0.855862, 0.436083, -0.278086, +-0.809017, 0.587785, 0.000000, 0.400000, 0.300000, -0.855862, 0.436083, -0.278086, +-0.951057, 0.309017, 0.000000, 0.400000, 0.400000, -0.855862, 0.436083, 0.278086, +-0.769421, 0.309017, 0.559017, 0.500000, 0.400000, -0.855862, 0.436083, 0.278086, +-0.654509, 0.587785, 0.475528, 0.500000, 0.300000, -0.855862, 0.436083, 0.278086, +-0.769421, 0.309017, 0.559017, 0.500000, 0.400000, -0.528952, 0.436083, 0.728039, +-0.293893, 0.309017, 0.904509, 0.600000, 0.400000, -0.528952, 0.436083, 0.728039, +-0.250000, 0.587785, 0.769421, 0.600000, 0.300000, -0.528952, 0.436083, 0.728039, +-0.293893, 0.309017, 0.904509, 0.600000, 0.400000, 0.000000, 0.436083, 0.899906, +0.293893, 0.309017, 0.904509, 0.700000, 0.400000, 0.000000, 0.436083, 0.899906, +0.250000, 0.587785, 0.769421, 0.700000, 0.300000, 0.000000, 0.436083, 0.899906, +0.293893, 0.309017, 0.904509, 0.700000, 0.400000, 0.528952, 0.436083, 0.728040, +0.769421, 0.309017, 0.559017, 0.800000, 0.400000, 0.528952, 0.436083, 0.728040, +0.654509, 0.587785, 0.475528, 0.800000, 0.300000, 0.528952, 0.436083, 0.728040, +0.769421, 0.309017, 0.559017, 0.800000, 0.400000, 0.855862, 0.436083, 0.278086, +0.951057, 0.309017, 0.000000, 0.900000, 0.400000, 0.855862, 0.436083, 0.278086, +0.809017, 0.587785, 0.000000, 0.900000, 0.300000, 0.855862, 0.436083, 0.278086, +0.951057, 0.309017, 0.000000, 0.900000, 0.400000, 0.855862, 0.436084, -0.278086, +0.769421, 0.309017, -0.559017, 1.000000, 0.400000, 0.855862, 0.436084, -0.278086, +0.654509, 0.587785, -0.475528, 1.000000, 0.300000, 0.855862, 0.436084, -0.278086, +0.654509, 0.587785, -0.475528, 0.000000, 0.300000, 0.425919, 0.689152, -0.586227, +0.250000, 0.587785, -0.769421, 0.100000, 0.300000, 0.425919, 0.689152, -0.586227, +0.181636, 0.809017, -0.559017, 0.100000, 0.200000, 0.425919, 0.689152, -0.586227, +0.250000, 0.587785, -0.769421, 0.100000, 0.300000, -0.000000, 0.689152, -0.724617, +-0.250000, 0.587785, -0.769421, 0.200000, 0.300000, -0.000000, 0.689152, -0.724617, +-0.181636, 0.809017, -0.559017, 0.200000, 0.200000, -0.000000, 0.689152, -0.724617, +-0.250000, 0.587785, -0.769421, 0.200000, 0.300000, -0.425919, 0.689152, -0.586227, +-0.654509, 0.587785, -0.475528, 0.300000, 0.300000, -0.425919, 0.689152, -0.586227, +-0.475528, 0.809017, -0.345491, 0.300000, 0.200000, -0.425919, 0.689152, -0.586227, +-0.654509, 0.587785, -0.475528, 0.300000, 0.300000, -0.689152, 0.689152, -0.223919, +-0.809017, 0.587785, 0.000000, 0.400000, 0.300000, -0.689152, 0.689152, -0.223919, +-0.587785, 0.809017, 0.000000, 0.400000, 0.200000, -0.689152, 0.689152, -0.223919, +-0.809017, 0.587785, 0.000000, 0.400000, 0.300000, -0.689152, 0.689152, 0.223919, +-0.654509, 0.587785, 0.475528, 0.500000, 0.300000, -0.689152, 0.689152, 0.223919, +-0.475528, 0.809017, 0.345492, 0.500000, 0.200000, -0.689152, 0.689152, 0.223919, +-0.654509, 0.587785, 0.475528, 0.500000, 0.300000, -0.425919, 0.689152, 0.586228, +-0.250000, 0.587785, 0.769421, 0.600000, 0.300000, -0.425919, 0.689152, 0.586228, +-0.181636, 0.809017, 0.559017, 0.600000, 0.200000, -0.425919, 0.689152, 0.586228, +-0.250000, 0.587785, 0.769421, 0.600000, 0.300000, 0.000000, 0.689152, 0.724617, +0.250000, 0.587785, 0.769421, 0.700000, 0.300000, 0.000000, 0.689152, 0.724617, +0.181636, 0.809017, 0.559017, 0.700000, 0.200000, 0.000000, 0.689152, 0.724617, +0.250000, 0.587785, 0.769421, 0.700000, 0.300000, 0.425919, 0.689152, 0.586227, +0.654509, 0.587785, 0.475528, 0.800000, 0.300000, 0.425919, 0.689152, 0.586227, +0.475528, 0.809017, 0.345491, 0.800000, 0.200000, 0.425919, 0.689152, 0.586227, +0.654509, 0.587785, 0.475528, 0.800000, 0.300000, 0.689152, 0.689152, 0.223919, +0.809017, 0.587785, 0.000000, 0.900000, 0.300000, 0.689152, 0.689152, 0.223919, +0.587785, 0.809017, 0.000000, 0.900000, 0.200000, 0.689152, 0.689152, 0.223919, +0.809017, 0.587785, 0.000000, 0.900000, 0.300000, 0.689152, 0.689152, -0.223919, +0.654509, 0.587785, -0.475528, 1.000000, 0.300000, 0.689152, 0.689152, -0.223919, +0.475528, 0.809017, -0.345492, 1.000000, 0.200000, 0.689152, 0.689152, -0.223919, +0.475528, 0.809017, -0.345492, 0.000000, 0.200000, 0.277578, 0.881468, -0.382053, +0.181636, 0.809017, -0.559017, 0.100000, 0.200000, 0.277578, 0.881468, -0.382053, +0.095491, 0.951057, -0.293893, 0.100000, 0.100000, 0.277578, 0.881468, -0.382053, +0.181636, 0.809017, -0.559017, 0.100000, 0.200000, -0.000000, 0.881468, -0.472244, +-0.181636, 0.809017, -0.559017, 0.200000, 0.200000, -0.000000, 0.881468, -0.472244, +-0.095492, 0.951057, -0.293893, 0.200000, 0.100000, -0.000000, 0.881468, -0.472244, +-0.181636, 0.809017, -0.559017, 0.200000, 0.200000, -0.277578, 0.881468, -0.382053, +-0.475528, 0.809017, -0.345491, 0.300000, 0.200000, -0.277578, 0.881468, -0.382053, +-0.250000, 0.951057, -0.181636, 0.300000, 0.100000, -0.277578, 0.881468, -0.382053, +-0.475528, 0.809017, -0.345491, 0.300000, 0.200000, -0.449130, 0.881468, -0.145931, +-0.587785, 0.809017, 0.000000, 0.400000, 0.200000, -0.449130, 0.881468, -0.145931, +-0.309017, 0.951057, 0.000000, 0.400000, 0.100000, -0.449130, 0.881468, -0.145931, +-0.587785, 0.809017, 0.000000, 0.400000, 0.200000, -0.449130, 0.881468, 0.145931, +-0.475528, 0.809017, 0.345492, 0.500000, 0.200000, -0.449130, 0.881468, 0.145931, +-0.250000, 0.951057, 0.181636, 0.500000, 0.100000, -0.449131, 0.881468, 0.145931, +-0.475528, 0.809017, 0.345492, 0.500000, 0.200000, -0.277578, 0.881468, 0.382053, +-0.181636, 0.809017, 0.559017, 0.600000, 0.200000, -0.277578, 0.881468, 0.382053, +-0.095491, 0.951057, 0.293893, 0.600000, 0.100000, -0.277578, 0.881468, 0.382053, +-0.181636, 0.809017, 0.559017, 0.600000, 0.200000, 0.000000, 0.881468, 0.472244, +0.181636, 0.809017, 0.559017, 0.700000, 0.200000, 0.000000, 0.881468, 0.472244, +0.095492, 0.951057, 0.293893, 0.700000, 0.100000, 0.000000, 0.881468, 0.472244, +0.181636, 0.809017, 0.559017, 0.700000, 0.200000, 0.277578, 0.881468, 0.382053, +0.475528, 0.809017, 0.345491, 0.800000, 0.200000, 0.277578, 0.881468, 0.382053, +0.250000, 0.951057, 0.181636, 0.800000, 0.100000, 0.277578, 0.881468, 0.382053, +0.475528, 0.809017, 0.345491, 0.800000, 0.200000, 0.449131, 0.881468, 0.145931, +0.587785, 0.809017, 0.000000, 0.900000, 0.200000, 0.449131, 0.881468, 0.145931, +0.309017, 0.951057, 0.000000, 0.900000, 0.100000, 0.449130, 0.881468, 0.145931, +0.587785, 0.809017, 0.000000, 0.900000, 0.200000, 0.449131, 0.881468, -0.145931, +0.475528, 0.809017, -0.345492, 1.000000, 0.200000, 0.449131, 0.881468, -0.145931, +0.250000, 0.951057, -0.181636, 1.000000, 0.100000, 0.449131, 0.881468, -0.145931, +0.095491, -0.951057, -0.293893, 0.100000, 0.900000, 0.096557, -0.986415, -0.132899, +0.250000, -0.951057, -0.181636, 0.000000, 0.900000, 0.096557, -0.986415, -0.132899, +0.000000, -1.000000, 0.000000, 0.050000, 1.000000, 0.096557, -0.986415, -0.132899, +-0.095492, -0.951057, -0.293893, 0.200000, 0.900000, -0.000000, -0.986415, -0.164272, +0.095491, -0.951057, -0.293893, 0.100000, 0.900000, -0.000000, -0.986415, -0.164272, +0.000000, -1.000000, 0.000000, 0.150000, 1.000000, -0.000000, -0.986415, -0.164272, +-0.250000, -0.951057, -0.181636, 0.300000, 0.900000, -0.096557, -0.986415, -0.132899, +-0.095492, -0.951057, -0.293893, 0.200000, 0.900000, -0.096557, -0.986415, -0.132899, +0.000000, -1.000000, 0.000000, 0.250000, 1.000000, -0.096557, -0.986415, -0.132899, +-0.309017, -0.951057, 0.000000, 0.400000, 0.900000, -0.156233, -0.986415, -0.050763, +-0.250000, -0.951057, -0.181636, 0.300000, 0.900000, -0.156233, -0.986415, -0.050763, +0.000000, -1.000000, 0.000000, 0.350000, 1.000000, -0.156233, -0.986415, -0.050763, +-0.250000, -0.951057, 0.181636, 0.500000, 0.900000, -0.156233, -0.986415, 0.050763, +-0.309017, -0.951057, 0.000000, 0.400000, 0.900000, -0.156233, -0.986415, 0.050763, +0.000000, -1.000000, 0.000000, 0.450000, 1.000000, -0.156233, -0.986415, 0.050763, +-0.095491, -0.951057, 0.293893, 0.600000, 0.900000, -0.096557, -0.986415, 0.132899, +-0.250000, -0.951057, 0.181636, 0.500000, 0.900000, -0.096557, -0.986415, 0.132899, +0.000000, -1.000000, 0.000000, 0.550000, 1.000000, -0.096557, -0.986415, 0.132899, +0.095492, -0.951057, 0.293893, 0.700000, 0.900000, 0.000000, -0.986415, 0.164272, +-0.095491, -0.951057, 0.293893, 0.600000, 0.900000, 0.000000, -0.986415, 0.164272, +0.000000, -1.000000, 0.000000, 0.650000, 1.000000, 0.000000, -0.986415, 0.164272, +0.250000, -0.951057, 0.181636, 0.800000, 0.900000, 0.096557, -0.986415, 0.132899, +0.095492, -0.951057, 0.293893, 0.700000, 0.900000, 0.096557, -0.986415, 0.132899, +0.000000, -1.000000, 0.000000, 0.750000, 1.000000, 0.096557, -0.986415, 0.132899, +0.309017, -0.951057, 0.000000, 0.900000, 0.900000, 0.156233, -0.986415, 0.050763, +0.250000, -0.951057, 0.181636, 0.800000, 0.900000, 0.156233, -0.986415, 0.050763, +0.000000, -1.000000, 0.000000, 0.850000, 1.000000, 0.156233, -0.986415, 0.050763, +0.250000, -0.951057, -0.181636, 1.000000, 0.900000, 0.156233, -0.986415, -0.050763, +0.309017, -0.951057, 0.000000, 0.900000, 0.900000, 0.156233, -0.986415, -0.050763, +0.000000, -1.000000, 0.000000, 0.950000, 1.000000, 0.156233, -0.986415, -0.050763, +0.250000, 0.951057, -0.181636, 0.000000, 0.100000, 0.096557, 0.986415, -0.132899, +0.095491, 0.951057, -0.293893, 0.100000, 0.100000, 0.096557, 0.986415, -0.132899, +0.000000, 1.000000, 0.000000, 0.050000, 0.000000, 0.096557, 0.986415, -0.132899, +0.095491, 0.951057, -0.293893, 0.100000, 0.100000, -0.000000, 0.986415, -0.164272, +-0.095492, 0.951057, -0.293893, 0.200000, 0.100000, -0.000000, 0.986415, -0.164272, +0.000000, 1.000000, 0.000000, 0.150000, 0.000000, -0.000000, 0.986415, -0.164272, +-0.095492, 0.951057, -0.293893, 0.200000, 0.100000, -0.096557, 0.986415, -0.132899, +-0.250000, 0.951057, -0.181636, 0.300000, 0.100000, -0.096557, 0.986415, -0.132899, +0.000000, 1.000000, 0.000000, 0.250000, 0.000000, -0.096557, 0.986415, -0.132899, +-0.250000, 0.951057, -0.181636, 0.300000, 0.100000, -0.156233, 0.986415, -0.050763, +-0.309017, 0.951057, 0.000000, 0.400000, 0.100000, -0.156233, 0.986415, -0.050763, +0.000000, 1.000000, 0.000000, 0.350000, 0.000000, -0.156233, 0.986415, -0.050763, +-0.309017, 0.951057, 0.000000, 0.400000, 0.100000, -0.156233, 0.986415, 0.050763, +-0.250000, 0.951057, 0.181636, 0.500000, 0.100000, -0.156233, 0.986415, 0.050763, +0.000000, 1.000000, 0.000000, 0.450000, 0.000000, -0.156233, 0.986415, 0.050763, +-0.250000, 0.951057, 0.181636, 0.500000, 0.100000, -0.096557, 0.986415, 0.132899, +-0.095491, 0.951057, 0.293893, 0.600000, 0.100000, -0.096557, 0.986415, 0.132899, +0.000000, 1.000000, 0.000000, 0.550000, 0.000000, -0.096557, 0.986415, 0.132899, +-0.095491, 0.951057, 0.293893, 0.600000, 0.100000, 0.000000, 0.986415, 0.164272, +0.095492, 0.951057, 0.293893, 0.700000, 0.100000, 0.000000, 0.986415, 0.164272, +0.000000, 1.000000, 0.000000, 0.650000, 0.000000, 0.000000, 0.986415, 0.164272, +0.095492, 0.951057, 0.293893, 0.700000, 0.100000, 0.096557, 0.986415, 0.132899, +0.250000, 0.951057, 0.181636, 0.800000, 0.100000, 0.096557, 0.986415, 0.132899, +0.000000, 1.000000, 0.000000, 0.750000, 0.000000, 0.096557, 0.986415, 0.132899, +0.250000, 0.951057, 0.181636, 0.800000, 0.100000, 0.156233, 0.986415, 0.050763, +0.309017, 0.951057, 0.000000, 0.900000, 0.100000, 0.156233, 0.986415, 0.050763, +0.000000, 1.000000, 0.000000, 0.850000, 0.000000, 0.156233, 0.986415, 0.050763, +0.309017, 0.951057, 0.000000, 0.900000, 0.100000, 0.156233, 0.986415, -0.050763, +0.250000, 0.951057, -0.181636, 1.000000, 0.100000, 0.156233, 0.986415, -0.050763, +0.000000, 1.000000, 0.000000, 0.950000, 0.000000, 0.156233, 0.986415, -0.050763, +}; diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/GeometryData/LightGeometryData.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/GeometryData/LightGeometryData.h new file mode 100644 index 0000000..ed21841 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/GeometryData/LightGeometryData.h @@ -0,0 +1,269 @@ +const int num_faces = 88; + +// pos.xyz, uv.uv, normal.xyz +float vertices[88*3*8] = { +2.977119, 2.977121, -34.306633, 0.375000, 0.687500, 0.177861, 0.429396, -0.885429, +0.000000, 4.210287, -34.306633, 0.406250, 0.687500, 0.177861, 0.429396, -0.885429, +0.000000, 9.084861, -31.942669, 0.406250, 0.640508, 0.177861, 0.429396, -0.885429, +0.000000, 4.210287, -34.306633, 0.406250, 0.687500, -0.177861, 0.429396, -0.885429, +-2.977119, 2.977121, -34.306633, 0.437500, 0.687500, -0.177861, 0.429396, -0.885429, +-6.423970, 6.423968, -31.942669, 0.437500, 0.640508, -0.177861, 0.429396, -0.885429, +-2.977119, 2.977121, -34.306633, 0.437500, 0.687500, -0.429395, 0.177862, -0.885430, +-4.210285, 0.000002, -34.306633, 0.468750, 0.687500, -0.429395, 0.177862, -0.885430, +-9.084864, -0.000001, -31.942669, 0.468750, 0.640508, -0.429395, 0.177862, -0.885429, +-4.210285, 0.000002, -34.306633, 0.468750, 0.687500, -0.429395, -0.177862, -0.885430, +-2.977119, -2.977118, -34.306633, 0.500000, 0.687500, -0.429395, -0.177862, -0.885430, +-6.423970, -6.423972, -31.942667, 0.500000, 0.640508, -0.429395, -0.177862, -0.885430, +-2.977119, -2.977118, -34.306633, 0.500000, 0.687500, -0.177861, -0.429395, -0.885429, +0.000000, -4.210283, -34.306633, 0.531250, 0.687500, -0.177861, -0.429395, -0.885429, +0.000000, -9.084865, -31.942671, 0.531250, 0.640508, -0.177861, -0.429395, -0.885429, +0.000000, -4.210283, -34.306633, 0.531250, 0.687500, 0.177862, -0.429395, -0.885429, +2.977120, -2.977118, -34.306633, 0.562500, 0.687500, 0.177862, -0.429395, -0.885429, +6.423971, -6.423972, -31.942667, 0.562500, 0.640508, 0.177862, -0.429395, -0.885429, +2.977120, -2.977118, -34.306633, 0.562500, 0.687500, 0.429395, -0.177862, -0.885430, +4.210286, 0.000002, -34.306633, 0.593750, 0.687500, 0.429395, -0.177862, -0.885430, +9.084865, -0.000001, -31.942669, 0.593750, 0.640508, 0.429395, -0.177862, -0.885429, +4.210286, 0.000002, -34.306633, 0.593750, 0.687500, 0.429395, 0.177862, -0.885429, +2.977119, 2.977121, -34.306633, 0.625000, 0.687500, 0.429395, 0.177862, -0.885429, +6.423971, 6.423968, -31.942669, 0.625000, 0.640508, 0.429395, 0.177862, -0.885429, +-4.210285, 0.000002, -34.306633, 0.343750, 0.843750, -0.124125, -0.051414, -0.990934, +0.000000, 0.000002, -34.834015, 0.500000, 0.843750, -0.124125, -0.051414, -0.990934, +-2.977119, -2.977118, -34.306633, 0.389515, 0.733265, -0.124125, -0.051414, -0.990934, +10.861003, 0.000000, -10.002398, 0.593750, 0.499530, 0.791070, 0.327672, -0.516564, +7.679888, 7.679888, -10.002398, 0.625000, 0.499530, 0.791071, 0.327672, -0.516564, +12.349342, 12.349340, 0.110407, 0.625000, 0.311560, 0.791070, 0.327672, -0.516564, +7.679889, -7.679889, -10.002397, 0.562500, 0.499530, 0.791071, -0.327672, -0.516564, +10.861003, 0.000000, -10.002398, 0.593750, 0.499530, 0.791070, -0.327672, -0.516564, +17.464600, 0.000000, 0.110407, 0.593750, 0.311560, 0.791070, -0.327672, -0.516564, +0.000000, -10.861002, -10.002398, 0.531250, 0.499530, 0.327672, -0.791071, -0.516564, +7.679889, -7.679889, -10.002397, 0.562500, 0.499530, 0.327672, -0.791071, -0.516564, +12.349343, -12.349342, 0.110407, 0.562500, 0.311560, 0.327672, -0.791071, -0.516564, +-7.679888, -7.679888, -10.002398, 0.500000, 0.499530, -0.327672, -0.791071, -0.516564, +0.000000, -10.861002, -10.002398, 0.531250, 0.499530, -0.327672, -0.791071, -0.516564, +0.000001, -17.464596, 0.110407, 0.531250, 0.311560, -0.327672, -0.791071, -0.516564, +-10.861002, 0.000000, -10.002398, 0.468750, 0.499530, -0.791071, -0.327672, -0.516564, +-7.679888, -7.679888, -10.002398, 0.500000, 0.499530, -0.791071, -0.327672, -0.516564, +-12.349340, -12.349340, 0.110407, 0.500000, 0.311560, -0.791071, -0.327672, -0.516564, +-7.679888, 7.679888, -10.002398, 0.437500, 0.499530, -0.791071, 0.327672, -0.516564, +-10.861002, 0.000000, -10.002398, 0.468750, 0.499530, -0.791071, 0.327672, -0.516564, +-17.464596, 0.000000, 0.110407, 0.468750, 0.311560, -0.791071, 0.327672, -0.516564, +0.000000, 10.861002, -10.002398, 0.406250, 0.499530, -0.327672, 0.791071, -0.516564, +-7.679888, 7.679888, -10.002398, 0.437500, 0.499530, -0.327672, 0.791071, -0.516564, +-12.349340, 12.349340, 0.110407, 0.437500, 0.311560, -0.327672, 0.791071, -0.516564, +7.679888, 7.679888, -10.002398, 0.375000, 0.499530, 0.327672, 0.791071, -0.516564, +0.000000, 10.861002, -10.002398, 0.406250, 0.499530, 0.327672, 0.791071, -0.516564, +0.000001, 17.464598, 0.110407, 0.406250, 0.311560, 0.327672, 0.791071, -0.516564, +10.861003, -0.000001, -29.138687, 0.593750, 0.593515, 0.923880, 0.382683, 0.000000, +7.679888, 7.679889, -29.138687, 0.625000, 0.593515, 0.923880, 0.382683, 0.000000, +7.679888, 7.679888, -10.002398, 0.625000, 0.499530, 0.923880, 0.382683, 0.000000, +7.679889, -7.679891, -29.138687, 0.562500, 0.593515, 0.923880, -0.382683, 0.000000, +10.861003, -0.000001, -29.138687, 0.593750, 0.593515, 0.923880, -0.382683, 0.000000, +10.861003, 0.000000, -10.002398, 0.593750, 0.499530, 0.923880, -0.382683, 0.000000, +0.000000, -10.861003, -29.138685, 0.531250, 0.593515, 0.382683, -0.923880, 0.000000, +7.679889, -7.679891, -29.138687, 0.562500, 0.593515, 0.382683, -0.923880, 0.000000, +7.679889, -7.679889, -10.002397, 0.562500, 0.499530, 0.382683, -0.923880, 0.000000, +-7.679888, -7.679889, -29.138689, 0.500000, 0.593515, -0.382683, -0.923880, 0.000000, +0.000000, -10.861003, -29.138685, 0.531250, 0.593515, -0.382683, -0.923880, 0.000000, +0.000000, -10.861002, -10.002398, 0.531250, 0.499530, -0.382683, -0.923880, 0.000000, +-10.861002, -0.000001, -29.138687, 0.468750, 0.593515, -0.923880, -0.382683, 0.000000, +-7.679888, -7.679889, -29.138689, 0.500000, 0.593515, -0.923880, -0.382683, 0.000000, +-7.679888, -7.679888, -10.002398, 0.500000, 0.499530, -0.923880, -0.382683, 0.000000, +-7.679888, 7.679889, -29.138687, 0.437500, 0.593515, -0.923880, 0.382683, 0.000000, +-10.861002, -0.000001, -29.138687, 0.468750, 0.593515, -0.923880, 0.382683, 0.000000, +-10.861002, 0.000000, -10.002398, 0.468750, 0.499530, -0.923880, 0.382683, 0.000000, +0.000000, 10.860999, -29.138687, 0.406250, 0.593515, -0.382683, 0.923880, -0.000000, +-7.679888, 7.679889, -29.138687, 0.437500, 0.593515, -0.382683, 0.923880, -0.000000, +-7.679888, 7.679888, -10.002398, 0.437500, 0.499530, -0.382683, 0.923880, -0.000000, +7.679888, 7.679889, -29.138687, 0.375000, 0.593515, 0.382683, 0.923880, -0.000000, +0.000000, 10.860999, -29.138687, 0.406250, 0.593515, 0.382683, 0.923880, -0.000000, +0.000000, 10.861002, -10.002398, 0.406250, 0.499530, 0.382683, 0.923880, -0.000000, +9.084865, -0.000001, -31.942669, 0.593750, 0.640508, 0.797373, 0.330283, -0.505083, +6.423971, 6.423968, -31.942669, 0.625000, 0.640508, 0.797373, 0.330283, -0.505083, +7.679888, 7.679889, -29.138687, 0.625000, 0.593515, 0.797373, 0.330283, -0.505083, +6.423971, -6.423972, -31.942667, 0.562500, 0.640508, 0.797373, -0.330283, -0.505083, +9.084865, -0.000001, -31.942669, 0.593750, 0.640508, 0.797373, -0.330283, -0.505083, +10.861003, -0.000001, -29.138687, 0.593750, 0.593515, 0.797373, -0.330283, -0.505083, +0.000000, -9.084865, -31.942671, 0.531250, 0.640508, 0.330283, -0.797373, -0.505083, +6.423971, -6.423972, -31.942667, 0.562500, 0.640508, 0.330283, -0.797373, -0.505083, +7.679889, -7.679891, -29.138687, 0.562500, 0.593515, 0.330283, -0.797373, -0.505083, +-6.423970, -6.423972, -31.942667, 0.500000, 0.640508, -0.330283, -0.797373, -0.505083, +0.000000, -9.084865, -31.942671, 0.531250, 0.640508, -0.330283, -0.797373, -0.505083, +0.000000, -10.861003, -29.138685, 0.531250, 0.593515, -0.330283, -0.797373, -0.505083, +-9.084864, -0.000001, -31.942669, 0.468750, 0.640508, -0.797373, -0.330283, -0.505083, +-6.423970, -6.423972, -31.942667, 0.500000, 0.640508, -0.797374, -0.330282, -0.505083, +-7.679888, -7.679889, -29.138689, 0.500000, 0.593515, -0.797374, -0.330282, -0.505083, +-6.423970, 6.423968, -31.942669, 0.437500, 0.640508, -0.797373, 0.330283, -0.505083, +-9.084864, -0.000001, -31.942669, 0.468750, 0.640508, -0.797373, 0.330283, -0.505083, +-10.861002, -0.000001, -29.138687, 0.468750, 0.593515, -0.797373, 0.330283, -0.505083, +0.000000, 9.084861, -31.942669, 0.406250, 0.640508, -0.330282, 0.797373, -0.505084, +-6.423970, 6.423968, -31.942669, 0.437500, 0.640508, -0.330282, 0.797373, -0.505084, +-7.679888, 7.679889, -29.138687, 0.437500, 0.593515, -0.330282, 0.797373, -0.505084, +6.423971, 6.423968, -31.942669, 0.375000, 0.640508, 0.330282, 0.797373, -0.505084, +0.000000, 9.084861, -31.942669, 0.406250, 0.640508, 0.330282, 0.797373, -0.505084, +0.000000, 10.860999, -29.138687, 0.406250, 0.593515, 0.330282, 0.797373, -0.505084, +2.977119, 2.977121, -34.306633, 0.610485, 0.954235, 0.124125, 0.051414, -0.990934, +4.210286, 0.000002, -34.306633, 0.656250, 0.843750, 0.124125, 0.051414, -0.990934, +0.000000, 0.000002, -34.834015, 0.500000, 0.843750, 0.124125, 0.051414, -0.990934, +0.000000, 0.000002, -34.834015, 0.500000, 0.843750, 0.124125, -0.051414, -0.990934, +4.210286, 0.000002, -34.306633, 0.656250, 0.843750, 0.124125, -0.051414, -0.990934, +2.977120, -2.977118, -34.306633, 0.610485, 0.733265, 0.124125, -0.051414, -0.990934, +0.000000, 0.000002, -34.834015, 0.500000, 0.843750, 0.051415, -0.124125, -0.990934, +2.977120, -2.977118, -34.306633, 0.610485, 0.733265, 0.051415, -0.124125, -0.990934, +0.000000, -4.210283, -34.306633, 0.500000, 0.687500, 0.051415, -0.124125, -0.990934, +0.000000, 0.000002, -34.834015, 0.500000, 0.843750, -0.051414, -0.124125, -0.990934, +0.000000, -4.210283, -34.306633, 0.500000, 0.687500, -0.051414, -0.124125, -0.990934, +-2.977119, -2.977118, -34.306633, 0.389515, 0.733265, -0.051414, -0.124125, -0.990934, +-2.977119, 2.977121, -34.306633, 0.389515, 0.954235, -0.124125, 0.051414, -0.990934, +0.000000, 0.000002, -34.834015, 0.500000, 0.843750, -0.124125, 0.051414, -0.990934, +-4.210285, 0.000002, -34.306633, 0.343750, 0.843750, -0.124125, 0.051414, -0.990934, +0.000000, 4.210287, -34.306633, 0.500000, 1.000000, -0.051414, 0.124125, -0.990934, +0.000000, 0.000002, -34.834015, 0.500000, 0.843750, -0.051414, 0.124125, -0.990934, +-2.977119, 2.977121, -34.306633, 0.389515, 0.954235, -0.051414, 0.124125, -0.990934, +2.977119, 2.977121, -34.306633, 0.610485, 0.954235, 0.051414, 0.124125, -0.990934, +0.000000, 0.000002, -34.834015, 0.500000, 0.843750, 0.051414, 0.124125, -0.990934, +0.000000, 4.210287, -34.306633, 0.500000, 1.000000, 0.051414, 0.124125, -0.990934, +12.349342, 12.349340, 0.110407, 0.610485, 0.045765, 0.382683, 0.923880, 0.000000, +0.000001, 17.464598, 0.110407, 0.500000, 0.000000, 0.382683, 0.923880, 0.000000, +0.000001, 17.464598, 1.144262, 0.500000, 0.000000, 0.382683, 0.923880, 0.000000, +0.000001, 17.464598, 0.110407, 0.500000, 0.000000, -0.382683, 0.923880, -0.000000, +-12.349340, 12.349340, 0.110407, 0.389515, 0.045765, -0.382683, 0.923880, -0.000000, +-12.349340, 12.349340, 1.144262, 0.389515, 0.045765, -0.382683, 0.923880, -0.000000, +-12.349340, 12.349340, 0.110407, 0.389515, 0.045765, -0.923880, 0.382683, 0.000000, +-17.464596, 0.000000, 0.110407, 0.343750, 0.156250, -0.923880, 0.382683, 0.000000, +-17.464596, 0.000000, 1.144262, 0.343750, 0.156250, -0.923880, 0.382683, 0.000000, +-17.464596, 0.000000, 0.110407, 0.343750, 0.156250, -0.923880, -0.382683, 0.000000, +-12.349340, -12.349340, 0.110407, 0.389515, 0.266735, -0.923880, -0.382683, 0.000000, +-12.349340, -12.349340, 1.144262, 0.389515, 0.266735, -0.923880, -0.382683, 0.000000, +-12.349340, -12.349340, 0.110407, 0.389515, 0.266735, -0.382683, -0.923880, -0.000002, +0.000001, -17.464596, 0.110407, 0.500000, 0.312500, -0.382683, -0.923880, -0.000002, +0.000001, -17.464600, 1.144262, 0.500000, 0.312500, -0.382683, -0.923880, -0.000002, +0.000001, -17.464596, 0.110407, 0.500000, 0.312500, 0.382683, -0.923880, -0.000002, +12.349343, -12.349342, 0.110407, 0.610485, 0.266735, 0.382683, -0.923880, -0.000002, +12.349343, -12.349342, 1.144262, 0.610485, 0.266735, 0.382683, -0.923880, -0.000002, +12.349343, -12.349342, 0.110407, 0.610485, 0.266735, 0.923880, -0.382683, 0.000000, +17.464600, 0.000000, 0.110407, 0.656250, 0.156250, 0.923880, -0.382683, 0.000000, +17.464600, 0.000000, 1.144262, 0.656250, 0.156250, 0.923880, -0.382683, 0.000000, +17.464600, 0.000000, 0.110407, 0.656250, 0.156250, 0.923880, 0.382683, 0.000000, +12.349342, 12.349340, 0.110407, 0.610485, 0.045765, 0.923880, 0.382683, 0.000000, +12.349342, 12.349340, 1.144262, 0.610485, 0.045765, 0.923880, 0.382683, 0.000000, +12.349342, 12.349340, 1.144262, 0.610485, 0.045765, -0.117337, -0.283277, 0.951833, +0.000001, 17.464598, 1.144262, 0.500000, 0.000000, -0.117337, -0.283277, 0.951833, +0.000001, 15.735191, 0.629568, 0.500000, 0.000000, -0.117337, -0.283277, 0.951833, +0.000001, 17.464598, 1.144262, 0.500000, 0.000000, 0.117337, -0.283277, 0.951833, +-12.349340, 12.349340, 1.144262, 0.389515, 0.045765, 0.117337, -0.283277, 0.951833, +-11.126453, 11.126453, 0.629568, 0.389515, 0.045765, 0.117337, -0.283277, 0.951833, +-12.349340, 12.349340, 1.144262, 0.389515, 0.045765, 0.283277, -0.117337, 0.951833, +-17.464596, 0.000000, 1.144262, 0.343750, 0.156250, 0.283277, -0.117337, 0.951833, +-15.735189, 0.000000, 0.629568, 0.343750, 0.156250, 0.283277, -0.117337, 0.951833, +-17.464596, 0.000000, 1.144262, 0.343750, 0.156250, 0.283277, 0.117337, 0.951833, +-12.349340, -12.349340, 1.144262, 0.389515, 0.266735, 0.283277, 0.117337, 0.951833, +-11.126453, -11.126453, 0.629568, 0.389515, 0.266735, 0.283277, 0.117337, 0.951833, +-12.349340, -12.349340, 1.144262, 0.389515, 0.266735, 0.117337, 0.283277, 0.951833, +0.000001, -17.464600, 1.144262, 0.500000, 0.312500, 0.117337, 0.283277, 0.951833, +0.000001, -15.735191, 0.629568, 0.500000, 0.312500, 0.117337, 0.283277, 0.951833, +0.000001, -17.464600, 1.144262, 0.500000, 0.312500, -0.117337, 0.283277, 0.951833, +12.349343, -12.349342, 1.144262, 0.610485, 0.266735, -0.117337, 0.283277, 0.951833, +11.126457, -11.126455, 0.629568, 0.610485, 0.266735, -0.117337, 0.283277, 0.951833, +12.349343, -12.349342, 1.144262, 0.610485, 0.266735, -0.283277, 0.117337, 0.951833, +17.464600, 0.000000, 1.144262, 0.656250, 0.156250, -0.283277, 0.117337, 0.951833, +15.735193, 0.000000, 0.629568, 0.656250, 0.156250, -0.283277, 0.117337, 0.951833, +17.464600, 0.000000, 1.144262, 0.656250, 0.156250, -0.283277, -0.117337, 0.951833, +12.349342, 12.349340, 1.144262, 0.610485, 0.045765, -0.283277, -0.117337, 0.951833, +11.126455, 11.126453, 0.629568, 0.610485, 0.045765, -0.283277, -0.117337, 0.951833, +15.735193, 0.000000, 0.629568, 0.656250, 0.156250, -0.301379, -0.124836, 0.945297, +11.126455, 11.126453, 0.629568, 0.610485, 0.045765, -0.301379, -0.124836, 0.945297, +1.172339, 1.172337, -3.858527, 0.610485, 0.045765, -0.301379, -0.124836, 0.945297, +11.126455, 11.126453, 0.629568, 0.610485, 0.045765, -0.124835, -0.301379, 0.945297, +0.000001, 15.735191, 0.629568, 0.500000, 0.000000, -0.124835, -0.301379, 0.945297, +0.000001, 1.657940, -3.858527, 0.500000, 0.000000, -0.124835, -0.301379, 0.945297, +0.000001, 15.735191, 0.629568, 0.500000, 0.000000, 0.124835, -0.301379, 0.945297, +-11.126453, 11.126453, 0.629568, 0.389515, 0.045765, 0.124835, -0.301379, 0.945297, +-1.172335, 1.172337, -3.858527, 0.389515, 0.045765, 0.124835, -0.301379, 0.945297, +-11.126453, 11.126453, 0.629568, 0.389515, 0.045765, 0.301379, -0.124835, 0.945297, +-15.735189, 0.000000, 0.629568, 0.343750, 0.156250, 0.301379, -0.124835, 0.945297, +-1.657938, 0.000000, -3.858527, 0.343750, 0.156250, 0.301379, -0.124835, 0.945297, +-15.735189, 0.000000, 0.629568, 0.343750, 0.156250, 0.301379, 0.124835, 0.945297, +-11.126453, -11.126453, 0.629568, 0.389515, 0.266735, 0.301379, 0.124835, 0.945297, +-1.172335, -1.172337, -3.858527, 0.389515, 0.266735, 0.301379, 0.124835, 0.945297, +-11.126453, -11.126453, 0.629568, 0.389515, 0.266735, 0.124836, 0.301379, 0.945297, +0.000001, -15.735191, 0.629568, 0.500000, 0.312500, 0.124835, 0.301379, 0.945297, +0.000001, -1.657940, -3.858527, 0.500000, 0.312500, 0.124836, 0.301379, 0.945297, +0.000001, -15.735191, 0.629568, 0.500000, 0.312500, -0.124835, 0.301379, 0.945297, +11.126457, -11.126455, 0.629568, 0.610485, 0.266735, -0.124835, 0.301379, 0.945297, +1.172339, -1.172337, -3.858527, 0.610485, 0.266735, -0.124835, 0.301379, 0.945297, +11.126457, -11.126455, 0.629568, 0.610485, 0.266735, -0.301379, 0.124835, 0.945297, +15.735193, 0.000000, 0.629568, 0.656250, 0.156250, -0.301379, 0.124835, 0.945297, +1.657941, 0.000000, -3.858527, 0.656250, 0.156250, -0.301379, 0.124835, 0.945297, +1.657941, 0.000000, -3.858527, 0.656250, 0.156250, 0.923878, 0.382687, 0.000000, +1.172339, 1.172337, -3.858527, 0.610485, 0.045765, 0.923878, 0.382687, 0.000000, +1.172338, 1.172337, 18.507620, 0.610485, 0.045765, 0.890349, 0.368798, -0.266959, +1.172339, 1.172337, -3.858527, 0.610485, 0.045765, 0.382687, 0.923878, 0.000000, +0.000001, 1.657940, -3.858527, 0.500000, 0.000000, 0.382687, 0.923878, 0.000000, +0.000001, 1.657940, 18.507620, 0.500000, 0.000000, 0.368799, 0.890348, -0.266960, +0.000001, 1.657940, -3.858527, 0.500000, 0.000000, -0.382687, 0.923878, -0.000000, +-1.172335, 1.172337, -3.858527, 0.389515, 0.045765, -0.382687, 0.923878, -0.000000, +-1.172336, 1.172337, 18.507620, 0.389515, 0.045765, -0.368799, 0.890348, -0.266959, +-1.172335, 1.172337, -3.858527, 0.389515, 0.045765, -0.923878, 0.382687, -0.000000, +-1.657938, 0.000000, -3.858527, 0.343750, 0.156250, -0.923878, 0.382687, -0.000000, +-1.657939, 0.000000, 18.507620, 0.343750, 0.156250, -0.890348, 0.368798, -0.266960, +-1.657938, 0.000000, -3.858527, 0.343750, 0.156250, -0.923878, -0.382687, -0.000000, +-1.172335, -1.172337, -3.858527, 0.389515, 0.266735, -0.923878, -0.382687, -0.000000, +-1.172336, -1.172337, 18.507620, 0.389515, 0.266735, -0.890348, -0.368798, -0.266959, +-1.172335, -1.172337, -3.858527, 0.389515, 0.266735, -0.382687, -0.923878, -0.000000, +0.000001, -1.657940, -3.858527, 0.500000, 0.312500, -0.382687, -0.923878, -0.000000, +0.000001, -1.657940, 18.507620, 0.500000, 0.312500, -0.368799, -0.890348, -0.266960, +0.000001, -1.657940, -3.858527, 0.500000, 0.312500, 0.382687, -0.923878, 0.000000, +1.172339, -1.172337, -3.858527, 0.610485, 0.266735, 0.382687, -0.923878, 0.000000, +1.172338, -1.172337, 18.507620, 0.610485, 0.266735, 0.368799, -0.890348, -0.266959, +1.172339, -1.172337, -3.858527, 0.610485, 0.266735, 0.923878, -0.382687, 0.000000, +1.657941, 0.000000, -3.858527, 0.656250, 0.156250, 0.923878, -0.382687, 0.000000, +1.657941, 0.000000, 18.507620, 0.656250, 0.156250, 0.890348, -0.368798, -0.266960, +1.657941, 0.000000, 18.507620, 0.656250, 0.156250, 0.890348, 0.368798, -0.266960, +1.172338, 1.172337, 18.507620, 0.610485, 0.045765, 0.890349, 0.368798, -0.266959, +3.204545, 3.204544, 18.507618, 0.610485, 0.045765, 0.916255, 0.379530, 0.128197, +1.172338, -1.172337, 18.507620, 0.610485, 0.266735, 0.890349, -0.368798, -0.266959, +1.657941, 0.000000, 18.507620, 0.656250, 0.156250, 0.890348, -0.368798, -0.266960, +4.531928, 0.000000, 18.507618, 0.656250, 0.156250, 0.916255, -0.379530, 0.128199, +0.000001, -1.657940, 18.507620, 0.500000, 0.312500, 0.368799, -0.890348, -0.266960, +1.172338, -1.172337, 18.507620, 0.610485, 0.266735, 0.368799, -0.890348, -0.266959, +3.204545, -3.204544, 18.507618, 0.610485, 0.266735, 0.379530, -0.916255, 0.128197, +-1.172336, -1.172337, 18.507620, 0.389515, 0.266735, -0.368799, -0.890348, -0.266959, +0.000001, -1.657940, 18.507620, 0.500000, 0.312500, -0.368799, -0.890348, -0.266960, +0.000000, -4.531925, 18.507618, 0.500000, 0.312500, -0.379530, -0.916255, 0.128199, +-1.657939, 0.000000, 18.507620, 0.343750, 0.156250, -0.890348, -0.368798, -0.266960, +-1.172336, -1.172337, 18.507620, 0.389515, 0.266735, -0.890348, -0.368798, -0.266959, +-3.204544, -3.204544, 18.507618, 0.389515, 0.266735, -0.916255, -0.379530, 0.128197, +-1.172336, 1.172337, 18.507620, 0.389515, 0.045765, -0.890348, 0.368798, -0.266959, +-1.657939, 0.000000, 18.507620, 0.343750, 0.156250, -0.890348, 0.368798, -0.266960, +-4.531927, 0.000000, 18.507618, 0.343750, 0.156250, -0.916254, 0.379530, 0.128199, +0.000001, 1.657940, 18.507620, 0.500000, 0.000000, -0.368799, 0.890348, -0.266960, +-1.172336, 1.172337, 18.507620, 0.389515, 0.045765, -0.368799, 0.890348, -0.266959, +-3.204544, 3.204544, 18.507618, 0.389515, 0.045765, -0.379530, 0.916255, 0.128197, +1.172338, 1.172337, 18.507620, 0.610485, 0.045765, 0.368799, 0.890348, -0.266959, +0.000001, 1.657940, 18.507620, 0.500000, 0.000000, 0.368799, 0.890348, -0.266960, +0.000000, 4.531925, 18.507618, 0.500000, 0.000000, 0.379530, 0.916255, 0.128199, +3.204545, -3.204544, 18.507618, 0.610485, 0.266735, 0.916255, -0.379530, 0.128197, +4.531928, 0.000000, 18.507618, 0.656250, 0.156250, 0.916255, -0.379530, 0.128199, +0.000000, 0.000000, 27.158279, 0.500000, 0.156250, 0.831594, -0.344462, 0.435657, +0.000000, -4.531925, 18.507618, 0.500000, 0.312500, 0.379530, -0.916255, 0.128199, +3.204545, -3.204544, 18.507618, 0.610485, 0.266735, 0.379530, -0.916255, 0.128197, +0.000000, 0.000000, 27.158279, 0.500000, 0.156250, 0.344462, -0.831594, 0.435657, +-3.204544, -3.204544, 18.507618, 0.389515, 0.266735, -0.379530, -0.916255, 0.128197, +0.000000, -4.531925, 18.507618, 0.500000, 0.312500, -0.379530, -0.916255, 0.128199, +0.000000, 0.000000, 27.158279, 0.500000, 0.156250, -0.344462, -0.831594, 0.435657, +-4.531927, 0.000000, 18.507618, 0.343750, 0.156250, -0.916254, -0.379530, 0.128199, +-3.204544, -3.204544, 18.507618, 0.389515, 0.266735, -0.916255, -0.379530, 0.128197, +0.000000, 0.000000, 27.158279, 0.500000, 0.156250, -0.831594, -0.344462, 0.435657, +-3.204544, 3.204544, 18.507618, 0.389515, 0.045765, -0.916255, 0.379530, 0.128197, +-4.531927, 0.000000, 18.507618, 0.343750, 0.156250, -0.916254, 0.379530, 0.128199, +0.000000, 0.000000, 27.158279, 0.500000, 0.156250, -0.831594, 0.344462, 0.435657, +0.000000, 4.531925, 18.507618, 0.500000, 0.000000, -0.379530, 0.916255, 0.128199, +-3.204544, 3.204544, 18.507618, 0.389515, 0.045765, -0.379530, 0.916255, 0.128197, +0.000000, 0.000000, 27.158279, 0.500000, 0.156250, -0.344462, 0.831594, 0.435657, +3.204545, 3.204544, 18.507618, 0.610485, 0.045765, 0.379530, 0.916255, 0.128197, +0.000000, 4.531925, 18.507618, 0.500000, 0.000000, 0.379530, 0.916255, 0.128199, +0.000000, 0.000000, 27.158279, 0.500000, 0.156250, 0.344462, 0.831594, 0.435657, +4.531928, 0.000000, 18.507618, 0.656250, 0.156250, 0.916255, 0.379530, 0.128199, +3.204545, 3.204544, 18.507618, 0.610485, 0.045765, 0.916255, 0.379530, 0.128197, +0.000000, 0.000000, 27.158279, 0.500000, 0.156250, 0.831594, 0.344462, 0.435657, +}; diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/GeometryData/WindGeometryData.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/GeometryData/WindGeometryData.h new file mode 100644 index 0000000..3d1390a --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/GeometryData/WindGeometryData.h @@ -0,0 +1,2513 @@ +const int num_faces = 836; + +// pos.xyz, uv.uv, normal.xyz +float vertices[836*3*8] = { +-1.002737, 3.502487, -29.476650, 1.000000, 0.966243, -0.570521, -0.819696, 0.051023, +-1.002737, 3.589727, -28.074986, 1.000000, 0.922656, -0.569426, -0.818637, 0.074745, +-1.336982, 4.293425, -28.133030, 0.500000, 0.922656, -0.999926, -0.012083, 0.001603, +-1.336982, 4.293425, -28.133030, 0.500000, 0.922656, -0.999926, -0.012083, 0.001603, +-1.002737, 4.997122, -28.191074, 0.000000, 0.932486, -0.582174, 0.810005, -0.070467, +-1.002737, 4.921762, -29.530731, 0.000000, 0.966243, -0.582241, 0.811733, -0.045666, +-1.002737, 5.199909, -26.333269, 0.000000, 0.859409, -0.582690, 0.803052, -0.124820, +-1.002737, 4.997122, -28.191074, 0.000000, 0.932486, -0.582174, 0.810005, -0.070467, +-1.336982, 4.293425, -28.133030, 0.500000, 0.922656, -0.999926, -0.012083, 0.001603, +-1.336982, 4.293425, -28.133030, 0.500000, 0.922656, -0.999926, -0.012083, 0.001603, +-1.002737, 3.589727, -28.074986, 1.000000, 0.922656, -0.569426, -0.818637, 0.074745, +-1.002737, 3.807196, -26.139326, 1.000000, 0.859409, -0.566467, -0.814177, 0.127399, +-1.002737, 3.807196, -26.139326, 1.000000, 0.859409, -0.566467, -0.814177, 0.127399, +-1.002737, 4.261988, -23.779169, 1.000000, 0.775297, -0.564634, -0.800896, 0.199384, +-1.336982, 4.951294, -23.914915, 0.500000, 0.775297, -0.999837, -0.017439, 0.004781, +-1.336982, 4.951294, -23.914915, 0.500000, 0.775297, -0.999837, -0.017439, 0.004781, +-1.002737, 5.640600, -24.050657, 0.000000, 0.786333, -0.583127, 0.787897, -0.197941, +-1.002737, 5.199909, -26.333269, 0.000000, 0.859409, -0.582690, 0.803052, -0.124820, +-1.002737, 6.429670, -21.436577, 0.000000, 0.669113, -0.579786, 0.770207, -0.265761, +-1.002737, 5.640600, -24.050657, 0.000000, 0.786333, -0.583127, 0.787897, -0.197941, +-1.336982, 4.951294, -23.914915, 0.500000, 0.775297, -0.999837, -0.017439, 0.004781, +-1.336982, 4.951294, -23.914915, 0.500000, 0.775297, -0.999837, -0.017439, 0.004781, +-1.002737, 4.261988, -23.779169, 1.000000, 0.775297, -0.564634, -0.800896, 0.199384, +-1.002737, 5.061195, -21.104027, 1.000000, 0.669113, -0.566458, -0.779905, 0.266220, +-1.002737, 5.061195, -21.104027, 1.000000, 0.669113, -0.566458, -0.779905, 0.266220, +-1.002737, 6.120935, -18.335461, 1.000000, 0.547971, -0.566613, -0.758528, 0.321845, +-1.336982, 6.802818, -18.519814, 0.500000, 0.547971, -0.999946, -0.009100, 0.005070, +-1.336982, 6.802818, -18.519814, 0.500000, 0.547971, -0.999946, -0.009100, 0.005070, +-1.002737, 7.484703, -18.704168, 0.000000, 0.551894, -0.576888, 0.751118, -0.320970, +-1.002737, 6.429670, -21.436577, 0.000000, 0.669113, -0.579786, 0.770207, -0.265761, +-1.002737, 8.723274, -16.066572, 0.000000, 0.418984, -0.570577, 0.739144, -0.357922, +-1.002737, 7.484703, -18.704168, 0.000000, 0.551894, -0.576888, 0.751118, -0.320970, +-1.336982, 6.802818, -18.519814, 0.500000, 0.547971, -0.999946, -0.009100, 0.005070, +-1.336982, 6.802818, -18.519814, 0.500000, 0.547971, -0.999946, -0.009100, 0.005070, +-1.002737, 6.120935, -18.335461, 1.000000, 0.547971, -0.566613, -0.758528, 0.321845, +-1.002737, 7.357327, -15.695049, 1.000000, 0.418984, -0.568348, -0.740553, 0.358555, +-1.002737, 7.357327, -15.695049, 1.000000, 0.418984, -0.568348, -0.740553, 0.358555, +-1.002737, 8.627859, -13.158705, 1.000000, 0.282904, -0.571429, -0.737705, 0.359528, +-1.336982, 9.314625, -13.332255, 0.500000, 0.282904, -0.999983, 0.005125, -0.002905, +-1.336982, 9.314625, -13.332255, 0.500000, 0.282904, -0.999983, 0.005125, -0.002905, +-1.002737, 10.001389, -13.505806, 0.000000, 0.286075, -0.565597, 0.742253, -0.359389, +-1.002737, 8.723274, -16.066572, 0.000000, 0.418984, -0.570577, 0.739144, -0.357922, +-1.002737, 11.175043, -11.003893, 0.000000, 0.140482, -0.562513, 0.757929, -0.330337, +-1.002737, 10.001389, -13.505806, 0.000000, 0.286075, -0.565597, 0.742253, -0.359389, +-1.336982, 9.314625, -13.332255, 0.500000, 0.282904, -0.999983, 0.005125, -0.002905, +-1.336982, 9.314625, -13.332255, 0.500000, 0.282904, -0.999983, 0.005125, -0.002905, +-1.002737, 8.627859, -13.158705, 1.000000, 0.282904, -0.571429, -0.737705, 0.359528, +-1.002737, 9.790028, -10.702334, 1.000000, 0.140482, -0.576949, -0.747604, 0.328966, +-1.002737, 9.790028, -10.702334, 1.000000, 0.140482, -0.576949, -0.747604, 0.328966, +-1.003346, 10.657795, -8.543959, 1.020833, -0.009381, -0.588551, -0.767718, 0.253411, +-1.337592, 11.355911, -8.670841, 0.583333, -0.069211, -0.999594, 0.026023, -0.011609, +-1.337592, 11.355911, -8.670841, 0.583333, -0.069211, -0.999594, 0.026023, -0.011609, +-1.003346, 12.054029, -8.797724, 0.000000, -0.005111, -0.560047, 0.787144, -0.258362, +-1.002737, 11.175043, -11.003893, 0.000000, 0.140482, -0.562513, 0.757929, -0.330337, +-1.005175, 12.448139, -7.124194, 0.666667, -0.726194, -0.564732, 0.815815, -0.124590, +-1.003346, 12.054029, -8.797724, 0.000000, -0.005111, -0.560047, 0.787144, -0.258362, +-1.337592, 11.355911, -8.670841, 0.583333, -0.069211, -0.999594, 0.026023, -0.011609, +-1.337592, 11.355911, -8.670841, 0.583333, -0.069211, -0.999594, 0.026023, -0.011609, +-1.003346, 10.657795, -8.543959, 1.020833, -0.009381, -0.588551, -0.767718, 0.253411, +-1.005175, 11.045135, -6.901599, 1.083333, -0.167786, -0.591577, -0.797310, 0.119726, +-1.005175, 11.045135, -6.901599, 1.083333, -0.167786, -0.591577, -0.797310, 0.119726, +-1.006394, 11.114811, -5.517140, 1.000000, -0.170915, -0.583093, -0.812392, -0.004755, +-1.340640, 11.818584, -5.617008, 1.166667, -0.809096, -0.999853, 0.017074, 0.001872, +-1.340640, 11.818584, -5.617008, 1.166667, -0.809096, -0.999853, 0.017074, 0.001872, +-1.006394, 12.522362, -5.716876, 1.333333, -1.447277, -0.566040, 0.824377, 0.001632, +-1.005175, 12.448139, -7.124194, 0.666667, -0.726194, -0.564732, 0.815815, -0.124590, +-1.002737, 11.560024, -0.158328, 0.000000, -0.503387, -0.548128, 0.812439, 0.198744, +-1.003346, 12.142200, -2.567771, 0.000000, -0.336720, -0.545383, 0.819886, 0.174196, +-1.337592, 11.435898, -2.488622, 0.500000, -0.336720, -0.999671, 0.024155, 0.008634, +-1.337592, 11.435898, -2.488622, 0.500000, -0.336720, -0.999671, 0.024155, 0.008634, +-1.003346, 10.729588, -2.409474, 1.000000, -0.336720, -0.568927, -0.804482, -0.170679, +-1.002737, 10.154959, -0.010050, 1.000000, -0.503387, -0.554465, -0.809442, -0.193318, +-1.002737, 10.154959, -0.010050, 1.000000, -0.503387, -0.554465, -0.809442, -0.193318, +-1.002737, 9.503082, 2.725576, 1.000000, -0.671927, -0.543427, -0.820485, -0.177458, +-1.336982, 10.194935, 2.646095, 0.500000, -0.671927, -0.999975, -0.006839, -0.001674, +-1.336982, 10.194935, 2.646095, 0.500000, -0.671927, -0.999975, -0.006839, -0.001674, +-1.002737, 10.886791, 2.566613, 0.000000, -0.670054, -0.549613, 0.814083, 0.187601, +-1.002737, 11.560024, -0.158328, 0.000000, -0.503387, -0.548128, 0.812439, 0.198744, +-1.002737, 10.314148, 5.254678, 0.000000, -0.844213, -0.550065, 0.824042, 0.135588, +-1.002737, 10.886791, 2.566613, 0.000000, -0.670054, -0.549613, 0.814083, 0.187601, +-1.336982, 10.194935, 2.646095, 0.500000, -0.671927, -0.999975, -0.006839, -0.001674, +-1.336982, 10.194935, 2.646095, 0.500000, -0.671927, -0.999975, -0.006839, -0.001674, +-1.002737, 9.503082, 2.725576, 1.000000, -0.671927, -0.543427, -0.820485, -0.177458, +-1.002737, 8.971350, 5.457178, 1.000000, -0.844213, -0.532911, -0.837943, -0.117722, +-1.002737, 8.971350, 5.457178, 1.000000, -0.844213, -0.532911, -0.837943, -0.117722, +-1.002737, 8.743584, 8.108688, 1.000000, -1.016250, -0.522039, -0.852900, 0.006099, +-1.336982, 9.384014, 7.968127, 0.500000, -1.016250, -0.999385, -0.034959, -0.002597, +-1.336982, 9.384014, 7.968127, 0.500000, -1.016250, -0.999385, -0.034959, -0.002597, +-1.002737, 10.024443, 7.827566, 0.000000, -1.018373, -0.552727, 0.833125, 0.019881, +-1.002737, 10.314148, 5.254678, 0.000000, -0.844213, -0.550065, 0.824042, 0.135588, +-1.002737, 10.200031, 10.206976, 0.000000, -1.184038, -0.545898, 0.826469, -0.137636, +-1.002737, 10.024443, 7.827566, 0.000000, -1.018373, -0.552727, 0.833125, 0.019881, +-1.336982, 9.384014, 7.968127, 0.500000, -1.016250, -0.999385, -0.034959, -0.002597, +-1.336982, 9.384014, 7.968127, 0.500000, -1.016250, -0.999385, -0.034959, -0.002597, +-1.002737, 8.743584, 8.108688, 1.000000, -1.016250, -0.522039, -0.852900, 0.006099, +-1.002737, 9.003599, 10.604042, 1.000000, -1.184038, -0.512969, -0.841946, 0.167304, +-1.002737, 9.003599, 10.604042, 1.000000, -1.184038, -0.512969, -0.841946, 0.167304, +-1.002737, 9.694744, 12.910284, 1.000000, -1.349954, -0.500990, -0.803388, 0.321833, +-1.336982, 10.239292, 12.641662, 0.500000, -1.349954, -0.999218, -0.036495, 0.015192, +-1.336982, 10.239292, 12.641662, 0.500000, -1.349954, -0.999218, -0.036495, 0.015192, +-1.002737, 10.783842, 12.373039, 0.000000, -1.349704, -0.535040, 0.792292, -0.293266, +-1.002737, 10.200031, 10.206976, 0.000000, -1.184038, -0.545898, 0.826469, -0.137636, +-1.002737, 11.718807, 14.305887, 0.000000, -1.516370, -0.524951, 0.731928, -0.434405, +-1.002737, 10.783842, 12.373039, 0.000000, -1.349704, -0.535040, 0.792292, -0.293266, +-1.336982, 10.239292, 12.641662, 0.500000, -1.349954, -0.999218, -0.036495, 0.015192, +-1.336982, 10.239292, 12.641662, 0.500000, -1.349954, -0.999218, -0.036495, 0.015192, +-1.002737, 9.694744, 12.910284, 1.000000, -1.349954, -0.500990, -0.803388, 0.321833, +-1.002737, 10.760361, 14.994465, 1.000000, -1.516370, -0.490912, -0.740187, 0.459488, +-1.002737, 10.760361, 14.994465, 1.000000, -1.516370, -0.490912, -0.740187, 0.459488, +-1.002737, 12.090717, 16.772659, 1.000000, -1.679268, -0.484165, -0.653669, 0.581636, +-1.336982, 12.495934, 16.355419, 0.500000, -1.679268, -0.999037, -0.033130, 0.028753, +-1.336982, 12.495934, 16.355419, 0.500000, -1.679268, -0.999037, -0.033130, 0.028753, +-1.002737, 12.901150, 15.938179, 0.000000, -1.683037, -0.520176, 0.645820, -0.558867, +-1.002737, 11.718807, 14.305887, 0.000000, -1.516370, -0.524951, 0.731928, -0.434405, +-1.002737, 14.227100, 17.202572, 0.000000, -1.834628, -0.519663, 0.527798, -0.671848, +-1.002737, 12.901150, 15.938179, 0.000000, -1.683037, -0.520176, 0.645820, -0.558867, +-1.336982, 12.495934, 16.355419, 0.500000, -1.679268, -0.999037, -0.033130, 0.028753, +-1.336982, 12.495934, 16.355419, 0.500000, -1.679268, -0.999037, -0.033130, 0.028753, +-1.002737, 12.090717, 16.772659, 1.000000, -1.679268, -0.484165, -0.653669, 0.581636, +-1.002737, 13.576077, 18.160946, 1.000000, -1.834628, -0.481336, -0.535363, 0.694048, +-1.002737, 13.576077, 18.160946, 1.000000, -1.834628, -0.481336, -0.535363, 0.694048, +-1.002737, 15.212280, 19.181923, 1.000000, -1.988039, -0.480827, -0.389724, 0.785443, +-1.336982, 15.450417, 18.654261, 0.500000, -1.988039, -0.998886, -0.021466, 0.042031, +-1.336982, 15.450417, 18.654261, 0.500000, -1.988039, -0.998886, -0.021466, 0.042031, +-1.002737, 15.688553, 18.126600, 0.000000, -1.986219, -0.519424, 0.384311, -0.763219, +-1.002737, 14.227100, 17.202572, 0.000000, -1.834628, -0.519663, 0.527798, -0.671848, +-1.002737, 17.277420, 18.737804, 0.000000, -2.145087, -0.519855, 0.222506, -0.824768, +-1.002737, 15.688553, 18.126600, 0.000000, -1.986219, -0.519424, 0.384311, -0.763219, +-1.336982, 15.450417, 18.654261, 0.500000, -1.988039, -0.998886, -0.021466, 0.042031, +-1.336982, 15.450417, 18.654261, 0.500000, -1.988039, -0.998886, -0.021466, 0.042031, +-1.002737, 15.212280, 19.181923, 1.000000, -1.988039, -0.480827, -0.389724, 0.785443, +-1.002737, 16.995155, 19.858189, 1.000000, -2.145087, -0.479530, -0.225145, 0.848151, +-1.002737, 16.995155, 19.858189, 1.000000, -2.145087, -0.479530, -0.225145, 0.848151, +-1.002737, 18.890533, 20.158619, 1.000000, -2.305904, -0.477686, -0.044014, 0.877427, +-1.336982, 18.926823, 19.584188, 0.500000, -2.305904, -0.998704, -0.001978, 0.050855, +-1.336982, 18.926823, 19.584188, 0.500000, -2.305904, -0.998704, -0.001978, 0.050855, +-1.002737, 18.963112, 19.009758, 0.000000, -2.303954, -0.519106, 0.044200, -0.853567, +-1.002737, 17.277420, 18.737804, 0.000000, -2.145087, -0.519855, 0.222506, -0.824768, +-1.002737, 20.715042, 18.916035, 0.000000, -2.470621, -0.518180, -0.147145, -0.842519, +-1.002737, 18.963112, 19.009758, 0.000000, -2.303954, -0.519106, 0.044200, -0.853567, +-1.336982, 18.926823, 19.584188, 0.500000, -2.305904, -0.998704, -0.001978, 0.050855, +-1.336982, 18.926823, 19.584188, 0.500000, -2.305904, -0.998704, -0.001978, 0.050855, +-1.002737, 18.890533, 20.158619, 1.000000, -2.305904, -0.477686, -0.044014, 0.877427, +-1.002737, 20.864250, 20.052088, 1.000000, -2.470621, -0.474232, 0.150976, 0.867358, +-1.002737, 20.864250, 20.052088, 1.000000, -2.470621, -0.474232, 0.150976, 0.867358, +-1.002737, 22.911228, 19.457972, 1.000000, -2.646001, -0.471248, 0.342725, 0.812690, +-1.336982, 22.719658, 18.922981, 0.500000, -2.646001, -0.998523, 0.022590, 0.049420, +-1.336982, 22.719658, 18.922981, 0.500000, -2.646001, -0.998523, 0.022590, 0.049420, +-1.002737, 22.528088, 18.387989, 0.000000, -2.637287, -0.514483, -0.334572, -0.789537, +-1.002737, 20.715042, 18.916035, 0.000000, -2.470621, -0.518180, -0.147145, -0.842519, +-1.002737, 24.397125, 17.356983, 0.000000, -2.838810, -0.512162, -0.495528, -0.701529, +-1.002737, 22.528088, 18.387989, 0.000000, -2.637287, -0.514483, -0.334572, -0.789537, +-1.336982, 22.719658, 18.922981, 0.500000, -2.646001, -0.998523, 0.022590, 0.049420, +-1.336982, 22.719658, 18.922981, 0.500000, -2.646001, -0.998523, 0.022590, 0.049420, +-1.002737, 22.911228, 19.457972, 1.000000, -2.646001, -0.471248, 0.342725, 0.812690, +-1.002737, 25.026405, 18.295650, 1.000000, -2.838810, -0.470077, 0.507995, 0.721781, +-1.002737, 25.026405, 18.295650, 1.000000, -2.838810, -0.470077, 0.507995, 0.721781, +-1.002737, 26.982025, 16.592329, 1.000000, -3.038383, -0.470672, 0.656259, 0.589739, +-1.336982, 26.551086, 16.221825, 0.500000, -3.038383, -0.998387, 0.041476, 0.038776, +-1.336982, 26.551086, 16.221825, 0.500000, -3.038383, -0.998387, 0.041476, 0.038776, +-1.002737, 26.120163, 15.851318, 0.000000, -3.040334, -0.515999, -0.637877, -0.571716, +-1.002737, 24.397125, 17.356983, 0.000000, -2.838810, -0.512162, -0.495528, -0.701529, +-1.002737, 27.495193, 13.899298, 0.000000, -3.234054, -0.529173, -0.759785, -0.377761, +-1.002737, 26.120163, 15.851318, 0.000000, -3.040334, -0.515999, -0.637877, -0.571716, +-1.336982, 26.551086, 16.221825, 0.500000, -3.038383, -0.998387, 0.041476, 0.038776, +-1.336982, 26.551086, 16.221825, 0.500000, -3.038383, -0.998387, 0.041476, 0.038776, +-1.002737, 26.982025, 16.592329, 1.000000, -3.038383, -0.470672, 0.656259, 0.589739, +-1.002737, 28.550339, 14.375221, 1.000000, -3.234054, -0.475606, 0.784875, 0.397203, +-1.002737, 28.550339, 14.375221, 1.000000, -3.234054, -0.475606, 0.784875, 0.397203, +-1.002737, 29.425041, 11.768046, 1.000000, -3.421010, -0.486094, 0.865825, 0.118573, +-1.336982, 28.829937, 11.681159, 0.500000, -3.421010, -0.997287, 0.072725, 0.011376, +-1.336982, 28.829937, 11.681159, 0.500000, -3.421010, -0.997287, 0.072725, 0.011376, +-1.002737, 28.234837, 11.594271, 0.000000, -3.427773, -0.549861, -0.829859, -0.094800, +-1.002737, 27.495193, 13.899298, 0.000000, -3.234054, -0.529173, -0.759785, -0.377761, +-1.002737, 28.051701, 9.029581, 0.000000, -3.594440, -0.552394, -0.818572, 0.157487, +-1.002737, 28.234837, 11.594271, 0.000000, -3.427773, -0.549861, -0.829859, -0.094800, +-1.336982, 28.829937, 11.681159, 0.500000, -3.421010, -0.997287, 0.072725, 0.011376, +-1.336982, 28.829937, 11.681159, 0.500000, -3.421010, -0.997287, 0.072725, 0.011376, +-1.002737, 29.425041, 11.768046, 1.000000, -3.421010, -0.486094, 0.865825, 0.118573, +-1.002737, 29.299828, 8.894522, 1.000000, -3.594440, -0.508085, 0.850361, -0.136877, +-1.002737, 29.299828, 8.894522, 1.000000, -3.594440, -0.508085, 0.850361, -0.136877, +-1.002737, 28.522129, 6.172330, 1.000000, -3.741287, -0.527924, 0.793569, -0.302563, +-1.336982, 27.897224, 6.377859, 0.500000, -3.741288, -0.999306, 0.035287, -0.011950, +-1.336982, 27.897224, 6.377859, 0.500000, -3.741288, -0.999306, 0.035287, -0.011950, +-1.002737, 27.272324, 6.583387, 0.000000, -3.761107, -0.563170, -0.762896, 0.317537, +-1.002737, 28.051701, 9.029581, 0.000000, -3.594440, -0.552394, -0.818572, 0.157487, +-1.002737, 26.223228, 4.633848, 0.000000, -3.848496, -0.571231, -0.699650, 0.429169, +-1.002737, 27.272324, 6.583387, 0.000000, -3.761107, -0.563170, -0.762896, 0.317537, +-1.336982, 27.897224, 6.377859, 0.500000, -3.741288, -0.999306, 0.035287, -0.011950, +-1.336982, 27.897224, 6.377859, 0.500000, -3.741288, -0.999306, 0.035287, -0.011950, +-1.002737, 28.522129, 6.172330, 1.000000, -3.741287, -0.527924, 0.793569, -0.302563, +-1.002737, 27.439381, 4.019153, 1.000000, -3.848496, -0.545786, 0.725589, -0.419091, +-1.002737, 27.439381, 4.019153, 1.000000, -3.848496, -0.545786, 0.725589, -0.419091, +-1.002737, 26.363422, 2.436586, 1.020833, -3.882167, -0.561369, 0.675750, -0.477732, +-1.336982, 25.778152, 2.814326, 0.583333, -3.762508, -0.999924, 0.011227, -0.005182, +-1.336982, 25.778152, 2.814326, 0.583333, -3.762508, -0.999924, 0.011227, -0.005182, +-1.002737, 25.192875, 3.192066, 0.000000, -3.935886, -0.573805, -0.657830, 0.487860, +-1.002737, 26.223228, 4.633848, 0.000000, -3.848496, -0.571231, -0.699650, 0.429169, +-1.002737, 24.600067, 1.327282, 1.166667, -2.723639, -0.595697, -0.491752, -0.635079, +-0.742768, 24.296909, 1.783397, 1.333333, -1.447277, -0.428917, -0.894621, -0.125234, +-1.002737, 24.469711, 2.269146, 0.666667, -2.691582, -0.583534, -0.710408, 0.393458, +-1.002737, 24.469711, 2.269146, 0.666667, -2.691582, -0.583534, -0.710408, 0.393458, +-1.002737, 25.192875, 3.192066, 0.000000, -3.935886, -0.573805, -0.657830, 0.487860, +-1.336982, 25.778152, 2.814326, 0.583333, -3.762508, -0.999924, 0.011227, -0.005182, +-1.336982, 25.778152, 2.814326, 0.583333, -3.762508, -0.999924, 0.011227, -0.005182, +-1.002737, 26.363422, 2.436586, 1.020833, -3.882167, -0.561369, 0.675750, -0.477732, +-1.002737, 25.606094, 1.426226, 1.083333, -3.808398, -0.572183, 0.564519, -0.594916, +-1.002737, 25.606094, 1.426226, 1.083333, -3.808398, -0.572183, 0.564519, -0.594916, +-0.742768, 25.130249, 1.141007, 1.000000, -4.000000, -0.424007, 0.088516, -0.901323, +-1.002737, 24.600067, 1.327282, 1.166667, -2.723639, -0.595697, -0.491752, -0.635079, +1.002737, 3.502487, -29.476650, 2.000000, 0.966243, 0.570521, -0.819696, 0.051023, +1.002737, 3.589725, -28.074989, 2.000000, 0.922656, 0.569426, -0.818637, 0.074745, +0.000000, 3.355162, -28.055641, 1.500000, 0.922656, -0.000000, -0.995829, 0.091245, +0.000000, 3.355162, -28.055641, 1.500000, 0.922656, -0.000000, -0.995829, 0.091245, +-1.002737, 3.589727, -28.074986, 1.000000, 0.922656, -0.569426, -0.818637, 0.074745, +-1.002737, 3.502487, -29.476650, 1.000000, 0.966243, -0.570521, -0.819696, 0.051023, +-1.002737, 3.807196, -26.139326, 1.000000, 0.859409, -0.566467, -0.814177, 0.127399, +-1.002737, 3.589727, -28.074986, 1.000000, 0.922656, -0.569426, -0.818637, 0.074745, +0.000000, 3.355162, -28.055641, 1.500000, 0.922656, -0.000000, -0.995829, 0.091245, +0.000000, 3.355162, -28.055641, 1.500000, 0.922656, -0.000000, -0.995829, 0.091245, +1.002737, 3.589725, -28.074989, 2.000000, 0.922656, 0.569426, -0.818637, 0.074745, +1.002737, 3.807196, -26.139326, 2.000000, 0.859409, 0.566467, -0.814178, 0.127399, +1.002737, 3.807196, -26.139326, 2.000000, 0.859409, 0.566467, -0.814178, 0.127399, +1.002737, 4.261988, -23.779171, 2.000000, 0.775297, 0.564634, -0.800896, 0.199384, +0.000000, 4.032219, -23.733923, 1.500000, 0.775297, 0.000000, -0.970479, 0.241185, +0.000000, 4.032219, -23.733923, 1.500000, 0.775297, 0.000000, -0.970479, 0.241185, +-1.002737, 4.261988, -23.779169, 1.000000, 0.775297, -0.564634, -0.800896, 0.199384, +-1.002737, 3.807196, -26.139326, 1.000000, 0.859409, -0.566467, -0.814177, 0.127399, +-1.002737, 5.061195, -21.104027, 1.000000, 0.669113, -0.566458, -0.779905, 0.266220, +-1.002737, 4.261988, -23.779169, 1.000000, 0.775297, -0.564634, -0.800896, 0.199384, +0.000000, 4.032219, -23.733923, 1.500000, 0.775297, 0.000000, -0.970479, 0.241185, +0.000000, 4.032219, -23.733923, 1.500000, 0.775297, 0.000000, -0.970479, 0.241185, +1.002737, 4.261988, -23.779171, 2.000000, 0.775297, 0.564634, -0.800896, 0.199384, +1.002737, 5.061195, -21.104025, 2.000000, 0.669113, 0.566458, -0.779905, 0.266220, +1.002737, 5.061195, -21.104025, 2.000000, 0.669113, 0.566458, -0.779905, 0.266220, +1.002737, 6.120935, -18.335461, 2.000000, 0.547971, 0.566613, -0.758528, 0.321845, +0.000000, 5.893641, -18.274008, 1.500000, 0.547971, -0.000000, -0.920850, 0.389917, +0.000000, 5.893641, -18.274008, 1.500000, 0.547971, -0.000000, -0.920850, 0.389917, +-1.002737, 6.120935, -18.335461, 1.000000, 0.547971, -0.566613, -0.758528, 0.321845, +-1.002737, 5.061195, -21.104027, 1.000000, 0.669113, -0.566458, -0.779905, 0.266220, +-1.002737, 7.357327, -15.695049, 1.000000, 0.418984, -0.568348, -0.740553, 0.358555, +-1.002737, 6.120935, -18.335461, 1.000000, 0.547971, -0.566613, -0.758528, 0.321845, +0.000000, 5.893641, -18.274008, 1.500000, 0.547971, -0.000000, -0.920850, 0.389917, +0.000000, 5.893641, -18.274008, 1.500000, 0.547971, -0.000000, -0.920850, 0.389917, +1.002737, 6.120935, -18.335461, 2.000000, 0.547971, 0.566613, -0.758528, 0.321845, +1.002737, 7.357327, -15.695049, 2.000000, 0.418984, 0.568348, -0.740553, 0.358555, +1.002737, 7.357327, -15.695049, 2.000000, 0.418984, 0.568348, -0.740553, 0.358555, +1.002737, 8.627859, -13.158705, 2.000000, 0.282904, 0.571429, -0.737705, 0.359528, +0.000000, 8.398937, -13.100854, 1.500000, 0.282904, 0.000000, -0.898731, 0.438502, +0.000000, 8.398937, -13.100854, 1.500000, 0.282904, 0.000000, -0.898731, 0.438502, +-1.002737, 8.627859, -13.158705, 1.000000, 0.282904, -0.571429, -0.737705, 0.359528, +-1.002737, 7.357327, -15.695049, 1.000000, 0.418984, -0.568348, -0.740553, 0.358555, +-1.002737, 9.790028, -10.702334, 1.000000, 0.140482, -0.576949, -0.747604, 0.328966, +-1.002737, 8.627859, -13.158705, 1.000000, 0.282904, -0.571429, -0.737705, 0.359528, +0.000000, 8.398937, -13.100854, 1.500000, 0.282904, 0.000000, -0.898731, 0.438502, +0.000000, 8.398937, -13.100854, 1.500000, 0.282904, 0.000000, -0.898731, 0.438502, +1.002737, 8.627859, -13.158705, 2.000000, 0.282904, 0.571429, -0.737705, 0.359528, +1.002737, 9.790028, -10.702334, 2.000000, 0.140482, 0.576977, -0.747533, 0.329077, +1.002737, 9.790028, -10.702334, 2.000000, 0.140482, 0.576977, -0.747533, 0.329077, +1.002127, 10.657795, -8.543959, 2.000000, 0.010562, 0.588607, -0.767452, 0.254084, +-0.000610, 10.425087, -8.501664, 1.500000, 0.010562, 0.000044, -0.949091, 0.315003, +-0.000610, 10.425087, -8.501664, 1.500000, 0.010562, 0.000044, -0.949091, 0.315003, +-1.003346, 10.657795, -8.543959, 1.020833, -0.009381, -0.588551, -0.767718, 0.253411, +-1.002737, 9.790028, -10.702334, 1.000000, 0.140482, -0.576949, -0.747604, 0.328966, +-1.005175, 11.045135, -6.901599, 1.083333, -0.167786, -0.591577, -0.797310, 0.119726, +-1.003346, 10.657795, -8.543959, 1.020833, -0.009381, -0.588551, -0.767718, 0.253411, +-0.000610, 10.425087, -8.501664, 1.500000, 0.010562, 0.000044, -0.949091, 0.315003, +-0.000610, 10.425087, -8.501664, 1.500000, 0.010562, 0.000044, -0.949091, 0.315003, +1.002127, 10.657795, -8.543959, 2.000000, 0.010562, 0.588607, -0.767452, 0.254084, +1.000299, 11.045135, -6.901599, 2.000000, -0.088013, 0.591516, -0.797171, 0.120947, +1.000299, 11.045135, -6.901599, 2.000000, -0.088013, 0.591516, -0.797171, 0.120947, +0.999079, 11.114811, -5.517140, 2.000000, -0.170915, 0.582792, -0.812607, -0.004817, +-0.003657, 10.880220, -5.483850, 1.500000, -0.170915, -0.000127, -0.999975, -0.007088, +-0.003657, 10.880220, -5.483850, 1.500000, -0.170915, -0.000127, -0.999975, -0.007088, +-1.006394, 11.114811, -5.517140, 1.000000, -0.170915, -0.583093, -0.812392, -0.004755, +-1.005175, 11.045135, -6.901599, 1.083333, -0.167786, -0.591577, -0.797310, 0.119726, +-1.002737, 10.154959, -0.010050, 1.000000, -0.503387, -0.554465, -0.809442, -0.193318, +-1.003346, 10.729588, -2.409474, 1.000000, -0.336720, -0.568927, -0.804482, -0.170679, +-0.000610, 10.494156, -2.383091, 1.500000, -0.336720, 0.000040, -0.977947, -0.208854, +-0.000610, 10.494156, -2.383091, 1.500000, -0.336720, 0.000040, -0.977947, -0.208854, +1.002127, 10.729588, -2.409474, 2.000000, -0.336720, 0.568931, -0.804350, -0.171283, +1.002737, 10.154957, -0.010050, 2.000000, -0.503387, 0.554487, -0.809403, -0.193422, +1.002737, 10.154957, -0.010050, 2.000000, -0.503387, 0.554487, -0.809403, -0.193422, +1.002737, 9.503082, 2.725576, 2.000000, -0.671927, 0.543427, -0.820485, -0.177458, +0.000000, 9.272461, 2.752070, 1.500000, -0.671927, -0.000000, -0.977791, -0.209581, +0.000000, 9.272461, 2.752070, 1.500000, -0.671927, -0.000000, -0.977791, -0.209581, +-1.002737, 9.503082, 2.725576, 1.000000, -0.671927, -0.543427, -0.820485, -0.177458, +-1.002737, 10.154959, -0.010050, 1.000000, -0.503387, -0.554465, -0.809442, -0.193318, +-1.002737, 8.971350, 5.457178, 1.000000, -0.844213, -0.532911, -0.837943, -0.117722, +-1.002737, 9.503082, 2.725576, 1.000000, -0.671927, -0.543427, -0.820485, -0.177458, +0.000000, 9.272461, 2.752070, 1.500000, -0.671927, -0.000000, -0.977791, -0.209581, +0.000000, 9.272461, 2.752070, 1.500000, -0.671927, -0.000000, -0.977791, -0.209581, +1.002737, 9.503082, 2.725576, 2.000000, -0.671927, 0.543427, -0.820485, -0.177458, +1.002737, 8.971350, 5.457179, 2.000000, -0.844213, 0.532911, -0.837943, -0.117722, +1.002737, 8.971350, 5.457179, 2.000000, -0.844213, 0.532911, -0.837943, -0.117722, +1.002737, 8.743584, 8.108689, 2.000000, -1.016250, 0.522039, -0.852900, 0.006099, +0.000000, 8.530107, 8.155542, 1.500000, -1.016250, 0.000000, -0.999937, 0.011225, +0.000000, 8.530107, 8.155542, 1.500000, -1.016250, 0.000000, -0.999937, 0.011225, +-1.002737, 8.743584, 8.108688, 1.000000, -1.016250, -0.522039, -0.852900, 0.006099, +-1.002737, 8.971350, 5.457178, 1.000000, -0.844213, -0.532911, -0.837943, -0.117722, +-1.002737, 9.003599, 10.604042, 1.000000, -1.184038, -0.512969, -0.841946, 0.167304, +-1.002737, 8.743584, 8.108688, 1.000000, -1.016250, -0.522039, -0.852900, 0.006099, +0.000000, 8.530107, 8.155542, 1.500000, -1.016250, 0.000000, -0.999937, 0.011225, +0.000000, 8.530107, 8.155542, 1.500000, -1.016250, 0.000000, -0.999937, 0.011225, +1.002737, 8.743584, 8.108689, 2.000000, -1.016250, 0.522039, -0.852900, 0.006099, +1.002737, 9.003599, 10.604041, 2.000000, -1.184038, 0.512969, -0.841946, 0.167304, +1.002737, 9.003599, 10.604041, 2.000000, -1.184038, 0.512969, -0.841946, 0.167304, +1.002737, 9.694744, 12.910284, 2.000000, -1.349954, 0.500990, -0.803388, 0.321833, +0.000000, 9.513226, 12.999825, 1.500000, -1.349954, 0.000000, -0.927387, 0.374104, +0.000000, 9.513226, 12.999825, 1.500000, -1.349954, 0.000000, -0.927387, 0.374104, +-1.002737, 9.694744, 12.910284, 1.000000, -1.349954, -0.500990, -0.803388, 0.321833, +-1.002737, 9.003599, 10.604042, 1.000000, -1.184038, -0.512969, -0.841946, 0.167304, +-1.002737, 10.760361, 14.994465, 1.000000, -1.516370, -0.490912, -0.740187, 0.459488, +-1.002737, 9.694744, 12.910284, 1.000000, -1.349954, -0.500990, -0.803388, 0.321833, +0.000000, 9.513226, 12.999825, 1.500000, -1.349954, 0.000000, -0.927387, 0.374104, +0.000000, 9.513226, 12.999825, 1.500000, -1.349954, 0.000000, -0.927387, 0.374104, +1.002737, 9.694744, 12.910284, 2.000000, -1.349954, 0.500990, -0.803388, 0.321833, +1.002737, 10.760361, 14.994465, 2.000000, -1.516370, 0.490912, -0.740187, 0.459488, +1.002737, 10.760361, 14.994465, 2.000000, -1.516370, 0.490912, -0.740187, 0.459488, +1.002737, 12.090717, 16.772659, 2.000000, -1.679268, 0.484165, -0.653669, 0.581636, +0.000000, 11.955647, 16.911739, 1.500000, -1.679268, 0.000000, -0.746148, 0.665780, +0.000000, 11.955647, 16.911739, 1.500000, -1.679268, 0.000000, -0.746148, 0.665780, +-1.002737, 12.090717, 16.772659, 1.000000, -1.679268, -0.484165, -0.653669, 0.581636, +-1.002737, 10.760361, 14.994465, 1.000000, -1.516370, -0.490912, -0.740187, 0.459488, +-1.002737, 13.576077, 18.160946, 1.000000, -1.834628, -0.481336, -0.535363, 0.694048, +-1.002737, 12.090717, 16.772659, 1.000000, -1.679268, -0.484165, -0.653669, 0.581636, +0.000000, 11.955647, 16.911739, 1.500000, -1.679268, 0.000000, -0.746148, 0.665780, +0.000000, 11.955647, 16.911739, 1.500000, -1.679268, 0.000000, -0.746148, 0.665780, +1.002737, 12.090717, 16.772659, 2.000000, -1.679268, 0.484165, -0.653669, 0.581636, +1.002737, 13.576080, 18.160946, 2.000000, -1.834628, 0.481336, -0.535363, 0.694048, +1.002737, 13.576080, 18.160946, 2.000000, -1.834628, 0.481336, -0.535363, 0.694048, +1.002737, 15.212280, 19.181923, 2.000000, -1.988039, 0.480828, -0.389724, 0.785442, +0.000000, 15.132900, 19.357809, 1.500000, -1.988039, 0.000001, -0.443892, 0.896080, +0.000000, 15.132900, 19.357809, 1.500000, -1.988039, 0.000001, -0.443892, 0.896080, +-1.002737, 15.212280, 19.181923, 1.000000, -1.988039, -0.480827, -0.389724, 0.785443, +-1.002737, 13.576077, 18.160946, 1.000000, -1.834628, -0.481336, -0.535363, 0.694048, +-1.002737, 16.995155, 19.858189, 1.000000, -2.145087, -0.479530, -0.225145, 0.848151, +-1.002737, 15.212280, 19.181923, 1.000000, -1.988039, -0.480827, -0.389724, 0.785443, +0.000000, 15.132900, 19.357809, 1.500000, -1.988039, 0.000001, -0.443892, 0.896080, +0.000000, 15.132900, 19.357809, 1.500000, -1.988039, 0.000001, -0.443892, 0.896080, +1.002737, 15.212280, 19.181923, 2.000000, -1.988039, 0.480828, -0.389724, 0.785442, +1.002737, 16.995155, 19.858189, 2.000000, -2.145087, 0.479530, -0.225145, 0.848151, +1.002737, 16.995155, 19.858189, 2.000000, -2.145087, 0.479530, -0.225145, 0.848151, +1.002737, 18.890533, 20.158619, 2.000000, -2.305904, 0.477686, -0.044014, 0.877427, +0.000000, 18.878441, 20.350098, 1.500000, -2.305904, 0.000000, -0.050074, 0.998746, +0.000000, 18.878441, 20.350098, 1.500000, -2.305904, 0.000000, -0.050074, 0.998746, +-1.002737, 18.890533, 20.158619, 1.000000, -2.305904, -0.477686, -0.044014, 0.877427, +-1.002737, 16.995155, 19.858189, 1.000000, -2.145087, -0.479530, -0.225145, 0.848151, +-1.002737, 20.864250, 20.052088, 1.000000, -2.470621, -0.474232, 0.150976, 0.867358, +-1.002737, 18.890533, 20.158619, 1.000000, -2.305904, -0.477686, -0.044014, 0.877427, +0.000000, 18.878441, 20.350098, 1.500000, -2.305904, 0.000000, -0.050074, 0.998746, +0.000000, 18.878441, 20.350098, 1.500000, -2.305904, 0.000000, -0.050074, 0.998746, +1.002737, 18.890533, 20.158619, 2.000000, -2.305904, 0.477686, -0.044014, 0.877427, +1.002737, 20.864250, 20.052088, 2.000000, -2.470621, 0.474231, 0.150976, 0.867359, +1.002737, 20.864250, 20.052088, 2.000000, -2.470621, 0.474231, 0.150976, 0.867359, +1.002737, 22.911228, 19.457972, 2.000000, -2.646001, 0.471248, 0.342725, 0.812690, +0.000000, 22.975082, 19.636301, 1.500000, -2.646001, 0.000000, 0.388135, 0.921603, +0.000000, 22.975082, 19.636301, 1.500000, -2.646001, 0.000000, 0.388135, 0.921603, +-1.002737, 22.911228, 19.457972, 1.000000, -2.646001, -0.471248, 0.342725, 0.812690, +-1.002737, 20.864250, 20.052088, 1.000000, -2.470621, -0.474232, 0.150976, 0.867358, +-1.002737, 25.026405, 18.295650, 1.000000, -2.838810, -0.470077, 0.507995, 0.721781, +-1.002737, 22.911228, 19.457972, 1.000000, -2.646001, -0.471248, 0.342725, 0.812690, +0.000000, 22.975082, 19.636301, 1.500000, -2.646001, 0.000000, 0.388135, 0.921603, +0.000000, 22.975082, 19.636301, 1.500000, -2.646001, 0.000000, 0.388135, 0.921603, +1.002737, 22.911228, 19.457972, 2.000000, -2.646001, 0.471248, 0.342725, 0.812690, +1.002737, 25.026405, 18.295650, 2.000000, -2.838810, 0.470077, 0.507995, 0.721781, +1.002737, 25.026405, 18.295650, 2.000000, -2.838810, 0.470077, 0.507995, 0.721781, +1.002737, 26.982021, 16.592329, 2.000000, -3.038383, 0.470672, 0.656258, 0.589740, +0.000000, 27.125668, 16.715830, 1.500000, -3.038383, 0.000001, 0.743876, 0.668318, +0.000000, 27.125668, 16.715830, 1.500000, -3.038383, 0.000001, 0.743876, 0.668318, +-1.002737, 26.982025, 16.592329, 1.000000, -3.038383, -0.470672, 0.656259, 0.589739, +-1.002737, 25.026405, 18.295650, 1.000000, -2.838810, -0.470077, 0.507995, 0.721781, +-1.002737, 28.550339, 14.375221, 1.000000, -3.234054, -0.475606, 0.784875, 0.397203, +-1.002737, 26.982025, 16.592329, 1.000000, -3.038383, -0.470672, 0.656259, 0.589739, +0.000000, 27.125668, 16.715830, 1.500000, -3.038383, 0.000001, 0.743876, 0.668318, +0.000000, 27.125668, 16.715830, 1.500000, -3.038383, 0.000001, 0.743876, 0.668318, +1.002737, 26.982021, 16.592329, 2.000000, -3.038383, 0.470672, 0.656258, 0.589740, +1.002737, 28.550339, 14.375221, 2.000000, -3.234054, 0.475606, 0.784875, 0.397204, +1.002737, 28.550339, 14.375221, 2.000000, -3.234054, 0.475606, 0.784875, 0.397204, +1.002737, 29.425041, 11.768046, 2.000000, -3.421010, 0.486093, 0.865826, 0.118573, +0.000000, 29.623409, 11.797009, 1.500000, -3.421010, 0.000000, 0.990552, 0.137137, +0.000000, 29.623409, 11.797009, 1.500000, -3.421010, 0.000000, 0.990552, 0.137137, +-1.002737, 29.425041, 11.768046, 1.000000, -3.421010, -0.486094, 0.865825, 0.118573, +-1.002737, 28.550339, 14.375221, 1.000000, -3.234054, -0.475606, 0.784875, 0.397203, +-1.002737, 29.299828, 8.894522, 1.000000, -3.594440, -0.508085, 0.850361, -0.136877, +-1.002737, 29.425041, 11.768046, 1.000000, -3.421010, -0.486094, 0.865825, 0.118573, +0.000000, 29.623409, 11.797009, 1.500000, -3.421010, 0.000000, 0.990552, 0.137137, +0.000000, 29.623409, 11.797009, 1.500000, -3.421010, 0.000000, 0.990552, 0.137137, +1.002737, 29.425041, 11.768046, 2.000000, -3.421010, 0.486093, 0.865826, 0.118573, +1.002737, 29.299828, 8.894522, 2.000000, -3.594440, 0.508084, 0.850362, -0.136877, +1.002737, 29.299828, 8.894522, 2.000000, -3.594440, 0.508084, 0.850362, -0.136877, +1.002737, 28.522129, 6.172330, 2.000000, -3.741287, 0.527923, 0.793569, -0.302564, +0.000000, 28.730427, 6.103821, 1.500000, -3.741288, 0.000000, 0.935308, -0.353834, +0.000000, 28.730427, 6.103821, 1.500000, -3.741288, 0.000000, 0.935308, -0.353834, +-1.002737, 28.522129, 6.172330, 1.000000, -3.741287, -0.527924, 0.793569, -0.302563, +-1.002737, 29.299828, 8.894522, 1.000000, -3.594440, -0.508085, 0.850361, -0.136877, +-1.002737, 27.439381, 4.019153, 1.000000, -3.848496, -0.545786, 0.725589, -0.419091, +-1.002737, 28.522129, 6.172330, 1.000000, -3.741287, -0.527924, 0.793569, -0.302563, +0.000000, 28.730427, 6.103821, 1.500000, -3.741288, 0.000000, 0.935308, -0.353834, +0.000000, 28.730427, 6.103821, 1.500000, -3.741288, 0.000000, 0.935308, -0.353834, +1.002737, 28.522129, 6.172330, 2.000000, -3.741287, 0.527923, 0.793569, -0.302564, +1.002737, 27.439377, 4.019153, 2.000000, -3.848496, 0.545786, 0.725589, -0.419091, +1.002737, 27.439377, 4.019153, 2.000000, -3.848496, 0.545786, 0.725589, -0.419091, +1.002737, 26.363422, 2.436586, 2.000000, -3.922053, 0.561369, 0.675750, -0.477732, +0.000000, 26.558514, 2.310673, 1.500000, -3.922053, 0.000001, 0.817607, -0.575776, +0.000000, 26.558514, 2.310673, 1.500000, -3.922053, 0.000001, 0.817607, -0.575776, +-1.002737, 26.363422, 2.436586, 1.020833, -3.882167, -0.561369, 0.675750, -0.477732, +-1.002737, 27.439381, 4.019153, 1.000000, -3.848496, -0.545786, 0.725589, -0.419091, +0.000000, 25.158775, 0.885566, 1.500000, -4.000000, 0.000000, 0.098978, -0.995090, +-0.742768, 25.130249, 1.141007, 1.000000, -4.000000, -0.424007, 0.088516, -0.901323, +-1.002737, 25.606094, 1.426226, 1.083333, -3.808398, -0.572183, 0.564519, -0.594916, +-1.002737, 25.606094, 1.426226, 1.083333, -3.808398, -0.572183, 0.564519, -0.594916, +-1.002737, 26.363422, 2.436586, 1.020833, -3.882167, -0.561369, 0.675750, -0.477732, +0.000000, 26.558514, 2.310673, 1.500000, -3.922053, 0.000001, 0.817607, -0.575776, +0.000000, 26.558514, 2.310673, 1.500000, -3.922053, 0.000001, 0.817607, -0.575776, +1.002737, 26.363422, 2.436586, 2.000000, -3.922053, 0.561369, 0.675750, -0.477732, +1.002737, 25.606094, 1.426226, 2.000000, -3.967943, 0.572183, 0.564519, -0.594916, +1.002737, 25.606094, 1.426226, 2.000000, -3.967943, 0.572183, 0.564519, -0.594916, +0.742768, 25.130249, 1.141007, 2.000000, -4.000000, 0.424007, 0.088516, -0.901323, +0.000000, 25.158775, 0.885566, 1.500000, -4.000000, 0.000000, 0.098978, -0.995090, +1.002737, 4.921762, -29.530731, 3.000000, 0.966243, 0.582240, 0.811733, -0.045667, +1.002737, 4.997122, -28.191074, 3.000000, 0.922656, 0.582175, 0.810004, -0.070467, +1.336982, 4.293425, -28.133030, 2.500000, 0.922656, 0.999926, -0.012083, 0.001603, +1.336982, 4.293425, -28.133030, 2.500000, 0.922656, 0.999926, -0.012083, 0.001603, +1.002737, 3.589725, -28.074989, 2.000000, 0.922656, 0.569426, -0.818637, 0.074745, +1.002737, 3.502487, -29.476650, 2.000000, 0.966243, 0.570521, -0.819696, 0.051023, +1.002737, 3.807196, -26.139326, 2.000000, 0.859409, 0.566467, -0.814178, 0.127399, +1.002737, 3.589725, -28.074989, 2.000000, 0.922656, 0.569426, -0.818637, 0.074745, +1.336982, 4.293425, -28.133030, 2.500000, 0.922656, 0.999926, -0.012083, 0.001603, +1.336982, 4.293425, -28.133030, 2.500000, 0.922656, 0.999926, -0.012083, 0.001603, +1.002737, 4.997122, -28.191074, 3.000000, 0.922656, 0.582175, 0.810004, -0.070467, +1.002737, 5.199909, -26.333269, 3.000000, 0.859409, 0.582690, 0.803052, -0.124820, +1.002737, 5.199909, -26.333269, 3.000000, 0.859409, 0.582690, 0.803052, -0.124820, +1.002737, 5.640600, -24.050657, 3.000000, 0.775297, 0.583127, 0.787897, -0.197941, +1.336982, 4.951294, -23.914915, 2.500000, 0.775297, 0.999837, -0.017439, 0.004781, +1.336982, 4.951294, -23.914915, 2.500000, 0.775297, 0.999837, -0.017439, 0.004781, +1.002737, 4.261988, -23.779171, 2.000000, 0.775297, 0.564634, -0.800896, 0.199384, +1.002737, 3.807196, -26.139326, 2.000000, 0.859409, 0.566467, -0.814178, 0.127399, +1.002737, 5.061195, -21.104025, 2.000000, 0.669113, 0.566458, -0.779905, 0.266220, +1.002737, 4.261988, -23.779171, 2.000000, 0.775297, 0.564634, -0.800896, 0.199384, +1.336982, 4.951294, -23.914915, 2.500000, 0.775297, 0.999837, -0.017439, 0.004781, +1.336982, 4.951294, -23.914915, 2.500000, 0.775297, 0.999837, -0.017439, 0.004781, +1.002737, 5.640600, -24.050657, 3.000000, 0.775297, 0.583127, 0.787897, -0.197941, +1.002737, 6.429670, -21.436577, 3.000000, 0.669113, 0.579786, 0.770207, -0.265761, +1.002737, 6.429670, -21.436577, 3.000000, 0.669113, 0.579786, 0.770207, -0.265761, +1.002737, 7.484703, -18.704170, 3.000000, 0.547971, 0.576888, 0.751119, -0.320970, +1.336982, 6.802818, -18.519814, 2.500000, 0.547971, 0.999946, -0.009100, 0.005070, +1.336982, 6.802818, -18.519814, 2.500000, 0.547971, 0.999946, -0.009100, 0.005070, +1.002737, 6.120935, -18.335461, 2.000000, 0.547971, 0.566613, -0.758528, 0.321845, +1.002737, 5.061195, -21.104025, 2.000000, 0.669113, 0.566458, -0.779905, 0.266220, +1.002737, 7.357327, -15.695049, 2.000000, 0.418984, 0.568348, -0.740553, 0.358555, +1.002737, 6.120935, -18.335461, 2.000000, 0.547971, 0.566613, -0.758528, 0.321845, +1.336982, 6.802818, -18.519814, 2.500000, 0.547971, 0.999946, -0.009100, 0.005070, +1.336982, 6.802818, -18.519814, 2.500000, 0.547971, 0.999946, -0.009100, 0.005070, +1.002737, 7.484703, -18.704170, 3.000000, 0.547971, 0.576888, 0.751119, -0.320970, +1.002737, 8.723274, -16.066572, 3.000000, 0.418984, 0.570576, 0.739144, -0.357922, +1.002737, 8.723274, -16.066572, 3.000000, 0.418984, 0.570576, 0.739144, -0.357922, +1.002737, 10.001389, -13.505806, 3.000000, 0.282904, 0.565597, 0.742254, -0.359389, +1.336982, 9.314625, -13.332256, 2.500000, 0.282904, 0.999983, 0.005126, -0.002905, +1.336982, 9.314625, -13.332256, 2.500000, 0.282904, 0.999983, 0.005126, -0.002905, +1.002737, 8.627859, -13.158705, 2.000000, 0.282904, 0.571429, -0.737705, 0.359528, +1.002737, 7.357327, -15.695049, 2.000000, 0.418984, 0.568348, -0.740553, 0.358555, +1.002737, 9.790028, -10.702334, 2.000000, 0.140482, 0.576977, -0.747533, 0.329077, +1.002737, 8.627859, -13.158705, 2.000000, 0.282904, 0.571429, -0.737705, 0.359528, +1.336982, 9.314625, -13.332256, 2.500000, 0.282904, 0.999983, 0.005126, -0.002905, +1.336982, 9.314625, -13.332256, 2.500000, 0.282904, 0.999983, 0.005126, -0.002905, +1.002737, 10.001389, -13.505806, 3.000000, 0.282904, 0.565597, 0.742254, -0.359389, +1.002737, 11.175043, -11.003893, 3.000000, 0.140482, 0.562569, 0.757951, -0.330192, +1.002737, 11.175043, -11.003893, 3.000000, 0.140482, 0.562569, 0.757951, -0.330192, +1.002127, 12.054029, -8.797724, 2.958333, -0.009381, 0.560195, 0.787255, -0.257702, +1.336373, 11.355911, -8.670841, 2.500000, 0.010562, 0.999602, 0.026239, -0.010414, +1.336373, 11.355911, -8.670841, 2.500000, 0.010562, 0.999602, 0.026239, -0.010414, +1.002127, 10.657795, -8.543959, 2.000000, 0.010562, 0.588607, -0.767452, 0.254084, +1.002737, 9.790028, -10.702334, 2.000000, 0.140482, 0.576977, -0.747533, 0.329077, +1.333325, 11.818588, -5.617008, 2.500000, -0.170915, 0.999852, 0.017082, 0.001868, +0.999079, 11.114811, -5.517140, 2.000000, -0.170915, 0.582792, -0.812607, -0.004817, +1.000299, 11.045135, -6.901599, 2.000000, -0.088013, 0.591516, -0.797171, 0.120947, +1.000299, 11.045135, -6.901599, 2.000000, -0.088013, 0.591516, -0.797171, 0.120947, +1.002127, 10.657795, -8.543959, 2.000000, 0.010562, 0.588607, -0.767452, 0.254084, +1.336373, 11.355911, -8.670841, 2.500000, 0.010562, 0.999602, 0.026239, -0.010414, +1.336373, 11.355911, -8.670841, 2.500000, 0.010562, 0.999602, 0.026239, -0.010414, +1.002127, 12.054029, -8.797724, 2.958333, -0.009381, 0.560195, 0.787255, -0.257702, +1.000299, 12.448139, -7.124194, 2.833333, -0.167786, 0.564659, 0.816023, -0.123558, +1.000299, 12.448139, -7.124194, 2.833333, -0.167786, 0.564659, 0.816023, -0.123558, +0.999079, 12.522362, -5.716876, 3.000000, -0.170915, 0.565733, 0.824587, 0.001687, +1.333325, 11.818588, -5.617008, 2.500000, -0.170915, 0.999852, 0.017082, 0.001868, +1.002737, 10.154957, -0.010050, 2.000000, -0.503387, 0.554487, -0.809403, -0.193422, +1.002127, 10.729588, -2.409474, 2.000000, -0.336720, 0.568931, -0.804350, -0.171283, +1.336373, 11.435898, -2.488622, 2.500000, -0.336720, 0.999684, 0.024018, 0.007427, +1.336373, 11.435898, -2.488622, 2.500000, -0.336720, 0.999684, 0.024018, 0.007427, +1.002127, 12.142200, -2.567771, 3.000000, -0.336720, 0.545588, 0.819894, 0.173516, +1.002737, 11.560024, -0.158328, 3.000000, -0.503387, 0.548192, 0.812432, 0.198592, +1.002737, 11.560024, -0.158328, 3.000000, -0.503387, 0.548192, 0.812432, 0.198592, +1.002737, 10.886791, 2.566613, 3.000000, -0.671927, 0.549613, 0.814083, 0.187601, +1.336982, 10.194935, 2.646095, 2.500000, -0.671927, 0.999975, -0.006839, -0.001674, +1.336982, 10.194935, 2.646095, 2.500000, -0.671927, 0.999975, -0.006839, -0.001674, +1.002737, 9.503082, 2.725576, 2.000000, -0.671927, 0.543427, -0.820485, -0.177458, +1.002737, 10.154957, -0.010050, 2.000000, -0.503387, 0.554487, -0.809403, -0.193422, +1.002737, 8.971350, 5.457179, 2.000000, -0.844213, 0.532911, -0.837943, -0.117722, +1.002737, 9.503082, 2.725576, 2.000000, -0.671927, 0.543427, -0.820485, -0.177458, +1.336982, 10.194935, 2.646095, 2.500000, -0.671927, 0.999975, -0.006839, -0.001674, +1.336982, 10.194935, 2.646095, 2.500000, -0.671927, 0.999975, -0.006839, -0.001674, +1.002737, 10.886791, 2.566613, 3.000000, -0.671927, 0.549613, 0.814083, 0.187601, +1.002737, 10.314148, 5.254678, 3.000000, -0.844213, 0.550065, 0.824042, 0.135587, +1.002737, 10.314148, 5.254678, 3.000000, -0.844213, 0.550065, 0.824042, 0.135587, +1.002737, 10.024445, 7.827566, 3.000000, -1.016250, 0.552727, 0.833125, 0.019881, +1.336982, 9.384014, 7.968127, 2.500000, -1.016250, 0.999385, -0.034959, -0.002597, +1.336982, 9.384014, 7.968127, 2.500000, -1.016250, 0.999385, -0.034959, -0.002597, +1.002737, 8.743584, 8.108689, 2.000000, -1.016250, 0.522039, -0.852900, 0.006099, +1.002737, 8.971350, 5.457179, 2.000000, -0.844213, 0.532911, -0.837943, -0.117722, +1.002737, 9.003599, 10.604041, 2.000000, -1.184038, 0.512969, -0.841946, 0.167304, +1.002737, 8.743584, 8.108689, 2.000000, -1.016250, 0.522039, -0.852900, 0.006099, +1.336982, 9.384014, 7.968127, 2.500000, -1.016250, 0.999385, -0.034959, -0.002597, +1.336982, 9.384014, 7.968127, 2.500000, -1.016250, 0.999385, -0.034959, -0.002597, +1.002737, 10.024445, 7.827566, 3.000000, -1.016250, 0.552727, 0.833125, 0.019881, +1.002737, 10.200031, 10.206976, 3.000000, -1.184038, 0.545898, 0.826469, -0.137636, +1.002737, 10.200031, 10.206976, 3.000000, -1.184038, 0.545898, 0.826469, -0.137636, +1.002737, 10.783842, 12.373039, 3.000000, -1.349954, 0.535040, 0.792292, -0.293267, +1.336982, 10.239292, 12.641662, 2.500000, -1.349954, 0.999218, -0.036495, 0.015192, +1.336982, 10.239292, 12.641662, 2.500000, -1.349954, 0.999218, -0.036495, 0.015192, +1.002737, 9.694744, 12.910284, 2.000000, -1.349954, 0.500990, -0.803388, 0.321833, +1.002737, 9.003599, 10.604041, 2.000000, -1.184038, 0.512969, -0.841946, 0.167304, +1.002737, 10.760361, 14.994465, 2.000000, -1.516370, 0.490912, -0.740187, 0.459488, +1.002737, 9.694744, 12.910284, 2.000000, -1.349954, 0.500990, -0.803388, 0.321833, +1.336982, 10.239292, 12.641662, 2.500000, -1.349954, 0.999218, -0.036495, 0.015192, +1.336982, 10.239292, 12.641662, 2.500000, -1.349954, 0.999218, -0.036495, 0.015192, +1.002737, 10.783842, 12.373039, 3.000000, -1.349954, 0.535040, 0.792292, -0.293267, +1.002737, 11.718807, 14.305887, 3.000000, -1.516370, 0.524951, 0.731928, -0.434405, +1.002737, 11.718807, 14.305887, 3.000000, -1.516370, 0.524951, 0.731928, -0.434405, +1.002737, 12.901150, 15.938179, 3.000000, -1.679268, 0.520177, 0.645820, -0.558867, +1.336982, 12.495934, 16.355419, 2.500000, -1.679268, 0.999037, -0.033131, 0.028753, +1.336982, 12.495934, 16.355419, 2.500000, -1.679268, 0.999037, -0.033131, 0.028753, +1.002737, 12.090717, 16.772659, 2.000000, -1.679268, 0.484165, -0.653669, 0.581636, +1.002737, 10.760361, 14.994465, 2.000000, -1.516370, 0.490912, -0.740187, 0.459488, +1.002737, 13.576080, 18.160946, 2.000000, -1.834628, 0.481336, -0.535363, 0.694048, +1.002737, 12.090717, 16.772659, 2.000000, -1.679268, 0.484165, -0.653669, 0.581636, +1.336982, 12.495934, 16.355419, 2.500000, -1.679268, 0.999037, -0.033131, 0.028753, +1.336982, 12.495934, 16.355419, 2.500000, -1.679268, 0.999037, -0.033131, 0.028753, +1.002737, 12.901150, 15.938179, 3.000000, -1.679268, 0.520177, 0.645820, -0.558867, +1.002737, 14.227100, 17.202572, 3.000000, -1.834628, 0.519663, 0.527798, -0.671848, +1.002737, 14.227100, 17.202572, 3.000000, -1.834628, 0.519663, 0.527798, -0.671848, +1.002737, 15.688553, 18.126600, 3.000000, -1.988039, 0.519424, 0.384311, -0.763219, +1.336982, 15.450417, 18.654261, 2.500000, -1.988039, 0.998886, -0.021467, 0.042031, +1.336982, 15.450417, 18.654261, 2.500000, -1.988039, 0.998886, -0.021467, 0.042031, +1.002737, 15.212280, 19.181923, 2.000000, -1.988039, 0.480828, -0.389724, 0.785442, +1.002737, 13.576080, 18.160946, 2.000000, -1.834628, 0.481336, -0.535363, 0.694048, +1.002737, 16.995155, 19.858189, 2.000000, -2.145087, 0.479530, -0.225145, 0.848151, +1.002737, 15.212280, 19.181923, 2.000000, -1.988039, 0.480828, -0.389724, 0.785442, +1.336982, 15.450417, 18.654261, 2.500000, -1.988039, 0.998886, -0.021467, 0.042031, +1.336982, 15.450417, 18.654261, 2.500000, -1.988039, 0.998886, -0.021467, 0.042031, +1.002737, 15.688553, 18.126600, 3.000000, -1.988039, 0.519424, 0.384311, -0.763219, +1.002737, 17.277420, 18.737804, 3.000000, -2.145087, 0.519855, 0.222506, -0.824768, +1.002737, 17.277420, 18.737804, 3.000000, -2.145087, 0.519855, 0.222506, -0.824768, +1.002737, 18.963112, 19.009758, 3.000000, -2.305904, 0.519106, 0.044200, -0.853567, +1.336982, 18.926823, 19.584188, 2.500000, -2.305904, 0.998704, -0.001978, 0.050856, +1.336982, 18.926823, 19.584188, 2.500000, -2.305904, 0.998704, -0.001978, 0.050856, +1.002737, 18.890533, 20.158619, 2.000000, -2.305904, 0.477686, -0.044014, 0.877427, +1.002737, 16.995155, 19.858189, 2.000000, -2.145087, 0.479530, -0.225145, 0.848151, +1.002737, 20.864250, 20.052088, 2.000000, -2.470621, 0.474231, 0.150976, 0.867359, +1.002737, 18.890533, 20.158619, 2.000000, -2.305904, 0.477686, -0.044014, 0.877427, +1.336982, 18.926823, 19.584188, 2.500000, -2.305904, 0.998704, -0.001978, 0.050856, +1.336982, 18.926823, 19.584188, 2.500000, -2.305904, 0.998704, -0.001978, 0.050856, +1.002737, 18.963112, 19.009758, 3.000000, -2.305904, 0.519106, 0.044200, -0.853567, +1.002737, 20.715042, 18.916035, 3.000000, -2.470621, 0.518180, -0.147145, -0.842519, +1.002737, 20.715042, 18.916035, 3.000000, -2.470621, 0.518180, -0.147145, -0.842519, +1.002737, 22.528091, 18.387989, 3.000000, -2.646001, 0.514483, -0.334572, -0.789537, +1.336982, 22.719658, 18.922981, 2.500000, -2.646001, 0.998523, 0.022591, 0.049420, +1.336982, 22.719658, 18.922981, 2.500000, -2.646001, 0.998523, 0.022591, 0.049420, +1.002737, 22.911228, 19.457972, 2.000000, -2.646001, 0.471248, 0.342725, 0.812690, +1.002737, 20.864250, 20.052088, 2.000000, -2.470621, 0.474231, 0.150976, 0.867359, +1.002737, 25.026405, 18.295650, 2.000000, -2.838810, 0.470077, 0.507995, 0.721781, +1.002737, 22.911228, 19.457972, 2.000000, -2.646001, 0.471248, 0.342725, 0.812690, +1.336982, 22.719658, 18.922981, 2.500000, -2.646001, 0.998523, 0.022591, 0.049420, +1.336982, 22.719658, 18.922981, 2.500000, -2.646001, 0.998523, 0.022591, 0.049420, +1.002737, 22.528091, 18.387989, 3.000000, -2.646001, 0.514483, -0.334572, -0.789537, +1.002737, 24.397125, 17.356983, 3.000000, -2.838810, 0.512162, -0.495528, -0.701529, +1.002737, 24.397125, 17.356983, 3.000000, -2.838810, 0.512162, -0.495528, -0.701529, +1.002737, 26.120163, 15.851318, 3.000000, -3.038383, 0.515999, -0.637877, -0.571716, +1.336982, 26.551086, 16.221825, 2.500000, -3.038383, 0.998387, 0.041476, 0.038776, +1.336982, 26.551086, 16.221825, 2.500000, -3.038383, 0.998387, 0.041476, 0.038776, +1.002737, 26.982021, 16.592329, 2.000000, -3.038383, 0.470672, 0.656258, 0.589740, +1.002737, 25.026405, 18.295650, 2.000000, -2.838810, 0.470077, 0.507995, 0.721781, +1.002737, 28.550339, 14.375221, 2.000000, -3.234054, 0.475606, 0.784875, 0.397204, +1.002737, 26.982021, 16.592329, 2.000000, -3.038383, 0.470672, 0.656258, 0.589740, +1.336982, 26.551086, 16.221825, 2.500000, -3.038383, 0.998387, 0.041476, 0.038776, +1.336982, 26.551086, 16.221825, 2.500000, -3.038383, 0.998387, 0.041476, 0.038776, +1.002737, 26.120163, 15.851318, 3.000000, -3.038383, 0.515999, -0.637877, -0.571716, +1.002737, 27.495193, 13.899298, 3.000000, -3.234054, 0.529173, -0.759785, -0.377761, +1.002737, 27.495193, 13.899298, 3.000000, -3.234054, 0.529173, -0.759785, -0.377761, +1.002737, 28.234837, 11.594270, 3.000000, -3.421010, 0.549862, -0.829858, -0.094800, +1.336982, 28.829941, 11.681159, 2.500000, -3.421010, 0.997287, 0.072725, 0.011376, +1.336982, 28.829941, 11.681159, 2.500000, -3.421010, 0.997287, 0.072725, 0.011376, +1.002737, 29.425041, 11.768046, 2.000000, -3.421010, 0.486093, 0.865826, 0.118573, +1.002737, 28.550339, 14.375221, 2.000000, -3.234054, 0.475606, 0.784875, 0.397204, +1.002737, 29.299828, 8.894522, 2.000000, -3.594440, 0.508084, 0.850362, -0.136877, +1.002737, 29.425041, 11.768046, 2.000000, -3.421010, 0.486093, 0.865826, 0.118573, +1.336982, 28.829941, 11.681159, 2.500000, -3.421010, 0.997287, 0.072725, 0.011376, +1.336982, 28.829941, 11.681159, 2.500000, -3.421010, 0.997287, 0.072725, 0.011376, +1.002737, 28.234837, 11.594270, 3.000000, -3.421010, 0.549862, -0.829858, -0.094800, +1.002737, 28.051701, 9.029581, 3.000000, -3.594440, 0.552395, -0.818570, 0.157487, +1.002737, 28.051701, 9.029581, 3.000000, -3.594440, 0.552395, -0.818570, 0.157487, +1.002737, 27.272324, 6.583387, 3.000000, -3.741287, 0.563171, -0.762895, 0.317537, +1.336982, 27.897228, 6.377859, 2.500000, -3.741288, 0.999306, 0.035287, -0.011950, +1.336982, 27.897228, 6.377859, 2.500000, -3.741288, 0.999306, 0.035287, -0.011950, +1.002737, 28.522129, 6.172330, 2.000000, -3.741287, 0.527923, 0.793569, -0.302564, +1.002737, 29.299828, 8.894522, 2.000000, -3.594440, 0.508084, 0.850362, -0.136877, +1.002737, 27.439377, 4.019153, 2.000000, -3.848496, 0.545786, 0.725589, -0.419091, +1.002737, 28.522129, 6.172330, 2.000000, -3.741287, 0.527923, 0.793569, -0.302564, +1.336982, 27.897228, 6.377859, 2.500000, -3.741288, 0.999306, 0.035287, -0.011950, +1.336982, 27.897228, 6.377859, 2.500000, -3.741288, 0.999306, 0.035287, -0.011950, +1.002737, 27.272324, 6.583387, 3.000000, -3.741287, 0.563171, -0.762895, 0.317537, +1.002737, 26.223228, 4.633848, 3.000000, -3.848496, 0.571231, -0.699649, 0.429169, +1.002737, 26.223228, 4.633848, 3.000000, -3.848496, 0.571231, -0.699649, 0.429169, +1.002737, 25.192875, 3.192066, 3.000000, -3.922053, 0.573805, -0.657830, 0.487860, +1.336982, 25.778152, 2.814326, 2.500000, -3.922053, 0.999924, 0.011227, -0.005182, +1.336982, 25.778152, 2.814326, 2.500000, -3.922053, 0.999924, 0.011227, -0.005182, +1.002737, 26.363422, 2.436586, 2.000000, -3.922053, 0.561369, 0.675750, -0.477732, +1.002737, 27.439377, 4.019153, 2.000000, -3.848496, 0.545786, 0.725589, -0.419091, +1.002737, 24.600067, 1.327282, 2.500000, -4.000000, 0.595697, -0.491752, -0.635079, +0.742768, 25.130249, 1.141007, 2.000000, -4.000000, 0.424007, 0.088516, -0.901323, +1.002737, 25.606094, 1.426226, 2.000000, -3.967943, 0.572183, 0.564519, -0.594916, +1.002737, 25.606094, 1.426226, 2.000000, -3.967943, 0.572183, 0.564519, -0.594916, +1.002737, 26.363422, 2.436586, 2.000000, -3.922053, 0.561369, 0.675750, -0.477732, +1.336982, 25.778152, 2.814326, 2.500000, -3.922053, 0.999924, 0.011227, -0.005182, +1.336982, 25.778152, 2.814326, 2.500000, -3.922053, 0.999924, 0.011227, -0.005182, +1.002737, 25.192875, 3.192066, 3.000000, -3.922053, 0.573805, -0.657830, 0.487860, +1.002737, 24.469711, 2.269146, 3.000000, -3.967943, 0.583534, -0.710408, 0.393458, +1.002737, 24.469711, 2.269146, 3.000000, -3.967943, 0.583534, -0.710408, 0.393458, +0.742768, 24.296909, 1.783397, 3.000000, -4.000000, 0.428917, -0.894621, -0.125234, +1.002737, 24.600067, 1.327282, 2.500000, -4.000000, 0.595697, -0.491752, -0.635079, +-1.002737, 4.921762, -29.530731, 4.000000, 0.966243, -0.582241, 0.811733, -0.045666, +-1.002737, 4.997122, -28.191074, 4.000000, 0.932486, -0.582174, 0.810005, -0.070467, +0.000000, 5.231688, -28.210423, 3.500000, 0.922656, 0.000000, 0.996270, -0.086288, +0.000000, 5.231688, -28.210423, 3.500000, 0.922656, 0.000000, 0.996270, -0.086288, +1.002737, 4.997122, -28.191074, 3.000000, 0.922656, 0.582175, 0.810004, -0.070467, +1.002737, 4.921762, -29.530731, 3.000000, 0.966243, 0.582240, 0.811733, -0.045667, +1.002737, 5.199909, -26.333269, 3.000000, 0.859409, 0.582690, 0.803052, -0.124820, +1.002737, 4.997122, -28.191074, 3.000000, 0.922656, 0.582175, 0.810004, -0.070467, +0.000000, 5.231688, -28.210423, 3.500000, 0.922656, 0.000000, 0.996270, -0.086288, +0.000000, 5.231688, -28.210423, 3.500000, 0.922656, 0.000000, 0.996270, -0.086288, +-1.002737, 4.997122, -28.191074, 4.000000, 0.932486, -0.582174, 0.810005, -0.070467, +-1.002737, 5.199909, -26.333269, 4.000000, 0.859409, -0.582690, 0.803052, -0.124820, +-1.002737, 5.199909, -26.333269, 4.000000, 0.859409, -0.582690, 0.803052, -0.124820, +-1.002737, 5.640600, -24.050657, 4.000000, 0.786333, -0.583127, 0.787897, -0.197941, +0.000000, 5.870369, -24.095905, 3.500000, 0.775297, 0.000000, 0.969755, -0.244081, +0.000000, 5.870369, -24.095905, 3.500000, 0.775297, 0.000000, 0.969755, -0.244081, +1.002737, 5.640600, -24.050657, 3.000000, 0.775297, 0.583127, 0.787897, -0.197941, +1.002737, 5.199909, -26.333269, 3.000000, 0.859409, 0.582690, 0.803052, -0.124820, +1.002737, 6.429670, -21.436577, 3.000000, 0.669113, 0.579786, 0.770207, -0.265761, +1.002737, 5.640600, -24.050657, 3.000000, 0.775297, 0.583127, 0.787897, -0.197941, +0.000000, 5.870369, -24.095905, 3.500000, 0.775297, 0.000000, 0.969755, -0.244081, +0.000000, 5.870369, -24.095905, 3.500000, 0.775297, 0.000000, 0.969755, -0.244081, +-1.002737, 5.640600, -24.050657, 4.000000, 0.786333, -0.583127, 0.787897, -0.197941, +-1.002737, 6.429670, -21.436577, 4.000000, 0.669113, -0.579786, 0.770207, -0.265761, +-1.002737, 6.429670, -21.436577, 4.000000, 0.669113, -0.579786, 0.770207, -0.265761, +-1.002737, 7.484703, -18.704168, 4.000000, 0.551894, -0.576888, 0.751118, -0.320970, +0.000000, 7.711994, -18.765621, 3.500000, 0.547971, -0.000000, 0.919277, -0.393611, +0.000000, 7.711994, -18.765621, 3.500000, 0.547971, -0.000000, 0.919277, -0.393611, +1.002737, 7.484703, -18.704170, 3.000000, 0.547971, 0.576888, 0.751119, -0.320970, +1.002737, 6.429670, -21.436577, 3.000000, 0.669113, 0.579786, 0.770207, -0.265761, +1.002737, 8.723274, -16.066572, 3.000000, 0.418984, 0.570576, 0.739144, -0.357922, +1.002737, 7.484703, -18.704170, 3.000000, 0.547971, 0.576888, 0.751119, -0.320970, +0.000000, 7.711994, -18.765621, 3.500000, 0.547971, -0.000000, 0.919277, -0.393611, +0.000000, 7.711994, -18.765621, 3.500000, 0.547971, -0.000000, 0.919277, -0.393611, +-1.002737, 7.484703, -18.704168, 4.000000, 0.551894, -0.576888, 0.751118, -0.320970, +-1.002737, 8.723274, -16.066572, 4.000000, 0.418984, -0.570577, 0.739144, -0.357922, +-1.002737, 8.723274, -16.066572, 4.000000, 0.418984, -0.570577, 0.739144, -0.357922, +-1.002737, 10.001389, -13.505806, 4.000000, 0.286075, -0.565597, 0.742253, -0.359389, +0.000000, 10.230309, -13.563657, 3.500000, 0.282904, -0.000000, 0.900257, -0.435359, +0.000000, 10.230309, -13.563657, 3.500000, 0.282904, -0.000000, 0.900257, -0.435359, +1.002737, 10.001389, -13.505806, 3.000000, 0.282904, 0.565597, 0.742254, -0.359389, +1.002737, 8.723274, -16.066572, 3.000000, 0.418984, 0.570576, 0.739144, -0.357922, +1.002737, 11.175043, -11.003893, 3.000000, 0.140482, 0.562569, 0.757951, -0.330192, +1.002737, 10.001389, -13.505806, 3.000000, 0.282904, 0.565597, 0.742254, -0.359389, +0.000000, 10.230309, -13.563657, 3.500000, 0.282904, -0.000000, 0.900257, -0.435359, +0.000000, 10.230309, -13.563657, 3.500000, 0.282904, -0.000000, 0.900257, -0.435359, +-1.002737, 10.001389, -13.505806, 4.000000, 0.286075, -0.565597, 0.742253, -0.359389, +-1.002737, 11.175043, -11.003893, 4.000000, 0.140482, -0.562513, 0.757929, -0.330337, +-1.002737, 11.175043, -11.003893, 4.000000, 0.140482, -0.562513, 0.757929, -0.330337, +-1.003346, 12.054029, -8.797724, 4.000000, -0.005111, -0.560047, 0.787144, -0.258362, +-0.000610, 12.286734, -8.840019, 3.333333, -0.069211, 0.000044, 0.950614, -0.310377, +-0.000610, 12.286734, -8.840019, 3.333333, -0.069211, 0.000044, 0.950614, -0.310377, +1.002127, 12.054029, -8.797724, 2.958333, -0.009381, 0.560195, 0.787255, -0.257702, +1.002737, 11.175043, -11.003893, 3.000000, 0.140482, 0.562569, 0.757951, -0.330192, +1.000299, 12.448139, -7.124194, 2.833333, -0.167786, 0.564659, 0.816023, -0.123558, +1.002127, 12.054029, -8.797724, 2.958333, -0.009381, 0.560195, 0.787255, -0.257702, +-0.000610, 12.286734, -8.840019, 3.333333, -0.069211, 0.000044, 0.950614, -0.310377, +-0.000610, 12.286734, -8.840019, 3.333333, -0.069211, 0.000044, 0.950614, -0.310377, +-1.003346, 12.054029, -8.797724, 4.000000, -0.005111, -0.560047, 0.787144, -0.258362, +-1.005175, 12.448139, -7.124194, 2.666667, -0.726194, -0.564732, 0.815815, -0.124590, +-1.005175, 12.448139, -7.124194, 2.666667, -0.726194, -0.564732, 0.815815, -0.124590, +-1.006394, 12.522362, -5.716876, 1.333333, -1.447277, -0.566040, 0.824377, 0.001632, +-0.003657, 12.756954, -5.750165, 2.166667, -0.809096, -0.000126, 1.000000, 0.000870, +-0.003657, 12.756954, -5.750165, 2.166667, -0.809096, -0.000126, 1.000000, 0.000870, +0.999079, 12.522362, -5.716876, 3.000000, -0.170915, 0.565733, 0.824587, 0.001687, +1.000299, 12.448139, -7.124194, 2.833333, -0.167786, 0.564659, 0.816023, -0.123558, +1.002737, 11.560024, -0.158328, 3.000000, -0.503387, 0.548192, 0.812432, 0.198592, +1.002127, 12.142200, -2.567771, 3.000000, -0.336720, 0.545588, 0.819894, 0.173516, +-0.000610, 12.377636, -2.594154, 3.500000, -0.336720, 0.000041, 0.978486, 0.206311, +-0.000610, 12.377636, -2.594154, 3.500000, -0.336720, 0.000041, 0.978486, 0.206311, +-1.003346, 12.142200, -2.567771, 4.000000, -0.336720, -0.545383, 0.819886, 0.174196, +-1.002737, 11.560024, -0.158328, 4.000000, -0.503387, -0.548128, 0.812439, 0.198744, +-1.002737, 11.560024, -0.158328, 4.000000, -0.503387, -0.548128, 0.812439, 0.198744, +-1.002737, 10.886791, 2.566613, 4.000000, -0.670054, -0.549613, 0.814083, 0.187601, +0.000000, 11.117409, 2.540119, 3.500000, -0.671927, 0.000000, 0.974103, 0.226104, +0.000000, 11.117409, 2.540119, 3.500000, -0.671927, 0.000000, 0.974103, 0.226104, +1.002737, 10.886791, 2.566613, 3.000000, -0.671927, 0.549613, 0.814083, 0.187601, +1.002737, 11.560024, -0.158328, 3.000000, -0.503387, 0.548192, 0.812432, 0.198592, +1.002737, 10.314148, 5.254678, 3.000000, -0.844213, 0.550065, 0.824042, 0.135587, +1.002737, 10.886791, 2.566613, 3.000000, -0.671927, 0.549613, 0.814083, 0.187601, +0.000000, 11.117409, 2.540119, 3.500000, -0.671927, 0.000000, 0.974103, 0.226104, +0.000000, 11.117409, 2.540119, 3.500000, -0.671927, 0.000000, 0.974103, 0.226104, +-1.002737, 10.886791, 2.566613, 4.000000, -0.670054, -0.549613, 0.814083, 0.187601, +-1.002737, 10.314148, 5.254678, 4.000000, -0.844213, -0.550065, 0.824042, 0.135588, +-1.002737, 10.314148, 5.254678, 4.000000, -0.844213, -0.550065, 0.824042, 0.135588, +-1.002737, 10.024443, 7.827566, 4.000000, -1.018373, -0.552727, 0.833125, 0.019881, +0.000000, 10.237921, 7.780712, 3.500000, -1.016250, -0.000000, 0.999593, 0.028523, +0.000000, 10.237921, 7.780712, 3.500000, -1.016250, -0.000000, 0.999593, 0.028523, +1.002737, 10.024445, 7.827566, 3.000000, -1.016250, 0.552727, 0.833125, 0.019881, +1.002737, 10.314148, 5.254678, 3.000000, -0.844213, 0.550065, 0.824042, 0.135587, +1.002737, 10.200031, 10.206976, 3.000000, -1.184038, 0.545898, 0.826469, -0.137636, +1.002737, 10.024445, 7.827566, 3.000000, -1.016250, 0.552727, 0.833125, 0.019881, +0.000000, 10.237921, 7.780712, 3.500000, -1.016250, -0.000000, 0.999593, 0.028523, +0.000000, 10.237921, 7.780712, 3.500000, -1.016250, -0.000000, 0.999593, 0.028523, +-1.002737, 10.024443, 7.827566, 4.000000, -1.018373, -0.552727, 0.833125, 0.019881, +-1.002737, 10.200031, 10.206976, 4.000000, -1.184038, -0.545898, 0.826469, -0.137636, +-1.002737, 10.200031, 10.206976, 4.000000, -1.184038, -0.545898, 0.826469, -0.137636, +-1.002737, 10.783842, 12.373039, 4.000000, -1.349704, -0.535040, 0.792292, -0.293266, +0.000000, 10.965359, 12.283498, 3.500000, -1.349954, -0.000000, 0.938935, -0.344095, +0.000000, 10.965359, 12.283498, 3.500000, -1.349954, -0.000000, 0.938935, -0.344095, +1.002737, 10.783842, 12.373039, 3.000000, -1.349954, 0.535040, 0.792292, -0.293267, +1.002737, 10.200031, 10.206976, 3.000000, -1.184038, 0.545898, 0.826469, -0.137636, +1.002737, 11.718807, 14.305887, 3.000000, -1.516370, 0.524951, 0.731928, -0.434405, +1.002737, 10.783842, 12.373039, 3.000000, -1.349954, 0.535040, 0.792292, -0.293267, +0.000000, 10.965359, 12.283498, 3.500000, -1.349954, -0.000000, 0.938935, -0.344095, +0.000000, 10.965359, 12.283498, 3.500000, -1.349954, -0.000000, 0.938935, -0.344095, +-1.002737, 10.783842, 12.373039, 4.000000, -1.349704, -0.535040, 0.792292, -0.293266, +-1.002737, 11.718807, 14.305887, 4.000000, -1.516370, -0.524951, 0.731928, -0.434405, +-1.002737, 11.718807, 14.305887, 4.000000, -1.516370, -0.524951, 0.731928, -0.434405, +-1.002737, 12.901150, 15.938179, 4.000000, -1.683037, -0.520176, 0.645820, -0.558867, +0.000000, 13.036221, 15.799099, 3.500000, -1.679268, 0.000000, 0.757369, -0.652987, +0.000000, 13.036221, 15.799099, 3.500000, -1.679268, 0.000000, 0.757369, -0.652987, +1.002737, 12.901150, 15.938179, 3.000000, -1.679268, 0.520177, 0.645820, -0.558867, +1.002737, 11.718807, 14.305887, 3.000000, -1.516370, 0.524951, 0.731928, -0.434405, +1.002737, 14.227100, 17.202572, 3.000000, -1.834628, 0.519663, 0.527798, -0.671848, +1.002737, 12.901150, 15.938179, 3.000000, -1.679268, 0.520177, 0.645820, -0.558867, +0.000000, 13.036221, 15.799099, 3.500000, -1.679268, 0.000000, 0.757369, -0.652987, +0.000000, 13.036221, 15.799099, 3.500000, -1.679268, 0.000000, 0.757369, -0.652987, +-1.002737, 12.901150, 15.938179, 4.000000, -1.683037, -0.520176, 0.645820, -0.558867, +-1.002737, 14.227100, 17.202572, 4.000000, -1.834628, -0.519663, 0.527798, -0.671848, +-1.002737, 14.227100, 17.202572, 4.000000, -1.834628, -0.519663, 0.527798, -0.671848, +-1.002737, 15.688553, 18.126600, 4.000000, -1.986219, -0.519424, 0.384311, -0.763219, +0.000000, 15.767933, 17.950714, 3.500000, -1.988039, 0.000000, 0.450479, -0.892787, +0.000000, 15.767933, 17.950714, 3.500000, -1.988039, 0.000000, 0.450479, -0.892787, +1.002737, 15.688553, 18.126600, 3.000000, -1.988039, 0.519424, 0.384311, -0.763219, +1.002737, 14.227100, 17.202572, 3.000000, -1.834628, 0.519663, 0.527798, -0.671848, +1.002737, 17.277420, 18.737804, 3.000000, -2.145087, 0.519855, 0.222506, -0.824768, +1.002737, 15.688553, 18.126600, 3.000000, -1.988039, 0.519424, 0.384311, -0.763219, +0.000000, 15.767933, 17.950714, 3.500000, -1.988039, 0.000000, 0.450479, -0.892787, +0.000000, 15.767933, 17.950714, 3.500000, -1.988039, 0.000000, 0.450479, -0.892787, +-1.002737, 15.688553, 18.126600, 4.000000, -1.986219, -0.519424, 0.384311, -0.763219, +-1.002737, 17.277420, 18.737804, 4.000000, -2.145087, -0.519855, 0.222506, -0.824768, +-1.002737, 17.277420, 18.737804, 4.000000, -2.145087, -0.519855, 0.222506, -0.824768, +-1.002737, 18.963112, 19.009758, 4.000000, -2.303954, -0.519106, 0.044200, -0.853567, +0.000000, 18.975204, 18.818281, 3.500000, -2.305904, -0.000000, 0.051821, -0.998656, +0.000000, 18.975204, 18.818281, 3.500000, -2.305904, -0.000000, 0.051821, -0.998656, +1.002737, 18.963112, 19.009758, 3.000000, -2.305904, 0.519106, 0.044200, -0.853567, +1.002737, 17.277420, 18.737804, 3.000000, -2.145087, 0.519855, 0.222506, -0.824768, +1.002737, 20.715042, 18.916035, 3.000000, -2.470621, 0.518180, -0.147145, -0.842519, +1.002737, 18.963112, 19.009758, 3.000000, -2.305904, 0.519106, 0.044200, -0.853567, +0.000000, 18.975204, 18.818281, 3.500000, -2.305904, -0.000000, 0.051821, -0.998656, +0.000000, 18.975204, 18.818281, 3.500000, -2.305904, -0.000000, 0.051821, -0.998656, +-1.002737, 18.963112, 19.009758, 4.000000, -2.303954, -0.519106, 0.044200, -0.853567, +-1.002737, 20.715042, 18.916035, 4.000000, -2.470621, -0.518180, -0.147145, -0.842519, +-1.002737, 20.715042, 18.916035, 4.000000, -2.470621, -0.518180, -0.147145, -0.842519, +-1.002737, 22.528088, 18.387989, 4.000000, -2.637287, -0.514483, -0.334572, -0.789537, +0.000000, 22.464233, 18.209660, 3.500000, -2.646001, -0.000000, -0.390600, -0.920561, +0.000000, 22.464233, 18.209660, 3.500000, -2.646001, -0.000000, -0.390600, -0.920561, +1.002737, 22.528091, 18.387989, 3.000000, -2.646001, 0.514483, -0.334572, -0.789537, +1.002737, 20.715042, 18.916035, 3.000000, -2.470621, 0.518180, -0.147145, -0.842519, +1.002737, 24.397125, 17.356983, 3.000000, -2.838810, 0.512162, -0.495528, -0.701529, +1.002737, 22.528091, 18.387989, 3.000000, -2.646001, 0.514483, -0.334572, -0.789537, +0.000000, 22.464233, 18.209660, 3.500000, -2.646001, -0.000000, -0.390600, -0.920561, +0.000000, 22.464233, 18.209660, 3.500000, -2.646001, -0.000000, -0.390600, -0.920561, +-1.002737, 22.528088, 18.387989, 4.000000, -2.637287, -0.514483, -0.334572, -0.789537, +-1.002737, 24.397125, 17.356983, 4.000000, -2.838810, -0.512162, -0.495528, -0.701529, +-1.002737, 24.397125, 17.356983, 4.000000, -2.838810, -0.512162, -0.495528, -0.701529, +-1.002737, 26.120163, 15.851318, 4.000000, -3.040334, -0.515999, -0.637877, -0.571716, +0.000000, 25.976517, 15.727814, 3.500000, -3.038383, -0.000000, -0.744667, -0.667436, +0.000000, 25.976517, 15.727814, 3.500000, -3.038383, -0.000000, -0.744667, -0.667436, +1.002737, 26.120163, 15.851318, 3.000000, -3.038383, 0.515999, -0.637877, -0.571716, +1.002737, 24.397125, 17.356983, 3.000000, -2.838810, 0.512162, -0.495528, -0.701529, +1.002737, 27.495193, 13.899298, 3.000000, -3.234054, 0.529173, -0.759785, -0.377761, +1.002737, 26.120163, 15.851318, 3.000000, -3.038383, 0.515999, -0.637877, -0.571716, +0.000000, 25.976517, 15.727814, 3.500000, -3.038383, -0.000000, -0.744667, -0.667436, +0.000000, 25.976517, 15.727814, 3.500000, -3.038383, -0.000000, -0.744667, -0.667436, +-1.002737, 26.120163, 15.851318, 4.000000, -3.040334, -0.515999, -0.637877, -0.571716, +-1.002737, 27.495193, 13.899298, 4.000000, -3.234054, -0.529173, -0.759785, -0.377761, +-1.002737, 27.495193, 13.899298, 4.000000, -3.234054, -0.529173, -0.759785, -0.377761, +-1.002737, 28.234837, 11.594271, 4.000000, -3.427773, -0.549861, -0.829859, -0.094800, +0.000000, 28.036469, 11.565307, 3.500000, -3.421010, -0.000000, -0.993846, -0.110776, +0.000000, 28.036469, 11.565307, 3.500000, -3.421010, -0.000000, -0.993846, -0.110776, +1.002737, 28.234837, 11.594270, 3.000000, -3.421010, 0.549862, -0.829858, -0.094800, +1.002737, 27.495193, 13.899298, 3.000000, -3.234054, 0.529173, -0.759785, -0.377761, +1.002737, 28.051701, 9.029581, 3.000000, -3.594440, 0.552395, -0.818570, 0.157487, +1.002737, 28.234837, 11.594270, 3.000000, -3.421010, 0.549862, -0.829858, -0.094800, +0.000000, 28.036469, 11.565307, 3.500000, -3.421010, -0.000000, -0.993846, -0.110776, +0.000000, 28.036469, 11.565307, 3.500000, -3.421010, -0.000000, -0.993846, -0.110776, +-1.002737, 28.234837, 11.594271, 4.000000, -3.427773, -0.549861, -0.829859, -0.094800, +-1.002737, 28.051701, 9.029581, 4.000000, -3.594440, -0.552394, -0.818572, 0.157487, +-1.002737, 28.051701, 9.029581, 4.000000, -3.594440, -0.552394, -0.818572, 0.157487, +-1.002737, 27.272324, 6.583387, 4.000000, -3.761107, -0.563170, -0.762896, 0.317537, +0.000000, 27.064018, 6.651896, 3.500000, -3.741288, 0.000000, -0.921832, 0.387591, +0.000000, 27.064018, 6.651896, 3.500000, -3.741288, 0.000000, -0.921832, 0.387591, +1.002737, 27.272324, 6.583387, 3.000000, -3.741287, 0.563171, -0.762895, 0.317537, +1.002737, 28.051701, 9.029581, 3.000000, -3.594440, 0.552395, -0.818570, 0.157487, +1.002737, 26.223228, 4.633848, 3.000000, -3.848496, 0.571231, -0.699649, 0.429169, +1.002737, 27.272324, 6.583387, 3.000000, -3.741287, 0.563171, -0.762895, 0.317537, +0.000000, 27.064018, 6.651896, 3.500000, -3.741288, 0.000000, -0.921832, 0.387591, +0.000000, 27.064018, 6.651896, 3.500000, -3.741288, 0.000000, -0.921832, 0.387591, +-1.002737, 27.272324, 6.583387, 4.000000, -3.761107, -0.563170, -0.762896, 0.317537, +-1.002737, 26.223228, 4.633848, 4.000000, -3.848496, -0.571231, -0.699650, 0.429169, +-1.002737, 26.223228, 4.633848, 4.000000, -3.848496, -0.571231, -0.699650, 0.429169, +-1.002737, 25.192875, 3.192066, 4.000000, -3.935886, -0.573805, -0.657830, 0.487860, +0.000000, 24.997784, 3.317980, 3.500000, -3.922053, -0.000000, -0.801896, 0.597463, +0.000000, 24.997784, 3.317980, 3.500000, -3.922053, -0.000000, -0.801896, 0.597463, +1.002737, 25.192875, 3.192066, 3.000000, -3.922053, 0.573805, -0.657830, 0.487860, +1.002737, 26.223228, 4.633848, 3.000000, -3.848496, 0.571231, -0.699649, 0.429169, +0.000000, 24.041351, 1.768998, 3.500000, -4.000000, 0.000000, -0.991299, -0.131630, +0.742768, 24.296909, 1.783397, 3.000000, -4.000000, 0.428917, -0.894621, -0.125234, +1.002737, 24.469711, 2.269146, 3.000000, -3.967943, 0.583534, -0.710408, 0.393458, +1.002737, 24.469711, 2.269146, 3.000000, -3.967943, 0.583534, -0.710408, 0.393458, +1.002737, 25.192875, 3.192066, 3.000000, -3.922053, 0.573805, -0.657830, 0.487860, +0.000000, 24.997784, 3.317980, 3.500000, -3.922053, -0.000000, -0.801896, 0.597463, +0.000000, 24.997784, 3.317980, 3.500000, -3.922053, -0.000000, -0.801896, 0.597463, +-1.002737, 25.192875, 3.192066, 4.000000, -3.935886, -0.573805, -0.657830, 0.487860, +-1.002737, 24.469711, 2.269146, 4.000000, -3.967943, -0.583534, -0.710408, 0.393458, +-1.002737, 24.469711, 2.269146, 4.000000, -3.967943, -0.583534, -0.710408, 0.393458, +-0.742768, 24.296909, 1.783397, 4.000000, -4.000000, -0.428917, -0.894621, -0.125234, +0.000000, 24.041351, 1.768998, 3.500000, -4.000000, 0.000000, -0.991299, -0.131630, +-1.002737, -1.292564, -32.294178, 1.000000, 0.972854, -0.576236, -0.817066, 0.018853, +-1.002737, -1.259859, -30.876823, 1.000000, 0.937170, -0.573164, -0.818796, 0.032517, +-1.336982, -0.552929, -30.921089, 0.500000, 0.937170, -0.999978, -0.006540, 0.000687, +-1.336982, -0.552929, -30.921089, 0.500000, 0.937170, -0.999978, -0.006540, 0.000687, +-1.002737, 0.153999, -30.965355, 0.000000, 0.945709, -0.580105, 0.814042, -0.028521, +-1.002737, 0.129889, -32.334755, 0.000000, 0.972854, -0.578352, 0.815661, -0.014359, +-1.002737, 0.245815, -29.027195, 0.000000, 0.884407, -0.580554, 0.811733, -0.063605, +-1.002737, 0.153999, -30.965355, 0.000000, 0.945709, -0.580105, 0.814042, -0.028521, +-1.336982, -0.552929, -30.921089, 0.500000, 0.937170, -0.999978, -0.006540, 0.000687, +-1.336982, -0.552929, -30.921089, 0.500000, 0.937170, -0.999978, -0.006540, 0.000687, +-1.002737, -1.259859, -30.876823, 1.000000, 0.937170, -0.573164, -0.818796, 0.032517, +-1.002737, -1.156864, -28.875961, 1.000000, 0.884407, -0.570246, -0.818776, 0.066533, +-1.002737, -1.156864, -28.875961, 1.000000, 0.884407, -0.570246, -0.818776, 0.066533, +-1.002737, -0.895025, -26.385366, 1.000000, 0.812277, -0.568649, -0.814249, 0.116778, +-1.336982, -0.199492, -26.493555, 0.500000, 0.812277, -0.999928, -0.011914, 0.001651, +-1.336982, -0.199492, -26.493555, 0.500000, 0.812277, -0.999928, -0.011914, 0.001651, +-1.002737, 0.496042, -26.601746, 0.000000, 0.823105, -0.581048, 0.805721, -0.114877, +-1.002737, 0.245815, -29.027195, 0.000000, 0.884407, -0.580554, 0.811733, -0.063605, +-1.002737, 0.995396, -23.770485, 0.000000, 0.718491, -0.583417, 0.789634, -0.190008, +-1.002737, 0.496042, -26.601746, 0.000000, 0.823105, -0.581048, 0.805721, -0.114877, +-1.336982, -0.199492, -26.493555, 0.500000, 0.812277, -0.999928, -0.011914, 0.001651, +-1.336982, -0.199492, -26.493555, 0.500000, 0.812277, -0.999928, -0.011914, 0.001651, +-1.002737, -0.895025, -26.385366, 1.000000, 0.812277, -0.568649, -0.814249, 0.116778, +-1.002737, -0.385786, -23.498796, 1.000000, 0.718491, -0.565019, -0.802220, 0.192863, +-1.002737, -0.385786, -23.498796, 1.000000, 0.718491, -0.565019, -0.802220, 0.192863, +-1.000716, 0.522999, -20.483551, 1.046875, 0.600702, -0.555184, -0.771596, 0.310500, +-1.334961, 1.211163, -20.628946, 0.687500, 0.612715, -0.999676, -0.020934, 0.014474, +-1.334961, 1.211163, -20.628946, 0.687500, 0.612715, -0.999676, -0.020934, 0.014474, +-1.000716, 1.899328, -20.774343, 0.000000, 0.613877, -0.578823, 0.757196, -0.302684, +-1.002737, 0.995396, -23.770485, 0.000000, 0.718491, -0.583417, 0.789634, -0.190008, +-0.994652, 3.363289, -17.854239, 1.500000, 0.568689, -0.554925, 0.739714, -0.380633, +-1.000716, 1.899328, -20.774343, 0.000000, 0.613877, -0.578823, 0.757196, -0.302684, +-1.334961, 1.211163, -20.628946, 0.687500, 0.612715, -0.999676, -0.020934, 0.014474, +-1.334961, 1.211163, -20.628946, 0.687500, 0.612715, -0.999676, -0.020934, 0.014474, +-1.000716, 0.522999, -20.483551, 1.046875, 0.600702, -0.555184, -0.771596, 0.310500, +-0.994652, 1.983473, -17.606916, 1.187500, 0.456561, -0.553223, -0.737418, 0.387504, +-0.994652, 1.983473, -17.606916, 1.187500, 0.456561, -0.553223, -0.737418, 0.387504, +-0.990610, 3.544037, -14.721523, 1.000000, 0.267209, -0.562098, -0.749029, 0.350717, +-1.324855, 4.237772, -14.807808, 2.000000, 0.395355, -0.999804, 0.015791, -0.011962, +-1.324855, 4.237772, -14.807808, 2.000000, 0.395355, -0.999804, 0.015791, -0.011962, +-0.990610, 4.931509, -14.894089, 3.000000, 0.523501, -0.544986, 0.762408, -0.348891, +-0.994652, 3.363289, -17.854239, 1.500000, 0.568689, -0.554925, 0.739714, -0.380633, +-1.002737, 6.556976, -6.071414, 0.000000, -0.308178, -0.553122, 0.818963, 0.152824, +-1.000716, 6.770885, -8.754030, 0.000000, -0.079458, -0.549751, 0.833161, -0.060139, +-1.334961, 6.071638, -8.749280, 0.500000, -0.079458, -0.999000, 0.044233, -0.006500, +-1.334961, 6.071638, -8.749280, 0.500000, -0.079458, -0.999000, 0.044233, -0.006500, +-1.000716, 5.372389, -8.744530, 1.000000, -0.079458, -0.594849, -0.801661, 0.059106, +-1.002737, 5.163677, -6.177338, 1.000000, -0.308178, -0.587361, -0.794674, -0.153298, +-1.002737, 5.163677, -6.177338, 1.000000, -0.308178, -0.587361, -0.794674, -0.153298, +-1.002737, 4.402004, -3.694788, 1.000000, -0.537451, -0.571136, -0.774985, -0.270559, +-1.336982, 5.093796, -3.594290, 0.500000, -0.537451, -0.999877, 0.014256, 0.006545, +-1.336982, 5.093796, -3.594290, 0.500000, -0.537451, -0.999877, 0.014256, 0.006545, +-1.002737, 5.785589, -3.493792, 0.000000, -0.536897, -0.556039, 0.785897, 0.270530, +-1.002737, 6.556976, -6.071414, 0.000000, -0.308178, -0.553122, 0.818963, 0.152824, +-1.002737, 4.735826, -0.785002, 0.000000, -0.767833, -0.563593, 0.774459, 0.287360, +-1.002737, 5.785589, -3.493792, 0.000000, -0.536897, -0.556039, 0.785897, 0.270530, +-1.336982, 5.093796, -3.594290, 0.500000, -0.537451, -0.999877, 0.014256, 0.006545, +-1.336982, 5.093796, -3.594290, 0.500000, -0.537451, -0.999877, 0.014256, 0.006545, +-1.002737, 4.402004, -3.694788, 1.000000, -0.537451, -0.571136, -0.774985, -0.270559, +-1.002737, 3.362402, -1.013249, 1.000000, -0.767833, -0.559574, -0.778227, -0.285025, +-1.002737, 3.362402, -1.013249, 1.000000, -0.767833, -0.559574, -0.778227, -0.285025, +-1.002737, 2.394936, 1.783656, 1.046875, -0.973474, -0.550621, -0.806194, -0.216490, +-1.336982, 3.076645, 1.877820, 0.687500, -0.955495, -0.999725, -0.022213, -0.007478, +-1.336982, 3.076645, 1.877820, 0.687500, -0.955495, -0.999725, -0.022213, -0.007478, +-1.002737, 3.758350, 1.971984, 0.000000, -0.998770, -0.573360, 0.788967, 0.220880, +-1.002737, 4.735826, -0.785002, 0.000000, -0.767833, -0.563593, 0.774459, 0.287360, +-1.002737, 3.203825, 4.694192, 1.500000, -0.960717, -0.573166, 0.812586, 0.105755, +-1.002737, 3.758350, 1.971984, 0.000000, -0.998770, -0.573360, 0.788967, 0.220880, +-1.336982, 3.076645, 1.877820, 0.687500, -0.955495, -0.999725, -0.022213, -0.007478, +-1.336982, 3.076645, 1.877820, 0.687500, -0.955495, -0.999725, -0.022213, -0.007478, +-1.002737, 2.394936, 1.783656, 1.046875, -0.973474, -0.550621, -0.806194, -0.216490, +-1.002737, 1.849670, 4.612304, 1.187500, -1.128520, -0.548005, -0.830422, -0.100446, +-1.002737, 1.849670, 4.612304, 1.187500, -1.128520, -0.548005, -0.830422, -0.100446, +-1.002737, 1.707661, 7.456823, 1.000000, -1.306215, -0.546192, -0.837529, 0.014826, +-1.336982, 2.380295, 7.427917, 2.000000, -1.114440, -0.999670, -0.025705, 0.000199, +-1.336982, 2.380295, 7.427917, 2.000000, -1.114440, -0.999670, -0.025705, 0.000199, +-1.002737, 3.052929, 7.399012, 3.000000, -0.922665, -0.571504, 0.820505, -0.012461, +-1.002737, 3.203825, 4.694192, 1.500000, -0.960717, -0.573166, 0.812586, 0.105755, +-1.022346, 4.637777, 15.286472, 1.333333, -1.667888, -0.574184, 0.765044, -0.291584, +-1.007639, 3.836994, 12.751901, 0.000000, -1.613659, -0.571038, 0.793815, -0.209219, +-1.341885, 3.176014, 12.915927, 0.500000, -1.613659, -0.999798, -0.020077, 0.001135, +-1.341885, 3.176014, 12.915927, 0.500000, -1.613659, -0.999798, -0.020077, 0.001135, +-1.007639, 2.515034, 13.079953, 1.000000, -1.613659, -0.551445, -0.808533, 0.205386, +-1.022346, 3.341311, 15.726742, 1.166667, -1.691614, -0.553953, -0.781075, 0.288198, +-1.022346, 3.341311, 15.726742, 1.166667, -1.691614, -0.553953, -0.781075, 0.288198, +-1.032151, 4.412262, 18.174877, 1.000000, -1.776346, -0.555665, -0.740194, 0.378615, +-1.366396, 5.044981, 17.903212, 1.833333, -1.749232, -0.999757, -0.019426, 0.010462, +-1.366396, 5.044981, 17.903212, 1.833333, -1.749232, -0.999757, -0.019426, 0.010462, +-1.032151, 5.677700, 17.631544, 2.666667, -1.722117, -0.577835, 0.723604, -0.377496, +-1.022346, 4.637777, 15.286472, 1.333333, -1.667888, -0.574184, 0.765044, -0.291584, +-1.002737, 8.987209, 23.827108, 0.500000, -2.000000, -0.690086, 0.408969, 0.597098, +-0.742768, 9.282909, 23.329664, 0.000000, -2.000000, -0.487251, 0.872639, 0.032983, +-1.002737, 9.038933, 22.663582, 0.000000, -1.969517, -0.582357, 0.720010, -0.377421, +-1.002737, 9.038933, 22.663582, 0.000000, -1.969517, -0.582357, 0.720010, -0.377421, +-1.007639, 8.160118, 21.422651, 0.000000, -1.939034, -0.574068, 0.669723, -0.471080, +-1.341885, 7.556932, 21.789433, 0.500000, -1.939034, -0.999989, 0.000304, 0.004665, +-1.341885, 7.556932, 21.789433, 0.500000, -1.939034, -0.999989, 0.000304, 0.004665, +-1.007639, 6.953747, 22.156216, 1.000000, -1.939034, -0.571627, -0.672843, 0.469600, +-1.002737, 7.854620, 23.452549, 1.000000, -1.969517, -0.579230, -0.604597, 0.546768, +-1.002737, 7.854620, 23.452549, 1.000000, -1.969517, -0.579230, -0.604597, 0.546768, +-0.742768, 8.411285, 23.925793, 1.000000, -2.000000, -0.485429, -0.281111, 0.827850, +-1.002737, 8.987209, 23.827108, 0.500000, -2.000000, -0.690086, 0.408969, 0.597098, +1.002737, -1.292564, -32.294174, 2.000000, 0.972854, 0.576237, -0.817066, 0.018853, +1.002737, -1.259859, -30.876823, 2.000000, 0.937170, 0.573164, -0.818795, 0.032517, +0.000000, -1.495502, -30.862072, 1.500000, 0.937170, 0.000000, -0.999196, 0.040090, +0.000000, -1.495502, -30.862072, 1.500000, 0.937170, 0.000000, -0.999196, 0.040090, +-1.002737, -1.259859, -30.876823, 1.000000, 0.937170, -0.573164, -0.818796, 0.032517, +-1.002737, -1.292564, -32.294178, 1.000000, 0.972854, -0.576236, -0.817066, 0.018853, +-1.002737, -1.156864, -28.875961, 1.000000, 0.884407, -0.570246, -0.818776, 0.066533, +-1.002737, -1.259859, -30.876823, 1.000000, 0.937170, -0.573164, -0.818796, 0.032517, +0.000000, -1.495502, -30.862072, 1.500000, 0.937170, 0.000000, -0.999196, 0.040090, +0.000000, -1.495502, -30.862072, 1.500000, 0.937170, 0.000000, -0.999196, 0.040090, +1.002737, -1.259859, -30.876823, 2.000000, 0.937170, 0.573164, -0.818795, 0.032517, +1.002737, -1.156864, -28.875965, 2.000000, 0.884407, 0.570246, -0.818775, 0.066533, +1.002737, -1.156864, -28.875965, 2.000000, 0.884407, 0.570246, -0.818775, 0.066533, +1.002737, -0.895025, -26.385365, 2.000000, 0.812277, 0.568649, -0.814249, 0.116778, +0.000000, -1.126870, -26.349302, 1.500000, 0.812277, 0.000000, -0.989855, 0.142082, +0.000000, -1.126870, -26.349302, 1.500000, 0.812277, 0.000000, -0.989855, 0.142082, +-1.002737, -0.895025, -26.385366, 1.000000, 0.812277, -0.568649, -0.814249, 0.116778, +-1.002737, -1.156864, -28.875961, 1.000000, 0.884407, -0.570246, -0.818776, 0.066533, +-1.002737, -0.385786, -23.498796, 1.000000, 0.718491, -0.565019, -0.802220, 0.192863, +-1.002737, -0.895025, -26.385366, 1.000000, 0.812277, -0.568649, -0.814249, 0.116778, +0.000000, -1.126870, -26.349302, 1.500000, 0.812277, 0.000000, -0.989855, 0.142082, +0.000000, -1.126870, -26.349302, 1.500000, 0.812277, 0.000000, -0.989855, 0.142082, +1.002737, -0.895025, -26.385365, 2.000000, 0.812277, 0.568649, -0.814249, 0.116778, +1.002737, -0.385786, -23.498796, 2.000000, 0.718491, 0.564910, -0.802377, 0.192532, +1.002737, -0.385786, -23.498796, 2.000000, 0.718491, 0.564910, -0.802377, 0.192532, +1.004758, 0.522999, -20.483551, 2.000000, 0.596697, 0.555081, -0.772140, 0.309331, +0.002021, 0.293610, -20.435085, 1.500000, 0.596697, -0.000089, -0.928581, 0.371129, +0.002021, 0.293610, -20.435085, 1.500000, 0.596697, -0.000089, -0.928581, 0.371129, +-1.000716, 0.522999, -20.483551, 1.046875, 0.600702, -0.555184, -0.771596, 0.310500, +-1.002737, -0.385786, -23.498796, 1.000000, 0.718491, -0.565019, -0.802220, 0.192863, +-0.994652, 1.983473, -17.606916, 1.187500, 0.456561, -0.553223, -0.737418, 0.387504, +-1.000716, 0.522999, -20.483551, 1.046875, 0.600702, -0.555184, -0.771596, 0.310500, +0.002021, 0.293610, -20.435085, 1.500000, 0.596697, -0.000089, -0.928581, 0.371129, +0.002021, 0.293610, -20.435085, 1.500000, 0.596697, -0.000089, -0.928581, 0.371129, +1.004758, 0.522999, -20.483551, 2.000000, 0.596697, 0.555081, -0.772140, 0.309331, +1.010821, 1.983473, -17.606916, 2.000000, 0.440543, 0.553586, -0.738015, 0.385845, +1.010821, 1.983473, -17.606916, 2.000000, 0.440543, 0.553586, -0.738015, 0.385845, +1.014864, 3.544037, -14.721523, 2.000000, 0.267209, 0.562535, -0.748836, 0.350428, +0.012127, 3.312792, -14.692760, 1.500000, 0.267209, 0.000169, -0.904592, 0.426279, +0.012127, 3.312792, -14.692760, 1.500000, 0.267209, 0.000169, -0.904592, 0.426279, +-0.990610, 3.544037, -14.721523, 1.000000, 0.267209, -0.562098, -0.749029, 0.350717, +-0.994652, 1.983473, -17.606916, 1.187500, 0.456561, -0.553223, -0.737418, 0.387504, +-1.002737, 5.163677, -6.177338, 1.000000, -0.308178, -0.587361, -0.794674, -0.153298, +-1.000716, 5.372389, -8.744530, 1.000000, -0.079458, -0.594849, -0.801661, 0.059106, +0.002021, 5.139305, -8.742946, 1.500000, -0.079458, -0.000101, -0.997122, 0.075814, +0.002021, 5.139305, -8.742946, 1.500000, -0.079458, -0.000101, -0.997122, 0.075814, +1.004758, 5.372389, -8.744530, 2.000000, -0.079458, 0.594556, -0.801738, 0.060986, +1.002737, 5.163681, -6.177338, 2.000000, -0.308178, 0.587260, -0.794834, -0.152858, +1.002737, 5.163681, -6.177338, 2.000000, -0.308178, 0.587260, -0.794834, -0.152858, +1.002737, 4.402004, -3.694788, 2.000000, -0.537451, 0.571136, -0.774985, -0.270560, +0.000000, 4.171406, -3.728287, 1.500000, -0.537451, 0.000000, -0.943782, -0.330570, +0.000000, 4.171406, -3.728287, 1.500000, -0.537451, 0.000000, -0.943782, -0.330570, +-1.002737, 4.402004, -3.694788, 1.000000, -0.537451, -0.571136, -0.774985, -0.270559, +-1.002737, 5.163677, -6.177338, 1.000000, -0.308178, -0.587361, -0.794674, -0.153298, +-1.002737, 3.362402, -1.013249, 1.000000, -0.767833, -0.559574, -0.778227, -0.285025, +-1.002737, 4.402004, -3.694788, 1.000000, -0.537451, -0.571136, -0.774985, -0.270559, +0.000000, 4.171406, -3.728287, 1.500000, -0.537451, 0.000000, -0.943782, -0.330570, +0.000000, 4.171406, -3.728287, 1.500000, -0.537451, 0.000000, -0.943782, -0.330570, +1.002737, 4.402004, -3.694788, 2.000000, -0.537451, 0.571136, -0.774985, -0.270560, +1.002737, 3.362402, -1.013249, 2.000000, -0.767833, 0.559574, -0.778227, -0.285025, +1.002737, 3.362402, -1.013249, 2.000000, -0.767833, 0.559574, -0.778227, -0.285025, +1.002737, 2.394936, 1.783656, 2.000000, -0.979466, 0.550621, -0.806194, -0.216490, +0.000000, 2.167702, 1.752268, 1.500000, -0.979466, -0.000000, -0.966229, -0.257685, +0.000000, 2.167702, 1.752268, 1.500000, -0.979466, -0.000000, -0.966229, -0.257685, +-1.002737, 2.394936, 1.783656, 1.046875, -0.973474, -0.550621, -0.806194, -0.216490, +-1.002737, 3.362402, -1.013249, 1.000000, -0.767833, -0.559574, -0.778227, -0.285025, +-1.002737, 1.849670, 4.612304, 1.187500, -1.128520, -0.548005, -0.830422, -0.100446, +-1.002737, 2.394936, 1.783656, 1.046875, -0.973474, -0.550621, -0.806194, -0.216490, +0.000000, 2.167702, 1.752268, 1.500000, -0.979466, -0.000000, -0.966229, -0.257685, +0.000000, 2.167702, 1.752268, 1.500000, -0.979466, -0.000000, -0.966229, -0.257685, +1.002737, 2.394936, 1.783656, 2.000000, -0.979466, 0.550621, -0.806194, -0.216490, +1.002737, 1.849670, 4.612304, 2.000000, -1.152493, 0.548005, -0.830422, -0.100446, +1.002737, 1.849670, 4.612304, 2.000000, -1.152493, 0.548005, -0.830422, -0.100446, +1.002737, 1.707661, 7.456823, 2.000000, -1.306215, 0.546192, -0.837529, 0.014826, +0.000000, 1.483450, 7.466458, 1.500000, -1.306215, 0.000000, -0.999837, 0.018050, +0.000000, 1.483450, 7.466458, 1.500000, -1.306215, 0.000000, -0.999837, 0.018050, +-1.002737, 1.707661, 7.456823, 1.000000, -1.306215, -0.546192, -0.837529, 0.014826, +-1.002737, 1.849670, 4.612304, 1.187500, -1.128520, -0.548005, -0.830422, -0.100446, +-1.022346, 3.341311, 15.726742, 1.166667, -1.691614, -0.553953, -0.781075, 0.288198, +-1.007639, 2.515034, 13.079953, 1.000000, -1.613659, -0.551445, -0.808533, 0.205386, +-0.004902, 2.294706, 13.134627, 1.500000, -1.613659, 0.000247, -0.968748, 0.248048, +-0.004902, 2.294706, 13.134627, 1.500000, -1.613659, 0.000247, -0.968748, 0.248048, +0.997835, 2.515034, 13.079953, 2.000000, -1.613659, 0.552074, -0.807195, 0.208929, +0.983128, 3.341311, 15.726744, 2.000000, -1.695003, 0.553551, -0.779630, 0.292845, +0.983128, 3.341311, 15.726744, 2.000000, -1.695003, 0.553551, -0.779630, 0.292845, +0.973323, 4.412262, 18.174875, 2.000000, -1.776346, 0.554281, -0.740975, 0.379115, +-0.029414, 4.201355, 18.265430, 1.500000, -1.776346, -0.000535, -0.890739, 0.454514, +-0.029414, 4.201355, 18.265430, 1.500000, -1.776346, -0.000535, -0.890739, 0.454514, +-1.032151, 4.412262, 18.174877, 1.000000, -1.776346, -0.555665, -0.740194, 0.378615, +-1.022346, 3.341311, 15.726742, 1.166667, -1.691614, -0.553953, -0.781075, 0.288198, +0.000000, 8.401409, 24.234768, 1.500000, -2.000000, -0.000001, -0.291501, 0.956571, +-0.742768, 8.411285, 23.925793, 1.000000, -2.000000, -0.485429, -0.281111, 0.827850, +-1.002737, 7.854620, 23.452549, 1.000000, -1.969517, -0.579230, -0.604597, 0.546768, +-1.002737, 7.854620, 23.452549, 1.000000, -1.969517, -0.579230, -0.604597, 0.546768, +-1.007639, 6.953747, 22.156216, 1.000000, -1.939034, -0.571627, -0.672843, 0.469600, +-0.004902, 6.752687, 22.278475, 1.500000, -1.939034, 0.000369, -0.822635, 0.568570, +-0.004902, 6.752687, 22.278475, 1.500000, -1.939034, 0.000369, -0.822635, 0.568570, +0.997835, 6.953747, 22.156214, 2.000000, -1.939034, 0.572743, -0.675634, 0.464203, +1.002737, 7.854620, 23.452549, 2.000000, -1.969517, 0.580173, -0.605657, 0.544591, +1.002737, 7.854620, 23.452549, 2.000000, -1.969517, 0.580173, -0.605657, 0.544591, +0.742768, 8.411285, 23.925795, 2.000000, -2.000000, 0.485428, -0.281111, 0.827851, +0.000000, 8.401409, 24.234768, 1.500000, -2.000000, -0.000001, -0.291501, 0.956571, +1.002737, 0.129889, -32.334755, 2.937500, 0.946466, 0.578352, 0.815661, -0.014359, +1.002737, 0.153999, -30.965355, 2.906250, 0.897588, 0.580105, 0.814042, -0.028521, +1.336982, -0.552929, -30.921089, 2.500000, 0.937170, 0.999978, -0.006539, 0.000687, +1.336982, -0.552929, -30.921089, 2.500000, 0.937170, 0.999978, -0.006539, 0.000687, +1.002737, -1.259859, -30.876823, 2.000000, 0.937170, 0.573164, -0.818795, 0.032517, +1.002737, -1.292564, -32.294174, 2.000000, 0.972854, 0.576237, -0.817066, 0.018853, +1.002737, -1.156864, -28.875965, 2.000000, 0.884407, 0.570246, -0.818775, 0.066533, +1.002737, -1.259859, -30.876823, 2.000000, 0.937170, 0.573164, -0.818795, 0.032517, +1.336982, -0.552929, -30.921089, 2.500000, 0.937170, 0.999978, -0.006539, 0.000687, +1.336982, -0.552929, -30.921089, 2.500000, 0.937170, 0.999978, -0.006539, 0.000687, +1.002737, 0.153999, -30.965355, 2.906250, 0.897588, 0.580105, 0.814042, -0.028521, +1.002737, 0.245815, -29.027195, 2.937500, 0.858019, 0.580554, 0.811733, -0.063605, +1.002737, 0.245815, -29.027195, 2.937500, 0.858019, 0.580554, 0.811733, -0.063605, +1.002737, 0.496042, -26.601746, 2.968750, 0.804268, 0.581048, 0.805721, -0.114877, +1.336982, -0.199492, -26.493555, 2.500000, 0.812277, 0.999928, -0.011914, 0.001651, +1.336982, -0.199492, -26.493555, 2.500000, 0.812277, 0.999928, -0.011914, 0.001651, +1.002737, -0.895025, -26.385365, 2.000000, 0.812277, 0.568649, -0.814249, 0.116778, +1.002737, -1.156864, -28.875965, 2.000000, 0.884407, 0.570246, -0.818775, 0.066533, +1.002737, -0.385786, -23.498796, 2.000000, 0.718491, 0.564910, -0.802377, 0.192532, +1.002737, -0.895025, -26.385365, 2.000000, 0.812277, 0.568649, -0.814249, 0.116778, +1.336982, -0.199492, -26.493555, 2.500000, 0.812277, 0.999928, -0.011914, 0.001651, +1.336982, -0.199492, -26.493555, 2.500000, 0.812277, 0.999928, -0.011914, 0.001651, +1.002737, 0.496042, -26.601746, 2.968750, 0.804268, 0.581048, 0.805721, -0.114877, +1.002737, 0.995396, -23.770485, 2.937500, 0.712843, 0.583294, 0.789623, -0.190427, +1.002737, 0.995396, -23.770485, 2.937500, 0.712843, 0.583294, 0.789623, -0.190427, +1.004758, 1.899328, -20.774343, 2.890625, 0.592229, 0.578470, 0.756840, -0.304248, +1.339004, 1.211163, -20.628948, 2.500000, 0.596697, 0.999699, -0.021427, 0.011933, +1.339004, 1.211163, -20.628948, 2.500000, 0.596697, 0.999699, -0.021427, 0.011933, +1.004758, 0.522999, -20.483551, 2.000000, 0.596697, 0.555081, -0.772140, 0.309331, +1.002737, -0.385786, -23.498796, 2.000000, 0.718491, 0.564910, -0.802377, 0.192532, +1.010821, 1.983473, -17.606916, 2.000000, 0.440543, 0.553586, -0.738015, 0.385845, +1.004758, 0.522999, -20.483551, 2.000000, 0.596697, 0.555081, -0.772140, 0.309331, +1.339004, 1.211163, -20.628948, 2.500000, 0.596697, 0.999699, -0.021427, 0.011933, +1.339004, 1.211163, -20.628948, 2.500000, 0.596697, 0.999699, -0.021427, 0.011933, +1.004758, 1.899328, -20.774343, 2.890625, 0.592229, 0.578470, 0.756840, -0.304248, +1.010821, 3.363289, -17.854240, 2.875000, 0.450913, 0.554791, 0.739026, -0.382161, +1.010821, 3.363289, -17.854240, 2.875000, 0.450913, 0.554791, 0.739026, -0.382161, +1.014864, 4.931509, -14.894089, 3.000000, 0.267209, 0.545447, 0.762198, -0.348629, +1.349109, 4.237772, -14.807808, 2.500000, 0.267209, 0.999805, 0.015731, -0.011963, +1.349109, 4.237772, -14.807808, 2.500000, 0.267209, 0.999805, 0.015731, -0.011963, +1.014864, 3.544037, -14.721523, 2.000000, 0.267209, 0.562535, -0.748836, 0.350428, +1.010821, 1.983473, -17.606916, 2.000000, 0.440543, 0.553586, -0.738015, 0.385845, +1.002737, 5.163681, -6.177338, 2.000000, -0.308178, 0.587260, -0.794834, -0.152858, +1.004758, 5.372389, -8.744530, 2.000000, -0.079458, 0.594556, -0.801738, 0.060986, +1.339004, 6.071638, -8.749280, 2.500000, -0.079458, 0.999013, 0.044275, -0.003633, +1.339004, 6.071638, -8.749280, 2.500000, -0.079458, 0.999013, 0.044275, -0.003633, +1.004758, 6.770885, -8.754030, 3.000000, -0.079458, 0.549543, 0.833398, -0.058740, +1.002737, 6.556976, -6.071414, 2.937500, -0.360878, 0.552962, 0.818993, 0.153246, +1.002737, 6.556976, -6.071414, 2.937500, -0.360878, 0.552962, 0.818993, 0.153246, +1.002737, 5.785589, -3.493792, 2.968750, -0.549437, 0.556039, 0.785897, 0.270530, +1.336982, 5.093796, -3.594290, 2.500000, -0.537451, 0.999877, 0.014256, 0.006545, +1.336982, 5.093796, -3.594290, 2.500000, -0.537451, 0.999877, 0.014256, 0.006545, +1.002737, 4.402004, -3.694788, 2.000000, -0.537451, 0.571136, -0.774985, -0.270560, +1.002737, 5.163681, -6.177338, 2.000000, -0.308178, 0.587260, -0.794834, -0.152858, +1.002737, 3.362402, -1.013249, 2.000000, -0.767833, 0.559574, -0.778227, -0.285025, +1.002737, 4.402004, -3.694788, 2.000000, -0.537451, 0.571136, -0.774985, -0.270560, +1.336982, 5.093796, -3.594290, 2.500000, -0.537451, 0.999877, 0.014256, 0.006545, +1.336982, 5.093796, -3.594290, 2.500000, -0.537451, 0.999877, 0.014256, 0.006545, +1.002737, 5.785589, -3.493792, 2.968750, -0.549437, 0.556039, 0.785897, 0.270530, +1.002737, 4.735826, -0.785002, 2.937500, -0.763077, 0.563593, 0.774459, 0.287360, +1.002737, 4.735826, -0.785002, 2.937500, -0.763077, 0.563593, 0.774459, 0.287360, +1.002737, 3.758350, 1.971984, 2.890625, -0.966339, 0.573361, 0.788967, 0.220880, +1.336982, 3.076645, 1.877820, 2.500000, -0.979466, 0.999725, -0.022213, -0.007478, +1.336982, 3.076645, 1.877820, 2.500000, -0.979466, 0.999725, -0.022213, -0.007478, +1.002737, 2.394936, 1.783656, 2.000000, -0.979466, 0.550621, -0.806194, -0.216490, +1.002737, 3.362402, -1.013249, 2.000000, -0.767833, 0.559574, -0.778227, -0.285025, +1.336982, 2.380295, 7.427917, 2.500000, -1.306215, 0.999670, -0.025705, 0.000199, +1.002737, 1.707661, 7.456823, 2.000000, -1.306215, 0.546192, -0.837529, 0.014826, +1.002737, 1.849670, 4.612304, 2.000000, -1.152493, 0.548005, -0.830422, -0.100446, +1.002737, 1.849670, 4.612304, 2.000000, -1.152493, 0.548005, -0.830422, -0.100446, +1.002737, 2.394936, 1.783656, 2.000000, -0.979466, 0.550621, -0.806194, -0.216490, +1.336982, 3.076645, 1.877820, 2.500000, -0.979466, 0.999725, -0.022213, -0.007478, +1.336982, 3.076645, 1.877820, 2.500000, -0.979466, 0.999725, -0.022213, -0.007478, +1.002737, 3.758350, 1.971984, 2.890625, -0.966339, 0.573361, 0.788967, 0.220880, +1.002737, 3.203825, 4.694192, 2.875000, -1.123764, 0.573167, 0.812586, 0.105755, +1.002737, 3.203825, 4.694192, 2.875000, -1.123764, 0.573167, 0.812586, 0.105755, +1.002737, 3.052929, 7.399012, 3.000000, -1.306215, 0.571504, 0.820504, -0.012461, +1.336982, 2.380295, 7.427917, 2.500000, -1.306215, 0.999670, -0.025705, 0.000199, +0.983128, 3.341311, 15.726744, 2.000000, -1.695003, 0.553551, -0.779630, 0.292845, +0.997835, 2.515034, 13.079953, 2.000000, -1.613659, 0.552074, -0.807195, 0.208929, +1.332080, 3.176014, 12.915927, 2.500000, -1.613659, 0.999801, -0.018232, 0.008046, +1.332080, 3.176014, 12.915927, 2.500000, -1.613659, 0.999801, -0.018232, 0.008046, +0.997834, 3.836994, 12.751901, 3.000000, -1.613659, 0.571655, 0.794480, -0.204969, +0.983128, 4.637777, 15.286472, 2.833333, -1.698392, 0.573967, 0.767126, -0.286495, +0.983128, 4.637777, 15.286472, 2.833333, -1.698392, 0.573967, 0.767126, -0.286495, +0.973323, 5.677700, 17.631544, 3.000000, -1.776346, 0.576561, 0.724323, -0.378066, +1.307569, 5.044981, 17.903212, 2.500000, -1.776346, 0.999751, -0.019683, 0.010530, +1.307569, 5.044981, 17.903212, 2.500000, -1.776346, 0.999751, -0.019683, 0.010530, +0.973323, 4.412262, 18.174875, 2.000000, -1.776346, 0.554281, -0.740975, 0.379115, +0.983128, 3.341311, 15.726744, 2.000000, -1.695003, 0.553551, -0.779630, 0.292845, +1.002737, 8.987209, 23.827108, 2.500000, -2.000000, 0.690085, 0.408969, 0.597099, +0.742768, 8.411285, 23.925795, 2.000000, -2.000000, 0.485428, -0.281111, 0.827851, +1.002737, 7.854620, 23.452549, 2.000000, -1.969517, 0.580173, -0.605657, 0.544591, +1.002737, 7.854620, 23.452549, 2.000000, -1.969517, 0.580173, -0.605657, 0.544591, +0.997835, 6.953747, 22.156214, 2.000000, -1.939034, 0.572743, -0.675634, 0.464203, +1.332080, 7.556932, 21.789433, 2.500000, -1.939034, 0.999977, -0.005048, -0.004524, +1.332080, 7.556932, 21.789433, 2.500000, -1.939034, 0.999977, -0.005048, -0.004524, +0.997834, 8.160118, 21.422651, 3.000000, -1.939034, 0.574744, 0.665807, -0.475784, +1.002737, 9.038933, 22.663582, 3.000000, -1.969517, 0.583232, 0.718345, -0.379238, +1.002737, 9.038933, 22.663582, 3.000000, -1.969517, 0.583232, 0.718345, -0.379238, +0.742768, 9.282909, 23.329664, 3.000000, -2.000000, 0.487250, 0.872639, 0.032983, +1.002737, 8.987209, 23.827108, 2.500000, -2.000000, 0.690085, 0.408969, 0.597099, +-1.002737, 0.129889, -32.334755, 3.500000, 0.761751, -0.578352, 0.815661, -0.014359, +-1.002737, 0.153999, -30.965355, 3.000000, 0.523501, -0.580105, 0.814042, -0.028521, +0.000000, 0.389645, -30.980114, 3.125000, 0.778842, -0.000000, 0.999403, -0.034561, +0.000000, 0.389645, -30.980114, 3.125000, 0.778842, -0.000000, 0.999403, -0.034561, +1.002737, 0.153999, -30.965355, 2.906250, 0.897588, 0.580105, 0.814042, -0.028521, +1.002737, 0.129889, -32.334755, 2.937500, 0.946466, 0.578352, 0.815661, -0.014359, +1.002737, 0.245815, -29.027195, 2.937500, 0.858019, 0.580554, 0.811733, -0.063605, +1.002737, 0.153999, -30.965355, 2.906250, 0.897588, 0.580105, 0.814042, -0.028521, +0.000000, 0.389645, -30.980114, 3.125000, 0.778842, -0.000000, 0.999403, -0.034561, +0.000000, 0.389645, -30.980114, 3.125000, 0.778842, -0.000000, 0.999403, -0.034561, +-1.002737, 0.153999, -30.965355, 3.000000, 0.523501, -0.580105, 0.814042, -0.028521, +-1.002737, 0.245815, -29.027195, 3.500000, 0.673303, -0.580554, 0.811733, -0.063605, +-1.002737, 0.245815, -29.027195, 3.500000, 0.673303, -0.580554, 0.811733, -0.063605, +-1.002737, 0.496042, -26.601746, 4.000000, 0.823105, -0.581048, 0.805721, -0.114877, +0.000000, 0.727886, -26.637808, 3.375000, 0.780241, 0.000000, 0.990007, -0.141020, +0.000000, 0.727886, -26.637808, 3.375000, 0.780241, 0.000000, 0.990007, -0.141020, +1.002737, 0.496042, -26.601746, 2.968750, 0.804268, 0.581048, 0.805721, -0.114877, +1.002737, 0.245815, -29.027195, 2.937500, 0.858019, 0.580554, 0.811733, -0.063605, +1.002737, 0.995396, -23.770485, 2.937500, 0.712843, 0.583294, 0.789623, -0.190427, +1.002737, 0.496042, -26.601746, 2.968750, 0.804268, 0.581048, 0.805721, -0.114877, +0.000000, 0.727886, -26.637808, 3.375000, 0.780241, 0.000000, 0.990007, -0.141020, +0.000000, 0.727886, -26.637808, 3.375000, 0.780241, 0.000000, 0.990007, -0.141020, +-1.002737, 0.496042, -26.601746, 4.000000, 0.823105, -0.581048, 0.805721, -0.114877, +-1.002737, 0.995396, -23.770485, 3.500000, 0.673303, -0.583417, 0.789634, -0.190008, +-1.002737, 0.995396, -23.770485, 3.500000, 0.673303, -0.583417, 0.789634, -0.190008, +-1.000716, 1.899328, -20.774343, 3.000000, 0.523501, -0.578823, 0.757196, -0.302684, +0.002021, 2.128716, -20.822807, 3.062500, 0.578824, -0.000086, 0.927679, -0.373379, +0.002021, 2.128716, -20.822807, 3.062500, 0.578824, -0.000086, 0.927679, -0.373379, +1.004758, 1.899328, -20.774343, 2.890625, 0.592229, 0.578470, 0.756840, -0.304248, +1.002737, 0.995396, -23.770485, 2.937500, 0.712843, 0.583294, 0.789623, -0.190427, +0.012127, 5.162754, -14.922852, 3.000000, 0.395355, 0.000167, 0.910359, -0.413819, +1.014864, 4.931509, -14.894089, 3.000000, 0.267209, 0.545447, 0.762198, -0.348629, +1.010821, 3.363289, -17.854240, 2.875000, 0.450913, 0.554791, 0.739026, -0.382161, +1.010821, 3.363289, -17.854240, 2.875000, 0.450913, 0.554791, 0.739026, -0.382161, +1.004758, 1.899328, -20.774343, 2.890625, 0.592229, 0.578470, 0.756840, -0.304248, +0.002021, 2.128716, -20.822807, 3.062500, 0.578824, -0.000086, 0.927679, -0.373379, +0.002021, 2.128716, -20.822807, 3.062500, 0.578824, -0.000086, 0.927679, -0.373379, +-1.000716, 1.899328, -20.774343, 3.000000, 0.523501, -0.578823, 0.757196, -0.302684, +-0.994652, 3.363289, -17.854239, 3.000000, 0.523501, -0.554925, 0.739714, -0.380633, +-0.994652, 3.363289, -17.854239, 3.000000, 0.523501, -0.554925, 0.739714, -0.380633, +-0.990610, 4.931509, -14.894089, 3.000000, 0.523501, -0.544986, 0.762408, -0.348891, +0.012127, 5.162754, -14.922852, 3.000000, 0.395355, 0.000167, 0.910359, -0.413819, +1.002737, 6.556976, -6.071414, 2.937500, -0.360878, 0.552962, 0.818993, 0.153246, +1.004758, 6.770885, -8.754030, 3.000000, -0.079458, 0.549543, 0.833398, -0.058740, +0.002021, 7.003967, -8.755614, 3.000000, -0.501061, -0.000102, 0.997541, -0.070087, +0.002021, 7.003967, -8.755614, 3.000000, -0.501061, -0.000102, 0.997541, -0.070087, +-1.000716, 6.770885, -8.754030, 3.000000, -0.922665, -0.549751, 0.833161, -0.060139, +-1.002737, 6.556976, -6.071414, 3.500000, -0.729781, -0.553122, 0.818963, 0.152824, +-1.002737, 6.556976, -6.071414, 3.500000, -0.729781, -0.553122, 0.818963, 0.152824, +-1.002737, 5.785589, -3.493792, 4.000000, -0.536897, -0.556039, 0.785897, 0.270530, +0.000000, 6.016188, -3.460293, 3.375000, -0.585395, -0.000000, 0.945916, 0.324411, +0.000000, 6.016188, -3.460293, 3.375000, -0.585395, -0.000000, 0.945916, 0.324411, +1.002737, 5.785589, -3.493792, 2.968750, -0.549437, 0.556039, 0.785897, 0.270530, +1.002737, 6.556976, -6.071414, 2.937500, -0.360878, 0.552962, 0.818993, 0.153246, +1.002737, 4.735826, -0.785002, 2.937500, -0.763077, 0.563593, 0.774459, 0.287360, +1.002737, 5.785589, -3.493792, 2.968750, -0.549437, 0.556039, 0.785897, 0.270530, +0.000000, 6.016188, -3.460293, 3.375000, -0.585395, -0.000000, 0.945916, 0.324411, +0.000000, 6.016188, -3.460293, 3.375000, -0.585395, -0.000000, 0.945916, 0.324411, +-1.002737, 5.785589, -3.493792, 4.000000, -0.536897, -0.556039, 0.785897, 0.270530, +-1.002737, 4.735826, -0.785002, 3.500000, -0.729781, -0.563593, 0.774459, 0.287360, +-1.002737, 4.735826, -0.785002, 3.500000, -0.729781, -0.563593, 0.774459, 0.287360, +-1.002737, 3.758350, 1.971984, 3.000000, -0.922665, -0.573360, 0.788967, 0.220880, +0.000000, 3.985586, 2.003372, 3.062500, -0.926955, 0.000000, 0.962477, 0.271365, +0.000000, 3.985586, 2.003372, 3.062500, -0.926955, 0.000000, 0.962477, 0.271365, +1.002737, 3.758350, 1.971984, 2.890625, -0.966339, 0.573361, 0.788967, 0.220880, +1.002737, 4.735826, -0.785002, 2.937500, -0.763077, 0.563593, 0.774459, 0.287360, +1.002737, 3.203825, 4.694192, 2.875000, -1.123764, 0.573167, 0.812586, 0.105755, +1.002737, 3.758350, 1.971984, 2.890625, -0.966339, 0.573361, 0.788967, 0.220880, +0.000000, 3.985586, 2.003372, 3.062500, -0.926955, 0.000000, 0.962477, 0.271365, +0.000000, 3.985586, 2.003372, 3.062500, -0.926955, 0.000000, 0.962477, 0.271365, +-1.002737, 3.758350, 1.971984, 3.000000, -0.922665, -0.573360, 0.788967, 0.220880, +-1.002737, 3.203825, 4.694192, 3.000000, -0.922665, -0.573166, 0.812586, 0.105755, +-1.002737, 3.203825, 4.694192, 3.000000, -0.922665, -0.573166, 0.812586, 0.105755, +-1.002737, 3.052929, 7.399012, 3.000000, -0.922665, -0.571504, 0.820505, -0.012461, +0.000000, 3.277142, 7.389376, 3.000000, -1.114440, 0.000000, 0.999891, -0.014768, +0.000000, 3.277142, 7.389376, 3.000000, -1.114440, 0.000000, 0.999891, -0.014768, +1.002737, 3.052929, 7.399012, 3.000000, -1.306215, 0.571504, 0.820504, -0.012461, +1.002737, 3.203825, 4.694192, 2.875000, -1.123764, 0.573167, 0.812586, 0.105755, +-0.029414, 5.888605, 17.540989, 2.833333, -1.749232, -0.000556, 0.885983, -0.463718, +0.973323, 5.677700, 17.631544, 3.000000, -1.776346, 0.576561, 0.724323, -0.378066, +0.983128, 4.637777, 15.286472, 2.833333, -1.698392, 0.573967, 0.767126, -0.286495, +0.983128, 4.637777, 15.286472, 2.833333, -1.698392, 0.573967, 0.767126, -0.286495, +0.997834, 3.836994, 12.751901, 3.000000, -1.613659, 0.571655, 0.794480, -0.204969, +-0.004902, 4.057320, 12.697225, 2.833333, -1.667888, 0.000259, 0.967531, -0.252752, +-0.004902, 4.057320, 12.697225, 2.833333, -1.667888, 0.000259, 0.967531, -0.252752, +-1.007639, 3.836994, 12.751901, 2.666667, -1.722117, -0.571038, 0.793815, -0.209219, +-1.022346, 4.637777, 15.286472, 2.666667, -1.722117, -0.574184, 0.765044, -0.291584, +-1.022346, 4.637777, 15.286472, 2.666667, -1.722117, -0.574184, 0.765044, -0.291584, +-1.032151, 5.677700, 17.631544, 2.666667, -1.722117, -0.577835, 0.723604, -0.377496, +-0.029414, 5.888605, 17.540989, 2.833333, -1.749232, -0.000556, 0.885983, -0.463718, +0.000000, 9.573013, 23.419453, 3.500000, -2.000000, -0.000000, 0.997856, 0.065453, +0.742768, 9.282909, 23.329664, 3.000000, -2.000000, 0.487250, 0.872639, 0.032983, +1.002737, 9.038933, 22.663582, 3.000000, -1.969517, 0.583232, 0.718345, -0.379238, +1.002737, 9.038933, 22.663582, 3.000000, -1.969517, 0.583232, 0.718345, -0.379238, +0.997834, 8.160118, 21.422651, 3.000000, -1.939034, 0.574744, 0.665807, -0.475784, +-0.004902, 8.361179, 21.300390, 3.500000, -1.939034, 0.000389, 0.815229, -0.579139, +-0.004902, 8.361179, 21.300390, 3.500000, -1.939034, 0.000389, 0.815229, -0.579139, +-1.007639, 8.160118, 21.422651, 4.000000, -1.939034, -0.574068, 0.669723, -0.471080, +-1.002737, 9.038933, 22.663582, 4.000000, -1.969517, -0.582357, 0.720010, -0.377421, +-1.002737, 9.038933, 22.663582, 4.000000, -1.969517, -0.582357, 0.720010, -0.377421, +-0.742768, 9.282909, 23.329664, 4.000000, -2.000000, -0.487251, 0.872639, 0.032983, +0.000000, 9.573013, 23.419453, 3.500000, -2.000000, -0.000000, 0.997856, 0.065453, +-1.002737, -2.734034, 6.657467, 1.500000, 0.761751, -0.582703, 0.762742, 0.280503, +-1.002737, -1.996943, 4.816424, 0.000000, 1.000000, -0.580237, 0.756078, 0.302774, +-1.336982, -2.618040, 4.463405, 0.500000, 1.000000, -0.999977, -0.006223, -0.002555, +-1.336982, -2.618040, 4.463405, 0.500000, 1.000000, -0.999977, -0.006223, -0.002555, +-1.002737, -3.239137, 4.110385, 1.000000, 1.000000, -0.573276, -0.760494, -0.304965, +-1.002737, -3.988198, 5.977939, 1.187500, 0.890530, -0.568961, -0.771457, -0.284847, +-1.002737, -3.988198, 5.977939, 1.187500, 0.890530, -0.568961, -0.771457, -0.284847, +-1.002737, -4.824668, 8.406097, 1.000000, 0.817855, -0.564875, -0.790113, -0.237986, +-1.336982, -4.187579, 8.722692, 2.000000, 0.670678, -0.999851, -0.016874, -0.003651, +-1.336982, -4.187579, 8.722692, 2.000000, 0.670678, -0.999851, -0.016874, -0.003651, +-1.002737, -3.550490, 9.039287, 3.000000, 0.523501, -0.582189, 0.779143, 0.232362, +-1.002737, -2.734034, 6.657467, 1.500000, 0.761751, -0.582703, 0.762742, 0.280503, +-1.002737, -4.339600, 12.037193, 0.000000, 0.651188, -0.578711, 0.795540, 0.179472, +-1.002737, -3.550490, 9.039287, 0.000000, 0.817855, -0.582189, 0.779143, 0.232362, +-1.336982, -4.187579, 8.722692, 0.500000, 0.817855, -0.999851, -0.016874, -0.003651, +-1.336982, -4.187579, 8.722692, 0.500000, 0.817855, -0.999851, -0.016874, -0.003651, +-1.002737, -4.824668, 8.406097, 1.000000, 0.817855, -0.564875, -0.790113, -0.237986, +-1.002737, -5.641894, 11.472322, 1.000000, 0.651188, -0.564280, -0.804601, -0.184946, +-1.002737, -5.641894, 11.472322, 1.000000, 0.651188, -0.564280, -0.804601, -0.184946, +-1.002737, -6.318611, 14.911804, 1.000000, 0.470545, -0.563019, -0.816504, -0.127790, +-1.336982, -5.652997, 15.157051, 0.500000, 0.470545, -0.999903, -0.013895, -0.000479, +-1.336982, -5.652997, 15.157051, 0.500000, 0.470545, -0.999903, -0.013895, -0.000479, +-1.002737, -4.987385, 15.402298, 0.000000, 0.484521, -0.576620, 0.807781, 0.122473, +-1.002737, -4.339600, 12.037193, 0.000000, 0.651188, -0.578711, 0.795540, 0.179472, +-1.002737, -5.379865, 18.885717, 0.000000, 0.261948, -0.572718, 0.816712, 0.070540, +-1.002737, -4.987385, 15.402298, 0.000000, 0.484521, -0.576620, 0.807781, 0.122473, +-1.336982, -5.652997, 15.157051, 0.500000, 0.470545, -0.999903, -0.013895, -0.000479, +-1.336982, -5.652997, 15.157051, 0.500000, 0.470545, -0.999903, -0.013895, -0.000479, +-1.002737, -6.318611, 14.911804, 1.000000, 0.470545, -0.563019, -0.816504, -0.127790, +-1.002737, -6.733546, 18.459730, 1.000000, 0.261948, -0.564150, -0.822280, -0.074773, +-1.002737, -6.733546, 18.459730, 1.000000, 0.261948, -0.564150, -0.822280, -0.074773, +-1.002737, -6.957025, 21.947737, 1.000000, 0.047044, -0.566391, -0.823173, -0.039848, +-1.336982, -6.271589, 22.133167, 0.500000, 0.047044, -0.999991, -0.004281, 0.000323, +-1.336982, -6.271589, 22.133167, 0.500000, 0.047044, -0.999991, -0.004281, 0.000323, +-1.002737, -5.586154, 22.318600, 0.000000, 0.039374, -0.570604, 0.820419, 0.036373, +-1.002737, -5.379865, 18.885717, 0.000000, 0.261948, -0.572718, 0.816712, 0.070540, +-1.002737, -5.675372, 25.532089, 0.000000, -0.152521, -0.572885, 0.819555, 0.011471, +-1.002737, -5.586154, 22.318600, 0.000000, 0.039374, -0.570604, 0.820419, 0.036373, +-1.336982, -6.271589, 22.133167, 0.500000, 0.047044, -0.999991, -0.004281, 0.000323, +-1.336982, -6.271589, 22.133167, 0.500000, 0.047044, -0.999991, -0.004281, 0.000323, +-1.002737, -6.957025, 21.947737, 1.000000, 0.047044, -0.566391, -0.823173, -0.039848, +-1.002737, -7.059372, 25.207462, 1.000000, -0.152521, -0.565822, -0.824400, -0.014526, +-1.002737, -7.059372, 25.207462, 1.000000, -0.152521, -0.565822, -0.824400, -0.014526, +-1.002737, -7.074721, 28.664906, 1.000000, -0.338108, -0.564757, -0.825254, 0.002341, +-1.336982, -6.377152, 28.805500, 0.500000, -0.338108, -0.999930, -0.011845, 0.000045, +-1.336982, -6.377152, 28.805500, 0.500000, -0.338108, -0.999930, -0.011845, 0.000045, +-1.002737, -5.679584, 28.946095, 0.000000, -0.344415, -0.577055, 0.816690, -0.004975, +-1.002737, -5.675372, 25.532089, 0.000000, -0.152521, -0.572885, 0.819555, 0.011471, +-1.002737, -5.630855, 32.893612, 0.000000, -0.511082, -0.132943, 0.189166, -0.972904, +-1.002737, -5.679584, 28.946095, 0.000000, -0.344415, -0.577055, 0.816690, -0.004975, +-1.336982, -6.377152, 28.805500, 0.500000, -0.338108, -0.999930, -0.011845, 0.000045, +-1.336982, -6.377152, 28.805500, 0.500000, -0.338108, -0.999930, -0.011845, 0.000045, +-1.002737, -7.074721, 28.664906, 1.000000, -0.338108, -0.564757, -0.825254, 0.002341, +-1.002737, -7.037199, 32.893612, 1.000000, -0.511082, -0.140149, -0.202450, -0.969212, +-1.002737, -7.037199, 32.893612, 1.000000, -0.511082, -0.140149, -0.202450, -0.969212, +-4.193409, -10.256766, 32.893612, 1.027778, -0.557378, -0.685012, -0.716396, 0.132421, +-5.620958, -6.307936, 32.893612, 0.625000, -0.573582, -0.991757, -0.001005, 0.128133, +-5.620958, -6.307936, 32.893612, 0.625000, -0.573582, -0.991757, -0.001005, 0.128133, +-4.193409, -2.445326, 32.893612, 0.000000, -0.594415, -0.686924, 0.716419, 0.121978, +-1.002737, -5.630855, 32.893612, 0.000000, -0.511082, -0.132943, 0.189166, -0.972904, +-1.002737, -3.988198, 5.977939, 1.187500, 0.890530, -0.568961, -0.771457, -0.284847, +-1.002737, -3.239137, 4.110385, 1.000000, 1.000000, -0.573276, -0.760494, -0.304965, +0.000000, -3.446170, 3.992712, 1.500000, 1.000000, 0.000000, -0.928140, -0.372231, +0.000000, -3.446170, 3.992712, 1.500000, 1.000000, 0.000000, -0.928140, -0.372231, +1.002737, -3.239137, 4.110385, 2.000000, 1.000000, 0.573276, -0.760494, -0.304965, +1.002737, -3.988198, 5.977940, 2.000000, 0.908927, 0.568961, -0.771457, -0.284847, +1.002737, -3.988198, 5.977940, 2.000000, 0.908927, 0.568961, -0.771457, -0.284847, +1.002737, -4.824668, 8.406097, 2.000000, 0.798956, 0.564875, -0.790113, -0.237986, +0.000000, -5.037031, 8.300566, 1.500000, 0.798956, 0.000000, -0.957267, -0.289205, +0.000000, -5.037031, 8.300566, 1.500000, 0.798956, 0.000000, -0.957267, -0.289205, +-1.002737, -4.824668, 8.406097, 1.000000, 0.817855, -0.564875, -0.790113, -0.237986, +-1.002737, -3.988198, 5.977939, 1.187500, 0.890530, -0.568961, -0.771457, -0.284847, +-1.002737, -5.641894, 11.472322, 1.000000, 0.651188, -0.564280, -0.804601, -0.184946, +-1.002737, -4.824668, 8.406097, 1.000000, 0.817855, -0.564875, -0.790113, -0.237986, +0.000000, -5.037031, 8.300566, 1.500000, 0.798956, 0.000000, -0.957267, -0.289205, +0.000000, -5.037031, 8.300566, 1.500000, 0.798956, 0.000000, -0.957267, -0.289205, +1.002737, -4.824668, 8.406097, 2.000000, 0.798956, 0.564875, -0.790113, -0.237986, +1.002737, -5.641894, 11.472323, 2.000000, 0.651188, 0.564280, -0.804601, -0.184946, +1.002737, -5.641894, 11.472323, 2.000000, 0.651188, 0.564280, -0.804601, -0.184946, +1.002737, -6.318611, 14.911802, 2.000000, 0.470545, 0.563019, -0.816504, -0.127790, +0.000000, -6.540482, 14.830055, 1.500000, 0.470545, -0.000000, -0.987788, -0.155806, +0.000000, -6.540482, 14.830055, 1.500000, 0.470545, -0.000000, -0.987788, -0.155806, +-1.002737, -6.318611, 14.911804, 1.000000, 0.470545, -0.563019, -0.816504, -0.127790, +-1.002737, -5.641894, 11.472322, 1.000000, 0.651188, -0.564280, -0.804601, -0.184946, +-1.002737, -6.733546, 18.459730, 1.000000, 0.261948, -0.564150, -0.822280, -0.074773, +-1.002737, -6.318611, 14.911804, 1.000000, 0.470545, -0.563019, -0.816504, -0.127790, +0.000000, -6.540482, 14.830055, 1.500000, 0.470545, -0.000000, -0.987788, -0.155806, +0.000000, -6.540482, 14.830055, 1.500000, 0.470545, -0.000000, -0.987788, -0.155806, +1.002737, -6.318611, 14.911802, 2.000000, 0.470545, 0.563019, -0.816504, -0.127790, +1.002737, -6.733546, 18.459730, 2.000000, 0.261948, 0.564150, -0.822280, -0.074773, +1.002737, -6.733546, 18.459730, 2.000000, 0.261948, 0.564150, -0.822280, -0.074773, +1.002737, -6.957025, 21.947737, 2.000000, 0.047044, 0.566391, -0.823173, -0.039848, +0.000000, -7.185503, 21.885925, 1.500000, 0.047044, 0.000000, -0.998796, -0.049054, +0.000000, -7.185503, 21.885925, 1.500000, 0.047044, 0.000000, -0.998796, -0.049054, +-1.002737, -6.957025, 21.947737, 1.000000, 0.047044, -0.566391, -0.823173, -0.039848, +-1.002737, -6.733546, 18.459730, 1.000000, 0.261948, -0.564150, -0.822280, -0.074773, +-1.002737, -7.059372, 25.207462, 1.000000, -0.152521, -0.565822, -0.824400, -0.014526, +-1.002737, -6.957025, 21.947737, 1.000000, 0.047044, -0.566391, -0.823173, -0.039848, +0.000000, -7.185503, 21.885925, 1.500000, 0.047044, 0.000000, -0.998796, -0.049054, +0.000000, -7.185503, 21.885925, 1.500000, 0.047044, 0.000000, -0.998796, -0.049054, +1.002737, -6.957025, 21.947737, 2.000000, 0.047044, 0.566391, -0.823173, -0.039848, +1.002737, -7.059372, 25.207462, 2.000000, -0.152521, 0.565821, -0.824400, -0.014526, +1.002737, -7.059372, 25.207462, 2.000000, -0.152521, 0.565821, -0.824400, -0.014526, +1.002737, -7.074721, 28.664906, 2.000000, -0.338108, 0.564757, -0.825254, 0.002341, +0.000000, -7.307243, 28.618042, 1.500000, -0.338108, 0.000000, -0.999997, 0.002440, +0.000000, -7.307243, 28.618042, 1.500000, -0.338108, 0.000000, -0.999997, 0.002440, +-1.002737, -7.074721, 28.664906, 1.000000, -0.338108, -0.564757, -0.825254, 0.002341, +-1.002737, -7.059372, 25.207462, 1.000000, -0.152521, -0.565822, -0.824400, -0.014526, +-1.002737, -7.037199, 32.893612, 1.000000, -0.511082, -0.140149, -0.202450, -0.969212, +-1.002737, -7.074721, 28.664906, 1.000000, -0.338108, -0.564757, -0.825254, 0.002341, +0.000000, -7.307243, 28.618042, 1.500000, -0.338108, 0.000000, -0.999997, 0.002440, +0.000000, -7.307243, 28.618042, 1.500000, -0.338108, 0.000000, -0.999997, 0.002440, +1.002737, -7.074721, 28.664906, 2.000000, -0.338108, 0.564757, -0.825254, 0.002341, +1.002737, -7.037199, 32.893612, 2.000000, -0.511082, 0.140149, -0.202450, -0.969212, +1.002737, -7.037199, 32.893612, 2.000000, -0.511082, 0.140149, -0.202450, -0.969212, +4.193409, -10.256766, 32.893612, 1.972222, -0.557378, 0.680284, -0.725440, 0.104643, +0.000000, -11.548096, 32.893612, 1.500000, -0.573582, -0.004203, -0.998166, 0.060395, +0.000000, -11.548096, 32.893612, 1.500000, -0.573582, -0.004203, -0.998166, 0.060395, +-4.193409, -10.256766, 32.893612, 1.027778, -0.557378, -0.685012, -0.716396, 0.132421, +-1.002737, -7.037199, 32.893612, 1.000000, -0.511082, -0.140149, -0.202450, -0.969212, +1.002737, -3.988198, 5.977940, 2.000000, 0.908927, 0.568961, -0.771457, -0.284847, +1.002737, -3.239137, 4.110385, 2.000000, 1.000000, 0.573276, -0.760494, -0.304965, +1.336982, -2.618040, 4.463405, 2.500000, 1.000000, 0.999977, -0.006223, -0.002555, +1.336982, -2.618040, 4.463405, 2.500000, 1.000000, 0.999977, -0.006223, -0.002555, +1.002737, -1.996943, 4.816424, 3.000000, 1.000000, 0.580237, 0.756078, 0.302774, +1.002737, -2.734034, 6.657467, 3.000000, 0.908927, 0.582703, 0.762742, 0.280503, +1.002737, -2.734034, 6.657467, 3.000000, 0.908927, 0.582703, 0.762742, 0.280503, +1.002737, -3.550490, 9.039287, 3.000000, 0.798956, 0.582189, 0.779143, 0.232362, +1.336982, -4.187579, 8.722693, 2.500000, 0.798956, 0.999851, -0.016874, -0.003651, +1.336982, -4.187579, 8.722693, 2.500000, 0.798956, 0.999851, -0.016874, -0.003651, +1.002737, -4.824668, 8.406097, 2.000000, 0.798956, 0.564875, -0.790113, -0.237986, +1.002737, -3.988198, 5.977940, 2.000000, 0.908927, 0.568961, -0.771457, -0.284847, +1.002737, -5.641894, 11.472323, 2.000000, 0.651188, 0.564280, -0.804601, -0.184946, +1.002737, -4.824668, 8.406097, 2.000000, 0.798956, 0.564875, -0.790113, -0.237986, +1.336982, -4.187579, 8.722693, 2.500000, 0.798956, 0.999851, -0.016874, -0.003651, +1.336982, -4.187579, 8.722693, 2.500000, 0.798956, 0.999851, -0.016874, -0.003651, +1.002737, -3.550490, 9.039287, 3.000000, 0.798956, 0.582189, 0.779143, 0.232362, +1.002737, -4.339600, 12.037193, 3.000000, 0.651188, 0.578711, 0.795540, 0.179472, +1.002737, -4.339600, 12.037193, 3.000000, 0.651188, 0.578711, 0.795540, 0.179472, +1.002737, -4.987385, 15.402298, 3.000000, 0.470545, 0.576620, 0.807781, 0.122473, +1.336982, -5.652997, 15.157051, 2.500000, 0.470545, 0.999903, -0.013895, -0.000479, +1.336982, -5.652997, 15.157051, 2.500000, 0.470545, 0.999903, -0.013895, -0.000479, +1.002737, -6.318611, 14.911802, 2.000000, 0.470545, 0.563019, -0.816504, -0.127790, +1.002737, -5.641894, 11.472323, 2.000000, 0.651188, 0.564280, -0.804601, -0.184946, +1.002737, -6.733546, 18.459730, 2.000000, 0.261948, 0.564150, -0.822280, -0.074773, +1.002737, -6.318611, 14.911802, 2.000000, 0.470545, 0.563019, -0.816504, -0.127790, +1.336982, -5.652997, 15.157051, 2.500000, 0.470545, 0.999903, -0.013895, -0.000479, +1.336982, -5.652997, 15.157051, 2.500000, 0.470545, 0.999903, -0.013895, -0.000479, +1.002737, -4.987385, 15.402298, 3.000000, 0.470545, 0.576620, 0.807781, 0.122473, +1.002737, -5.379865, 18.885717, 3.000000, 0.261948, 0.572718, 0.816712, 0.070540, +1.002737, -5.379865, 18.885717, 3.000000, 0.261948, 0.572718, 0.816712, 0.070540, +1.002737, -5.586154, 22.318600, 3.000000, 0.047044, 0.570604, 0.820419, 0.036373, +1.336982, -6.271589, 22.133167, 2.500000, 0.047044, 0.999991, -0.004281, 0.000323, +1.336982, -6.271589, 22.133167, 2.500000, 0.047044, 0.999991, -0.004281, 0.000323, +1.002737, -6.957025, 21.947737, 2.000000, 0.047044, 0.566391, -0.823173, -0.039848, +1.002737, -6.733546, 18.459730, 2.000000, 0.261948, 0.564150, -0.822280, -0.074773, +1.002737, -7.059372, 25.207462, 2.000000, -0.152521, 0.565821, -0.824400, -0.014526, +1.002737, -6.957025, 21.947737, 2.000000, 0.047044, 0.566391, -0.823173, -0.039848, +1.336982, -6.271589, 22.133167, 2.500000, 0.047044, 0.999991, -0.004281, 0.000323, +1.336982, -6.271589, 22.133167, 2.500000, 0.047044, 0.999991, -0.004281, 0.000323, +1.002737, -5.586154, 22.318600, 3.000000, 0.047044, 0.570604, 0.820419, 0.036373, +1.002737, -5.675372, 25.532089, 3.000000, -0.152521, 0.572885, 0.819555, 0.011471, +1.002737, -5.675372, 25.532089, 3.000000, -0.152521, 0.572885, 0.819555, 0.011471, +1.002737, -5.679584, 28.946095, 3.000000, -0.338108, 0.577055, 0.816690, -0.004975, +1.336982, -6.377152, 28.805500, 2.500000, -0.338108, 0.999930, -0.011845, 0.000045, +1.336982, -6.377152, 28.805500, 2.500000, -0.338108, 0.999930, -0.011845, 0.000045, +1.002737, -7.074721, 28.664906, 2.000000, -0.338108, 0.564757, -0.825254, 0.002341, +1.002737, -7.059372, 25.207462, 2.000000, -0.152521, 0.565821, -0.824400, -0.014526, +1.002737, -7.037199, 32.893612, 2.000000, -0.511082, 0.140149, -0.202450, -0.969212, +1.002737, -7.074721, 28.664906, 2.000000, -0.338108, 0.564757, -0.825254, 0.002341, +1.336982, -6.377152, 28.805500, 2.500000, -0.338108, 0.999930, -0.011845, 0.000045, +1.336982, -6.377152, 28.805500, 2.500000, -0.338108, 0.999930, -0.011845, 0.000045, +1.002737, -5.679584, 28.946095, 3.000000, -0.338108, 0.577055, 0.816690, -0.004975, +1.002737, -5.630855, 32.893612, 3.000000, -0.511082, 0.132943, 0.189166, -0.972904, +1.002737, -5.630855, 32.893612, 3.000000, -0.511082, 0.132943, 0.189166, -0.972904, +4.193409, -2.445326, 32.893612, 3.000000, -0.594415, 0.682263, 0.725032, 0.094055, +5.620958, -6.307936, 32.893612, 2.375000, -0.573582, 0.996241, -0.000983, 0.086619, +5.620958, -6.307936, 32.893612, 2.375000, -0.573582, 0.996241, -0.000983, 0.086619, +4.193409, -10.256766, 32.893612, 1.972222, -0.557378, 0.680284, -0.725440, 0.104643, +1.002737, -7.037199, 32.893612, 2.000000, -0.511082, 0.140149, -0.202450, -0.969212, +-1.002737, -1.445931, 3.440848, 2.500000, -1.666667, -0.596303, 0.745197, 0.298504, +-1.002737, -1.996943, 4.816424, 3.000000, -1.666667, -0.580237, 0.756078, 0.302774, +0.000000, -1.789911, 4.934098, 3.000000, -1.833333, -0.000000, 0.928348, 0.371713, +0.000000, -1.789911, 4.934098, 3.000000, -1.833333, -0.000000, 0.928348, 0.371713, +1.002737, -1.996943, 4.816424, 3.000000, -2.000000, 0.580237, 0.756078, 0.302774, +1.002737, -1.445931, 3.440848, 2.500000, -2.000000, 0.596303, 0.745197, 0.298504, +1.002737, -2.734034, 6.657467, 3.000000, 0.908927, 0.582703, 0.762742, 0.280503, +1.002737, -1.996943, 4.816424, 3.000000, 1.000000, 0.580237, 0.756078, 0.302774, +0.000000, -1.789911, 4.934098, 3.500000, 1.000000, -0.000000, 0.928348, 0.371713, +0.000000, -1.789911, 4.934098, 3.500000, 1.000000, -0.000000, 0.928348, 0.371713, +-1.002737, -1.996943, 4.816424, 4.000000, 1.000000, -0.580237, 0.756078, 0.302774, +-1.002737, -2.734034, 6.657467, 4.000000, 0.908927, -0.582703, 0.762742, 0.280503, +-1.002737, -2.734034, 6.657467, 4.000000, 0.908927, -0.582703, 0.762742, 0.280503, +-1.002737, -3.550490, 9.039287, 4.000000, 0.817855, -0.582189, 0.779143, 0.232362, +0.000000, -3.338127, 9.144818, 3.500000, 0.798956, 0.000000, 0.958542, 0.284953, +0.000000, -3.338127, 9.144818, 3.500000, 0.798956, 0.000000, 0.958542, 0.284953, +1.002737, -3.550490, 9.039287, 3.000000, 0.798956, 0.582189, 0.779143, 0.232362, +1.002737, -2.734034, 6.657467, 3.000000, 0.908927, 0.582703, 0.762742, 0.280503, +1.002737, -4.339600, 12.037193, 3.000000, 0.651188, 0.578711, 0.795540, 0.179472, +1.002737, -3.550490, 9.039287, 3.000000, 0.798956, 0.582189, 0.779143, 0.232362, +0.000000, -3.338127, 9.144818, 3.500000, 0.798956, 0.000000, 0.958542, 0.284953, +0.000000, -3.338127, 9.144818, 3.500000, 0.798956, 0.000000, 0.958542, 0.284953, +-1.002737, -3.550490, 9.039287, 4.000000, 0.817855, -0.582189, 0.779143, 0.232362, +-1.002737, -4.339600, 12.037193, 4.000000, 0.651188, -0.578711, 0.795540, 0.179472, +-1.002737, -4.339600, 12.037193, 4.000000, 0.651188, -0.578711, 0.795540, 0.179472, +-1.002737, -4.987385, 15.402298, 4.000000, 0.484521, -0.576620, 0.807781, 0.122473, +0.000000, -4.765513, 15.484047, 3.500000, 0.470545, 0.000000, 0.988884, 0.148690, +0.000000, -4.765513, 15.484047, 3.500000, 0.470545, 0.000000, 0.988884, 0.148690, +1.002737, -4.987385, 15.402298, 3.000000, 0.470545, 0.576620, 0.807781, 0.122473, +1.002737, -4.339600, 12.037193, 3.000000, 0.651188, 0.578711, 0.795540, 0.179472, +1.002737, -5.379865, 18.885717, 3.000000, 0.261948, 0.572718, 0.816712, 0.070540, +1.002737, -4.987385, 15.402298, 3.000000, 0.470545, 0.576620, 0.807781, 0.122473, +0.000000, -4.765513, 15.484047, 3.500000, 0.470545, 0.000000, 0.988884, 0.148690, +0.000000, -4.765513, 15.484047, 3.500000, 0.470545, 0.000000, 0.988884, 0.148690, +-1.002737, -4.987385, 15.402298, 4.000000, 0.484521, -0.576620, 0.807781, 0.122473, +-1.002737, -5.379865, 18.885717, 4.000000, 0.261948, -0.572718, 0.816712, 0.070540, +-1.002737, -5.379865, 18.885717, 4.000000, 0.261948, -0.572718, 0.816712, 0.070540, +-1.002737, -5.586154, 22.318600, 4.000000, 0.039374, -0.570604, 0.820419, 0.036373, +0.000000, -5.357677, 22.380409, 3.500000, 0.047044, -0.000000, 0.999050, 0.043579, +0.000000, -5.357677, 22.380409, 3.500000, 0.047044, -0.000000, 0.999050, 0.043579, +1.002737, -5.586154, 22.318600, 3.000000, 0.047044, 0.570604, 0.820419, 0.036373, +1.002737, -5.379865, 18.885717, 3.000000, 0.261948, 0.572718, 0.816712, 0.070540, +1.002737, -5.675372, 25.532089, 3.000000, -0.152521, 0.572885, 0.819555, 0.011471, +1.002737, -5.586154, 22.318600, 3.000000, 0.047044, 0.570604, 0.820419, 0.036373, +0.000000, -5.357677, 22.380409, 3.500000, 0.047044, -0.000000, 0.999050, 0.043579, +0.000000, -5.357677, 22.380409, 3.500000, 0.047044, -0.000000, 0.999050, 0.043579, +-1.002737, -5.586154, 22.318600, 4.000000, 0.039374, -0.570604, 0.820419, 0.036373, +-1.002737, -5.675372, 25.532089, 4.000000, -0.152521, -0.572885, 0.819555, 0.011471, +-1.002737, -5.675372, 25.532089, 4.000000, -0.152521, -0.572885, 0.819555, 0.011471, +-1.002737, -5.679584, 28.946095, 4.000000, -0.344415, -0.577055, 0.816690, -0.004975, +0.000000, -5.447061, 28.992958, 3.500000, -0.338108, 0.000000, 0.999979, -0.006525, +0.000000, -5.447061, 28.992958, 3.500000, -0.338108, 0.000000, 0.999979, -0.006525, +1.002737, -5.679584, 28.946095, 3.000000, -0.338108, 0.577055, 0.816690, -0.004975, +1.002737, -5.675372, 25.532089, 3.000000, -0.152521, 0.572885, 0.819555, 0.011471, +1.002737, -5.630855, 32.893612, 3.000000, -0.511082, 0.132943, 0.189166, -0.972904, +1.002737, -5.679584, 28.946095, 3.000000, -0.338108, 0.577055, 0.816690, -0.004975, +0.000000, -5.447061, 28.992958, 3.500000, -0.338108, 0.000000, 0.999979, -0.006525, +0.000000, -5.447061, 28.992958, 3.500000, -0.338108, 0.000000, 0.999979, -0.006525, +-1.002737, -5.679584, 28.946095, 4.000000, -0.344415, -0.577055, 0.816690, -0.004975, +-1.002737, -5.630855, 32.893612, 4.000000, -0.511082, -0.132943, 0.189166, -0.972904, +-1.002737, -5.630855, 32.893612, 4.000000, -0.511082, -0.132943, 0.189166, -0.972904, +-4.193409, -2.445326, 32.893612, 4.000000, -0.594415, -0.686924, 0.716419, 0.121978, +0.000000, -1.067776, 32.893612, 3.500000, -0.594415, -0.004492, 0.998437, 0.055707, +0.000000, -1.067776, 32.893612, 3.500000, -0.594415, -0.004492, 0.998437, 0.055707, +4.193409, -2.445326, 32.893612, 3.000000, -0.594415, 0.682263, 0.725032, 0.094055, +1.002737, -5.630855, 32.893612, 3.000000, -0.511082, 0.132943, 0.189166, -0.972904, +-1.002737, -2.684134, 2.725971, 3.500000, -1.666667, -0.555812, -0.771611, -0.309336, +-1.002737, -3.239137, 4.110385, 4.000000, -1.666667, -0.573276, -0.760494, -0.304965, +-1.336982, -2.618040, 4.463405, 4.000000, -1.833333, -0.999977, -0.006223, -0.002555, +-1.336982, -2.618040, 4.463405, 4.000000, -1.833333, -0.999977, -0.006223, -0.002555, +-1.002737, -1.996943, 4.816424, 4.000000, -2.000000, -0.580237, 0.756078, 0.302774, +-1.002737, -1.445931, 3.440848, 3.500000, -2.000000, -0.596303, 0.745197, 0.298504, +1.002737, -2.684134, 2.725971, 4.500000, -1.666667, 0.555812, -0.771611, -0.309336, +1.002737, -3.239137, 4.110385, 5.000000, -1.666667, 0.573276, -0.760494, -0.304965, +0.000000, -3.446170, 3.992712, 5.000000, -1.833333, 0.000000, -0.928140, -0.372231, +0.000000, -3.446170, 3.992712, 5.000000, -1.833333, 0.000000, -0.928140, -0.372231, +-1.002737, -3.239137, 4.110385, 5.000000, -2.000000, -0.573276, -0.760494, -0.304965, +-1.002737, -2.684134, 2.725971, 4.500000, -2.000000, -0.555812, -0.771611, -0.309336, +-1.336982, -22.914524, -4.929887, 7.000000, -1.833333, -0.999805, -0.016666, 0.010584, +-1.002737, -22.289114, -5.237599, 7.000000, -1.666667, -0.580101, 0.726129, -0.369081, +-1.002737, -22.791559, -6.324653, 6.500000, -1.666667, -0.585182, 0.679392, -0.442706, +-1.002737, -22.791559, -6.324653, 6.500000, -1.666667, -0.585182, 0.679392, -0.442706, +-0.742768, -23.169422, -6.772669, 6.000000, -1.666667, -0.444774, 0.383424, -0.809421, +-1.002737, -23.736286, -6.771559, 6.000000, -1.833333, -0.633041, -0.276747, -0.722959, +-1.002737, -23.736286, -6.771559, 6.000000, -1.833333, -0.633041, -0.276747, -0.722959, +-0.742768, -24.152987, -6.401496, 6.000000, -2.000000, -0.455754, -0.834431, -0.309862, +-1.002737, -24.101816, -5.795360, 6.500000, -2.000000, -0.571338, -0.788867, 0.226409, +-1.002737, -24.101816, -5.795360, 6.500000, -2.000000, -0.571338, -0.788867, 0.226409, +-1.002737, -23.539934, -4.622173, 7.000000, -2.000000, -0.559738, -0.733607, 0.385376, +-1.336982, -22.914524, -4.929887, 7.000000, -1.833333, -0.999805, -0.016666, 0.010584, +-1.336982, -20.877926, -1.798224, 0.500000, 4.901888, -0.999242, -0.027513, 0.027552, +-1.002737, -20.362839, -2.232996, 1.000000, 4.901887, -0.577401, 0.607255, -0.545756, +-1.002737, -21.510138, -3.803390, 1.000000, 4.957545, -0.579339, 0.686160, -0.439944, +-1.002737, -21.510138, -3.803390, 1.000000, 4.957545, -0.579339, 0.686160, -0.439944, +-1.002737, -22.289114, -5.237599, 1.000000, 5.000000, -0.580101, 0.726129, -0.369081, +-1.336982, -22.914524, -4.929887, 0.500000, 5.000000, -0.999805, -0.016666, 0.010584, +-1.336982, -22.914524, -4.929887, 0.500000, 5.000000, -0.999805, -0.016666, 0.010584, +-1.002737, -23.539934, -4.622173, 0.000000, 5.000000, -0.559738, -0.733607, 0.385376, +-1.002737, -22.670450, -3.070609, 0.000000, 4.957545, -0.549531, -0.697669, 0.459646, +-1.002737, -22.670450, -3.070609, 0.000000, 4.957545, -0.549531, -0.697669, 0.459646, +-1.002737, -21.393009, -1.363454, 0.000000, 4.915090, -0.538985, -0.621423, 0.568620, +-1.336982, -20.877926, -1.798224, 0.500000, 4.901888, -0.999242, -0.027513, 0.027552, +-1.336982, -17.125900, 1.021948, 0.500000, 4.706708, -0.998755, -0.017888, 0.046575, +-1.002737, -16.806824, 0.450041, 1.000000, 4.706708, -0.570721, 0.333495, -0.750372, +-1.002737, -18.755436, -0.737389, 1.000000, 4.819824, -0.571841, 0.493951, -0.654989, +-1.002737, -18.755436, -0.737389, 1.000000, 4.819824, -0.571841, 0.493951, -0.654989, +-1.002737, -20.362839, -2.232996, 1.000000, 4.901887, -0.577401, 0.607255, -0.545756, +-1.336982, -20.877926, -1.798224, 0.500000, 4.901888, -0.999242, -0.027513, 0.027552, +-1.336982, -20.877926, -1.798224, 0.500000, 4.901888, -0.999242, -0.027513, 0.027552, +-1.002737, -21.393009, -1.363454, 0.000000, 4.915090, -0.538985, -0.621423, 0.568620, +-1.002737, -19.607264, 0.276508, 0.000000, 4.819824, -0.531663, -0.507888, 0.677779, +-1.002737, -19.607264, 0.276508, 0.000000, 4.819824, -0.531663, -0.507888, 0.677779, +-1.002737, -17.444981, 1.593854, 0.000000, 4.724558, -0.523473, -0.350048, 0.776815, +-1.336982, -17.125900, 1.021948, 0.500000, 4.706708, -0.998755, -0.017888, 0.046575, +-1.336982, -12.461710, 1.998980, 0.500000, 4.382352, -0.999581, -0.002143, 0.028884, +-1.002737, -12.384212, 1.352605, 1.000000, 4.382352, -0.556840, 0.051516, -0.829021, +-1.002737, -14.635897, 1.095908, 1.000000, 4.557891, -0.560822, 0.165222, -0.811283, +-1.002737, -14.635897, 1.095908, 1.000000, 4.557891, -0.560822, 0.165222, -0.811283, +-1.002737, -16.806824, 0.450041, 1.000000, 4.706708, -0.570721, 0.333495, -0.750372, +-1.336982, -17.125900, 1.021948, 0.500000, 4.706708, -0.998755, -0.017888, 0.046575, +-1.336982, -17.125900, 1.021948, 0.500000, 4.706708, -0.998755, -0.017888, 0.046575, +-1.002737, -17.444981, 1.593854, 0.000000, 4.724558, -0.523473, -0.350048, 0.776815, +-1.002737, -15.037928, 2.333167, 0.000000, 4.557892, -0.524224, -0.178780, 0.832603, +-1.002737, -15.037928, 2.333167, 0.000000, 4.557892, -0.524224, -0.178780, 0.832603, +-1.002737, -12.539209, 2.645355, 0.000000, 4.391225, -0.529316, -0.059790, 0.846315, +-1.336982, -12.461710, 1.998980, 0.500000, 4.382352, -0.999581, -0.002143, 0.028884, +-1.336982, -8.028582, 1.726443, 0.500000, 3.977933, -0.998903, 0.011916, 0.045285, +-1.002737, -8.188779, 1.086162, 1.000000, 3.977933, -0.571796, -0.203921, -0.794648, +-1.002737, -10.193326, 1.372527, 1.000000, 4.189068, -0.563923, -0.052320, -0.824168, +-1.002737, -10.193326, 1.372527, 1.000000, 4.189068, -0.563923, -0.052320, -0.824168, +-1.002737, -12.384212, 1.352605, 1.000000, 4.382352, -0.556840, 0.051516, -0.829021, +-1.336982, -12.461710, 1.998980, 0.500000, 4.382352, -0.999581, -0.002143, 0.028884, +-1.336982, -12.461710, 1.998980, 0.500000, 4.382352, -0.999581, -0.002143, 0.028884, +-1.002737, -12.539209, 2.645355, 0.000000, 4.391225, -0.529316, -0.059790, 0.846315, +-1.002737, -10.101929, 2.681329, 0.000000, 4.189068, -0.529646, 0.050516, 0.846713, +-1.002737, -10.101929, 2.681329, 0.000000, 4.189068, -0.529646, 0.050516, 0.846713, +-1.002737, -7.868385, 2.366725, 0.000000, 3.986911, -0.526810, 0.210598, 0.823480, +-1.336982, -8.028582, 1.726443, 0.500000, 3.977933, -0.998903, 0.011916, 0.045285, +-1.336982, -4.681401, -0.053863, 0.500000, 3.518014, -0.999076, 0.030579, 0.030219, +-1.002737, -5.023273, -0.595701, 1.000000, 3.518014, -0.554291, -0.537252, -0.635706, +-1.002737, -6.496116, 0.423996, 1.000000, 3.748844, -0.567467, -0.386666, -0.726960, +-1.002737, -6.496116, 0.423996, 1.000000, 3.748844, -0.567467, -0.386666, -0.726960, +-1.002737, -8.188779, 1.086162, 1.000000, 3.977933, -0.571796, -0.203921, -0.794648, +-1.336982, -8.028582, 1.726443, 0.500000, 3.977933, -0.998903, 0.011916, 0.045285, +-1.336982, -8.028582, 1.726443, 0.500000, 3.977933, -0.998903, 0.011916, 0.045285, +-1.002737, -7.868385, 2.366725, 0.000000, 3.986911, -0.526810, 0.210598, 0.823480, +-1.002737, -5.980879, 1.627182, 0.000000, 3.748844, -0.522694, 0.400366, 0.752661, +-1.002737, -5.980879, 1.627182, 0.000000, 3.748844, -0.522694, 0.400366, 0.752661, +-1.002737, -4.339529, 0.487975, 0.000000, 3.510776, -0.515414, 0.553092, 0.654552, +-1.336982, -4.681401, -0.053863, 0.500000, 3.518014, -0.999076, 0.030579, 0.030219, +-1.336982, -2.032626, -3.152671, 0.500000, 3.096704, -0.999446, 0.028671, 0.016899, +-1.002737, -2.514818, -3.530164, 1.000000, 3.096704, -0.535283, -0.710141, -0.457353, +-1.002737, -3.678185, -1.954659, 1.000000, 3.301661, -0.541786, -0.639146, -0.545858, +-1.002737, -3.678185, -1.954659, 1.000000, 3.301661, -0.541786, -0.639146, -0.545858, +-1.002737, -5.023273, -0.595701, 1.000000, 3.518014, -0.554291, -0.537252, -0.635706, +-1.336982, -4.681401, -0.053863, 0.500000, 3.518014, -0.999076, 0.030579, 0.030219, +-1.336982, -4.681401, -0.053863, 0.500000, 3.518014, -0.999076, 0.030579, 0.030219, +-1.002737, -4.339529, 0.487975, 0.000000, 3.510776, -0.515414, 0.553092, 0.654552, +-1.002737, -2.844458, -1.025621, 0.000000, 3.301661, -0.509526, 0.653879, 0.559309, +-1.002737, -2.844458, -1.025621, 0.000000, 3.301661, -0.509526, 0.653879, 0.559309, +-1.002737, -1.550434, -2.775177, 0.000000, 3.092546, -0.505987, 0.723592, 0.469458, +-1.336982, -2.032626, -3.152671, 0.500000, 3.096704, -0.999446, 0.028671, 0.016899, +-1.336982, -0.371475, -6.820555, 0.500000, 2.714038, -0.999078, 0.041649, 0.010372, +-1.002737, -0.955311, -7.018215, 1.000000, 2.714038, -0.543592, -0.816934, -0.192683, +-1.002737, -1.587135, -5.199499, 1.000000, 2.900065, -0.538039, -0.769598, -0.343850, +-1.002737, -1.587135, -5.199499, 1.000000, 2.900065, -0.538039, -0.769598, -0.343850, +-1.002737, -2.514818, -3.530164, 1.000000, 3.096704, -0.535283, -0.710141, -0.457353, +-1.336982, -2.032626, -3.152671, 0.500000, 3.096704, -0.999446, 0.028671, 0.016899, +-1.336982, -2.032626, -3.152671, 0.500000, 3.096704, -0.999446, 0.028671, 0.016899, +-1.002737, -1.550434, -2.775177, 0.000000, 3.092546, -0.505987, 0.723592, 0.469458, +-1.002737, -0.512230, -4.622262, 0.000000, 2.900065, -0.503207, 0.785550, 0.360132, +-1.002737, -0.512230, -4.622262, 0.000000, 2.900065, -0.503207, 0.785550, 0.360132, +-1.002737, 0.212360, -6.622896, 0.000000, 2.707584, -0.505652, 0.835716, 0.214230, +-1.336982, -0.371475, -6.820555, 0.500000, 2.714038, -0.999078, 0.041649, 0.010372, +-1.336982, -0.183937, -11.115767, 0.500000, 2.371212, -0.999002, 0.043336, -0.010816, +-1.002737, -0.835270, -11.133001, 1.000000, 2.371212, -0.556778, -0.814518, 0.162970, +-1.002737, -0.679522, -9.041862, 1.000000, 2.540917, -0.550509, -0.834486, -0.023924, +-1.002737, -0.679522, -9.041862, 1.000000, 2.540917, -0.550509, -0.834486, -0.023924, +-1.002737, -0.955311, -7.018215, 1.000000, 2.714038, -0.543592, -0.816934, -0.192683, +-1.336982, -0.371475, -6.820555, 0.500000, 2.714038, -0.999078, 0.041649, 0.010372, +-1.336982, -0.371475, -6.820555, 0.500000, 2.714038, -0.999078, 0.041649, 0.010372, +-1.002737, 0.212360, -6.622896, 0.000000, 2.707584, -0.505652, 0.835716, 0.214230, +-1.002737, 0.565540, -8.833092, 0.000000, 2.540917, -0.512670, 0.857167, 0.049331, +-1.002737, 0.565540, -8.833092, 0.000000, 2.540917, -0.512670, 0.857167, 0.049331, +-1.002737, 0.467394, -11.098533, 0.000000, 2.374251, -0.517497, 0.844529, -0.137721, +-1.336982, -0.183937, -11.115767, 0.500000, 2.371212, -0.999002, 0.043336, -0.010816, +-1.336982, -1.762512, -15.300098, 0.500000, 2.020624, -0.999977, 0.006790, -0.000522, +-1.002737, -2.439466, -15.191065, 1.000000, 2.020624, -0.552162, -0.756555, 0.350343, +-1.002737, -1.498060, -13.154191, 1.000000, 2.195430, -0.550846, -0.775955, 0.307348, +-1.002737, -1.498060, -13.154191, 1.000000, 2.195430, -0.550846, -0.775955, 0.307348, +-1.002737, -0.835270, -11.133001, 1.000000, 2.371212, -0.556778, -0.814518, 0.162970, +-1.336982, -0.183937, -11.115767, 0.500000, 2.371212, -0.999002, 0.043336, -0.010816, +-1.336982, -0.183937, -11.115767, 0.500000, 2.371212, -0.999002, 0.043336, -0.010816, +-1.002737, 0.467394, -11.098533, 0.000000, 2.374251, -0.517497, 0.844529, -0.137721, +-1.002737, -0.161999, -13.264900, 0.000000, 2.195430, -0.528455, 0.798898, -0.287224, +-1.002737, -0.161999, -13.264900, 0.000000, 2.195430, -0.528455, 0.798898, -0.287224, +-1.002737, -1.085560, -15.409132, 0.000000, 2.016609, -0.545979, 0.767296, -0.336399, +-1.336982, -1.762512, -15.300098, 0.500000, 2.020624, -0.999977, 0.006790, -0.000522, +-1.336982, -3.677238, -19.700720, 0.500000, 1.696742, -0.999943, -0.009227, 0.005371, +-1.002737, -4.363696, -19.552979, 1.000000, 1.696742, -0.563275, -0.773529, 0.290474, +-1.002737, -3.431055, -17.329250, 1.000000, 1.853850, -0.559291, -0.758482, 0.334513, +-1.002737, -3.431055, -17.329250, 1.000000, 1.853850, -0.559291, -0.758482, 0.334513, +-1.002737, -2.439466, -15.191065, 1.000000, 2.020624, -0.552162, -0.756555, 0.350343, +-1.336982, -1.762512, -15.300098, 0.500000, 2.020624, -0.999977, 0.006790, -0.000522, +-1.336982, -1.762512, -15.300098, 0.500000, 2.020624, -0.999977, 0.006790, -0.000522, +-1.002737, -1.085560, -15.409132, 0.000000, 2.016609, -0.545979, 0.767296, -0.336399, +-1.002737, -2.066217, -17.608171, 0.000000, 1.853850, -0.561407, 0.760416, -0.326481, +-1.002737, -2.066217, -17.608171, 0.000000, 1.853850, -0.561407, 0.760416, -0.326481, +-1.002737, -2.990782, -19.848455, 0.000000, 1.691091, -0.573541, 0.767562, -0.286181, +-1.336982, -3.677238, -19.700720, 0.500000, 1.696742, -0.999943, -0.009227, 0.005371, +-1.336982, -4.998410, -24.141369, 0.500000, 1.417808, -0.999879, -0.015054, 0.003873, +-1.002737, -5.694758, -24.033106, 1.000000, 1.417808, -0.566494, -0.804616, 0.177981, +-1.002737, -5.128252, -21.846479, 1.000000, 1.550938, -0.566340, -0.790066, 0.234638, +-1.002737, -5.128252, -21.846479, 1.000000, 1.550938, -0.566340, -0.790066, 0.234638, +-1.002737, -4.363696, -19.552979, 1.000000, 1.696742, -0.563275, -0.773529, 0.290474, +-1.336982, -3.677238, -19.700720, 0.500000, 1.696742, -0.999943, -0.009227, 0.005371, +-1.336982, -3.677238, -19.700720, 0.500000, 1.696742, -0.999943, -0.009227, 0.005371, +-1.002737, -2.990782, -19.848455, 0.000000, 1.691091, -0.573541, 0.767562, -0.286181, +-1.002737, -3.746061, -22.116426, 0.000000, 1.550938, -0.578794, 0.781497, -0.232937, +-1.002737, -3.746061, -22.116426, 0.000000, 1.550938, -0.578794, 0.781497, -0.232937, +-1.002737, -4.302059, -24.249632, 0.000000, 1.410785, -0.582444, 0.793471, -0.176531, +-1.336982, -4.998410, -24.141369, 0.500000, 1.417808, -0.999879, -0.015054, 0.003873, +-1.336982, -5.505962, -27.491592, 0.500000, 1.186658, -0.999932, -0.011525, 0.001722, +-1.002737, -6.213656, -27.449341, 1.000000, 1.186658, -0.570758, -0.816393, 0.087968, +-1.002737, -6.033253, -25.936214, 1.000000, 1.298722, -0.568446, -0.813396, 0.123515, +-1.002737, -6.033253, -25.936214, 1.000000, 1.298722, -0.568446, -0.813396, 0.123515, +-1.002737, -5.694758, -24.033106, 1.000000, 1.417808, -0.566494, -0.804616, 0.177981, +-1.336982, -4.998410, -24.141369, 0.500000, 1.417808, -0.999879, -0.015054, 0.003873, +-1.336982, -4.998410, -24.141369, 0.500000, 1.417808, -0.999879, -0.015054, 0.003873, +-1.002737, -4.302059, -24.249632, 0.000000, 1.410785, -0.582444, 0.793471, -0.176531, +-1.002737, -4.628780, -26.085621, 0.000000, 1.298722, -0.582983, 0.803361, -0.121414, +-1.002737, -4.628780, -26.085621, 0.000000, 1.298722, -0.582983, 0.803361, -0.121414, +-1.002737, -4.798269, -27.533844, 0.000000, 1.186658, -0.583018, 0.808019, -0.084825, +-1.336982, -5.505962, -27.491592, 0.500000, 1.186658, -0.999932, -0.011525, 0.001722, +-1.002737, -6.305892, -28.466030, 0.500000, 1.053028, -0.565626, -0.821288, 0.074517, +-1.002737, -6.213656, -27.449341, 1.000000, 1.053028, -0.570758, -0.816393, 0.087968, +-1.336982, -5.505962, -27.491592, 1.000000, 1.119843, -0.999932, -0.011525, 0.001722, +-1.336982, -5.505962, -27.491592, 1.000000, 1.119843, -0.999932, -0.011525, 0.001722, +-1.002737, -4.798269, -27.533844, 1.000000, 1.186658, -0.583018, 0.808019, -0.084825, +-1.002737, -4.882575, -28.503754, 0.500000, 1.186658, -0.589040, 0.805068, -0.069986, +0.000000, -22.080643, -5.340171, 1.000000, 1.026514, 0.000000, 0.892013, -0.452009, +1.002737, -22.289114, -5.237599, 1.000000, 1.053028, 0.580101, 0.726128, -0.369081, +1.002737, -22.791559, -6.324653, 0.500000, 1.053028, 0.585182, 0.679392, -0.442706, +1.002737, -22.791559, -6.324653, 0.500000, 1.053028, 0.585182, 0.679392, -0.442706, +0.742768, -23.169422, -6.772669, 0.000000, 1.053028, 0.444774, 0.383425, -0.809421, +0.000000, -23.066525, -7.012697, 0.000000, 1.026514, -0.000000, 0.424976, -0.905205, +0.000000, -23.066525, -7.012697, 0.000000, 1.026514, -0.000000, 0.424976, -0.905205, +-0.742768, -23.169422, -6.772669, 0.000000, 1.000000, -0.444774, 0.383424, -0.809421, +-1.002737, -22.791559, -6.324653, 0.500000, 1.000000, -0.585182, 0.679392, -0.442706, +-1.002737, -22.791559, -6.324653, 0.500000, 1.000000, -0.585182, 0.679392, -0.442706, +-1.002737, -22.289114, -5.237599, 1.000000, 1.000000, -0.580101, 0.726129, -0.369081, +0.000000, -22.080643, -5.340171, 1.000000, 1.026514, 0.000000, 0.892013, -0.452009, +0.000000, -20.191145, -2.377919, 1.500000, 4.901888, 0.000000, 0.744223, -0.667931, +1.002737, -20.362839, -2.232996, 2.000000, 4.901887, 0.577401, 0.607255, -0.545756, +1.002737, -21.510138, -3.803390, 2.000000, 4.957545, 0.579339, 0.686160, -0.439944, +1.002737, -21.510138, -3.803390, 2.000000, 4.957545, 0.579339, 0.686160, -0.439944, +1.002737, -22.289114, -5.237599, 2.000000, 5.000000, 0.580101, 0.726128, -0.369081, +0.000000, -22.080643, -5.340171, 1.500000, 5.000000, 0.000000, 0.892013, -0.452009, +0.000000, -22.080643, -5.340171, 1.500000, 5.000000, 0.000000, 0.892013, -0.452009, +-1.002737, -22.289114, -5.237599, 1.000000, 5.000000, -0.580101, 0.726129, -0.369081, +-1.002737, -21.510138, -3.803390, 1.000000, 4.957545, -0.579339, 0.686160, -0.439944, +-1.002737, -21.510138, -3.803390, 1.000000, 4.957545, -0.579339, 0.686160, -0.439944, +-1.002737, -20.362839, -2.232996, 1.000000, 4.901887, -0.577401, 0.607255, -0.545756, +0.000000, -20.191145, -2.377919, 1.500000, 4.901888, 0.000000, 0.744223, -0.667931, +0.000000, -16.700464, 0.259406, 1.500000, 4.706708, -0.000000, 0.404784, -0.914412, +1.002737, -16.806824, 0.450041, 2.000000, 4.706708, 0.570721, 0.333495, -0.750372, +1.002737, -18.755436, -0.737389, 2.000000, 4.819824, 0.571841, 0.493951, -0.654989, +1.002737, -18.755436, -0.737389, 2.000000, 4.819824, 0.571841, 0.493951, -0.654989, +1.002737, -20.362839, -2.232996, 2.000000, 4.901887, 0.577401, 0.607255, -0.545756, +0.000000, -20.191145, -2.377919, 1.500000, 4.901888, 0.000000, 0.744223, -0.667931, +0.000000, -20.191145, -2.377919, 1.500000, 4.901888, 0.000000, 0.744223, -0.667931, +-1.002737, -20.362839, -2.232996, 1.000000, 4.901887, -0.577401, 0.607255, -0.545756, +-1.002737, -18.755436, -0.737389, 1.000000, 4.819824, -0.571841, 0.493951, -0.654989, +-1.002737, -18.755436, -0.737389, 1.000000, 4.819824, -0.571841, 0.493951, -0.654989, +-1.002737, -16.806824, 0.450041, 1.000000, 4.706708, -0.570721, 0.333495, -0.750372, +0.000000, -16.700464, 0.259406, 1.500000, 4.706708, -0.000000, 0.404784, -0.914412, +0.000000, -12.358379, 1.137146, 1.500000, 4.382352, 0.000000, 0.060964, -0.998140, +1.002737, -12.384212, 1.352605, 2.000000, 4.382352, 0.556840, 0.051516, -0.829021, +1.002737, -14.635897, 1.095908, 2.000000, 4.557891, 0.560822, 0.165222, -0.811283, +1.002737, -14.635897, 1.095908, 2.000000, 4.557891, 0.560822, 0.165222, -0.811283, +1.002737, -16.806824, 0.450041, 2.000000, 4.706708, 0.570721, 0.333495, -0.750372, +0.000000, -16.700464, 0.259406, 1.500000, 4.706708, -0.000000, 0.404784, -0.914412, +0.000000, -16.700464, 0.259406, 1.500000, 4.706708, -0.000000, 0.404784, -0.914412, +-1.002737, -16.806824, 0.450041, 1.000000, 4.706708, -0.570721, 0.333495, -0.750372, +-1.002737, -14.635897, 1.095908, 1.000000, 4.557891, -0.560822, 0.165222, -0.811283, +-1.002737, -14.635897, 1.095908, 1.000000, 4.557891, -0.560822, 0.165222, -0.811283, +-1.002737, -12.384212, 1.352605, 1.000000, 4.382352, -0.556840, 0.051516, -0.829021, +0.000000, -12.358379, 1.137146, 1.500000, 4.382352, 0.000000, 0.060964, -0.998140, +0.000000, -8.242178, 0.872734, 1.500000, 3.977933, 0.000000, -0.248755, -0.968567, +1.002737, -8.188779, 1.086162, 2.000000, 3.977933, 0.571796, -0.203921, -0.794648, +1.002737, -10.193325, 1.372527, 2.000000, 4.189068, 0.563923, -0.052320, -0.824168, +1.002737, -10.193325, 1.372527, 2.000000, 4.189068, 0.563923, -0.052320, -0.824168, +1.002737, -12.384212, 1.352605, 2.000000, 4.382352, 0.556840, 0.051516, -0.829021, +0.000000, -12.358379, 1.137146, 1.500000, 4.382352, 0.000000, 0.060964, -0.998140, +0.000000, -12.358379, 1.137146, 1.500000, 4.382352, 0.000000, 0.060964, -0.998140, +-1.002737, -12.384212, 1.352605, 1.000000, 4.382352, -0.556840, 0.051516, -0.829021, +-1.002737, -10.193326, 1.372527, 1.000000, 4.189068, -0.563923, -0.052320, -0.824168, +-1.002737, -10.193326, 1.372527, 1.000000, 4.189068, -0.563923, -0.052320, -0.824168, +-1.002737, -8.188779, 1.086162, 1.000000, 3.977933, -0.571796, -0.203921, -0.794648, +0.000000, -8.242178, 0.872734, 1.500000, 3.977933, 0.000000, -0.248755, -0.968567, +0.000000, -5.137229, -0.776313, 1.500000, 3.518014, -0.000000, -0.646205, -0.763164, +1.002737, -5.023273, -0.595701, 2.000000, 3.518014, 0.554291, -0.537252, -0.635706, +1.002737, -6.496116, 0.423996, 2.000000, 3.748844, 0.567467, -0.386666, -0.726960, +1.002737, -6.496116, 0.423996, 2.000000, 3.748844, 0.567467, -0.386666, -0.726960, +1.002737, -8.188779, 1.086162, 2.000000, 3.977933, 0.571796, -0.203921, -0.794648, +0.000000, -8.242178, 0.872734, 1.500000, 3.977933, 0.000000, -0.248755, -0.968567, +0.000000, -8.242178, 0.872734, 1.500000, 3.977933, 0.000000, -0.248755, -0.968567, +-1.002737, -8.188779, 1.086162, 1.000000, 3.977933, -0.571796, -0.203921, -0.794648, +-1.002737, -6.496116, 0.423996, 1.000000, 3.748844, -0.567467, -0.386666, -0.726960, +-1.002737, -6.496116, 0.423996, 1.000000, 3.748844, -0.567467, -0.386666, -0.726960, +-1.002737, -5.023273, -0.595701, 1.000000, 3.518014, -0.554291, -0.537252, -0.635706, +0.000000, -5.137229, -0.776313, 1.500000, 3.518014, -0.000000, -0.646205, -0.763164, +0.000000, -2.675549, -3.655995, 1.500000, 3.096704, -0.000000, -0.841132, -0.540830, +1.002737, -2.514818, -3.530164, 2.000000, 3.096704, 0.535283, -0.710141, -0.457354, +1.002737, -3.678185, -1.954659, 2.000000, 3.301661, 0.541785, -0.639146, -0.545858, +1.002737, -3.678185, -1.954659, 2.000000, 3.301661, 0.541785, -0.639146, -0.545858, +1.002737, -5.023273, -0.595701, 2.000000, 3.518014, 0.554291, -0.537252, -0.635706, +0.000000, -5.137229, -0.776313, 1.500000, 3.518014, -0.000000, -0.646205, -0.763164, +0.000000, -5.137229, -0.776313, 1.500000, 3.518014, -0.000000, -0.646205, -0.763164, +-1.002737, -5.023273, -0.595701, 1.000000, 3.518014, -0.554291, -0.537252, -0.635706, +-1.002737, -3.678185, -1.954659, 1.000000, 3.301661, -0.541786, -0.639146, -0.545858, +-1.002737, -3.678185, -1.954659, 1.000000, 3.301661, -0.541786, -0.639146, -0.545858, +-1.002737, -2.514818, -3.530164, 1.000000, 3.096704, -0.535283, -0.710141, -0.457353, +0.000000, -2.675549, -3.655995, 1.500000, 3.096704, -0.000000, -0.841132, -0.540830, +0.000000, -1.149923, -7.084101, 1.500000, 2.714038, 0.000000, -0.973883, -0.227050, +1.002737, -0.955311, -7.018215, 2.000000, 2.714038, 0.543591, -0.816934, -0.192683, +1.002737, -1.587135, -5.199499, 2.000000, 2.900065, 0.538039, -0.769598, -0.343850, +1.002737, -1.587135, -5.199499, 2.000000, 2.900065, 0.538039, -0.769598, -0.343850, +1.002737, -2.514818, -3.530164, 2.000000, 3.096704, 0.535283, -0.710141, -0.457354, +0.000000, -2.675549, -3.655995, 1.500000, 3.096704, -0.000000, -0.841132, -0.540830, +0.000000, -2.675549, -3.655995, 1.500000, 3.096704, -0.000000, -0.841132, -0.540830, +-1.002737, -2.514818, -3.530164, 1.000000, 3.096704, -0.535283, -0.710141, -0.457353, +-1.002737, -1.587135, -5.199499, 1.000000, 2.900065, -0.538039, -0.769598, -0.343850, +-1.002737, -1.587135, -5.199499, 1.000000, 2.900065, -0.538039, -0.769598, -0.343850, +-1.002737, -0.955311, -7.018215, 1.000000, 2.714038, -0.543592, -0.816934, -0.192683, +0.000000, -1.149923, -7.084101, 1.500000, 2.714038, 0.000000, -0.973883, -0.227050, +0.000000, -1.052381, -11.138744, 1.500000, 2.371212, 0.000000, -0.979438, 0.201745, +1.002737, -0.835270, -11.133000, 2.000000, 2.371212, 0.556778, -0.814518, 0.162970, +1.002737, -0.679521, -9.041862, 2.000000, 2.540917, 0.550509, -0.834486, -0.023924, +1.002737, -0.679521, -9.041862, 2.000000, 2.540917, 0.550509, -0.834486, -0.023924, +1.002737, -0.955311, -7.018215, 2.000000, 2.714038, 0.543591, -0.816934, -0.192683, +0.000000, -1.149923, -7.084101, 1.500000, 2.714038, 0.000000, -0.973883, -0.227050, +0.000000, -1.149923, -7.084101, 1.500000, 2.714038, 0.000000, -0.973883, -0.227050, +-1.002737, -0.955311, -7.018215, 1.000000, 2.714038, -0.543592, -0.816934, -0.192683, +-1.002737, -0.679522, -9.041862, 1.000000, 2.540917, -0.550509, -0.834486, -0.023924, +-1.002737, -0.679522, -9.041862, 1.000000, 2.540917, -0.550509, -0.834486, -0.023924, +-1.002737, -0.835270, -11.133001, 1.000000, 2.371212, -0.556778, -0.814518, 0.162970, +0.000000, -1.052381, -11.138744, 1.500000, 2.371212, 0.000000, -0.979438, 0.201745, +0.000000, -2.665116, -15.154720, 1.500000, 2.020624, -0.000000, -0.906717, 0.421740, +1.002737, -2.439466, -15.191065, 2.000000, 2.020624, 0.552162, -0.756556, 0.350343, +1.002737, -1.498060, -13.154191, 2.000000, 2.195430, 0.550846, -0.775955, 0.307348, +1.002737, -1.498060, -13.154191, 2.000000, 2.195430, 0.550846, -0.775955, 0.307348, +1.002737, -0.835270, -11.133000, 2.000000, 2.371212, 0.556778, -0.814518, 0.162970, +0.000000, -1.052381, -11.138744, 1.500000, 2.371212, 0.000000, -0.979438, 0.201745, +0.000000, -1.052381, -11.138744, 1.500000, 2.371212, 0.000000, -0.979438, 0.201745, +-1.002737, -0.835270, -11.133001, 1.000000, 2.371212, -0.556778, -0.814518, 0.162970, +-1.002737, -1.498060, -13.154191, 1.000000, 2.195430, -0.550846, -0.775955, 0.307348, +-1.002737, -1.498060, -13.154191, 1.000000, 2.195430, -0.550846, -0.775955, 0.307348, +-1.002737, -2.439466, -15.191065, 1.000000, 2.020624, -0.552162, -0.756555, 0.350343, +0.000000, -2.665116, -15.154720, 1.500000, 2.020624, -0.000000, -0.906717, 0.421740, +0.000000, -4.592515, -19.503733, 1.500000, 1.696742, -0.000000, -0.936315, 0.351162, +1.002737, -4.363696, -19.552979, 2.000000, 1.696742, 0.563275, -0.773529, 0.290474, +1.002737, -3.431055, -17.329250, 2.000000, 1.853850, 0.559291, -0.758482, 0.334513, +1.002737, -3.431055, -17.329250, 2.000000, 1.853850, 0.559291, -0.758482, 0.334513, +1.002737, -2.439466, -15.191065, 2.000000, 2.020624, 0.552162, -0.756556, 0.350343, +0.000000, -2.665116, -15.154720, 1.500000, 2.020624, -0.000000, -0.906717, 0.421740, +0.000000, -2.665116, -15.154720, 1.500000, 2.020624, -0.000000, -0.906717, 0.421740, +-1.002737, -2.439466, -15.191065, 1.000000, 2.020624, -0.552162, -0.756555, 0.350343, +-1.002737, -3.431055, -17.329250, 1.000000, 1.853850, -0.559291, -0.758482, 0.334513, +-1.002737, -3.431055, -17.329250, 1.000000, 1.853850, -0.559291, -0.758482, 0.334513, +-1.002737, -4.363696, -19.552979, 1.000000, 1.696742, -0.563275, -0.773529, 0.290474, +0.000000, -4.592515, -19.503733, 1.500000, 1.696742, -0.000000, -0.936315, 0.351162, +0.000000, -5.926875, -23.997019, 1.500000, 1.417808, -0.000000, -0.976472, 0.215645, +1.002737, -5.694758, -24.033106, 2.000000, 1.417808, 0.566494, -0.804616, 0.177981, +1.002737, -5.128252, -21.846479, 2.000000, 1.550938, 0.566340, -0.790066, 0.234638, +1.002737, -5.128252, -21.846479, 2.000000, 1.550938, 0.566340, -0.790066, 0.234638, +1.002737, -4.363696, -19.552979, 2.000000, 1.696742, 0.563275, -0.773529, 0.290474, +0.000000, -4.592515, -19.503733, 1.500000, 1.696742, -0.000000, -0.936315, 0.351162, +0.000000, -4.592515, -19.503733, 1.500000, 1.696742, -0.000000, -0.936315, 0.351162, +-1.002737, -4.363696, -19.552979, 1.000000, 1.696742, -0.563275, -0.773529, 0.290474, +-1.002737, -5.128252, -21.846479, 1.000000, 1.550938, -0.566340, -0.790066, 0.234638, +-1.002737, -5.128252, -21.846479, 1.000000, 1.550938, -0.566340, -0.790066, 0.234638, +-1.002737, -5.694758, -24.033106, 1.000000, 1.417808, -0.566494, -0.804616, 0.177981, +0.000000, -5.926875, -23.997019, 1.500000, 1.417808, -0.000000, -0.976472, 0.215645, +0.000000, -6.449554, -27.435261, 1.500000, 1.186658, -0.000000, -0.994229, 0.107280, +1.002737, -6.213656, -27.449341, 2.000000, 1.186658, 0.570758, -0.816393, 0.087968, +1.002737, -6.033253, -25.936216, 2.000000, 1.298722, 0.568446, -0.813396, 0.123515, +1.002737, -6.033253, -25.936216, 2.000000, 1.298722, 0.568446, -0.813396, 0.123515, +1.002737, -5.694758, -24.033106, 2.000000, 1.417808, 0.566494, -0.804616, 0.177981, +0.000000, -5.926875, -23.997019, 1.500000, 1.417808, -0.000000, -0.976472, 0.215645, +0.000000, -5.926875, -23.997019, 1.500000, 1.417808, -0.000000, -0.976472, 0.215645, +-1.002737, -5.694758, -24.033106, 1.000000, 1.417808, -0.566494, -0.804616, 0.177981, +-1.002737, -6.033253, -25.936214, 1.000000, 1.298722, -0.568446, -0.813396, 0.123515, +-1.002737, -6.033253, -25.936214, 1.000000, 1.298722, -0.568446, -0.813396, 0.123515, +-1.002737, -6.213656, -27.449341, 1.000000, 1.186658, -0.570758, -0.816393, 0.087968, +0.000000, -6.449554, -27.435261, 1.500000, 1.186658, -0.000000, -0.994229, 0.107280, +1.002737, -6.305892, -28.466030, 1.500000, 1.053028, 0.565626, -0.821288, 0.074517, +1.002737, -6.213656, -27.449341, 2.000000, 1.053028, 0.570758, -0.816393, 0.087968, +0.000000, -6.449554, -27.435261, 2.000000, 1.119843, -0.000000, -0.994229, 0.107280, +0.000000, -6.449554, -27.435261, 2.000000, 1.119843, -0.000000, -0.994229, 0.107280, +-1.002737, -6.213656, -27.449341, 2.000000, 1.186658, -0.570758, -0.816393, 0.087968, +-1.002737, -6.305892, -28.466030, 1.500000, 1.186658, -0.565626, -0.821288, 0.074517, +1.336982, -22.914524, -4.929887, 2.000000, 1.026514, 0.999805, -0.016666, 0.010584, +1.002737, -23.539934, -4.622173, 2.000000, 1.053028, 0.559738, -0.733607, 0.385376, +1.002737, -24.101816, -5.795360, 1.500000, 1.053028, 0.571338, -0.788867, 0.226409, +1.002737, -24.101816, -5.795360, 1.500000, 1.053028, 0.571338, -0.788867, 0.226409, +0.742768, -24.152987, -6.401496, 1.000000, 1.053028, 0.455754, -0.834430, -0.309862, +1.002737, -23.736286, -6.771559, 1.000000, 1.026514, 0.633041, -0.276748, -0.722959, +1.002737, -23.736286, -6.771559, 1.000000, 1.026514, 0.633041, -0.276748, -0.722959, +0.742768, -23.169422, -6.772669, 1.000000, 1.000000, 0.444774, 0.383425, -0.809421, +1.002737, -22.791559, -6.324653, 1.500000, 1.000000, 0.585182, 0.679392, -0.442706, +1.002737, -22.791559, -6.324653, 1.500000, 1.000000, 0.585182, 0.679392, -0.442706, +1.002737, -22.289114, -5.237599, 2.000000, 1.000000, 0.580101, 0.726128, -0.369081, +1.336982, -22.914524, -4.929887, 2.000000, 1.026514, 0.999805, -0.016666, 0.010584, +1.336982, -20.877926, -1.798224, 2.500000, 4.901888, 0.999242, -0.027513, 0.027552, +1.002737, -21.393009, -1.363454, 3.000000, 4.901887, 0.538985, -0.621423, 0.568620, +1.002737, -22.670450, -3.070609, 3.000000, 4.957545, 0.549531, -0.697669, 0.459646, +1.002737, -22.670450, -3.070609, 3.000000, 4.957545, 0.549531, -0.697669, 0.459646, +1.002737, -23.539934, -4.622173, 3.000000, 5.000000, 0.559738, -0.733607, 0.385376, +1.336982, -22.914524, -4.929887, 2.500000, 5.000000, 0.999805, -0.016666, 0.010584, +1.336982, -22.914524, -4.929887, 2.500000, 5.000000, 0.999805, -0.016666, 0.010584, +1.002737, -22.289114, -5.237599, 2.000000, 5.000000, 0.580101, 0.726128, -0.369081, +1.002737, -21.510138, -3.803390, 2.000000, 4.957545, 0.579339, 0.686160, -0.439944, +1.002737, -21.510138, -3.803390, 2.000000, 4.957545, 0.579339, 0.686160, -0.439944, +1.002737, -20.362839, -2.232996, 2.000000, 4.901887, 0.577401, 0.607255, -0.545756, +1.336982, -20.877926, -1.798224, 2.500000, 4.901888, 0.999242, -0.027513, 0.027552, +1.336982, -17.125900, 1.021948, 2.500000, 4.706708, 0.998755, -0.017888, 0.046575, +1.002737, -17.444981, 1.593854, 3.000000, 4.706708, 0.523473, -0.350048, 0.776815, +1.002737, -19.607264, 0.276508, 3.000000, 4.819824, 0.531663, -0.507888, 0.677779, +1.002737, -19.607264, 0.276508, 3.000000, 4.819824, 0.531663, -0.507888, 0.677779, +1.002737, -21.393009, -1.363454, 3.000000, 4.901887, 0.538985, -0.621423, 0.568620, +1.336982, -20.877926, -1.798224, 2.500000, 4.901888, 0.999242, -0.027513, 0.027552, +1.336982, -20.877926, -1.798224, 2.500000, 4.901888, 0.999242, -0.027513, 0.027552, +1.002737, -20.362839, -2.232996, 2.000000, 4.901887, 0.577401, 0.607255, -0.545756, +1.002737, -18.755436, -0.737389, 2.000000, 4.819824, 0.571841, 0.493951, -0.654989, +1.002737, -18.755436, -0.737389, 2.000000, 4.819824, 0.571841, 0.493951, -0.654989, +1.002737, -16.806824, 0.450041, 2.000000, 4.706708, 0.570721, 0.333495, -0.750372, +1.336982, -17.125900, 1.021948, 2.500000, 4.706708, 0.998755, -0.017888, 0.046575, +1.336982, -12.461710, 1.998980, 2.500000, 4.382352, 0.999581, -0.002143, 0.028884, +1.002737, -12.539209, 2.645355, 3.000000, 4.382352, 0.529316, -0.059790, 0.846315, +1.002737, -15.037928, 2.333167, 3.000000, 4.557891, 0.524224, -0.178780, 0.832603, +1.002737, -15.037928, 2.333167, 3.000000, 4.557891, 0.524224, -0.178780, 0.832603, +1.002737, -17.444981, 1.593854, 3.000000, 4.706708, 0.523473, -0.350048, 0.776815, +1.336982, -17.125900, 1.021948, 2.500000, 4.706708, 0.998755, -0.017888, 0.046575, +1.336982, -17.125900, 1.021948, 2.500000, 4.706708, 0.998755, -0.017888, 0.046575, +1.002737, -16.806824, 0.450041, 2.000000, 4.706708, 0.570721, 0.333495, -0.750372, +1.002737, -14.635897, 1.095908, 2.000000, 4.557891, 0.560822, 0.165222, -0.811283, +1.002737, -14.635897, 1.095908, 2.000000, 4.557891, 0.560822, 0.165222, -0.811283, +1.002737, -12.384212, 1.352605, 2.000000, 4.382352, 0.556840, 0.051516, -0.829021, +1.336982, -12.461710, 1.998980, 2.500000, 4.382352, 0.999581, -0.002143, 0.028884, +1.336982, -8.028582, 1.726443, 2.500000, 3.977933, 0.998903, 0.011916, 0.045285, +1.002737, -7.868385, 2.366725, 3.000000, 3.977933, 0.526810, 0.210598, 0.823480, +1.002737, -10.101929, 2.681329, 3.000000, 4.189068, 0.529646, 0.050516, 0.846713, +1.002737, -10.101929, 2.681329, 3.000000, 4.189068, 0.529646, 0.050516, 0.846713, +1.002737, -12.539209, 2.645355, 3.000000, 4.382352, 0.529316, -0.059790, 0.846315, +1.336982, -12.461710, 1.998980, 2.500000, 4.382352, 0.999581, -0.002143, 0.028884, +1.336982, -12.461710, 1.998980, 2.500000, 4.382352, 0.999581, -0.002143, 0.028884, +1.002737, -12.384212, 1.352605, 2.000000, 4.382352, 0.556840, 0.051516, -0.829021, +1.002737, -10.193325, 1.372527, 2.000000, 4.189068, 0.563923, -0.052320, -0.824168, +1.002737, -10.193325, 1.372527, 2.000000, 4.189068, 0.563923, -0.052320, -0.824168, +1.002737, -8.188779, 1.086162, 2.000000, 3.977933, 0.571796, -0.203921, -0.794648, +1.336982, -8.028582, 1.726443, 2.500000, 3.977933, 0.998903, 0.011916, 0.045285, +1.336982, -4.681401, -0.053863, 2.500000, 3.518014, 0.999076, 0.030579, 0.030219, +1.002737, -4.339529, 0.487975, 3.000000, 3.518014, 0.515414, 0.553092, 0.654552, +1.002737, -5.980879, 1.627182, 3.000000, 3.748844, 0.522693, 0.400366, 0.752661, +1.002737, -5.980879, 1.627182, 3.000000, 3.748844, 0.522693, 0.400366, 0.752661, +1.002737, -7.868385, 2.366725, 3.000000, 3.977933, 0.526810, 0.210598, 0.823480, +1.336982, -8.028582, 1.726443, 2.500000, 3.977933, 0.998903, 0.011916, 0.045285, +1.336982, -8.028582, 1.726443, 2.500000, 3.977933, 0.998903, 0.011916, 0.045285, +1.002737, -8.188779, 1.086162, 2.000000, 3.977933, 0.571796, -0.203921, -0.794648, +1.002737, -6.496116, 0.423996, 2.000000, 3.748844, 0.567467, -0.386666, -0.726960, +1.002737, -6.496116, 0.423996, 2.000000, 3.748844, 0.567467, -0.386666, -0.726960, +1.002737, -5.023273, -0.595701, 2.000000, 3.518014, 0.554291, -0.537252, -0.635706, +1.336982, -4.681401, -0.053863, 2.500000, 3.518014, 0.999076, 0.030579, 0.030219, +1.336982, -2.032627, -3.152670, 2.500000, 3.096704, 0.999446, 0.028671, 0.016899, +1.002737, -1.550435, -2.775177, 3.000000, 3.096704, 0.505988, 0.723592, 0.469458, +1.002737, -2.844458, -1.025621, 3.000000, 3.301661, 0.509526, 0.653879, 0.559309, +1.002737, -2.844458, -1.025621, 3.000000, 3.301661, 0.509526, 0.653879, 0.559309, +1.002737, -4.339529, 0.487975, 3.000000, 3.518014, 0.515414, 0.553092, 0.654552, +1.336982, -4.681401, -0.053863, 2.500000, 3.518014, 0.999076, 0.030579, 0.030219, +1.336982, -4.681401, -0.053863, 2.500000, 3.518014, 0.999076, 0.030579, 0.030219, +1.002737, -5.023273, -0.595701, 2.000000, 3.518014, 0.554291, -0.537252, -0.635706, +1.002737, -3.678185, -1.954659, 2.000000, 3.301661, 0.541785, -0.639146, -0.545858, +1.002737, -3.678185, -1.954659, 2.000000, 3.301661, 0.541785, -0.639146, -0.545858, +1.002737, -2.514818, -3.530164, 2.000000, 3.096704, 0.535283, -0.710141, -0.457354, +1.336982, -2.032627, -3.152670, 2.500000, 3.096704, 0.999446, 0.028671, 0.016899, +1.336982, -0.371475, -6.820555, 2.500000, 2.714038, 0.999079, 0.041649, 0.010372, +1.002737, 0.212362, -6.622896, 3.000000, 2.714038, 0.505651, 0.835716, 0.214230, +1.002737, -0.512230, -4.622262, 3.000000, 2.900065, 0.503207, 0.785549, 0.360132, +1.002737, -0.512230, -4.622262, 3.000000, 2.900065, 0.503207, 0.785549, 0.360132, +1.002737, -1.550435, -2.775177, 3.000000, 3.096704, 0.505988, 0.723592, 0.469458, +1.336982, -2.032627, -3.152670, 2.500000, 3.096704, 0.999446, 0.028671, 0.016899, +1.336982, -2.032627, -3.152670, 2.500000, 3.096704, 0.999446, 0.028671, 0.016899, +1.002737, -2.514818, -3.530164, 2.000000, 3.096704, 0.535283, -0.710141, -0.457354, +1.002737, -1.587135, -5.199499, 2.000000, 2.900065, 0.538039, -0.769598, -0.343850, +1.002737, -1.587135, -5.199499, 2.000000, 2.900065, 0.538039, -0.769598, -0.343850, +1.002737, -0.955311, -7.018215, 2.000000, 2.714038, 0.543591, -0.816934, -0.192683, +1.336982, -0.371475, -6.820555, 2.500000, 2.714038, 0.999079, 0.041649, 0.010372, +1.336982, -0.183937, -11.115767, 2.500000, 2.371212, 0.999002, 0.043336, -0.010816, +1.002737, 0.467394, -11.098533, 3.000000, 2.371212, 0.517497, 0.844529, -0.137721, +1.002737, 0.565540, -8.833092, 3.000000, 2.540917, 0.512670, 0.857168, 0.049331, +1.002737, 0.565540, -8.833092, 3.000000, 2.540917, 0.512670, 0.857168, 0.049331, +1.002737, 0.212362, -6.622896, 3.000000, 2.714038, 0.505651, 0.835716, 0.214230, +1.336982, -0.371475, -6.820555, 2.500000, 2.714038, 0.999079, 0.041649, 0.010372, +1.336982, -0.371475, -6.820555, 2.500000, 2.714038, 0.999079, 0.041649, 0.010372, +1.002737, -0.955311, -7.018215, 2.000000, 2.714038, 0.543591, -0.816934, -0.192683, +1.002737, -0.679521, -9.041862, 2.000000, 2.540917, 0.550509, -0.834486, -0.023924, +1.002737, -0.679521, -9.041862, 2.000000, 2.540917, 0.550509, -0.834486, -0.023924, +1.002737, -0.835270, -11.133000, 2.000000, 2.371212, 0.556778, -0.814518, 0.162970, +1.336982, -0.183937, -11.115767, 2.500000, 2.371212, 0.999002, 0.043336, -0.010816, +1.336982, -1.762512, -15.300098, 2.500000, 2.020624, 0.999977, 0.006790, -0.000522, +1.002737, -1.085560, -15.409132, 3.000000, 2.020624, 0.545979, 0.767296, -0.336399, +1.002737, -0.161999, -13.264900, 3.000000, 2.195430, 0.528455, 0.798898, -0.287224, +1.002737, -0.161999, -13.264900, 3.000000, 2.195430, 0.528455, 0.798898, -0.287224, +1.002737, 0.467394, -11.098533, 3.000000, 2.371212, 0.517497, 0.844529, -0.137721, +1.336982, -0.183937, -11.115767, 2.500000, 2.371212, 0.999002, 0.043336, -0.010816, +1.336982, -0.183937, -11.115767, 2.500000, 2.371212, 0.999002, 0.043336, -0.010816, +1.002737, -0.835270, -11.133000, 2.000000, 2.371212, 0.556778, -0.814518, 0.162970, +1.002737, -1.498060, -13.154191, 2.000000, 2.195430, 0.550846, -0.775955, 0.307348, +1.002737, -1.498060, -13.154191, 2.000000, 2.195430, 0.550846, -0.775955, 0.307348, +1.002737, -2.439466, -15.191065, 2.000000, 2.020624, 0.552162, -0.756556, 0.350343, +1.336982, -1.762512, -15.300098, 2.500000, 2.020624, 0.999977, 0.006790, -0.000522, +1.336982, -3.677238, -19.700720, 2.500000, 1.696742, 0.999943, -0.009227, 0.005371, +1.002737, -2.990782, -19.848455, 3.000000, 1.696742, 0.573541, 0.767561, -0.286181, +1.002737, -2.066217, -17.608171, 3.000000, 1.853850, 0.561407, 0.760416, -0.326481, +1.002737, -2.066217, -17.608171, 3.000000, 1.853850, 0.561407, 0.760416, -0.326481, +1.002737, -1.085560, -15.409132, 3.000000, 2.020624, 0.545979, 0.767296, -0.336399, +1.336982, -1.762512, -15.300098, 2.500000, 2.020624, 0.999977, 0.006790, -0.000522, +1.336982, -1.762512, -15.300098, 2.500000, 2.020624, 0.999977, 0.006790, -0.000522, +1.002737, -2.439466, -15.191065, 2.000000, 2.020624, 0.552162, -0.756556, 0.350343, +1.002737, -3.431055, -17.329250, 2.000000, 1.853850, 0.559291, -0.758482, 0.334513, +1.002737, -3.431055, -17.329250, 2.000000, 1.853850, 0.559291, -0.758482, 0.334513, +1.002737, -4.363696, -19.552979, 2.000000, 1.696742, 0.563275, -0.773529, 0.290474, +1.336982, -3.677238, -19.700720, 2.500000, 1.696742, 0.999943, -0.009227, 0.005371, +1.336982, -4.998410, -24.141369, 2.500000, 1.417808, 0.999879, -0.015055, 0.003873, +1.002737, -4.302059, -24.249632, 3.000000, 1.417808, 0.582444, 0.793471, -0.176531, +1.002737, -3.746061, -22.116426, 3.000000, 1.550938, 0.578794, 0.781497, -0.232937, +1.002737, -3.746061, -22.116426, 3.000000, 1.550938, 0.578794, 0.781497, -0.232937, +1.002737, -2.990782, -19.848455, 3.000000, 1.696742, 0.573541, 0.767561, -0.286181, +1.336982, -3.677238, -19.700720, 2.500000, 1.696742, 0.999943, -0.009227, 0.005371, +1.336982, -3.677238, -19.700720, 2.500000, 1.696742, 0.999943, -0.009227, 0.005371, +1.002737, -4.363696, -19.552979, 2.000000, 1.696742, 0.563275, -0.773529, 0.290474, +1.002737, -5.128252, -21.846479, 2.000000, 1.550938, 0.566340, -0.790066, 0.234638, +1.002737, -5.128252, -21.846479, 2.000000, 1.550938, 0.566340, -0.790066, 0.234638, +1.002737, -5.694758, -24.033106, 2.000000, 1.417808, 0.566494, -0.804616, 0.177981, +1.336982, -4.998410, -24.141369, 2.500000, 1.417808, 0.999879, -0.015055, 0.003873, +1.336982, -5.505962, -27.491592, 2.500000, 1.186658, 0.999932, -0.011526, 0.001722, +1.002737, -4.798269, -27.533844, 3.000000, 1.186658, 0.583019, 0.808019, -0.084825, +1.002737, -4.628780, -26.085621, 3.000000, 1.298722, 0.582983, 0.803361, -0.121414, +1.002737, -4.628780, -26.085621, 3.000000, 1.298722, 0.582983, 0.803361, -0.121414, +1.002737, -4.302059, -24.249632, 3.000000, 1.417808, 0.582444, 0.793471, -0.176531, +1.336982, -4.998410, -24.141369, 2.500000, 1.417808, 0.999879, -0.015055, 0.003873, +1.336982, -4.998410, -24.141369, 2.500000, 1.417808, 0.999879, -0.015055, 0.003873, +1.002737, -5.694758, -24.033106, 2.000000, 1.417808, 0.566494, -0.804616, 0.177981, +1.002737, -6.033253, -25.936216, 2.000000, 1.298722, 0.568446, -0.813396, 0.123515, +1.002737, -6.033253, -25.936216, 2.000000, 1.298722, 0.568446, -0.813396, 0.123515, +1.002737, -6.213656, -27.449341, 2.000000, 1.186658, 0.570758, -0.816393, 0.087968, +1.336982, -5.505962, -27.491592, 2.500000, 1.186658, 0.999932, -0.011526, 0.001722, +1.002737, -4.882575, -28.503754, 2.500000, 1.053028, 0.589040, 0.805067, -0.069986, +1.002737, -4.798269, -27.533844, 3.000000, 1.053028, 0.583019, 0.808019, -0.084825, +1.336982, -5.505962, -27.491592, 3.000000, 1.119843, 0.999932, -0.011526, 0.001722, +1.336982, -5.505962, -27.491592, 3.000000, 1.119843, 0.999932, -0.011526, 0.001722, +1.002737, -6.213656, -27.449341, 3.000000, 1.186658, 0.570758, -0.816393, 0.087968, +1.002737, -6.305892, -28.466030, 2.500000, 1.186658, 0.565626, -0.821288, 0.074517, +0.000000, -23.748404, -4.519603, 3.000000, 1.026514, -0.000000, -0.884854, 0.465869, +-1.002737, -23.539934, -4.622173, 3.000000, 1.053028, -0.559738, -0.733607, 0.385376, +-1.002737, -24.101816, -5.795360, 2.500000, 1.053028, -0.571338, -0.788867, 0.226409, +-1.002737, -24.101816, -5.795360, 2.500000, 1.053028, -0.571338, -0.788867, 0.226409, +-0.742768, -24.152987, -6.401496, 2.000000, 1.053028, -0.455754, -0.834431, -0.309862, +0.000000, -24.406044, -6.530420, 2.000000, 1.026514, 0.000000, -0.933376, -0.358900, +0.000000, -24.406044, -6.530420, 2.000000, 1.026514, 0.000000, -0.933376, -0.358900, +0.742768, -24.152987, -6.401496, 2.000000, 1.000000, 0.455754, -0.834430, -0.309862, +1.002737, -24.101816, -5.795360, 2.500000, 1.000000, 0.571338, -0.788867, 0.226409, +1.002737, -24.101816, -5.795360, 2.500000, 1.000000, 0.571338, -0.788867, 0.226409, +1.002737, -23.539934, -4.622173, 3.000000, 1.000000, 0.559738, -0.733607, 0.385376, +0.000000, -23.748404, -4.519603, 3.000000, 1.026514, -0.000000, -0.884854, 0.465869, +0.000000, -21.564705, -1.218530, 3.500000, 4.901888, 0.000000, -0.737549, 0.675293, +-1.002737, -21.393009, -1.363454, 4.000000, 4.915090, -0.538985, -0.621423, 0.568620, +-1.002737, -22.670450, -3.070609, 4.000000, 4.957545, -0.549531, -0.697669, 0.459646, +-1.002737, -22.670450, -3.070609, 4.000000, 4.957545, -0.549531, -0.697669, 0.459646, +-1.002737, -23.539934, -4.622173, 4.000000, 5.000000, -0.559738, -0.733607, 0.385376, +0.000000, -23.748404, -4.519603, 3.500000, 5.000000, -0.000000, -0.884854, 0.465869, +0.000000, -23.748404, -4.519603, 3.500000, 5.000000, -0.000000, -0.884854, 0.465869, +1.002737, -23.539934, -4.622173, 3.000000, 5.000000, 0.559738, -0.733607, 0.385376, +1.002737, -22.670450, -3.070609, 3.000000, 4.957545, 0.549531, -0.697669, 0.459646, +1.002737, -22.670450, -3.070609, 3.000000, 4.957545, 0.549531, -0.697669, 0.459646, +1.002737, -21.393009, -1.363454, 3.000000, 4.901887, 0.538985, -0.621423, 0.568620, +0.000000, -21.564705, -1.218530, 3.500000, 4.901888, 0.000000, -0.737549, 0.675293, +0.000000, -17.551340, 1.784490, 3.500000, 4.706708, -0.000000, -0.412059, 0.911157, +-1.002737, -17.444981, 1.593854, 4.000000, 4.724558, -0.523473, -0.350048, 0.776815, +-1.002737, -19.607264, 0.276508, 4.000000, 4.819824, -0.531663, -0.507888, 0.677779, +-1.002737, -19.607264, 0.276508, 4.000000, 4.819824, -0.531663, -0.507888, 0.677779, +-1.002737, -21.393009, -1.363454, 4.000000, 4.915090, -0.538985, -0.621423, 0.568620, +0.000000, -21.564705, -1.218530, 3.500000, 4.901888, 0.000000, -0.737549, 0.675293, +0.000000, -21.564705, -1.218530, 3.500000, 4.901888, 0.000000, -0.737549, 0.675293, +1.002737, -21.393009, -1.363454, 3.000000, 4.901887, 0.538985, -0.621423, 0.568620, +1.002737, -19.607264, 0.276508, 3.000000, 4.819824, 0.531663, -0.507888, 0.677779, +1.002737, -19.607264, 0.276508, 3.000000, 4.819824, 0.531663, -0.507888, 0.677779, +1.002737, -17.444981, 1.593854, 3.000000, 4.706708, 0.523473, -0.350048, 0.776815, +0.000000, -17.551340, 1.784490, 3.500000, 4.706708, -0.000000, -0.412059, 0.911157, +0.000000, -12.565042, 2.860814, 3.500000, 4.382352, -0.000000, -0.071332, 0.997453, +-1.002737, -12.539209, 2.645355, 4.000000, 4.391225, -0.529316, -0.059790, 0.846315, +-1.002737, -15.037928, 2.333167, 4.000000, 4.557892, -0.524224, -0.178780, 0.832603, +-1.002737, -15.037928, 2.333167, 4.000000, 4.557892, -0.524224, -0.178780, 0.832603, +-1.002737, -17.444981, 1.593854, 4.000000, 4.724558, -0.523473, -0.350048, 0.776815, +0.000000, -17.551340, 1.784490, 3.500000, 4.706708, -0.000000, -0.412059, 0.911157, +0.000000, -17.551340, 1.784490, 3.500000, 4.706708, -0.000000, -0.412059, 0.911157, +1.002737, -17.444981, 1.593854, 3.000000, 4.706708, 0.523473, -0.350048, 0.776815, +1.002737, -15.037928, 2.333167, 3.000000, 4.557891, 0.524224, -0.178780, 0.832603, +1.002737, -15.037928, 2.333167, 3.000000, 4.557891, 0.524224, -0.178780, 0.832603, +1.002737, -12.539209, 2.645355, 3.000000, 4.382352, 0.529316, -0.059790, 0.846315, +0.000000, -12.565042, 2.860814, 3.500000, 4.382352, -0.000000, -0.071332, 0.997453, +0.000000, -7.814985, 2.580152, 3.500000, 3.977933, -0.000000, 0.247588, 0.968866, +-1.002737, -7.868385, 2.366725, 4.000000, 3.986911, -0.526810, 0.210598, 0.823480, +-1.002737, -10.101929, 2.681329, 4.000000, 4.189068, -0.529646, 0.050516, 0.846713, +-1.002737, -10.101929, 2.681329, 4.000000, 4.189068, -0.529646, 0.050516, 0.846713, +-1.002737, -12.539209, 2.645355, 4.000000, 4.391225, -0.529316, -0.059790, 0.846315, +0.000000, -12.565042, 2.860814, 3.500000, 4.382352, -0.000000, -0.071332, 0.997453, +0.000000, -12.565042, 2.860814, 3.500000, 4.382352, -0.000000, -0.071332, 0.997453, +1.002737, -12.539209, 2.645355, 3.000000, 4.382352, 0.529316, -0.059790, 0.846315, +1.002737, -10.101929, 2.681329, 3.000000, 4.189068, 0.529646, 0.050516, 0.846713, +1.002737, -10.101929, 2.681329, 3.000000, 4.189068, 0.529646, 0.050516, 0.846713, +1.002737, -7.868385, 2.366725, 3.000000, 3.977933, 0.526810, 0.210598, 0.823480, +0.000000, -7.814985, 2.580152, 3.500000, 3.977933, -0.000000, 0.247588, 0.968866, +0.000000, -4.225573, 0.668588, 3.500000, 3.518014, -0.000000, 0.644556, 0.764557, +-1.002737, -4.339529, 0.487975, 4.000000, 3.510776, -0.515414, 0.553092, 0.654552, +-1.002737, -5.980879, 1.627182, 4.000000, 3.748844, -0.522694, 0.400366, 0.752661, +-1.002737, -5.980879, 1.627182, 4.000000, 3.748844, -0.522694, 0.400366, 0.752661, +-1.002737, -7.868385, 2.366725, 4.000000, 3.986911, -0.526810, 0.210598, 0.823480, +0.000000, -7.814985, 2.580152, 3.500000, 3.977933, -0.000000, 0.247588, 0.968866, +0.000000, -7.814985, 2.580152, 3.500000, 3.977933, -0.000000, 0.247588, 0.968866, +1.002737, -7.868385, 2.366725, 3.000000, 3.977933, 0.526810, 0.210598, 0.823480, +1.002737, -5.980879, 1.627182, 3.000000, 3.748844, 0.522693, 0.400366, 0.752661, +1.002737, -5.980879, 1.627182, 3.000000, 3.748844, 0.522693, 0.400366, 0.752661, +1.002737, -4.339529, 0.487975, 3.000000, 3.518014, 0.515414, 0.553092, 0.654552, +0.000000, -4.225573, 0.668588, 3.500000, 3.518014, -0.000000, 0.644556, 0.764557, +0.000000, -1.389704, -2.649346, 3.500000, 3.096704, 0.000000, 0.838537, 0.544844, +-1.002737, -1.550434, -2.775177, 4.000000, 3.092546, -0.505987, 0.723592, 0.469458, +-1.002737, -2.844458, -1.025621, 4.000000, 3.301661, -0.509526, 0.653879, 0.559309, +-1.002737, -2.844458, -1.025621, 4.000000, 3.301661, -0.509526, 0.653879, 0.559309, +-1.002737, -4.339529, 0.487975, 4.000000, 3.510776, -0.515414, 0.553092, 0.654552, +0.000000, -4.225573, 0.668588, 3.500000, 3.518014, -0.000000, 0.644556, 0.764557, +0.000000, -4.225573, 0.668588, 3.500000, 3.518014, -0.000000, 0.644556, 0.764557, +1.002737, -4.339529, 0.487975, 3.000000, 3.518014, 0.515414, 0.553092, 0.654552, +1.002737, -2.844458, -1.025621, 3.000000, 3.301661, 0.509526, 0.653879, 0.559309, +1.002737, -2.844458, -1.025621, 3.000000, 3.301661, 0.509526, 0.653879, 0.559309, +1.002737, -1.550435, -2.775177, 3.000000, 3.096704, 0.505988, 0.723592, 0.469458, +0.000000, -1.389704, -2.649346, 3.500000, 3.096704, 0.000000, 0.838537, 0.544844, +0.000000, 0.406973, -6.557009, 3.500000, 2.714038, -0.000000, 0.968208, 0.250145, +-1.002737, 0.212360, -6.622896, 4.000000, 2.707584, -0.505652, 0.835716, 0.214230, +-1.002737, -0.512230, -4.622262, 4.000000, 2.900065, -0.503207, 0.785550, 0.360132, +-1.002737, -0.512230, -4.622262, 4.000000, 2.900065, -0.503207, 0.785550, 0.360132, +-1.002737, -1.550434, -2.775177, 4.000000, 3.092546, -0.505987, 0.723592, 0.469458, +0.000000, -1.389704, -2.649346, 3.500000, 3.096704, 0.000000, 0.838537, 0.544844, +0.000000, -1.389704, -2.649346, 3.500000, 3.096704, 0.000000, 0.838537, 0.544844, +1.002737, -1.550435, -2.775177, 3.000000, 3.096704, 0.505988, 0.723592, 0.469458, +1.002737, -0.512230, -4.622262, 3.000000, 2.900065, 0.503207, 0.785549, 0.360132, +1.002737, -0.512230, -4.622262, 3.000000, 2.900065, 0.503207, 0.785549, 0.360132, +1.002737, 0.212362, -6.622896, 3.000000, 2.714038, 0.505651, 0.835716, 0.214230, +0.000000, 0.406973, -6.557009, 3.500000, 2.714038, -0.000000, 0.968208, 0.250145, +0.000000, 0.684505, -11.092790, 3.500000, 2.371212, 0.000000, 0.987685, -0.156457, +-1.002737, 0.467394, -11.098533, 4.000000, 2.374251, -0.517497, 0.844529, -0.137721, +-1.002737, 0.565540, -8.833092, 4.000000, 2.540917, -0.512670, 0.857167, 0.049331, +-1.002737, 0.565540, -8.833092, 4.000000, 2.540917, -0.512670, 0.857167, 0.049331, +-1.002737, 0.212360, -6.622896, 4.000000, 2.707584, -0.505652, 0.835716, 0.214230, +0.000000, 0.406973, -6.557009, 3.500000, 2.714038, -0.000000, 0.968208, 0.250145, +0.000000, 0.406973, -6.557009, 3.500000, 2.714038, -0.000000, 0.968208, 0.250145, +1.002737, 0.212362, -6.622896, 3.000000, 2.714038, 0.505651, 0.835716, 0.214230, +1.002737, 0.565540, -8.833092, 3.000000, 2.540917, 0.512670, 0.857168, 0.049331, +1.002737, 0.565540, -8.833092, 3.000000, 2.540917, 0.512670, 0.857168, 0.049331, +1.002737, 0.467394, -11.098533, 3.000000, 2.371212, 0.517497, 0.844529, -0.137721, +0.000000, 0.684505, -11.092790, 3.500000, 2.371212, 0.000000, 0.987685, -0.156457, +0.000000, -0.859908, -15.445475, 3.500000, 2.020624, 0.000000, 0.916600, -0.399806, +-1.002737, -1.085560, -15.409132, 4.000000, 2.016609, -0.545979, 0.767296, -0.336399, +-1.002737, -0.161999, -13.264900, 4.000000, 2.195430, -0.528455, 0.798898, -0.287224, +-1.002737, -0.161999, -13.264900, 4.000000, 2.195430, -0.528455, 0.798898, -0.287224, +-1.002737, 0.467394, -11.098533, 4.000000, 2.374251, -0.517497, 0.844529, -0.137721, +0.000000, 0.684505, -11.092790, 3.500000, 2.371212, 0.000000, 0.987685, -0.156457, +0.000000, 0.684505, -11.092790, 3.500000, 2.371212, 0.000000, 0.987685, -0.156457, +1.002737, 0.467394, -11.098533, 3.000000, 2.371212, 0.517497, 0.844529, -0.137721, +1.002737, -0.161999, -13.264900, 3.000000, 2.195430, 0.528455, 0.798898, -0.287224, +1.002737, -0.161999, -13.264900, 3.000000, 2.195430, 0.528455, 0.798898, -0.287224, +1.002737, -1.085560, -15.409132, 3.000000, 2.020624, 0.545979, 0.767296, -0.336399, +0.000000, -0.859908, -15.445475, 3.500000, 2.020624, 0.000000, 0.916600, -0.399806, +0.000000, -2.761963, -19.897703, 3.500000, 1.696742, 0.000000, 0.936891, -0.349623, +-1.002737, -2.990782, -19.848455, 4.000000, 1.691091, -0.573541, 0.767562, -0.286181, +-1.002737, -2.066217, -17.608171, 4.000000, 1.853850, -0.561407, 0.760416, -0.326481, +-1.002737, -2.066217, -17.608171, 4.000000, 1.853850, -0.561407, 0.760416, -0.326481, +-1.002737, -1.085560, -15.409132, 4.000000, 2.016609, -0.545979, 0.767296, -0.336399, +0.000000, -0.859908, -15.445475, 3.500000, 2.020624, 0.000000, 0.916600, -0.399806, +0.000000, -0.859908, -15.445475, 3.500000, 2.020624, 0.000000, 0.916600, -0.399806, +1.002737, -1.085560, -15.409132, 3.000000, 2.020624, 0.545979, 0.767296, -0.336399, +1.002737, -2.066217, -17.608171, 3.000000, 1.853850, 0.561407, 0.760416, -0.326481, +1.002737, -2.066217, -17.608171, 3.000000, 1.853850, 0.561407, 0.760416, -0.326481, +1.002737, -2.990782, -19.848455, 3.000000, 1.696742, 0.573541, 0.767561, -0.286181, +0.000000, -2.761963, -19.897703, 3.500000, 1.696742, 0.000000, 0.936891, -0.349623, +0.000000, -4.069942, -24.285717, 3.500000, 1.417808, 0.000000, 0.976057, -0.217516, +-1.002737, -4.302059, -24.249632, 4.000000, 1.410785, -0.582444, 0.793471, -0.176531, +-1.002737, -3.746061, -22.116426, 4.000000, 1.550938, -0.578794, 0.781497, -0.232937, +-1.002737, -3.746061, -22.116426, 4.000000, 1.550938, -0.578794, 0.781497, -0.232937, +-1.002737, -2.990782, -19.848455, 4.000000, 1.691091, -0.573541, 0.767562, -0.286181, +0.000000, -2.761963, -19.897703, 3.500000, 1.696742, 0.000000, 0.936891, -0.349623, +0.000000, -2.761963, -19.897703, 3.500000, 1.696742, 0.000000, 0.936891, -0.349623, +1.002737, -2.990782, -19.848455, 3.000000, 1.696742, 0.573541, 0.767561, -0.286181, +1.002737, -3.746061, -22.116426, 3.000000, 1.550938, 0.578794, 0.781497, -0.232937, +1.002737, -3.746061, -22.116426, 3.000000, 1.550938, 0.578794, 0.781497, -0.232937, +1.002737, -4.302059, -24.249632, 3.000000, 1.417808, 0.582444, 0.793471, -0.176531, +0.000000, -4.069942, -24.285717, 3.500000, 1.417808, 0.000000, 0.976057, -0.217516, +0.000000, -4.562372, -27.547928, 3.500000, 1.186658, 0.000000, 0.994554, -0.104226, +-1.002737, -4.798269, -27.533844, 4.000000, 1.186658, -0.583018, 0.808019, -0.084825, +-1.002737, -4.628780, -26.085621, 4.000000, 1.298722, -0.582983, 0.803361, -0.121414, +-1.002737, -4.628780, -26.085621, 4.000000, 1.298722, -0.582983, 0.803361, -0.121414, +-1.002737, -4.302059, -24.249632, 4.000000, 1.410785, -0.582444, 0.793471, -0.176531, +0.000000, -4.069942, -24.285717, 3.500000, 1.417808, 0.000000, 0.976057, -0.217516, +0.000000, -4.069942, -24.285717, 3.500000, 1.417808, 0.000000, 0.976057, -0.217516, +1.002737, -4.302059, -24.249632, 3.000000, 1.417808, 0.582444, 0.793471, -0.176531, +1.002737, -4.628780, -26.085621, 3.000000, 1.298722, 0.582983, 0.803361, -0.121414, +1.002737, -4.628780, -26.085621, 3.000000, 1.298722, 0.582983, 0.803361, -0.121414, +1.002737, -4.798269, -27.533844, 3.000000, 1.186658, 0.583019, 0.808019, -0.084825, +0.000000, -4.562372, -27.547928, 3.500000, 1.186658, 0.000000, 0.994554, -0.104226, +-1.002737, -4.882575, -28.503754, 3.500000, 1.053028, -0.589040, 0.805068, -0.069986, +-1.002737, -4.798269, -27.533844, 4.000000, 1.053028, -0.583018, 0.808019, -0.084825, +0.000000, -4.562372, -27.547928, 4.000000, 1.119843, 0.000000, 0.994554, -0.104226, +0.000000, -4.562372, -27.547928, 4.000000, 1.119843, 0.000000, 0.994554, -0.104226, +1.002737, -4.798269, -27.533844, 4.000000, 1.186658, 0.583019, 0.808019, -0.084825, +1.002737, -4.882575, -28.503754, 3.500000, 1.186658, 0.589040, 0.805067, -0.069986, +1.010821, 4.753092, -11.679992, 3.500000, 1.000000, 0.576512, -0.780907, 0.240454, +1.014864, 3.544037, -14.721523, 3.000000, 1.000000, 0.562535, -0.748836, 0.350428, +1.349109, 4.237772, -14.807808, 3.000000, 1.026514, 0.999805, 0.015731, -0.011963, +1.349109, 4.237772, -14.807808, 3.000000, 1.026514, 0.999805, 0.015731, -0.011963, +1.014864, 4.931509, -14.894089, 3.000000, 1.053028, 0.545447, 0.762198, -0.348629, +1.010821, 6.148220, -11.777804, 3.500000, 1.053028, 0.548873, 0.801150, -0.238531, +1.010821, 6.148220, -11.777804, 3.500000, 1.053028, 0.548873, 0.801150, -0.238531, +1.004758, 6.770885, -8.754030, 4.000000, 1.053028, 0.549543, 0.833398, -0.058740, +1.339004, 6.071638, -8.749280, 4.000000, 1.026514, 0.999013, 0.044275, -0.003633, +1.339004, 6.071638, -8.749280, 4.000000, 1.026514, 0.999013, 0.044275, -0.003633, +1.004758, 5.372389, -8.744530, 4.000000, 1.000000, 0.594556, -0.801738, 0.060986, +1.010821, 4.753092, -11.679992, 3.500000, 1.000000, 0.576512, -0.780907, 0.240454, +-0.994652, 4.753092, -11.679992, 2.000000, 0.093876, -0.576606, -0.781401, 0.238616, +-0.990610, 3.544037, -14.721523, 2.000000, 0.267209, -0.562098, -0.749029, 0.350717, +0.012127, 3.312792, -14.692760, 2.500000, 0.267209, 0.000169, -0.904592, 0.426279, +0.012127, 3.312792, -14.692760, 2.500000, 0.267209, 0.000169, -0.904592, 0.426279, +1.014864, 3.544037, -14.721523, 3.000000, 0.267209, 0.562535, -0.748836, 0.350428, +1.010821, 4.753092, -11.679992, 3.000000, 0.093875, 0.576512, -0.780907, 0.240454, +1.010821, 4.753092, -11.679992, 3.000000, 0.093875, 0.576512, -0.780907, 0.240454, +1.004758, 5.372389, -8.744530, 3.000000, -0.079458, 0.594556, -0.801738, 0.060986, +0.002021, 5.139305, -8.742946, 2.500000, -0.079458, -0.000101, -0.997122, 0.075814, +0.002021, 5.139305, -8.742946, 2.500000, -0.079458, -0.000101, -0.997122, 0.075814, +-1.000716, 5.372389, -8.744530, 2.000000, -0.079458, -0.594849, -0.801661, 0.059106, +-0.994652, 4.753092, -11.679992, 2.000000, 0.093876, -0.576606, -0.781401, 0.238616, +-0.994652, 6.148220, -11.777804, 1.187500, 0.109894, -0.548576, 0.800857, -0.240193, +-0.990610, 4.931509, -14.894089, 1.000000, 0.267209, -0.544986, 0.762408, -0.348891, +-1.324855, 4.237772, -14.807808, 1.500000, 0.267209, -0.999804, 0.015791, -0.011962, +-1.324855, 4.237772, -14.807808, 1.500000, 0.267209, -0.999804, 0.015791, -0.011962, +-0.990610, 3.544037, -14.721523, 2.000000, 0.267209, -0.562098, -0.749029, 0.350717, +-0.994652, 4.753092, -11.679992, 2.000000, 0.093876, -0.576606, -0.781401, 0.238616, +-0.994652, 4.753092, -11.679992, 2.000000, 0.093876, -0.576606, -0.781401, 0.238616, +-1.000716, 5.372389, -8.744530, 2.000000, -0.079458, -0.594849, -0.801661, 0.059106, +-1.334961, 6.071638, -8.749280, 1.500000, -0.079458, -0.999000, 0.044233, -0.006500, +-1.334961, 6.071638, -8.749280, 1.500000, -0.079458, -0.999000, 0.044233, -0.006500, +-1.000716, 6.770885, -8.754030, 1.000000, -0.079458, -0.549751, 0.833161, -0.060139, +-0.994652, 6.148220, -11.777804, 1.187500, 0.109894, -0.548576, 0.800857, -0.240193, +1.010821, 6.148220, -11.777804, 1.500000, 0.222021, 0.548873, 0.801150, -0.238531, +1.014864, 4.931509, -14.894089, 3.000000, 0.523501, 0.545447, 0.762198, -0.348629, +0.012127, 5.162754, -14.922852, 2.000000, 0.395355, 0.000167, 0.910359, -0.413819, +0.012127, 5.162754, -14.922852, 2.000000, 0.395355, 0.000167, 0.910359, -0.413819, +-0.990610, 4.931509, -14.894089, 1.000000, 0.267209, -0.544986, 0.762408, -0.348891, +-0.994652, 6.148220, -11.777804, 1.187500, 0.109894, -0.548576, 0.800857, -0.240193, +-0.994652, 6.148220, -11.777804, 1.187500, 0.109894, -0.548576, 0.800857, -0.240193, +-1.000716, 6.770885, -8.754030, 1.000000, -0.079458, -0.549751, 0.833161, -0.060139, +0.002021, 7.003967, -8.755614, 0.500000, -0.079458, -0.000102, 0.997541, -0.070087, +0.002021, 7.003967, -8.755614, 0.500000, -0.079458, -0.000102, 0.997541, -0.070087, +1.004758, 6.770885, -8.754030, 0.000000, -0.079458, 0.549543, 0.833398, -0.058740, +1.010821, 6.148220, -11.777804, 1.500000, 0.222021, 0.548873, 0.801150, -0.238531, +-1.002737, 1.949966, 10.301342, 3.000000, 0.093875, -0.548106, -0.827983, 0.118418, +-1.002737, 1.707661, 7.456823, 3.000000, 0.267209, -0.546192, -0.837529, 0.014826, +0.000000, 1.483450, 7.466458, 3.000000, 0.395355, 0.000000, -0.999837, 0.018050, +0.000000, 1.483450, 7.466458, 3.000000, 0.395355, 0.000000, -0.999837, 0.018050, +1.002737, 1.707661, 7.456823, 3.000000, 0.523501, 0.546192, -0.837529, 0.014826, +1.002737, 1.949966, 10.301342, 3.000000, -0.199582, 0.548430, -0.827643, 0.119301, +1.002737, 1.949966, 10.301342, 3.000000, -0.199582, 0.548430, -0.827643, 0.119301, +0.997835, 2.515034, 13.079953, 3.000000, -0.922665, 0.552074, -0.807195, 0.208929, +-0.004902, 2.294706, 13.134627, 3.000000, -0.501061, 0.000247, -0.968748, 0.248048, +-0.004902, 2.294706, 13.134627, 3.000000, -0.501061, 0.000247, -0.968748, 0.248048, +-1.007639, 2.515034, 13.079953, 3.000000, -0.079458, -0.551445, -0.808533, 0.205386, +-1.002737, 1.949966, 10.301342, 3.000000, 0.093875, -0.548106, -0.827983, 0.118418, +-1.002737, 3.286348, 10.103830, 1.187500, -1.435965, -0.570397, 0.812622, -0.119555, +-1.002737, 3.052929, 7.399012, 1.000000, -1.306215, -0.571504, 0.820505, -0.012461, +-1.336982, 2.380295, 7.427917, 1.500000, -1.306215, -0.999670, -0.025705, 0.000199, +-1.336982, 2.380295, 7.427917, 1.500000, -1.306215, -0.999670, -0.025705, 0.000199, +-1.002737, 1.707661, 7.456823, 2.000000, -1.306215, -0.546192, -0.837529, 0.014826, +-1.002737, 1.949966, 10.301342, 2.000000, -1.459937, -0.548106, -0.827983, 0.118418, +-1.002737, 1.949966, 10.301342, 2.000000, -1.459937, -0.548106, -0.827983, 0.118418, +-1.007639, 2.515034, 13.079953, 2.000000, -1.613659, -0.551445, -0.808533, 0.205386, +-1.341885, 3.176014, 12.915927, 1.500000, -1.613659, -0.999798, -0.020077, 0.001135, +-1.341885, 3.176014, 12.915927, 1.500000, -1.613659, -0.999798, -0.020077, 0.001135, +-1.007639, 3.836994, 12.751901, 1.000000, -1.613659, -0.571038, 0.793815, -0.209219, +-1.002737, 3.286348, 10.103830, 1.187500, -1.435965, -0.570397, 0.812622, -0.119555, +1.002737, 3.286348, 10.103830, 1.500000, -1.268162, 0.570686, 0.812576, -0.118478, +1.002737, 3.052929, 7.399012, 3.000000, -0.922665, 0.571504, 0.820504, -0.012461, +0.000000, 3.277142, 7.389376, 2.000000, -1.114440, 0.000000, 0.999891, -0.014768, +0.000000, 3.277142, 7.389376, 2.000000, -1.114440, 0.000000, 0.999891, -0.014768, +-1.002737, 3.052929, 7.399012, 1.000000, -1.306215, -0.571504, 0.820505, -0.012461, +-1.002737, 3.286348, 10.103830, 1.187500, -1.435965, -0.570397, 0.812622, -0.119555, +-1.002737, 3.286348, 10.103830, 1.187500, -1.435965, -0.570397, 0.812622, -0.119555, +-1.007639, 3.836994, 12.751901, 1.000000, -1.613659, -0.571038, 0.793815, -0.209219, +-0.004902, 4.057320, 12.697225, 0.500000, -1.613659, 0.000259, 0.967531, -0.252752, +-0.004902, 4.057320, 12.697225, 0.500000, -1.613659, 0.000259, 0.967531, -0.252752, +0.997834, 3.836994, 12.751901, 0.000000, -1.613659, 0.571655, 0.794480, -0.204969, +1.002737, 3.286348, 10.103830, 1.500000, -1.268162, 0.570686, 0.812576, -0.118478, +1.002737, 1.949966, 10.301342, 3.000000, -1.459937, 0.548430, -0.827643, 0.119301, +1.002737, 1.707661, 7.456823, 3.000000, -1.306215, 0.546192, -0.837529, 0.014826, +1.336982, 2.380295, 7.427917, 3.000000, -1.114440, 0.999670, -0.025705, 0.000199, +1.336982, 2.380295, 7.427917, 3.000000, -1.114440, 0.999670, -0.025705, 0.000199, +1.002737, 3.052929, 7.399012, 3.000000, -0.922665, 0.571504, 0.820504, -0.012461, +1.002737, 3.286348, 10.103830, 2.833333, -1.322391, 0.570686, 0.812576, -0.118478, +1.002737, 3.286348, 10.103830, 2.833333, -1.322391, 0.570686, 0.812576, -0.118478, +0.997834, 3.836994, 12.751901, 2.666667, -1.722117, 0.571655, 0.794480, -0.204969, +1.332080, 3.176014, 12.915927, 2.833333, -1.667888, 0.999801, -0.018232, 0.008046, +1.332080, 3.176014, 12.915927, 2.833333, -1.667888, 0.999801, -0.018232, 0.008046, +0.997835, 2.515034, 13.079953, 3.000000, -1.613659, 0.552074, -0.807195, 0.208929, +1.002737, 1.949966, 10.301342, 3.000000, -1.459937, 0.548430, -0.827643, 0.119301, +0.983128, 5.711351, 20.357510, 2.000000, -1.459937, 0.562328, -0.698593, 0.442442, +0.973323, 4.412262, 18.174875, 2.000000, -1.306215, 0.554281, -0.740975, 0.379115, +1.307569, 5.044981, 17.903212, 2.500000, -1.306215, 0.999751, -0.019683, 0.010530, +1.307569, 5.044981, 17.903212, 2.500000, -1.306215, 0.999751, -0.019683, 0.010530, +0.973323, 5.677700, 17.631544, 3.000000, -1.306215, 0.576561, 0.724323, -0.378066, +0.983128, 6.945759, 19.711123, 3.000000, -1.459937, 0.574803, 0.682785, -0.451006, +0.983128, 6.945759, 19.711123, 3.000000, -1.459937, 0.574803, 0.682785, -0.451006, +0.997834, 8.160118, 21.422651, 3.000000, -1.613659, 0.574744, 0.665807, -0.475784, +1.332080, 7.556932, 21.789433, 2.500000, -1.613659, 0.999977, -0.005048, -0.004524, +1.332080, 7.556932, 21.789433, 2.500000, -1.613659, 0.999977, -0.005048, -0.004524, +0.997835, 6.953747, 22.156214, 2.000000, -1.613659, 0.572743, -0.675634, 0.464203, +0.983128, 5.711351, 20.357510, 2.000000, -1.459937, 0.562328, -0.698593, 0.442442, +-1.022346, 5.711351, 20.357510, 2.000000, -1.857690, -0.562464, -0.695442, 0.447208, +-1.032151, 4.412262, 18.174877, 2.000000, -1.776346, -0.555665, -0.740194, 0.378615, +-0.029414, 4.201355, 18.265430, 2.500000, -1.776346, -0.000535, -0.890739, 0.454514, +-0.029414, 4.201355, 18.265430, 2.500000, -1.776346, -0.000535, -0.890739, 0.454514, +0.973323, 4.412262, 18.174875, 3.000000, -1.776346, 0.554281, -0.740975, 0.379115, +0.983128, 5.711351, 20.357510, 3.000000, -1.857690, 0.562328, -0.698593, 0.442442, +0.983128, 5.711351, 20.357510, 3.000000, -1.857690, 0.562328, -0.698593, 0.442442, +0.997835, 6.953747, 22.156214, 3.000000, -1.939034, 0.572743, -0.675634, 0.464203, +-0.004902, 6.752687, 22.278475, 2.500000, -1.939034, 0.000369, -0.822635, 0.568570, +-0.004902, 6.752687, 22.278475, 2.500000, -1.939034, 0.000369, -0.822635, 0.568570, +-1.007639, 6.953747, 22.156216, 2.000000, -1.939034, -0.571627, -0.672843, 0.469600, +-1.022346, 5.711351, 20.357510, 2.000000, -1.857690, -0.562464, -0.695442, 0.447208, +-1.022346, 6.945759, 19.711123, 1.000000, -1.857690, -0.575450, 0.685898, -0.445422, +-1.032151, 5.677700, 17.631544, 1.000000, -1.776346, -0.577835, 0.723604, -0.377496, +-1.366396, 5.044981, 17.903212, 1.500000, -1.776346, -0.999757, -0.019426, 0.010462, +-1.366396, 5.044981, 17.903212, 1.500000, -1.776346, -0.999757, -0.019426, 0.010462, +-1.032151, 4.412262, 18.174877, 2.000000, -1.776346, -0.555665, -0.740194, 0.378615, +-1.022346, 5.711351, 20.357510, 2.000000, -1.857690, -0.562464, -0.695442, 0.447208, +-1.022346, 5.711351, 20.357510, 2.000000, -1.857690, -0.562464, -0.695442, 0.447208, +-1.007639, 6.953747, 22.156216, 2.000000, -1.939034, -0.571627, -0.672843, 0.469600, +-1.341885, 7.556932, 21.789433, 1.500000, -1.939034, -0.999989, 0.000304, 0.004665, +-1.341885, 7.556932, 21.789433, 1.500000, -1.939034, -0.999989, 0.000304, 0.004665, +-1.007639, 8.160118, 21.422651, 1.000000, -1.939034, -0.574068, 0.669723, -0.471080, +-1.022346, 6.945759, 19.711123, 1.000000, -1.857690, -0.575450, 0.685898, -0.445422, +-1.002737, 8.987209, 23.827108, 1.833333, -1.749232, -0.690086, 0.408969, 0.597098, +-0.742768, 8.411285, 23.925793, 1.000000, -1.776346, -0.485429, -0.281111, 0.827850, +0.000000, 8.401409, 24.234768, 1.000000, -1.857690, -0.000001, -0.291501, 0.956571, +0.000000, 8.401409, 24.234768, 1.000000, -1.857690, -0.000001, -0.291501, 0.956571, +0.742768, 8.411285, 23.925795, 1.000000, -1.939034, 0.485428, -0.281111, 0.827851, +1.002737, 8.987209, 23.827108, 0.500000, -1.939034, 0.690085, 0.408969, 0.597099, +1.002737, 8.987209, 23.827108, 0.500000, -1.939034, 0.690085, 0.408969, 0.597099, +0.742768, 9.282909, 23.329664, 0.000000, -1.939034, 0.487250, 0.872639, 0.032983, +0.000000, 9.573013, 23.419453, 1.333333, -1.830575, -0.000000, 0.997856, 0.065453, +0.000000, 9.573013, 23.419453, 1.333333, -1.830575, -0.000000, 0.997856, 0.065453, +-0.742768, 9.282909, 23.329664, 2.666667, -1.722117, -0.487251, 0.872639, 0.032983, +-1.002737, 8.987209, 23.827108, 1.833333, -1.749232, -0.690086, 0.408969, 0.597098, +0.983128, 6.945759, 19.711123, 1.500000, -2.000000, 0.574803, 0.682785, -0.451006, +0.973323, 5.677700, 17.631544, 2.000000, -2.000000, 0.576561, 0.724323, -0.378066, +-0.029414, 5.888605, 17.540989, 2.500000, -2.000000, -0.000556, 0.885983, -0.463718, +-0.029414, 5.888605, 17.540989, 2.500000, -2.000000, -0.000556, 0.885983, -0.463718, +-1.032151, 5.677700, 17.631544, 3.000000, -2.000000, -0.577835, 0.723604, -0.377496, +-1.022346, 6.945759, 19.711123, 3.500000, -2.000000, -0.575450, 0.685898, -0.445422, +-1.022346, 6.945759, 19.711123, 3.500000, -2.000000, -0.575450, 0.685898, -0.445422, +-1.007639, 8.160118, 21.422651, 4.000000, -2.000000, -0.574068, 0.669723, -0.471080, +-0.004902, 8.361179, 21.300390, 2.500000, -2.000000, 0.000389, 0.815229, -0.579139, +-0.004902, 8.361179, 21.300390, 2.500000, -2.000000, 0.000389, 0.815229, -0.579139, +0.997834, 8.160118, 21.422651, 1.000000, -2.000000, 0.574744, 0.665807, -0.475784, +0.983128, 6.945759, 19.711123, 1.500000, -2.000000, 0.574803, 0.682785, -0.451006, +-1.005175, 11.029587, -4.132468, 3.000000, -1.857690, -0.578521, -0.809497, -0.100142, +-1.006394, 11.114811, -5.517140, 3.000000, -1.776346, -0.583093, -0.812392, -0.004755, +-0.003657, 10.880220, -5.483850, 2.833333, -1.749232, -0.000127, -0.999975, -0.007088, +-0.003657, 10.880220, -5.483850, 2.833333, -1.749232, -0.000127, -0.999975, -0.007088, +0.999079, 11.114811, -5.517140, 2.666667, -1.722117, 0.582792, -0.812607, -0.004817, +1.000299, 11.029585, -4.132468, 3.333333, -1.830575, 0.578319, -0.809495, -0.101318, +1.000299, 11.029585, -4.132468, 3.333333, -1.830575, 0.578319, -0.809495, -0.101318, +1.002127, 10.729588, -2.409474, 4.000000, -1.939034, 0.568931, -0.804350, -0.171283, +-0.000610, 10.494156, -2.383091, 3.500000, -1.939034, 0.000040, -0.977947, -0.208854, +-0.000610, 10.494156, -2.383091, 3.500000, -1.939034, 0.000040, -0.977947, -0.208854, +-1.003346, 10.729588, -2.409474, 3.000000, -1.939034, -0.568927, -0.804482, -0.170679, +-1.005175, 11.029587, -4.132468, 3.000000, -1.857690, -0.578521, -0.809497, -0.100142, +-1.005175, 12.441681, -4.309345, 1.000000, -0.253818, -0.554831, 0.825951, 0.099839, +-1.006394, 12.522362, -5.716876, 1.000000, -0.170915, -0.566040, 0.824377, 0.001632, +-1.340640, 11.818584, -5.617008, 1.500000, -0.170915, -0.999853, 0.017074, 0.001872, +-1.340640, 11.818584, -5.617008, 1.500000, -0.170915, -0.999853, 0.017074, 0.001872, +-1.006394, 11.114811, -5.517140, 2.000000, -0.170915, -0.583093, -0.812392, -0.004755, +-1.005175, 11.029587, -4.132468, 2.000000, -0.253818, -0.578521, -0.809497, -0.100142, +-1.005175, 11.029587, -4.132468, 2.000000, -0.253818, -0.578521, -0.809497, -0.100142, +-1.003346, 10.729588, -2.409474, 2.000000, -0.336720, -0.568927, -0.804482, -0.170679, +-1.337592, 11.435898, -2.488622, 1.500000, -0.336720, -0.999671, 0.024155, 0.008634, +-1.337592, 11.435898, -2.488622, 1.500000, -0.336720, -0.999671, 0.024155, 0.008634, +-1.003346, 12.142200, -2.567771, 1.000000, -0.336720, -0.545383, 0.819886, 0.174196, +-1.005175, 12.441681, -4.309345, 1.000000, -0.253818, -0.554831, 0.825951, 0.099839, +0.000000, 25.158775, 0.885566, 0.666667, -0.891999, 0.000000, 0.098978, -0.995090, +0.742768, 25.130249, 1.141007, 1.333333, -1.447277, 0.424007, 0.088516, -0.901323, +1.002737, 24.600067, 1.327282, 1.166667, -0.809096, 0.595697, -0.491752, -0.635079, +1.002737, 24.600067, 1.327282, 1.166667, -0.809096, 0.595697, -0.491752, -0.635079, +0.742768, 24.296909, 1.783397, 1.000000, -0.170915, 0.428917, -0.894621, -0.125234, +0.000000, 24.041351, 1.768998, 1.000000, -0.253818, 0.000000, -0.991299, -0.131630, +0.000000, 24.041351, 1.768998, 1.000000, -0.253818, 0.000000, -0.991299, -0.131630, +-0.742768, 24.296909, 1.783397, 1.000000, -0.336720, -0.428917, -0.894621, -0.125234, +-1.002737, 24.600067, 1.327282, 0.500000, -0.336720, -0.595697, -0.491752, -0.635079, +-1.002737, 24.600067, 1.327282, 0.500000, -0.336720, -0.595697, -0.491752, -0.635079, +-0.742768, 25.130249, 1.141007, 0.000000, -0.336720, -0.424007, 0.088516, -0.901323, +0.000000, 25.158775, 0.885566, 0.666667, -0.891999, 0.000000, 0.098978, -0.995090, +1.000299, 12.441681, -4.309345, 1.500000, -4.000000, 0.554885, 0.826037, 0.098819, +0.999079, 12.522362, -5.716876, 2.000000, -4.000000, 0.565733, 0.824587, 0.001687, +-0.003657, 12.756954, -5.750165, 2.500000, -4.000000, -0.000126, 1.000000, 0.000870, +-0.003657, 12.756954, -5.750165, 2.500000, -4.000000, -0.000126, 1.000000, 0.000870, +-1.006394, 12.522362, -5.716876, 3.000000, -4.000000, -0.566040, 0.824377, 0.001632, +-1.005175, 12.441681, -4.309345, 3.500000, -4.000000, -0.554831, 0.825951, 0.099839, +-1.005175, 12.441681, -4.309345, 3.500000, -4.000000, -0.554831, 0.825951, 0.099839, +-1.003346, 12.142200, -2.567771, 4.000000, -4.000000, -0.545383, 0.819886, 0.174196, +-0.000610, 12.377636, -2.594154, 2.500000, -4.000000, 0.000041, 0.978486, 0.206311, +-0.000610, 12.377636, -2.594154, 2.500000, -4.000000, 0.000041, 0.978486, 0.206311, +1.002127, 12.142200, -2.567771, 1.000000, -4.000000, 0.545588, 0.819894, 0.173516, +1.000299, 12.441681, -4.309345, 1.500000, -4.000000, 0.554885, 0.826037, 0.098819, +1.000299, 11.029585, -4.132468, 4.000000, -3.848496, 0.578319, -0.809495, -0.101318, +0.999079, 11.114811, -5.517140, 4.000000, -3.761107, 0.582792, -0.812607, -0.004817, +1.333325, 11.818588, -5.617008, 4.000000, -3.594440, 0.999852, 0.017082, 0.001868, +1.333325, 11.818588, -5.617008, 4.000000, -3.594440, 0.999852, 0.017082, 0.001868, +0.999079, 12.522362, -5.716876, 4.000000, -3.427773, 0.565733, 0.824587, 0.001687, +1.000299, 12.441681, -4.309345, 4.000000, -3.234054, 0.554885, 0.826037, 0.098819, +1.000299, 12.441681, -4.309345, 4.000000, -3.234054, 0.554885, 0.826037, 0.098819, +1.002127, 12.142200, -2.567771, 4.000000, -3.040334, 0.545588, 0.819894, 0.173516, +1.336373, 11.435898, -2.488622, 4.000000, -3.488110, 0.999684, 0.024018, 0.007427, +1.336373, 11.435898, -2.488622, 4.000000, -3.488110, 0.999684, 0.024018, 0.007427, +1.002127, 10.729588, -2.409474, 4.000000, -3.935886, 0.568931, -0.804350, -0.171283, +1.000299, 11.029585, -4.132468, 4.000000, -3.848496, 0.578319, -0.809495, -0.101318, +1.002737, -23.736286, -6.771559, 0.500000, 1.053028, 0.633041, -0.276748, -0.722959, +0.742768, -24.152987, -6.401496, 1.000000, 1.053028, 0.455754, -0.834430, -0.309862, +0.000000, -24.406044, -6.530420, 1.500000, 1.053028, 0.000000, -0.933376, -0.358900, +0.000000, -24.406044, -6.530420, 1.500000, 1.053028, 0.000000, -0.933376, -0.358900, +-0.742768, -24.152987, -6.401496, 2.000000, 1.053028, -0.455754, -0.834431, -0.309862, +-1.002737, -23.736286, -6.771559, 4.000000, -0.306819, -0.633041, -0.276747, -0.722959, +-1.002737, -23.736286, -6.771559, 4.000000, -0.306819, -0.633041, -0.276747, -0.722959, +-0.742768, -23.169422, -6.772669, 6.000000, -1.666667, -0.444774, 0.383424, -0.809421, +0.000000, -23.066525, -7.012697, 3.000000, -0.306819, -0.000000, 0.424976, -0.905205, +0.000000, -23.066525, -7.012697, 3.000000, -0.306819, -0.000000, 0.424976, -0.905205, +0.742768, -23.169422, -6.772669, 0.000000, 1.053028, 0.444774, 0.383425, -0.809421, +1.002737, -23.736286, -6.771559, 0.500000, 1.053028, 0.633041, -0.276748, -0.722959, +1.336982, -2.618040, 4.463405, 4.000000, -0.333333, 0.999977, -0.006223, -0.002555, +1.002737, -3.239137, 4.110385, 5.000000, -1.666667, 0.573276, -0.760494, -0.304965, +1.002737, -2.684134, 2.725971, 2.500000, -0.689796, 0.555812, -0.771611, -0.309336, +1.002737, -1.445931, 3.440848, 2.500000, -0.500000, 0.596303, 0.745197, 0.298504, +1.002737, -1.996943, 4.816424, 3.000000, 1.000000, 0.580237, 0.756078, 0.302774, +1.336982, -2.618040, 4.463405, 4.000000, -0.333333, 0.999977, -0.006223, -0.002555, +-1.336982, -0.581338, -32.314465, 0.500000, 0.972854, 0.000000, -0.028514, -0.999593, +-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593, +-1.002737, -1.292564, -32.294178, 1.000000, 0.972854, 0.000000, -0.028512, -0.999593, +-1.336982, 4.212124, -29.503693, 0.500000, 0.966243, 0.000000, -0.038077, -0.999275, +-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275, +-1.002737, 3.502487, -29.476650, 1.000000, 0.966243, 0.000000, -0.038077, -0.999275, +-1.336982, -5.594234, -28.484890, 0.500000, 1.119843, -0.000004, -0.026495, -0.999649, +0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649, +-1.002737, -6.305892, -28.466030, 0.500000, 1.053028, -0.000002, -0.026494, -0.999649, +-1.336982, -2.065033, 3.083410, 3.500000, -1.833333, 0.000000, 0.500000, -0.866025, +0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025, +-1.002737, -2.684134, 2.725971, 3.500000, -1.666667, 0.000000, 0.500000, -0.866025, +1.002737, 0.129889, -32.334755, 2.937500, 0.946466, 0.000002, -0.028517, -0.999593, +1.336982, -0.581338, -32.314465, 2.500000, 0.972854, 0.000000, -0.028517, -0.999593, +-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593, +-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593, +1.336982, -0.581338, -32.314465, 2.500000, 0.972854, 0.000000, -0.028517, -0.999593, +1.002737, -1.292564, -32.294174, 2.000000, 0.972854, 0.000002, -0.028516, -0.999593, +-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593, +1.002737, -1.292564, -32.294174, 2.000000, 0.972854, 0.000002, -0.028516, -0.999593, +0.000000, -1.529640, -32.287415, 1.500000, 0.972854, 0.000002, -0.028513, -0.999593, +-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593, +0.000000, -1.529640, -32.287415, 1.500000, 0.972854, 0.000002, -0.028513, -0.999593, +-1.002737, -1.292564, -32.294178, 1.000000, 0.972854, 0.000000, -0.028512, -0.999593, +-1.002737, 0.129889, -32.334755, 3.500000, 0.761751, -0.000002, -0.028517, -0.999593, +-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593, +-1.336982, -0.581338, -32.314465, 0.500000, 0.972854, 0.000000, -0.028514, -0.999593, +0.000000, 0.366964, -32.341518, 3.250000, 0.867302, 0.000000, -0.028517, -0.999593, +-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593, +-1.002737, 0.129889, -32.334755, 3.500000, 0.761751, -0.000002, -0.028517, -0.999593, +1.002737, 0.129889, -32.334755, 2.937500, 0.946466, 0.000002, -0.028517, -0.999593, +-0.000000, -0.581338, -32.314465, 1.968750, 0.959660, 0.000001, -0.028515, -0.999593, +0.000000, 0.366964, -32.341518, 3.250000, 0.867302, 0.000000, -0.028517, -0.999593, +1.002737, 4.921762, -29.530731, 3.000000, 0.966243, -0.000000, -0.038080, -0.999275, +1.336982, 4.212124, -29.503689, 2.500000, 0.966243, 0.000000, -0.038077, -0.999275, +-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275, +-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275, +1.336982, 4.212124, -29.503689, 2.500000, 0.966243, 0.000000, -0.038077, -0.999275, +1.002737, 3.502487, -29.476650, 2.000000, 0.966243, 0.000000, -0.038075, -0.999275, +-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275, +1.002737, 3.502487, -29.476650, 2.000000, 0.966243, 0.000000, -0.038075, -0.999275, +0.000000, 3.265942, -29.467636, 1.500000, 0.966243, 0.000000, -0.038076, -0.999275, +-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275, +0.000000, 3.265942, -29.467636, 1.500000, 0.966243, 0.000000, -0.038076, -0.999275, +-1.002737, 3.502487, -29.476650, 1.000000, 0.966243, 0.000000, -0.038077, -0.999275, +-1.002737, 4.921762, -29.530731, 4.000000, 0.966243, 0.000000, -0.038077, -0.999275, +-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275, +-1.336982, 4.212124, -29.503693, 0.500000, 0.966243, 0.000000, -0.038077, -0.999275, +0.000000, 5.158308, -29.539745, 3.500000, 0.966243, -0.000000, -0.038080, -0.999275, +-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275, +-1.002737, 4.921762, -29.530731, 4.000000, 0.966243, 0.000000, -0.038077, -0.999275, +1.002737, 4.921762, -29.530731, 3.000000, 0.966243, -0.000000, -0.038080, -0.999275, +-0.000000, 4.212124, -29.503689, 2.000000, 0.966243, -0.000000, -0.038077, -0.999275, +0.000000, 5.158308, -29.539745, 3.500000, 0.966243, -0.000000, -0.038080, -0.999275, +1.002737, -4.882575, -28.503754, 2.500000, 1.053028, -0.000002, -0.026493, -0.999649, +1.336982, -5.594234, -28.484890, 2.500000, 1.119843, 0.000002, -0.026495, -0.999649, +0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649, +0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649, +1.336982, -5.594234, -28.484890, 2.500000, 1.119843, 0.000002, -0.026495, -0.999649, +1.002737, -6.305892, -28.466030, 1.500000, 1.053028, 0.000002, -0.026494, -0.999649, +0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649, +1.002737, -6.305892, -28.466030, 1.500000, 1.053028, 0.000002, -0.026494, -0.999649, +0.000000, -6.543112, -28.459743, 1.500000, 1.119843, 0.000000, -0.026496, -0.999649, +0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649, +0.000000, -6.543112, -28.459743, 1.500000, 1.119843, 0.000000, -0.026496, -0.999649, +-1.002737, -6.305892, -28.466030, 0.500000, 1.053028, -0.000002, -0.026494, -0.999649, +-1.002737, -4.882575, -28.503754, 3.500000, 1.053028, -0.000001, -0.026493, -0.999649, +0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649, +-1.336982, -5.594234, -28.484890, 0.500000, 1.119843, -0.000004, -0.026495, -0.999649, +0.000000, -4.645356, -28.510036, 3.500000, 1.119843, 0.000000, -0.026488, -0.999649, +0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649, +-1.002737, -4.882575, -28.503754, 3.500000, 1.053028, -0.000001, -0.026493, -0.999649, +1.002737, -4.882575, -28.503754, 2.500000, 1.053028, -0.000002, -0.026493, -0.999649, +0.000000, -5.594234, -28.484894, 1.500000, 1.053028, -0.000000, -0.026493, -0.999649, +0.000000, -4.645356, -28.510036, 3.500000, 1.119843, 0.000000, -0.026488, -0.999649, +1.002737, -1.445931, 3.440848, 2.500000, -0.500000, -0.000000, 0.500000, -0.866025, +1.336982, -2.065033, 3.083410, 2.500000, -0.594898, 0.000000, 0.500000, -0.866025, +0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025, +0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025, +1.336982, -2.065033, 3.083410, 2.500000, -0.594898, 0.000000, 0.500000, -0.866025, +1.002737, -2.684134, 2.725971, 4.500000, -1.666667, -0.000000, 0.500000, -0.866025, +0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025, +1.002737, -2.684134, 2.725971, 4.500000, -1.666667, -0.000000, 0.500000, -0.866025, +0.000000, -2.890502, 2.606825, 4.500000, -1.833333, 0.000000, 0.500000, -0.866026, +0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025, +0.000000, -2.890502, 2.606825, 4.500000, -1.833333, 0.000000, 0.500000, -0.866026, +-1.002737, -2.684134, 2.725971, 3.500000, -1.666667, 0.000000, 0.500000, -0.866025, +-1.002737, -1.445931, 3.440848, 2.500000, -1.666667, 0.000000, 0.500000, -0.866025, +0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025, +-1.336982, -2.065033, 3.083410, 3.500000, -1.833333, 0.000000, 0.500000, -0.866025, +0.000000, -1.239565, 3.559994, 2.500000, -1.833333, 0.000000, 0.500000, -0.866025, +0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025, +-1.002737, -1.445931, 3.440848, 2.500000, -1.666667, 0.000000, 0.500000, -0.866025, +1.002737, -1.445931, 3.440848, 2.500000, -0.500000, -0.000000, 0.500000, -0.866025, +0.000000, -2.065034, 3.083410, 3.000000, -1.083333, 0.000000, 0.500000, -0.866025, +0.000000, -1.239565, 3.559994, 2.500000, -1.833333, 0.000000, 0.500000, -0.866025, +4.193409, -2.445326, 32.893612, 3.000000, -0.594415, 0.682263, 0.725032, 0.094055, +0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957, +5.620958, -6.307936, 32.893612, 2.375000, -0.573582, 0.996241, -0.000983, 0.086619, +0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957, +4.193409, -10.256766, 32.893612, 1.972222, -0.557378, 0.680284, -0.725440, 0.104643, +5.620958, -6.307936, 32.893612, 2.375000, -0.573582, 0.996241, -0.000983, 0.086619, +0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957, +0.000000, -11.548096, 32.893612, 1.500000, -0.573582, -0.004203, -0.998166, 0.060395, +4.193409, -10.256766, 32.893612, 1.972222, -0.557378, 0.680284, -0.725440, 0.104643, +0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957, +-4.193409, -10.256766, 32.893612, 1.027778, -0.557378, -0.685012, -0.716396, 0.132421, +0.000000, -11.548096, 32.893612, 1.500000, -0.573582, -0.004203, -0.998166, 0.060395, +-5.620958, -6.307936, 32.893612, 0.625000, -0.573582, -0.991757, -0.001005, 0.128133, +-4.193409, -10.256766, 32.893612, 1.027778, -0.557378, -0.685012, -0.716396, 0.132421, +0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957, +0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957, +-4.193409, -2.445326, 32.893612, 0.000000, -0.594415, -0.686924, 0.716419, 0.121978, +-5.620958, -6.307936, 32.893612, 0.625000, -0.573582, -0.991757, -0.001005, 0.128133, +0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957, +0.000000, -1.067776, 32.893612, 3.500000, -0.594415, -0.004492, 0.998437, 0.055707, +-4.193409, -2.445326, 32.893612, 4.000000, -0.594415, -0.686924, 0.716419, 0.121978, +0.250684, -6.277495, 43.932335, 1.687500, -0.646499, 0.009105, 0.001936, 0.999957, +4.193409, -2.445326, 32.893612, 3.000000, -0.594415, 0.682263, 0.725032, 0.094055, +0.000000, -1.067776, 32.893612, 3.500000, -0.594415, -0.004492, 0.998437, 0.055707, +}; diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.cpp new file mode 100644 index 0000000..61586d8 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.cpp @@ -0,0 +1,351 @@ +// 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. +// +#include "RenderInterface.h" +#include "MeshShaderParam.h" +#include "RenderPlugin.h" + +namespace RenderInterface +{ + +//////////////////////////////////////////////////////////////////////////////////////////// +bool InitDevice(int deviceID) +{ + if (!RenderPlugin::Instance()->InitDevice(deviceID)) + { + MessageBox( 0, L"Could not create device.", L"Error", MB_ICONEXCLAMATION ); + return false; + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +bool GetDeviceInfoString(wchar_t *str) +{ + return RenderPlugin::Instance()->GetDeviceInfoString(str); +} + +////////////////////////////////////////////////////////////////////////// +bool Initialize() +{ + return RenderPlugin::Instance()->Initialize(); +} + +/////////////////////////////////////////////////////////////////////////////// +void Shutdown() +{ + RenderPlugin::Instance()->Shutdown(); +} + +/////////////////////////////////////////////////////////////////////////////// +// gpu buffer management +/////////////////////////////////////////////////////////////////////////////// +GPUBufferResource* CreateVertexBuffer( + unsigned int ByteWidth, void* pSysMem) +{ + return RenderPlugin::Instance()->CreateVertexBuffer(ByteWidth, pSysMem); +} + +/////////////////////////////////////////////////////////////////////////////// +void CopyToDevice( + GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth) +{ + RenderPlugin::Instance()->CopyToDevice(pDevicePtr, pSysMem, ByteWidth); +} + +/////////////////////////////////////////////////////////////////// +// texture resource mangement +/////////////////////////////////////////////////////////////////// +GPUShaderResource* CreateTextureResource(const char* filepath) +{ + return RenderPlugin::Instance()->CreateTextureSRV(filepath); +} + +/////////////////////////////////////////////////////////////////////////////// +void RenderShadowMap(GPUShaderResource* pShadowSRV, float znear, float zfar) +{ + // update constant buffer + ShadowVizParam shaderParam; + { + shaderParam.m_zFar = zfar; + shaderParam.m_zNear = znear; + } + CopyShaderParam(SHADER_TYPE_VISUALIZE_SHADOW, &shaderParam, sizeof(ShadowVizParam), 0); + + RenderPlugin::Instance()->BindPixelShaderResources(0, 1, &pShadowSRV); + + // render states + RenderPlugin::Instance()->ApplySampler(0, SAMPLER_TYPE_POINTCLAMP); + + RenderPlugin::Instance()->BindShaderResources(SHADER_TYPE_VISUALIZE_SHADOW, 1, &pShadowSRV); + + + RenderPlugin::Instance()->ApplyRasterizerState(RASTERIZER_STATE_FILL_CULL_NONE); + RenderPlugin::Instance()->ApplyDepthStencilState(DEPTH_STENCIL_DEPTH_NONE); + + // set IA vars + RenderPlugin::Instance()->ClearInputLayout(); + + RenderPlugin::Instance()->SetPrimitiveTopologyTriangleStrip(); + + // set shader and tex resource + ApplyShader(SHADER_TYPE_VISUALIZE_SHADOW); + + // draw quad + RenderPlugin::Instance()->Draw(3, 0); + + // cleanup shader and its resource + RenderPlugin::Instance()->ClearPixelShaderResources(0, 1); + RenderPlugin::Instance()->DisableShader(SHADER_TYPE_VISUALIZE_SHADOW); +} + +/////////////////////////////////////////////////////////////////////////////// +// render with full color shader +void RenderScreenQuad( + GPUShaderResource* pTextureSRV + ) +{ + RenderPlugin::Instance()->ApplyRasterizerState(RASTERIZER_STATE_FILL_CULL_NONE); + RenderPlugin::Instance()->ApplyDepthStencilState(DEPTH_STENCIL_DEPTH_NONE); + + RenderPlugin::Instance()->ClearInputLayout(); + + RenderPlugin::Instance()->SetPrimitiveTopologyTriangleStrip(); + + if(pTextureSRV) + { + RenderPlugin::Instance()->BindShaderResources(SHADER_TYPE_SCREEN_QUAD, 1, &pTextureSRV); + + ApplyShader(SHADER_TYPE_SCREEN_QUAD); + + RenderPlugin::Instance()->BindPixelShaderResources(0, 1, &pTextureSRV); + RenderPlugin::Instance()->ApplySampler(0, SAMPLER_TYPE_POINTCLAMP); + + RenderPlugin::Instance()->Draw(3,0); + + RenderPlugin::Instance()->ClearPixelShaderResources(0, 1); + RenderPlugin::Instance()->DisableShader(SHADER_TYPE_SCREEN_QUAD); + } + else + { + ApplyShader(SHADER_TYPE_SCREEN_QUAD_COLOR); + + RenderPlugin::Instance()->Draw(3,0); + + RenderPlugin::Instance()->DisableShader(SHADER_TYPE_SCREEN_QUAD_COLOR); + } +} + + +void SubmitGpuWork() +{ + RenderPlugin::Instance()->SubmitGpuWork(); +} + +void WaitForGpu() +{ + RenderPlugin::Instance()->WaitForGpu(); +} + + +/////////////////////////////////////////////////////////////////////////////// +// draw calls +/////////////////////////////////////////////////////////////////////////////// +void DrawLineList(GPUBufferResource* pDevicePtr, unsigned int nVerts, unsigned int stride) +{ + RenderPlugin::Instance()->SetVertexBuffer(pDevicePtr, stride); + RenderPlugin::Instance()->SetPrimitiveTopologyLineList(); + RenderPlugin::Instance()->Draw(nVerts, 0); +} + +/////////////////////////////////////////////////////////////////////////////// +// render states management +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +void ApplyDepthStencilState(DEPTH_STENCIL_STATE state) +{ + RenderPlugin::Instance()->ApplyDepthStencilState(state); +} + +/////////////////////////////////////////////////////////////////////////////// +void ApplyRasterizerState(RASTERIZER_STATE state) +{ + RenderPlugin::Instance()->ApplyRasterizerState(state); +} + +/////////////////////////////////////////////////////////////////////////////// +void ApplySampler(int slot, SAMPLER_TYPE st) +{ + RenderPlugin::Instance()->ApplySampler(slot, st); +} + +/////////////////////////////////////////////////////////////////////////////// +void ApplyBlendState(BLEND_STATE st) +{ + RenderPlugin::Instance()->ApplyBlendState(st); +} + +void ApplyForShadow(int ForShadow) +{ + RenderPlugin::Instance()->ApplyForShadow(ForShadow); +} + +void SwitchToDX11() +{ + RenderPlugin::Instance()->SwitchToDX11(); +} + +void FlushDX11() +{ + RenderPlugin::Instance()->FlushDX11(); +} + +void FlushDX12() +{ + RenderPlugin::Instance()->FlushDX12(); +} + +void ApplyPrimitiveTopologyLine() +{ + RenderPlugin::Instance()->ApplyPrimitiveTopologyLine(); +} + +void ApplyPrimitiveTopologyTriangle() +{ + RenderPlugin::Instance()->ApplyPrimitiveTopologyTriangle(); +} + +/////////////////////////////////////////////////////////////////// +// shader magement +/////////////////////////////////////////////////////////////////// +void ApplyShader(SHADER_TYPE st) +{ + RenderPlugin::Instance()->ApplyShader(st); +} + +/////////////////////////////////////////////////////////////////////////////// +void CopyShaderParam(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot) +{ + RenderPlugin::Instance()->CopyShaderParam(st, pSysMem, bytes, slot); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Viewport magement +///////////////////////////////////////////////////////////////////////////////////////// +void GetViewport(Viewport& vp) +{ + RenderPlugin::Instance()->GetViewport(vp); +} + +/////////////////////////////////////////////////////////////////////////////// +void SetViewport(const Viewport& vp) +{ + RenderPlugin::Instance()->SetViewport(vp); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Render window interafce +///////////////////////////////////////////////////////////////////////////////////////// +bool CreateRenderWindow(HWND hWnd, int nSamples) +{ + return RenderPlugin::Instance()->CreateRenderWindow(hWnd, nSamples); +} + +bool ResizeRenderWindow(int w, int h) +{ + return RenderPlugin::Instance()->ResizeRenderWindow(w,h); +} + +void PresentRenderWindow() +{ + return RenderPlugin::Instance()->PresentRenderWindow(); +} + +void ClearRenderWindow(float r, float g, float b) +{ + return RenderPlugin::Instance()->ClearRenderWindow(r,g,b); +} + +/////////////////////////////////////////////////////////////////////////////// +// Texture resource management +/////////////////////////////////////////////////////////////////////////////// +static GPUShaderResource* g_backgroundTextureSRV = 0; + +bool LoadBackgroundTexture(const char* filePath) +{ + ClearBackgroundTexture(); + + RenderPlugin::Instance()->PreRender(); + g_backgroundTextureSRV = RenderPlugin::Instance()->CreateTextureSRV(filePath); + RenderPlugin::Instance()->PostRender(); + + return (g_backgroundTextureSRV != 0); +} + +/////////////////////////////////////////////////////////////////////////////// +void RenderBackgroundTexture() +{ + RenderScreenQuad(g_backgroundTextureSRV); +} + +/////////////////////////////////////////////////////////////////////////////// +void ClearBackgroundTexture() +{ + SAFE_RELEASE(g_backgroundTextureSRV); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Text draw helper functions (using DXUT) +///////////////////////////////////////////////////////////////////////////////////////// +void TxtHelperBegin() +{ + RenderPlugin::Instance()->TxtHelperBegin(); +} + +void TxtHelperEnd() +{ + RenderPlugin::Instance()->TxtHelperEnd(); +} + +void TxtHelperSetInsertionPos(int x, int y) +{ + RenderPlugin::Instance()->TxtHelperSetInsertionPos(x,y); +} + +void TxtHelperSetForegroundColor(float r, float g, float b, float a) +{ + RenderPlugin::Instance()->TxtHelperSetForegroundColor(r,g,b,a); +} + +void TxtHelperDrawTextLine(wchar_t* str) +{ + RenderPlugin::Instance()->TxtHelperDrawTextLine(str); +} + +} // end namespace
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.h new file mode 100644 index 0000000..9bc4036 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderInterface.h @@ -0,0 +1,175 @@ +// 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. +// + +#pragma once + +#include "windows.h" + +#include "RenderResources.h" + +// API agnostic interface for rendering +namespace RenderInterface +{ + /////////////////////////////////////////////////////////////////// + enum RASTERIZER_STATE + { + RASTERIZER_STATE_FILL_CULL_NONE, + RASTERIZER_STATE_FILL_CULL_FRONT, + RASTERIZER_STATE_FILL_CULL_BACK, + RASTERIZER_STATE_WIRE, + RASTERIZER_STATE_END + }; + + /////////////////////////////////////////////////////////////////// + enum DEPTH_STENCIL_STATE + { + DEPTH_STENCIL_DEPTH_TEST, + DEPTH_STENCIL_DEPTH_NONE, + DEPTH_STENCIL_STATE_END + }; + + /////////////////////////////////////////////////////////////////// + enum SAMPLER_TYPE + { + SAMPLER_TYPE_LINEAR, + SAMPLER_TYPE_POINTCLAMP, + SAMPLER_TYPE_END, + }; + + /////////////////////////////////////////////////////////////////// + enum BLEND_STATE + { + BLEND_STATE_ALPHA, + BLEND_STATE_NONE, + BLEND_STATE_END + }; + + /////////////////////////////////////////////////////////////////// + enum SHADER_TYPE + { + SHADER_TYPE_MESH_RENDERING, + SHADER_TYPE_MESH_SHADOW, + SHADER_TYPE_SCREEN_QUAD, + SHADER_TYPE_SCREEN_QUAD_COLOR, + SHADER_TYPE_VISUALIZE_SHADOW, + SHADER_TYPE_SIMPLE_COLOR, +#ifndef NV_ARTISTTOOLS + SHADER_TYPE_HAIR_SHADER_DEFAULT, + SHADER_TYPE_HAIR_SHADER_SHADOW, +#endif // NV_ARTISTTOOLS + }; + + /////////////////////////////////////////////////////////////////// + // global acess for render context and device to minimize D3D entry points + /////////////////////////////////////////////////////////////////// + CORELIB_EXPORT bool InitDevice(int deviceID); + CORELIB_EXPORT bool Initialize(); + CORELIB_EXPORT void Shutdown(); + + CORELIB_EXPORT void SubmitGpuWork(); + CORELIB_EXPORT void WaitForGpu(); + + /////////////////////////////////////////////////////////////////// + // render window management + /////////////////////////////////////////////////////////////////// + CORELIB_EXPORT bool CreateRenderWindow(HWND hWnd, int nSamples); + CORELIB_EXPORT bool ResizeRenderWindow(int w, int h); + CORELIB_EXPORT void PresentRenderWindow(); + CORELIB_EXPORT void ClearRenderWindow(float r, float g, float b); + + /////////////////////////////////////////////////////////////////// + // shader magement + /////////////////////////////////////////////////////////////////// + CORELIB_EXPORT void ApplyShader(SHADER_TYPE st); + CORELIB_EXPORT void CopyShaderParam(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0); + + /////////////////////////////////////////////////////////////////// + // viewport management + /////////////////////////////////////////////////////////////////// + struct Viewport + { + float TopLeftX; + float TopLeftY; + float Width; + float Height; + float MinDepth; + float MaxDepth; + }; + + CORELIB_EXPORT void GetViewport(Viewport& vp); + CORELIB_EXPORT void SetViewport(const Viewport& vp); + + /////////////////////////////////////////////////////////////////// + // gpu buffer management + /////////////////////////////////////////////////////////////////// + CORELIB_EXPORT GPUBufferResource* CreateVertexBuffer( unsigned int ByteWidth, void* pSysMem = 0); + CORELIB_EXPORT void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth); + + /////////////////////////////////////////////////////////////////// + // texture resource mangement + /////////////////////////////////////////////////////////////////// + CORELIB_EXPORT GPUShaderResource* CreateTextureResource(const char* filePath); + CORELIB_EXPORT void RenderShadowMap(GPUShaderResource* pShadowSRV, float znear, float zfar); + + /////////////////////////////////////////////////////////////////// + // render state management + /////////////////////////////////////////////////////////////////// + CORELIB_EXPORT void ApplyDepthStencilState(DEPTH_STENCIL_STATE state); + CORELIB_EXPORT void ApplyRasterizerState(RASTERIZER_STATE state); + CORELIB_EXPORT void ApplySampler(int slot, SAMPLER_TYPE st); + CORELIB_EXPORT void ApplyBlendState(BLEND_STATE st); + + CORELIB_EXPORT void ApplyForShadow(int ForShadow); + CORELIB_EXPORT void SwitchToDX11(); + CORELIB_EXPORT void FlushDX11(); + CORELIB_EXPORT void FlushDX12(); + CORELIB_EXPORT void ApplyPrimitiveTopologyLine(); + CORELIB_EXPORT void ApplyPrimitiveTopologyTriangle(); + /////////////////////////////////////////////////////////////////// + // draw calls + /////////////////////////////////////////////////////////////////// + void DrawLineList(GPUBufferResource* pVertexBuffer, unsigned int nVerts, unsigned int bytesize); + + /////////////////////////////////////////////////////////////////// + // background textures + /////////////////////////////////////////////////////////////////// + bool LoadBackgroundTexture(const char* filePath); + void RenderBackgroundTexture(); + void ClearBackgroundTexture(); + + /////////////////////////////////////////////////////////////////// + CORELIB_EXPORT bool GetDeviceInfoString(wchar_t *str); + + /////////////////////////////////////////////////////////////////// + // text helpers + CORELIB_EXPORT void TxtHelperBegin(); + CORELIB_EXPORT void TxtHelperEnd(); + CORELIB_EXPORT void TxtHelperSetInsertionPos(int x, int y); + CORELIB_EXPORT void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f); + CORELIB_EXPORT void TxtHelperDrawTextLine(wchar_t* str); +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.cpp new file mode 100644 index 0000000..3df8c85 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.cpp @@ -0,0 +1,86 @@ +#include "RenderPlugin.h" + +#include <io.h> +#include <stdio.h> +#include <stdlib.h> + +RenderPlugin* g_Plugin = nullptr; + +RenderPlugin::RenderPlugin() +{ + m_RenderApi = ""; +} + +typedef RenderPlugin*(*Func)(void); + +bool RenderPlugin::Load(std::vector<std::string>& render_plugins) +{ + if (render_plugins.size() == 0) + { + return false; + } + + std::vector<std::string>::iterator it; + std::string pluginDll = ""; + HMODULE module = NULL; + Func CreateFunc = NULL; + bool loaded = false; + for (it = render_plugins.begin(); it != render_plugins.end(); it++) + { +#ifdef NV_ARTISTTOOLS + pluginDll = "RenderPlugin"; +#else + pluginDll = "FurRender"; +#endif + + pluginDll.append(*it); + +#ifdef _WIN64 + pluginDll.append(".win64"); +#else + pluginDll.append(".win32"); +#endif + +#ifdef _DEBUG + pluginDll.append(".d"); +#else +#endif + + pluginDll.append(".dll"); + + module = LoadLibraryA(pluginDll.c_str()); + if (NULL == module) + return false; + + CreateFunc = (Func)GetProcAddress(module, "CreateRenderPlugin"); + if (NULL == CreateFunc) + return false; + + g_Plugin = CreateFunc(); + if (NULL != g_Plugin) + { + loaded = true; + break; + } + } + return loaded; +} + +RenderPlugin::~RenderPlugin() +{ +} + + +RenderPlugin* RenderPlugin::Instance() +{ + return g_Plugin; +} + +void RenderPlugin::Destroy() +{ + if (nullptr == g_Plugin) + return; + + delete g_Plugin; + g_Plugin = nullptr; +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.h new file mode 100644 index 0000000..e755aea --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderPlugin.h @@ -0,0 +1,124 @@ +#pragma once + +#include "RenderInterface.h" +using namespace RenderInterface; + +class NVHairReadOnlyBuffer; +class GPUProfiler; +class ShadowMap; + +class IDXGIAdapter; +class IUnknown; +class IDXGIFactory1; +class IDXGISwapChain; + +struct D3DHandles +{ +public: + IDXGIAdapter* pAdapter; + IDXGIFactory1* pFactory; + IUnknown* pDevice; + IUnknown* pDeviceContext; + + IDXGISwapChain* pDXGISwapChain; + IUnknown* pD3D11BackBuffer; + IUnknown* pD3D11RenderTargetView; + IUnknown* pD3D11DepthBuffer; + IUnknown* pD3D11DepthStencilView; +}; + +#ifdef CORERENDER_LIB +# define CORERENDER_EXPORT Q_DECL_EXPORT +#else +# define CORERENDER_EXPORT Q_DECL_IMPORT +#endif + +class CORELIB_EXPORT RenderPlugin +{ +public: + static bool Load(std::vector<std::string>& render_plugins); + static RenderPlugin* Instance(); + static void Destroy(); + + ~RenderPlugin(); + + // self + virtual std::string GetRenderApi() { return m_RenderApi; } + + // interface + virtual bool InitDevice(int deviceID) = 0; + virtual bool Initialize() = 0; + virtual void Shutdown() = 0; + virtual void CopyToDevice(GPUBufferResource *pDevicePtr, void* pSysMem, unsigned int ByteWidth) = 0; + virtual void ApplyDepthStencilState(DEPTH_STENCIL_STATE state) = 0; + virtual void ApplyRasterizerState(RASTERIZER_STATE state) = 0; + virtual void ApplySampler(int slot, SAMPLER_TYPE st) = 0; + virtual void ApplyBlendState(BLEND_STATE st) = 0; + virtual void GetViewport(Viewport& vp) = 0; + virtual void SetViewport(const Viewport& vp) = 0; + virtual void BindVertexShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs) = 0; + virtual void BindPixelShaderResources(int startSlot, int numSRVs, GPUShaderResource** ppSRVs) = 0; + virtual void ClearVertexShaderResources(int startSlot, int numSRVs) = 0; + virtual void ClearPixelShaderResources(int startSlot, int numSRVs) = 0; + virtual void ClearInputLayout() = 0; + virtual void SetVertexBuffer(GPUBufferResource* pBuffer, UINT stride, UINT offset = 0) = 0; + virtual void SetPrimitiveTopologyTriangleStrip() = 0; + virtual void SetPrimitiveTopologyTriangleList() = 0; + virtual void SetPrimitiveTopologyLineList() = 0; + virtual void Draw(unsigned int vertexCount, unsigned int startCount = 0) = 0; + virtual GPUBufferResource* CreateVertexBuffer(unsigned int ByteWidth, void* pSysMem = 0) = 0; + virtual GPUShaderResource* CreateShaderResource(unsigned int stride, unsigned int numElements, void* pSysMem, NVHairReadOnlyBuffer* pReadOnlyBuffer = NULL) = 0; + + // interface dx12 + virtual void ApplyForShadow(int ForShadow) = 0; + virtual void SwitchToDX11() = 0; + virtual void FlushDX11() = 0; + virtual void FlushDX12() = 0; + virtual void ApplyPrimitiveTopologyLine() = 0; + virtual void ApplyPrimitiveTopologyTriangle() = 0; + virtual void SubmitGpuWork() = 0; + virtual void WaitForGpu() = 0; + + // util + virtual bool CreateRenderWindow(HWND hWnd, int nSamples) = 0; + virtual bool ResizeRenderWindow(int w, int h) = 0; + virtual void PresentRenderWindow() = 0; + virtual void ClearRenderWindow(float r, float g, float b) = 0; + virtual bool GetDeviceInfoString(wchar_t *str) = 0; + virtual GPUShaderResource* CreateTextureSRV(const char* texturename) = 0; + virtual void TxtHelperBegin() = 0; + virtual void TxtHelperEnd() = 0; + virtual void TxtHelperSetInsertionPos(int x, int y) = 0; + virtual void TxtHelperSetForegroundColor(float r, float g, float b, float a = 1.0f) = 0; + virtual void TxtHelperDrawTextLine(wchar_t* str) = 0; + + // shader + virtual bool InitializeShaders() = 0; + virtual void DestroyShaders() = 0; + virtual void ApplyShader(SHADER_TYPE st) = 0; + virtual void DisableShader(SHADER_TYPE st) = 0; + virtual void BindShaderResources(SHADER_TYPE st, int numSRVs, GPUShaderResource** ppSRVs) = 0; + virtual void CopyShaderParam(SHADER_TYPE st, void* pSysMem, unsigned int bytes, unsigned int slot = 0) = 0; + + // GPUProfiler + virtual GPUProfiler* CreateGPUProfiler() = 0; + + // ShadowMap + virtual ShadowMap* CreateShadowMap(int resolution) = 0; + + // D3D12RenderContext + virtual void PreRender() = 0; + virtual void PostRender() = 0; + + // GPUMeshResources + virtual GPUMeshResources* GPUMeshResourcesCreate(MeshData* pMeshData, const SkinData& skinData) = 0; + virtual void GPUMeshResourcesRelease(GPUMeshResources* pResource) = 0; + + // Get devices related + virtual D3DHandles& GetDeviceHandles(D3DHandles& deviceHandles) = 0; + +protected: + RenderPlugin(); + std::string m_RenderApi; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.cpp new file mode 100644 index 0000000..19863fc --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.cpp @@ -0,0 +1,47 @@ +// 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-2015 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. +// +#include "RenderResources.h" + +// shared path +#include "AnimUtil.h" +#include "MeshData.h" + +#include "RenderPlugin.h" + +//////////////////////////////////////////////////////////////////////////////////////// +GPUMeshResources* GPUMeshResources::Create(MeshData* pMeshData, const SkinData& skinData) +{ + return RenderPlugin::Instance()->GPUMeshResourcesCreate(pMeshData, skinData); +} + +//////////////////////////////////////////////////////////////////////////////////////// +void GPUMeshResources::Release() +{ + RenderPlugin::Instance()->GPUMeshResourcesRelease(this); +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.h new file mode 100644 index 0000000..c261730 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/Interface/RenderResources.h @@ -0,0 +1,72 @@ +// 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-2015 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. +// +#pragma once + +#include "corelib_global.h" +#include "CoreLib.h" + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(x) { if (x) x->Release(); x = 0; } +#endif + +////////////////////////////////////////////////////////////////////////////////////// +// API specific GPU resources (todo - add reference counting) +////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////// +class GPUBufferResource +{ +public: + virtual ~GPUBufferResource() {} + virtual void Release() = 0; +}; + +//////////////////////////////////////////////////////////////////////////////////////// +class GPUShaderResource +{ +public: + virtual ~GPUShaderResource() {} + virtual void Release() = 0; +}; + +class MeshData; +class SkinData; + +//////////////////////////////////////////////////////////////////////////////////////// +class GPUMeshResources +{ +public: + GPUBufferResource* m_pVertexBuffer; + GPUShaderResource* m_pBoneIndicesSRV; + GPUShaderResource* m_pBoneWeightsSRV; + + static GPUMeshResources* Create(MeshData*, const SkinData& skinData); + void Release(); +}; + + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/LightShaderParam.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/LightShaderParam.h new file mode 100644 index 0000000..9935f71 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/LightShaderParam.h @@ -0,0 +1,83 @@ +// 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-2015 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. +// + +#pragma once + +#include "MathUtil.h" + +#define MAX_LIGHTS 4 + +// shader parameter for light +struct LightParam +{ + int m_enable; + atcore_float3 m_dir; + + int m_useShadows; + atcore_float3 m_color; + + atcore_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; + + atcore_float4x4 m_viewMatrix; + atcore_float4x4 m_lightMatrix; + +public: + LightParam() + { + m_dir = gfsdk_makeFloat3(-1.0f, -1.0f, -1.0f); + m_enable = 0; + m_useShadows = false; + m_isEnvLight = 0; + m_useEnvMap = 0; + + m_depthBias = 1.0f; + m_depthGain = 1.0f; + + m_color = gfsdk_makeFloat3(1.0f, 1.0f, 1.0f); + m_ambientColor = gfsdk_makeFloat3(0.0f, 0.0f, 0.0f); + } +}; + + +// light shader block in c-buffer +struct LightShaderParam +{ + LightParam m_lightParam[MAX_LIGHTS]; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/MeshShaderParam.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/MeshShaderParam.h new file mode 100644 index 0000000..5dce51d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/MeshShaderParam.h @@ -0,0 +1,142 @@ +// 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-2015 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. +// + +#pragma once + +#include "MathUtil.h" +#include "LightShaderParam.h" + +// same layout as the constant buffer used in body shader +#define MAX_BONE_MATRICES 512 + +// shared struct for mesh shader cbuffer and material access +struct MeshShaderParam +{ + atcore_float4x4 m_ViewProjection; + atcore_float4x4 m_BodyTransformation; + + LightShaderParam m_lightParam; + + atcore_float3 m_eyePosition; + float m_specularShininess; + + int m_useDiffuseTextures; + int m_useSpecularTextures; + int m_useNormalTextures; + int m_useTextures; + + + atcore_float4 m_ambientColor; + atcore_float4 m_diffuseColor; + atcore_float4 m_specularColor; + + int m_wireFrame; + int m_useLighting; + int m_wireFrameOver; + float m_unitScale; + + int m_useDQs; + int m_diffuseChannel; + int m_flatNormal; + int m_usePinPos; + + atcore_float4x4 m_boneMatrices[MAX_BONE_MATRICES]; + atcore_dualquaternion m_boneDQs[MAX_BONE_MATRICES]; + + MeshShaderParam() + { + m_specularShininess = 30.0f; + + m_ambientColor = gfsdk_makeFloat4(0.0f, 0.0f, 0.0f, 1.0f); + m_diffuseColor = gfsdk_makeFloat4(1.0f, 1.0f, 1.0f, 1.0f); + m_specularColor = gfsdk_makeFloat4(0.0f, 0.0f, 0.0f, 0.0f); + + m_useDiffuseTextures = true; + m_useSpecularTextures = true; + m_useNormalTextures = true; + m_useTextures = true; + + m_wireFrame = false; + m_wireFrameOver = false; + m_useLighting = true; + m_unitScale = 1.0f; + + m_useDQs = false; + m_flatNormal = false; + + m_usePinPos = false; + + memset(m_boneMatrices, 0, sizeof(atcore_float4x4) * MAX_BONE_MATRICES); + memset(m_boneDQs, 0, sizeof(atcore_dualquaternion) * MAX_BONE_MATRICES); + } +}; + +// struct for mesh shadow shader cbuffer +struct MeshShadowShaderParam +{ + atcore_float4x4 m_ViewProjection; + atcore_float4x4 m_ViewMatrix; + atcore_float4x4 m_BodyTransformation; + + int m_useDQs; + int m_usePinPos; + float _reserved_[2]; + + atcore_float4x4 m_boneMatrices[MAX_BONE_MATRICES]; + atcore_dualquaternion m_boneDQs[MAX_BONE_MATRICES]; + + MeshShadowShaderParam() + { + m_useDQs = false; + m_usePinPos = false; + + memset(m_boneMatrices, 0, sizeof(atcore_float4x4) * MAX_BONE_MATRICES); + memset(m_boneDQs, 0, sizeof(atcore_dualquaternion) * MAX_BONE_MATRICES); + } +}; + +struct SimpleShaderParam +{ + atcore_float4x4 world; + atcore_float4x4 view; + atcore_float4x4 projection; + atcore_float4 color; + + int useVertexColor; + int dummy2; + int dummy3; + int dummy4; +}; + +struct ShadowVizParam +{ + float m_zNear; + float m_zFar; + float _align1; + float _align2; +};
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/ShadowMap.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/ShadowMap.cpp new file mode 100644 index 0000000..72b90be --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/ShadowMap.cpp @@ -0,0 +1,36 @@ +// 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-2015 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. +// +#include "ShadowMap.h" + +#include "RenderPlugin.h" + +///////////////////////////////////////////////////////////////////////// +ShadowMap* ShadowMap::Create(int resolution) +{ + return RenderPlugin::Instance()->CreateShadowMap(resolution); +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/ShadowMap.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/ShadowMap.h new file mode 100644 index 0000000..9a62b06 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/ShadowMap.h @@ -0,0 +1,48 @@ +// 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-2015 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. +// + +#pragma once + +#include "d3d11.h" + +class GPUShaderResource; + +struct ShadowMap +{ +public: + static ShadowMap* ShadowMap::Create(int resolution); + virtual ~ShadowMap() {} + + virtual void Release() = 0; + virtual void BeginRendering(float clearDepth) = 0; + virtual void EndRendering() = 0; + + virtual GPUShaderResource* GetShadowSRV() = 0; +}; + + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.cpp new file mode 100644 index 0000000..0dfb169 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.cpp @@ -0,0 +1,493 @@ +// 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-2015 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. +// + +#include "SimpleRenderable.h" + +#include "RenderInterface.h" + +#include <vector> + +#include "Nv.h" + +static std::vector<SimpleRenderable*> g_SimpleShapes; + +struct DefaultVertexType +{ + atcore_float3 pos; + atcore_float4 color; +}; + +/////////////////////////////////////////////////////////////////////////////// +SimpleRenderable::SimpleRenderable() + : m_pVertexBuffer(NV_NULL) + , m_numIndices(0) + , m_numVertices(0) +{ + +} + +/////////////////////////////////////////////////////////////////////////////// +SimpleRenderable::~SimpleRenderable() +{ + Free(); +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleRenderable::Free() +{ + SAFE_RELEASE(m_pVertexBuffer); +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleRenderable::Initialize() +{ + ////////////////////////////////////////////////////////////////////////////// + // create icon shape + g_SimpleShapes.resize(NUM_SHAPE_TYPES); + + g_SimpleShapes[GROUND_YUP] = new SimpleRenderable; + g_SimpleShapes[GROUND_YUP]->InitGroundGeometry(false); + + g_SimpleShapes[GROUND_ZUP] = new SimpleRenderable; + g_SimpleShapes[GROUND_ZUP]->InitGroundGeometry(true); + + g_SimpleShapes[AXIS_YUP] = new SimpleRenderable; + g_SimpleShapes[AXIS_YUP]->InitAxisGeometry(false); + + g_SimpleShapes[AXIS_ZUP] = new SimpleRenderable; + g_SimpleShapes[AXIS_ZUP]->InitAxisGeometry(true); + + g_SimpleShapes[WIND_YUP] = new SimpleRenderable; + g_SimpleShapes[WIND_YUP]->InitWindGeometry(); + + g_SimpleShapes[WIND_ZUP] = new SimpleRenderable; + g_SimpleShapes[WIND_ZUP]->InitWindGeometry(); + + g_SimpleShapes[LIGHT] = new SimpleRenderable; + g_SimpleShapes[LIGHT]->InitLightGeometry(); + + g_SimpleShapes[LIGHT_RAY] = new SimpleRenderable; + g_SimpleShapes[LIGHT_RAY]->InitLightRayGeometry(); + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void SimpleRenderable::Draw(SHAPE_TYPE t, bool depthTest) +{ + if (t >= g_SimpleShapes.size()) + return; + + g_SimpleShapes[t]->Draw(depthTest); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +void SimpleRenderable::Shutdown() +{ + for (int i = 0; i < g_SimpleShapes.size(); i++) + { + if (g_SimpleShapes[i]) + { + g_SimpleShapes[i]->Free(); + delete g_SimpleShapes[i]; + } + } + + g_SimpleShapes.clear(); +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleRenderable::InitGroundGeometry(bool zUP) +{ + const int nSeed = 10; + const int nRow = nSeed * 2 + 1; + const int nLines = nRow * 2; + const float fLen = 25.0f; + const float fSpace = fLen/nSeed; + float groundHeight = 0.0f; + + const atcore_float4 color1 = gfsdk_makeFloat4(0.65, 0.65, 0.65, 1.0f); + const atcore_float4 color2 = gfsdk_makeFloat4(0.1f, 0.1f, 0.1f, 1.0f); + + DWORD offset; + + const int numVerts = nLines * 2; + DefaultVertexType* buf = new DefaultVertexType[numVerts]; + DefaultVertexType* pData = buf; + + //build ground lines/verts + for(int i = 0; i < nSeed; i++) + { + if ( zUP ) + { + // lines parallel to y + pData->pos = gfsdk_makeFloat3(-fSpace * (i+1), -fLen, groundHeight); + pData->color = color1; + pData++; + + pData->pos = gfsdk_makeFloat3(-fSpace * (i+1), fLen, groundHeight); + pData->color = color1; + pData++; + + // lines parallel to y + pData->pos = gfsdk_makeFloat3(fSpace * (i+1), -fLen, groundHeight); + pData->color = color1; + pData++; + + pData->pos = gfsdk_makeFloat3(fSpace * (i+1), fLen, groundHeight); + pData->color = color1; + pData++; + + // line x + pData->pos = gfsdk_makeFloat3(-fLen, -fSpace * (i+1), groundHeight); + pData->color = color1; + pData++; + + pData->pos = gfsdk_makeFloat3(fLen, -fSpace * (i+1), groundHeight); + pData->color = color1; + pData++; + + // line x + pData->pos = gfsdk_makeFloat3(-fLen, fSpace * (i+1), groundHeight); + pData->color = color1; + pData++; + + pData->pos = gfsdk_makeFloat3(fLen, fSpace * (i+1), groundHeight); + pData->color = color1; + pData++; + } + else + { + // lines parallel to z + pData->pos = gfsdk_makeFloat3(-fSpace * (i+1), groundHeight, -fLen); + pData->color = color1; + pData++; + + pData->pos = gfsdk_makeFloat3(-fSpace * (i+1), groundHeight, fLen); + pData->color = color1; + pData++; + + // lines parallel to z + pData->pos = gfsdk_makeFloat3(fSpace * (i+1), groundHeight, -fLen); + pData->color = color1; + pData++; + + pData->pos = gfsdk_makeFloat3(fSpace * (i+1), groundHeight, fLen); + pData->color = color1; + pData++; + + // line x + pData->pos = gfsdk_makeFloat3(-fLen, groundHeight, -fSpace * (i+1)); + pData->color = color1; + pData++; + + pData->pos = gfsdk_makeFloat3(fLen, groundHeight, -fSpace * (i+1)); + pData->color = color1; + pData++; + + // line x + pData->pos = gfsdk_makeFloat3(-fLen, groundHeight, fSpace * (i+1)); + pData->color = color1; + pData++; + + pData->pos = gfsdk_makeFloat3(fLen, groundHeight, fSpace * (i+1)); + pData->color = color1; + pData++; + } + } + + if ( zUP ) + { + // line y + pData->pos = gfsdk_makeFloat3(-fLen, 0.0f, groundHeight); + pData->color = color2; + pData++; + + pData->pos = gfsdk_makeFloat3(fLen, 0.0f, groundHeight); + pData->color = color2; + pData++; + + // line x + pData->pos = gfsdk_makeFloat3(0.0f, -fLen, groundHeight); + pData->color = color2; + pData++; + + pData->pos = gfsdk_makeFloat3(0.0f, fLen, groundHeight); + pData->color = color2; + pData++; + } + else + { + // line z + pData->pos = gfsdk_makeFloat3(-fLen, groundHeight, 0.0f); + pData->color = color2; + pData++; + + pData->pos = gfsdk_makeFloat3(fLen, groundHeight, 0.0f); + pData->color = color2; + pData++; + + // line x + pData->pos = gfsdk_makeFloat3(0.0f, groundHeight, -fLen); + pData->color = color2; + pData++; + + pData->pos = gfsdk_makeFloat3(0.0f, groundHeight, fLen); + pData->color = color2; + pData++; + } + + int bufBytes = sizeof(DefaultVertexType) * numVerts; + + m_pVertexBuffer = RenderInterface::CreateVertexBuffer(bufBytes, buf); + + m_numVertices = numVerts; + + return (NV_NULL != m_pVertexBuffer); +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleRenderable::InitAxisGeometry(bool zUP) +{ + const atcore_float4 colorRed = gfsdk_makeFloat4(1.0f, 0, 0, 1.0f); + const atcore_float4 colorGreen = gfsdk_makeFloat4(0, 1.0f, 0, 1.0f); + const atcore_float4 colorBlue = gfsdk_makeFloat4(0, 0, 1.0f, 1.0f); + const float dist = 1.0f; + const int numVerts = 3 * 2; + DefaultVertexType* buf = new DefaultVertexType[numVerts]; + DefaultVertexType* pData = buf; + + { + // x axis + pData->pos = gfsdk_makeFloat3(0, 0, 0); + pData->color = colorRed; + pData++; + + pData->pos = gfsdk_makeFloat3(dist, 0, 0); + pData->color = colorRed; + pData++; + + // y axis + pData->pos = gfsdk_makeFloat3(0, 0, 0); + pData->color = colorGreen; + pData++; + + pData->pos = gfsdk_makeFloat3(0, dist, 0); + pData->color = colorGreen; + pData++; + + // z axis + pData->pos = gfsdk_makeFloat3(0, 0, 0); + pData->color = colorBlue; + pData++; + + pData->pos = gfsdk_makeFloat3(0, 0, dist); + pData->color = colorBlue; + pData++; + } + + int bufBytes = sizeof(DefaultVertexType) * numVerts; + + m_pVertexBuffer = RenderInterface::CreateVertexBuffer(bufBytes, buf); + + m_numVertices = numVerts; + + return (NV_NULL != m_pVertexBuffer); +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleRenderable::InitLightGeometry() +{ + // The following geometry data are generated by external/ObjLoad tool +#include "GeometryData/LightGeometryData.h" + const atcore_float4 colorYellow = gfsdk_makeFloat4(1.0f, 1.0f, 0, 1.0f); + const int numVerts = num_faces*3*2; + DefaultVertexType* buf = new DefaultVertexType[numVerts]; + DefaultVertexType* pData = buf; + + const float modelScale = 0.25f; + for (int fi = 0; fi < num_faces; ++fi) + { + float* v0 = &vertices[(fi*3+0)*8]; + float* v1 = &vertices[(fi*3+1)*8]; + float* v2 = &vertices[(fi*3+2)*8]; + + // flip Y + v0[2] *= -1; + v1[2] *= -1; + v2[2] *= -1; + + // line 0 + pData->pos = modelScale * gfsdk_makeFloat3(v0[0], v0[1], v0[2]); + pData->color = colorYellow; + pData++; + + pData->pos = modelScale * gfsdk_makeFloat3(v1[0], v1[1], v1[2]); + pData->color = colorYellow; + pData++; + + // line 1 + pData->pos = modelScale * gfsdk_makeFloat3(v1[0], v1[1], v1[2]); + pData->color = colorYellow; + pData++; + + pData->pos = modelScale * gfsdk_makeFloat3(v2[0], v2[1], v2[2]); + pData->color = colorYellow; + pData++; + + // line 2 + pData->pos = modelScale * gfsdk_makeFloat3(v2[0], v2[1], v2[2]); + pData->color = colorYellow; + pData++; + + pData->pos = modelScale * gfsdk_makeFloat3(v0[0], v0[1], v0[2]); + pData->color = colorYellow; + pData++; + } + + int bufBytes = sizeof(DefaultVertexType) * numVerts; + + m_pVertexBuffer = RenderInterface::CreateVertexBuffer(bufBytes, buf); + + m_numVertices = numVerts; + + return (NV_NULL != m_pVertexBuffer); +} + + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleRenderable::InitLightRayGeometry() +{ + const atcore_float4 colorRed = gfsdk_makeFloat4(1.0f, 0, 0, 1.0f); + const int numVerts = 2; + DefaultVertexType* buf = new DefaultVertexType[numVerts]; + DefaultVertexType* pData = buf; + + pData->pos = gfsdk_makeFloat3(0, 0, 0); + pData->color = colorRed; + pData++; + + pData->pos = gfsdk_makeFloat3(0, 0, 0); + pData->color = colorRed; + pData++; + + int bufBytes = sizeof(DefaultVertexType) * numVerts; + + m_pVertexBuffer = RenderInterface::CreateVertexBuffer(bufBytes, buf); + + m_numVertices = numVerts; + + return (NV_NULL != m_pVertexBuffer); +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleRenderable::InitWindGeometry() +{ + // The following geometry data are generated by external/ObjLoad tool +#include "GeometryData/WindGeometryData.h" + const atcore_float4 colorBlue = gfsdk_makeFloat4(0, 0, 1.0f, 1.0f); + const int numVerts = num_faces*3*2; + DefaultVertexType* buf = new DefaultVertexType[numVerts]; + DefaultVertexType* pData = buf; + + const float modelScale = 0.5f; + for (int fi = 0; fi < num_faces; ++fi) + { + float* v0 = &vertices[(fi*3+0)*8]; + float* v1 = &vertices[(fi*3+1)*8]; + float* v2 = &vertices[(fi*3+2)*8]; + + pData->pos = modelScale * gfsdk_makeFloat3(v0[0], v0[1], v0[2]); + pData->color = colorBlue; + pData++; + + pData->pos = modelScale * gfsdk_makeFloat3(v1[0], v1[1], v1[2]); + pData->color = colorBlue; + pData++; + + pData->pos = modelScale * gfsdk_makeFloat3(v1[0], v1[1], v1[2]); + pData->color = colorBlue; + pData++; + + pData->pos = modelScale * gfsdk_makeFloat3(v2[0], v2[1], v2[2]); + pData->color = colorBlue; + pData++; + + pData->pos = modelScale * gfsdk_makeFloat3(v2[0], v2[1], v2[2]); + pData->color = colorBlue; + pData++; + + pData->pos = modelScale * gfsdk_makeFloat3(v0[0], v0[1], v0[2]); + pData->color = colorBlue; + pData++; + } + + int bufBytes = sizeof(DefaultVertexType) * numVerts; + + m_pVertexBuffer = RenderInterface::CreateVertexBuffer(bufBytes, buf); + + m_numVertices = numVerts; + + return (NV_NULL != m_pVertexBuffer); +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleRenderable::Draw(bool depthTest) +{ + RenderInterface::ApplyPrimitiveTopologyLine(); + + RenderInterface::ApplyShader(RenderInterface::SHADER_TYPE_SIMPLE_COLOR); + RenderInterface::DrawLineList(m_pVertexBuffer, m_numVertices, sizeof(DefaultVertexType)); + + RenderInterface::FlushDX12(); + RenderInterface::ApplyPrimitiveTopologyTriangle(); +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleRenderable::DrawLine(const atcore_float3& from, const atcore_float3& to) +{ + SimpleRenderable* pShape = g_SimpleShapes[LIGHT_RAY]; + + DefaultVertexType buf[2]; + DefaultVertexType* pData = buf; + + // start position + pData->pos = from; + pData->color = gfsdk_makeFloat4(1.0f, 1.0f, 0, 1.0f); + pData++; + + // end position + pData->pos = to; + pData->color = gfsdk_makeFloat4(1.0f, 1.0f, 0, 1.0f); + pData++; + + RenderInterface::CopyToDevice(pShape->m_pVertexBuffer, buf, 2 * sizeof(DefaultVertexType)); + + pShape->Draw(true); +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.h b/NvBlast/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.h new file mode 100644 index 0000000..c43c07d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Render/SimpleRenderable.h @@ -0,0 +1,75 @@ +// 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. +// +#pragma once + +#include "MathUtil.h" + +class GPUBufferResource; + +class SimpleRenderable +{ +public: + enum SHAPE_TYPE + { + GROUND_YUP, + GROUND_ZUP, + AXIS_YUP, + AXIS_ZUP, + WIND_YUP, + WIND_ZUP, + LIGHT, + LIGHT_RAY, + NUM_SHAPE_TYPES + }; + + static bool Initialize(); + static void Shutdown(); + static void Draw(SHAPE_TYPE t, bool depthTest = true); + static void DrawLine(const atcore_float3& from, const atcore_float3& to); + +protected: + GPUBufferResource* m_pVertexBuffer; + + unsigned int m_numVertices; + unsigned int m_numIndices; + + SimpleRenderable(); + ~SimpleRenderable(); + + bool InitGroundGeometry(bool zUp); + bool InitAxisGeometry(bool zUp); + bool InitLightGeometry(); + bool InitLightRayGeometry(); + bool InitWindGeometry(); + + void Draw(bool depthTest = true); + + void Free(); + +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Camera.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Camera.cpp new file mode 100644 index 0000000..74d93f4 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Camera.cpp @@ -0,0 +1,867 @@ +// 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-2015 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. +// + +#include "Camera.h" + +//#define USE_D3DX9MATH +#ifdef USE_D3DX9MATH +#include <d3dx9math.h> // TODO - remove d3dx reference (quaternion funcs) + +#pragma comment(lib, "d3dx9.lib") +#define MAKEVECTOR3 D3DXVECTOR3 +#else +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#define FLOAT float +#define D3DXVECTOR3 atcore_float3 +#define D3DXMATRIX atcore_float4x4 +#define D3DXQUATERNION atcore_float4 + +#define MAKEVECTOR3 gfsdk_makeFloat3 + +#define D3DXToRadian( degree ) ((degree) * 0.01745329251994329547) + +D3DXQUATERNION * D3DXQuaternionIdentity( + __inout D3DXQUATERNION *pOut + ) +{ + *pOut = gfsdk_makeFloat4(0, 0, 0, 1); + return pOut; +} + +D3DXQUATERNION * D3DXQuaternionNormalize( + __inout D3DXQUATERNION *pOut, + __in const D3DXQUATERNION *pQ + ) +{ + gfsdk_normalize(*pOut); + return pOut; +} + +D3DXQUATERNION * D3DXQuaternionRotationAxis( + __inout D3DXQUATERNION *pOut, + __in const D3DXVECTOR3 *pV, + __in FLOAT Angle + ) +{ + FLOAT s = sin(Angle * 0.5); + + FLOAT x = pV->x * s; + FLOAT y = pV->y * s; + FLOAT z = pV->z * s; + FLOAT w = cos(Angle * 0.5); + + *pOut = gfsdk_makeFloat4(x, y, z, w); + return pOut; +} + +D3DXQUATERNION * D3DXQuaternionMultiply( + __inout D3DXQUATERNION *pOut, + __in const D3DXQUATERNION *pQ1, + __in const D3DXQUATERNION *pQ2 + ) +{ + gfsdk_normalize(*pQ1); + gfsdk_normalize(*pQ2); + + FLOAT px = pQ2->x; + FLOAT py = pQ2->y; + FLOAT pz = pQ2->z; + FLOAT pw = pQ2->w; + + FLOAT qx = pQ1->x; + FLOAT qy = pQ1->y; + FLOAT qz = pQ1->z; + FLOAT qw = pQ1->w; + + FLOAT x = pw * qx + px * qw + py * qz - pz * qy; + FLOAT y = pw * qy + py * qw + pz * qx - px * qz; + FLOAT z = pw * qz + pz * qw + px * qy - py * qx; + FLOAT w = pw * qw - px * qx - py * qy - pz * qz; + + *pOut = gfsdk_makeFloat4(x, y, z, w); + gfsdk_normalize(*pOut); + return pOut; +} + +D3DXMATRIX * D3DXMatrixLookAtLH( + __inout D3DXMATRIX *pOut, + __in const D3DXVECTOR3 *pEye, + __in const D3DXVECTOR3 *pAt, + __in const D3DXVECTOR3 *pUp + ) +{ + /* + zaxis = normal(At - Eye) + xaxis = normal(cross(Up, zaxis)) + yaxis = cross(zaxis, xaxis) + + xaxis.x yaxis.x zaxis.x 0 + xaxis.y yaxis.y zaxis.y 0 + xaxis.z yaxis.z zaxis.z 0 + -dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1 + */ + + D3DXVECTOR3 zaxis = *pAt - *pEye; + gfsdk_normalize(zaxis); + D3DXVECTOR3 xaxis = gfsdk_cross(*pUp, zaxis); + gfsdk_normalize(xaxis); + D3DXVECTOR3 yaxis = gfsdk_cross(zaxis, xaxis); + + gfsdk_makeIdentity(*pOut); + pOut->_11 = zaxis.x; + pOut->_21 = zaxis.y; + pOut->_31 = zaxis.z; + pOut->_12 = yaxis.x; + pOut->_22 = yaxis.y; + pOut->_32 = yaxis.z; + pOut->_13 = zaxis.x; + pOut->_23 = zaxis.y; + pOut->_33 = zaxis.z; + pOut->_41 = -gfsdk_dot(xaxis, *pEye); + pOut->_42 = -gfsdk_dot(yaxis, *pEye); + pOut->_43 = -gfsdk_dot(zaxis, *pEye); + return pOut; +} + +D3DXMATRIX * D3DXMatrixLookAtRH( + __inout D3DXMATRIX *pOut, + __in const D3DXVECTOR3 *pEye, + __in const D3DXVECTOR3 *pAt, + __in const D3DXVECTOR3 *pUp + ) +{ + /* + zaxis = normal(Eye - At) + xaxis = normal(cross(Up, zaxis)) + yaxis = cross(zaxis, xaxis) + + xaxis.x yaxis.x zaxis.x 0 + xaxis.y yaxis.y zaxis.y 0 + xaxis.z yaxis.z zaxis.z 0 + -dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1 + */ + + D3DXVECTOR3 zaxis = *pEye - *pAt; + gfsdk_normalize(zaxis); + D3DXVECTOR3 xaxis = gfsdk_cross(*pUp, zaxis); + gfsdk_normalize(xaxis); + D3DXVECTOR3 yaxis = gfsdk_cross(zaxis, xaxis); + + gfsdk_makeIdentity(*pOut); + pOut->_11 = xaxis.x; + pOut->_21 = xaxis.y; + pOut->_31 = xaxis.z; + pOut->_12 = yaxis.x; + pOut->_22 = yaxis.y; + pOut->_32 = yaxis.z; + pOut->_13 = zaxis.x; + pOut->_23 = zaxis.y; + pOut->_33 = zaxis.z; + pOut->_41 = -gfsdk_dot(xaxis, *pEye); + pOut->_42 = -gfsdk_dot(yaxis, *pEye); + pOut->_43 = gfsdk_dot(zaxis, *pEye); + return pOut; +} + +D3DXMATRIX * D3DXMatrixPerspectiveFovLH( + __inout D3DXMATRIX *pOut, + __in FLOAT fovy, + __in FLOAT Aspect, + __in FLOAT zn, + __in FLOAT zf + ) +{ + /* + cot(fovY/2) 0 0 0 + 0 cot(fovY/2)/aspect 0 0 + 0 0 zf/(zf-zn) 1 + 0 0 -zn*zf/(zf-zn) 0 + */ + + memset(pOut, 0, sizeof(D3DXMATRIX)); + FLOAT cosHalfFovy = 1 / tan(fovy * 0.5); + pOut->_11 = cosHalfFovy; + pOut->_22 = cosHalfFovy / Aspect; + pOut->_33 = zf / (zf - zn); + pOut->_34 = 1; + pOut->_43 = -zn*zf / (zf - zn); + return pOut; +} + +D3DXMATRIX * D3DXMatrixPerspectiveFovRH( + __inout D3DXMATRIX *pOut, + __in FLOAT fovy, + __in FLOAT Aspect, + __in FLOAT zn, + __in FLOAT zf + ) +{ + /* + cot(fovY/2)/aspect 0 0 0 + 0 cot(fovY/2) 0 0 + 0 0 zf/(zn-zf) -1 + 0 0 zn*zf/(zn-zf) 0 + */ + + memset(pOut, 0, sizeof(D3DXMATRIX)); + FLOAT cosHalfFovy = 1 / tan(fovy * 0.5); + pOut->_11 = cosHalfFovy / Aspect; + pOut->_22 = cosHalfFovy; + pOut->_33 = zf / (zn - zf); + pOut->_34 = -1; + pOut->_43 = zn*zf / (zn - zf); + return pOut; +} + +D3DXMATRIX * D3DXMatrixOrthoLH( + __inout D3DXMATRIX *pOut, + __in FLOAT w, + __in FLOAT h, + __in FLOAT zn, + __in FLOAT zf + ) +{ + /* + 2/w 0 0 0 + 0 2/h 0 0 + 0 0 1/(zf-zn) 0 + 0 0 zn/(zn-zf) 1 + */ + + gfsdk_makeIdentity(*pOut); + pOut->_11 = 2 / w; + pOut->_22 = 2 / h; + pOut->_33 = 1 / (zf - zn); + pOut->_43 = zn / (zn - zf); + return pOut; +} + +D3DXMATRIX * D3DXMatrixOrthoRH( + __inout D3DXMATRIX *pOut, + __in FLOAT w, + __in FLOAT h, + __in FLOAT zn, + __in FLOAT zf + ) +{ + /* + 2/w 0 0 0 + 0 2/h 0 0 + 0 0 1/(zn-zf) 0 + 0 0 zn/(zn-zf) 1 + */ + + gfsdk_makeIdentity(*pOut); + pOut->_11 = 2 / w; + pOut->_22 = 2 / h; + pOut->_33 = 1 / (zn - zf); + pOut->_43 = zn / (zn - zf); + return pOut; +} + +D3DXQUATERNION * D3DXQuaternionRotationMatrix( + __inout D3DXQUATERNION *pOut, + __in const D3DXMATRIX *pM + ) +{ + FLOAT fourXSquaredMinus1 = pM->_11 - pM->_22 - pM->_33; + FLOAT fourYSquaredMinus1 = pM->_22 - pM->_11 - pM->_33; + FLOAT fourZSquaredMinus1 = pM->_33 - pM->_11 - pM->_22; + FLOAT fourWSquaredMinus1 = pM->_11 + pM->_22 + pM->_33; + + int biggestIndex = 0; + FLOAT fourBiggestSquaredMinus1 = fourWSquaredMinus1; + if (fourXSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourXSquaredMinus1; + biggestIndex = 1; + } + if (fourYSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourYSquaredMinus1; + biggestIndex = 2; + } + if (fourZSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourZSquaredMinus1; + biggestIndex = 3; + } + + FLOAT biggestVal = sqrt(fourBiggestSquaredMinus1 + 1) * 0.5; + FLOAT mult = 0.25 / biggestVal; + + D3DXQuaternionIdentity(pOut); + switch (biggestIndex) + { + case 0: + pOut->w = biggestVal; + pOut->x = (pM->_23 - pM->_32) * mult; + pOut->y = (pM->_31 - pM->_13) * mult; + pOut->z = (pM->_12 - pM->_21) * mult; + break; + case 1: + pOut->w = (pM->_23 - pM->_32) * mult; + pOut->x = biggestVal; + pOut->y = (pM->_12 + pM->_21) * mult; + pOut->z = (pM->_31 + pM->_13) * mult; + break; + case 2: + pOut->w = (pM->_31 - pM->_13) * mult; + pOut->x = (pM->_12 + pM->_21) * mult; + pOut->y = biggestVal; + pOut->z = (pM->_23 + pM->_32) * mult; + break; + case 3: + pOut->w = (pM->_12 - pM->_21) * mult; + pOut->x = (pM->_31 + pM->_13) * mult; + pOut->y = (pM->_23 + pM->_32) * mult; + pOut->z = biggestVal; + break; + default: + break; + } + return pOut; +} + +D3DXMATRIX * D3DXMatrixRotationQuaternion( + __inout D3DXMATRIX *pOut, + __in const D3DXQUATERNION *pQ + ) +{ + gfsdk_makeIdentity(*pOut); + FLOAT qxx = (pQ->x * pQ->x); + FLOAT qyy = (pQ->y * pQ->y); + FLOAT qzz = (pQ->z * pQ->z); + FLOAT qxz = (pQ->x * pQ->z); + FLOAT qxy = (pQ->x * pQ->y); + FLOAT qyz = (pQ->y * pQ->z); + FLOAT qwx = (pQ->w * pQ->x); + FLOAT qwy = (pQ->w * pQ->y); + FLOAT qwz = (pQ->w * pQ->z); + pOut->_11 = 1 - 2 * (qyy + qzz); + pOut->_12 = 2 * (qxy + qwz); + pOut->_13 = 2 * (qxz - qwy); + pOut->_21 = 2 * (qxy - qwz); + pOut->_22 = 1 - 2 * (qxx + qzz); + pOut->_23 = 2 * (qyz + qwx); + pOut->_31 = 2 * (qxz + qwy); + pOut->_32 = 2 * (qyz - qwx); + pOut->_33 = 1 - 2 * (qxx + qyy); + return pOut; +} +#endif // USE_D3DX9MATH + +Camera::Camera(bool zup, bool lhs) + : + _zup(zup), + _lhs(lhs), + _isPerspective(true) +{ + + D3DXQuaternionIdentity((D3DXQUATERNION*)&_orientation); + + gfsdk_makeIdentity(_viewMatrix); + gfsdk_makeIdentity(_projectionMatrix); + + _fov = (75.0f / 360.0f) * 3.141592653589793; +} + +Camera::~Camera() +{ +} + +void +Camera::Init(bool zup, bool lhs) +{ + _lhs = lhs; + _zup = zup; +} + +atcore_float3 Camera::GetUp() const +{ + atcore_float3 up; + + if (IsYUp()) + up = gfsdk_makeFloat3(0.0f, 1.0f, 0.0f); + else + up = gfsdk_makeFloat3(0.0f, 0.0f, 1.0f); + + return up; +} + +void Camera::SetDefaults() +{ + atcore_float3 eye; + atcore_float3 at = gfsdk_makeFloat3(0.0f, 0.0f, 0.0f); + + if (IsYUp()) + { + if (_lhs) + eye = gfsdk_makeFloat3(0.0f, 60.0f, -120.0f); + else + eye = gfsdk_makeFloat3(0.0f, 60.0f, 120.0f); + } + else // zup + { + if (_lhs) + eye = gfsdk_makeFloat3(0.0f, 120.0f, 60.0f); + else + eye = gfsdk_makeFloat3(0.0f, -120.0f, 60.0f); + } + + atcore_float3 up = GetUp(); + + LookAt(eye, at, up); +} + +// Build a look at matrix, and calculate the major axis and rotation component. +void Camera::LookAt(const atcore_float3& eye, const atcore_float3& at, const atcore_float3& up) +{ + if (_lhs) + D3DXMatrixLookAtLH((D3DXMATRIX*)&_viewMatrix, (D3DXVECTOR3*)&eye, (D3DXVECTOR3*)&at, (D3DXVECTOR3*)&up); + else + D3DXMatrixLookAtRH((D3DXMATRIX*)&_viewMatrix, (D3DXVECTOR3*)&eye, (D3DXVECTOR3*)&at, (D3DXVECTOR3*)&up); + + _eye = eye; + _at = at; + + atcore_float3 dir = at - eye; + _lookDistance = gfsdk_length(dir); + + D3DXQuaternionRotationMatrix((D3DXQUATERNION*)&_orientation, (D3DXMATRIX*)&_viewMatrix); + BuildViewMatrix(); +} + +void Camera::SetEye(const atcore_float3& eye) +{ + _eye = eye; + _lookDistance = gfsdk_distance(_eye, _at); +} + +void Camera::SetAt(const atcore_float3& at) +{ + _at = at; + _lookDistance = gfsdk_distance(_eye, _at); +} + +void Camera::SetViewMatrix(const atcore_float3& xAxis, const atcore_float3& yAxis, const atcore_float3& zAxis) +{ + _viewMatrix._11 = xAxis.x; _viewMatrix._21 = xAxis.y; _viewMatrix._31 = xAxis.z; + _viewMatrix._12 = yAxis.x; _viewMatrix._22 = yAxis.y; _viewMatrix._32 = yAxis.z; + _viewMatrix._13 = zAxis.x; _viewMatrix._23 = zAxis.y; _viewMatrix._33 = zAxis.z; + + D3DXQuaternionRotationMatrix((D3DXQUATERNION*)&_orientation, (D3DXMATRIX*)&_viewMatrix); + D3DXQuaternionNormalize((D3DXQUATERNION*)&_orientation, (D3DXQUATERNION*)&_orientation); + + atcore_float3 _viewDirection = _lhs ? -1.0f * zAxis : zAxis; + + _eye = _at + _viewDirection * _lookDistance; + + _viewMatrix._41 = - gfsdk_dot(xAxis,_eye); + _viewMatrix._42 = - gfsdk_dot(yAxis,_eye); + _viewMatrix._43 = - gfsdk_dot(zAxis,_eye); +} + +// Build a perspective matrix +void Camera::Perspective() +{ + _isPerspective = true; + + if (_lhs) + D3DXMatrixPerspectiveFovLH( (D3DXMATRIX*)&_projectionMatrix, _fov, _aspectRatio, _znear, _zfar); + else + D3DXMatrixPerspectiveFovRH( (D3DXMATRIX*)&_projectionMatrix, _fov, _aspectRatio, _znear, _zfar); + +} + +void Camera::Ortho(float width, float height, float znear, float zfar) +{ + if (_lhs) + D3DXMatrixOrthoLH( (D3DXMATRIX*)&_projectionMatrix, width, height, znear, zfar); + else + D3DXMatrixOrthoRH( (D3DXMATRIX*)&_projectionMatrix, width, height, znear, zfar); + + _znear = znear; + _zfar = zfar; + _width = width; + _height = height; + _isPerspective = false; +} + +// Dolly towards the viewpoint +void Camera::Dolly(float zoom) +{ + if (_isPerspective) + { + atcore_float3 offset = _eye - _at; + + _lookDistance = gfsdk_length(offset); + + gfsdk_normalize(offset); + + float zoomFactor = zoom * _lookDistance; + + _lookDistance += zoomFactor; + + _eye = _lookDistance * offset + _at; + + BuildViewMatrix(); + } + else + { + _width += zoom * 4.0f; + _height += zoom * 4.0f; + + D3DXMatrixOrthoRH( (D3DXMATRIX*)&_projectionMatrix, _width, _height, _znear, _zfar); + + } +} + +// Orbit around the viewpoint +void Camera::Orbit(const atcore_float2& delta) +{ + + float heading = D3DXToRadian(delta.x); + float pitch = D3DXToRadian(delta.y); + + if (_lhs) + { + heading *= -1.0f; + pitch *= -1.0f; + } + + D3DXQUATERNION rot; + + D3DXVECTOR3 yAxis = MAKEVECTOR3(0.0f, 0.0f, 1.0f); + if (IsYUp()) // change up axis if Y is the up axis (for maya) + { + yAxis = MAKEVECTOR3( 0.0f, 1.0f, 0.0f ); + } + + D3DXVECTOR3 xAxis = MAKEVECTOR3(1.0f, 0.0f, 0.0f); + if (heading != 0.0f) + { + D3DXQuaternionRotationAxis(&rot, &yAxis, heading); + D3DXQuaternionMultiply((D3DXQUATERNION*)&_orientation, &rot, (D3DXQUATERNION*)&_orientation); + } + + if (pitch != 0.0f) + { + D3DXQuaternionRotationAxis(&rot, &xAxis, pitch); + D3DXQuaternionMultiply((D3DXQUATERNION*)&_orientation, (D3DXQUATERNION*)&_orientation, &rot); + } + BuildViewMatrix(); + +} + +// Orbit around the model's center for HAIR-188 +void Camera::OrbitLight(const atcore_float2& delta) +{ + + float heading = D3DXToRadian(delta.x); + float pitch = D3DXToRadian(delta.y); + + if (_lhs) + { + heading *= -1.0f; + pitch *= -1.0f; + } + + D3DXQUATERNION rot; + + D3DXVECTOR3 yAxis = MAKEVECTOR3(0.0f, 0.0f, 1.0f); + if (IsYUp()) // change up axis if Y is the up axis (for maya) + { + yAxis = MAKEVECTOR3( 0.0f, 1.0f, 0.0f ); + } + + D3DXVECTOR3 xAxis = MAKEVECTOR3(1.0f, 0.0f, 0.0f); + if (heading != 0.0f) + { + D3DXQuaternionRotationAxis(&rot, &yAxis, heading); + D3DXQuaternionMultiply((D3DXQUATERNION*)&_orientation, &rot, (D3DXQUATERNION*)&_orientation); + } + + if (pitch != 0.0f) + { + D3DXQuaternionRotationAxis(&rot, &xAxis, pitch); + D3DXQuaternionMultiply((D3DXQUATERNION*)&_orientation, &rot, (D3DXQUATERNION*)&_orientation); + } + BuildViewMatrix(); + +} + +void Camera::Pan(const atcore_float2& delta) +{ + //Scale the movement by the current view + //float depth = depthRange.y - depthRange.x; + + atcore_float3 viewDir = GetEye() - GetAt(); + float depth = gfsdk_length(viewDir); + if (depth <= 0.0f) + depth = 1.0f; + + atcore_float3 xAxis = GetXAxis(); + atcore_float3 yAxis = GetYAxis(); + + if (_isPerspective) + { + float fov2 = ((float)-tan(0.5 * _fov) * (depth)); + atcore_float2 newDelta = fov2 * delta; + + _at = _at + (-1.0f * yAxis * newDelta.y) + (xAxis * newDelta.x); + } + else + { + atcore_float2 newDelta = depth * delta; + _at = _at + (yAxis * newDelta.y) + (-1.0f * xAxis * newDelta.x); + } + + + BuildViewMatrix(); +} + +atcore_float3 Camera::GetXAxis() const +{ + return gfsdk_makeFloat3(_viewMatrix._11, _viewMatrix._21, _viewMatrix._31); + +} + +atcore_float3 Camera::GetYAxis() const +{ + return gfsdk_makeFloat3(_viewMatrix._12, _viewMatrix._22, _viewMatrix._32); +} + +atcore_float3 Camera::GetZAxis() const +{ + return gfsdk_makeFloat3(_viewMatrix._13, _viewMatrix._23, _viewMatrix._33); +} + +atcore_float3 Camera::GetViewDirection() const +{ + atcore_float3 zAxis = GetZAxis(); + return _lhs ? -1.0f * zAxis : zAxis; +} + +// Reconstruct the view matrix from the current orientation and eye/look direction. +void Camera::BuildViewMatrix() +{ + // Reconstruct the view matrix. + D3DXQuaternionNormalize((D3DXQUATERNION*)&_orientation, (D3DXQUATERNION*)&_orientation); + D3DXMatrixRotationQuaternion((D3DXMATRIX*)&_viewMatrix, (D3DXQUATERNION*)&_orientation); + + atcore_float3 xAxis = GetXAxis(); + atcore_float3 yAxis = GetYAxis(); + atcore_float3 zAxis = GetZAxis(); + + atcore_float3 viewDirection = GetViewDirection(); + + _eye = _at + viewDirection * _lookDistance; + + _viewMatrix._41 = - gfsdk_dot(xAxis,_eye); + _viewMatrix._42 = - gfsdk_dot(yAxis,_eye); + _viewMatrix._43 = - gfsdk_dot(zAxis,_eye); +} + +// Set Z Up or Y Up. +void Camera::ResetUpDir(bool zup) +{ + if (zup == _zup) + return; + + _zup = zup; + + atcore_float3 eye = GetEye(); + atcore_float3 at = GetAt(); + atcore_float3 up; + + if (IsYUp()) + { + // Swap eye z and y + float temp = eye.y; + eye.y = eye.z; + eye.z = -temp; + // Swap at z and y + temp = at.y; + at.y = at.z; + at.z = -temp; + + // Set up dir + up = gfsdk_makeFloat3(0.0f, 1.0f, 0.0f); + } + else + { + // Swap eye z and y + float temp = eye.y; + eye.y = -eye.z; + eye.z = temp; + // Swap at z and y + temp = at.y; + at.y = -at.z; + at.z = temp; + + // Set up dir + up = gfsdk_makeFloat3(0.0f, 0.0f, 1.0f); + } + LookAt(eye, at, up); + BuildViewMatrix(); +} + +// Set Z Up or Y Up. +void Camera::ResetLhs(bool lhs) +{ + if (lhs == _lhs) + return; + + _lhs = lhs; + + atcore_float3 eye = GetEye(); + atcore_float3 at = GetAt(); + + if (_zup) + { + eye.y *= -1; + at.y *= -1; + } + else + { + eye.z *= -1; + at.z *= -1; + } + + if (_isPerspective) + Perspective(); + else + Ortho(_width, _height, _znear, _zfar); + + atcore_float3 up = GetUp(); + + LookAt(eye, at, up); + BuildViewMatrix(); +} + +void Camera::FitBounds(const atcore_float3& center, const atcore_float3& extents) +{ + SetAt(center); + // set center first to get eye + BuildViewMatrix(); + if (_isPerspective) + { + float size = extents.x; + size = max(size, extents.y); + size = max(size, extents.z); + atcore_float3 eye = GetEye(); + + atcore_float3 dir = eye - center; + gfsdk_normalize(dir); + float distance = size / tanf(_fov/2.f); + + eye = center + distance * dir; + + SetEye(eye); + BuildViewMatrix(); + } +} + +#ifndef NV_ARTISTTOOLS +#include "ProjectParams.h" +#endif // NV_ARTISTTOOLS + +bool Camera::LoadParameters(void* ptr) +{ +#ifndef NV_ARTISTTOOLS + nvidia::parameterized::HairProjectParametersNS::Camera_Type* param = + static_cast<nvidia::parameterized::HairProjectParametersNS::Camera_Type*>(ptr); + + _zup = param->flags == 1; + _fov = param->fov; + _aspectRatio = param->aspectRatio; + _znear = param->znear; + _zfar = param->zfar; + _isPerspective = param->isPerspective; + memcpy(&_eye, ¶m->eye, sizeof(_eye)); + memcpy(&_at, ¶m->at, sizeof(_at)); + _lookDistance = param->lookDistance; + memcpy(&_orientation, ¶m->orientation, sizeof(_orientation)); + memcpy(&_viewMatrix, ¶m->viewMatrix, sizeof(_viewMatrix)); + memcpy(&_projectionMatrix, ¶m->projectionMatrix, sizeof(_projectionMatrix)); +#else + CoreLib::Inst()->Camera_LoadParameters(ptr, this); +#endif // NV_ARTISTTOOLS + return true; +} + +bool Camera::SaveParameters(void *ptr) +{ +#ifndef NV_ARTISTTOOLS + nvidia::parameterized::HairProjectParametersNS::Camera_Type* outParam = + static_cast<nvidia::parameterized::HairProjectParametersNS::Camera_Type*>(ptr); + + outParam->flags = (_zup ? 1 : 2); + outParam->fov = _fov; + outParam->aspectRatio = _aspectRatio; + outParam->znear = _znear; + outParam->zfar = _zfar; + outParam->width = 0; + outParam->height = 0; + outParam->isPerspective = _isPerspective; + memcpy(&outParam->eye, &_eye, sizeof(outParam->eye)); + memcpy(&outParam->at, &_at, sizeof(outParam->at)); + outParam->lookDistance = _lookDistance; + memcpy(&outParam->orientation, &_orientation, sizeof(outParam->orientation)); + memcpy(&outParam->viewMatrix, &_viewMatrix, sizeof(outParam->viewMatrix)); + memcpy(&outParam->projectionMatrix, &_projectionMatrix, sizeof(outParam->projectionMatrix)); +#else + CoreLib::Inst()->Camera_SaveParameters(ptr, this); +#endif // NV_ARTISTTOOLS + return true; +} + +void Camera::getScreenCoord(float x, float y, float z, int &sx, int &sy) +{ + atcore_float4x4 view = (atcore_float4x4&)GetViewMatrix(); + atcore_float4x4 projection = (atcore_float4x4&)GetProjectionMatrix(); + + atcore_float4x4 viewProjection = view * projection; + + atcore_float4 vp = gfsdk_transform(viewProjection, gfsdk_makeFloat4(x, y, z, 1.0f)); + + float nx = vp.x / vp.w; + float ny = vp.y / vp.w; + + float w = GetWidth(); + float h = GetHeight(); + + sx = w * (0.5f + 0.5f * nx); + sy = h * (0.5f - 0.5f * ny); + +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Camera.h b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Camera.h new file mode 100644 index 0000000..23fb0c6 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Camera.h @@ -0,0 +1,128 @@ +// 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-2015 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. +// + +#pragma once + +#include "MathUtil.h" + +class CORELIB_EXPORT Camera +{ +public: + + // YUp default + Camera(bool zUp = false, bool lhs = false); + ~Camera(); + + void Init(bool zup, bool lhs); + void LookAt(const atcore_float3& eye, const atcore_float3& target, const atcore_float3& up); + void Perspective(); + void Ortho(float width, float height, float znear, float zfar); + void Dolly(float zoom); + void Orbit(const atcore_float2& delta); + void OrbitLight(const atcore_float2& delta); // special for HAIR-188 + void Pan(const atcore_float2& delta); + + void getScreenCoord(float x, float y, float z, int &sx, int &sy); + + float GetZNear() { return _znear; } + float GetZFar() { return _zfar; } + + const atcore_float3& GetAt() const { return _at; } + const atcore_float3& GetEye() const { return _eye; } + + float GetWidth() const { return _width; } + float GetHeight() const { return _height; } + + void SetFOV(float fov) { _fov = fov; } + void SetAspetRatio(float aspect) { _aspectRatio = aspect; } + void SetZNear(float znear) { _znear = znear; } + void SetZFar(float zfar) { _zfar = zfar; } + + void SetSize(int w, int h) { _width = w; _height = h; } + + atcore_float3 GetXAxis() const; + atcore_float3 GetYAxis() const; + atcore_float3 GetZAxis() const; + + atcore_float3 GetViewDirection() const; + + void SetViewMatrix(const atcore_float3& xAxis, const atcore_float3& yAxis, const atcore_float3& zAxis); + + float GetLookDistance() const { return _lookDistance; } + atcore_float3 GetUp() const; + + void SetEye(const atcore_float3& eye); + void SetAt(const atcore_float3& at); + + atcore_float2 GetZRange() const { return gfsdk_makeFloat2(_znear, _zfar); } + + const atcore_float4x4& GetProjectionMatrix() const { return _projectionMatrix; } + const atcore_float4x4& GetViewMatrix() const { return _viewMatrix; } + + // Change Up Dir and reset internal eye and at. + void ResetUpDir(bool zup); + void ResetLhs(bool lhs); + + bool IsYUp() const { return _zup == false; } + bool UseLHS() const { return _lhs; } + + bool LoadParameters(void* param); + bool SaveParameters(void* outParam); + + void BuildViewMatrix(); + + void SetDefaults(); + + void FitBounds(const atcore_float3& center, const atcore_float3& extents); + + +//private: + // coordinate axis + bool _zup; + bool _lhs; + + // Perspective + bool _isPerspective; + float _fov; + float _aspectRatio; + + float _znear; + float _zfar; + float _width; + float _height; + + float _lookDistance; + + atcore_float3 _eye; + atcore_float3 _at; + + atcore_float4 _orientation; + atcore_float4x4 _viewMatrix; + atcore_float4x4 _projectionMatrix; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp new file mode 100644 index 0000000..01e3323 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Gamepad.cpp @@ -0,0 +1,1310 @@ +#include <windows.h> +#include <SDL.h> +#include <QtWidgets/QApplication> +#include <QtCore/QDir> +#include <QtCore/QDirIterator> +#include <QtCore/QString> +#include <QtCore/QList> + +#include "Gamepad.h" + +#include "Camera.h" +#include "SimpleScene.h" +#include "AppMainWindow.h" +#include "DisplayLightPanel.h" +#include "DisplayScenePanel.h" + +#include "DXUT.h" +//#include "D3D11RendererWindow.h" +#include "sdkmisc.h" +#include "GlobalSettings.h" +#include "Light.h" +#include "DisplayPreferencesPanel.h" +#include "ViewerOutput.h" +#include "D3DWidget.h" +#include <stdarg.h> +#include <vector> +#include <string> + +#ifndef NV_ARTISTTOOLS +#include "BlastToolbar.h" +#include "DisplayVisualizersPanel.h" +#include "FurCharacter.h" +#include "HairParams.h" +#endif // NV_ARTISTTOOLS + +const bool bSaveLogToDisk = true; +bool bDefaultDemoMode = false; + +static QList<QString> demoProjects; + +static int curentPrjIdx = -1; +static int iQuitState = 0; + +static std::string strAppDir; + +SimpleScene* theScene = NV_NULL; + +bool bUseOldLightCam = false, bUseOldSceneCam = false; + +enum ButtonState +{ + BUTTON_NOTHING, + BUTTON_DOWN, + BUTTON_HOLDING, + BUTTON_UP, +}; + +class GamepadHandler +{ +public: + GamepadHandler() + :joystick(0) + { + } + + ~GamepadHandler() + { + DisConnect(); + } + + void DisConnect() + { + if(joystick) + { + SDL_JoystickClose(joystick); + joystick = NV_NULL; + } + } + + void Process(); + + inline ButtonState ButtonState(int button) + { + if (button >= 0 && button < iButtonState.size()) + { + if (iButtonState[button] && iButtonStateOld[button] == 0) + return BUTTON_DOWN; + else if (iButtonState[button] && iButtonStateOld[button]) + return BUTTON_HOLDING; + else if (iButtonState[button] == 0 && iButtonStateOld[button]) + return BUTTON_UP; + } + return BUTTON_NOTHING; + } + + inline int AxisChange(int idx) + { + if (idx >= 0 && idx < iAxisState.size()) + { + return (iAxisState[idx] - iAxisStateAtBegin[idx]); + } + return 0; + } + + const char* pjsName; + int numAxis; + int numTrackballs; + int numPov; + int numButtons; + + std::vector<int> bKeyHolding; + std::vector<int> iAxisStateAtBegin; + std::vector<int> iAxisStateOld; + std::vector<int> iAxisState; + std::vector<int> iButtonStateOld; + std::vector<int> iButtonState; + + SDL_Joystick* joystick; + SDL_JoystickGUID jsGuid; +}; + +std::vector<GamepadHandler> gHandlers; + +// +// Gamepad thresholds taken from XINPUT API +// +//#define GAMEPAD_LEFT_THUMB_DEADZONE 7849 +//#define GAMEPAD_RIGHT_THUMB_DEADZONE 8689 +//#define GAMEPAD_TRIGGER_THRESHOLD 30 + +#define GAMEPAD_BUMPER_DEADZONE 9000 +inline int ClampAxis(int value) +{ + if((value>GAMEPAD_BUMPER_DEADZONE) || (value<-GAMEPAD_BUMPER_DEADZONE)) + return value; + return 0; +} + +std::vector<std::string> keylog; + +void LogAdd(const char *fmt,...) +{ + if(bSaveLogToDisk) + { + static char logBuf[2048]; + va_list arg; + va_start( arg, fmt ); + vsprintf(logBuf, fmt, arg); + va_end(arg); + keylog.push_back(logBuf); + } +} + +void SaveLog() +{ + if(keylog.size()) + { + std::string fn = strAppDir + "\\buttonLog.txt"; + FILE* fp = fopen(fn.c_str(), "w+"); + if(fp) + { + for(int i = 0; i < keylog.size(); ++i) + { + std::string& info = keylog[i]; + fputs(info.c_str(), fp); + fputs("\n", fp); + } + fclose(fp); + } + } +} + +//XBOX 360 AXIS +static int AXIS_LS_X = 0; +static int AXIS_LS_Y = 1; +static int AXIS_RS_X = 2; +static int AXIS_RS_Y = 3; +static int AXIS_LT = 4; +static int AXIS_RT = 5; + +// XBox 360 Key codes +static int GAMEPAD_KEY_DPAD_UP = 0; +static int GAMEPAD_KEY_DPAD_DOWN = 1; +static int GAMEPAD_KEY_DPAD_LEFT = 2; +static int GAMEPAD_KEY_DPAD_RIGHT = 3; +static int GAMEPAD_KEY_START = 4; +static int GAMEPAD_KEY_BACK = 5; +static int GAMEPAD_KEY_LS = 6; +static int GAMEPAD_KEY_RS = 7; +static int GAMEPAD_KEY_LEFT_BUMP = 8; +static int GAMEPAD_KEY_RIGHT_BUMP = 9; +static int GAMEPAD_KEY_A = 10; +static int GAMEPAD_KEY_B = 11; +static int GAMEPAD_KEY_X = 12; +static int GAMEPAD_KEY_Y = 13; + +double GetSeconds() +{ + static LARGE_INTEGER lastTime; + static LARGE_INTEGER freq; + static bool first = true; + + if (first) + { + QueryPerformanceCounter(&lastTime); + QueryPerformanceFrequency(&freq); + + first = false; + } + + static double time = 0.0; + + LARGE_INTEGER t; + QueryPerformanceCounter(&t); + + __int64 delta = t.QuadPart-lastTime.QuadPart; + double deltaSeconds = double(delta) / double(freq.QuadPart); + + time += deltaSeconds; + + lastTime = t; + + return time; + +} + +Gamepad::Gamepad() +{ +} + +Gamepad::~Gamepad() +{ +} + +Gamepad& Gamepad::Instance() +{ + static Gamepad gmpad; + return gmpad; +} + +void ChangeMode() +{ + AppMainWindow::Inst().shortcut_expert(); +} + +void ToggleSimulation() +{ +#ifndef NV_ARTISTTOOLS + BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar(); + toolbar->on_btnEnableSimulation_clicked(); + // read simulation state; have to call it twice to avoid change it. + GlobalSettings::Inst().toggleSimulation(); + + bool anim = GlobalSettings::Inst().toggleSimulation(); + DisplayFurVisualizersPanel* furPanel = AppMainWindow::Inst().GetFurVisualizersPanel(); + if(furPanel) + { + furPanel->on_btnShowHair_stateChanged(anim); + furPanel->updateValues(); + } +#else + CoreLib::Inst()->Gamepad_ToggleSimulation(); +#endif // NV_ARTISTTOOLS +} + +void StartAnimation() +{ +#ifndef NV_ARTISTTOOLS + GlobalSettings::Inst().toggleSimulation(); + bool simulating = GlobalSettings::Inst().toggleSimulation(); // call it twice to get right state + + GlobalSettings::Inst().toggleAnimation(); + bool animating = GlobalSettings::Inst().toggleAnimation(); // call it twice to get right state + + BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar(); + if(!simulating) + toolbar->on_btnEnableSimulation_clicked(); + + if(!animating) + toolbar->on_btnPlayAnimation_clicked(); + + // reset animation + //toolbar->on_btnResetAnimation_clicked(); +#else + CoreLib::Inst()->Gamepad_StartAnimation(); +#endif // NV_ARTISTTOOLS +} + +void ButtonAPressed() +{ + // Play/Pause the animation + Gamepad::PlayPauseAnimation(); +} + +void ButtonBPressed() +{ + // Stops and re-starts animation + Gamepad::ResetAnimation(); +} + +void Gamepad::ShowProjectName() +{ + bool bExpertMode = AppMainWindow::IsExpertMode(); + // need change title + char msg[1024]; + // show title + if(curentPrjIdx != -1) + { + QString fn = demoProjects.at(curentPrjIdx); + sprintf(msg, "Blast Viewer - %s %s", fn.toUtf8().data(), (bExpertMode ? "Demo Mode" : "")); + AppMainWindow::Inst().setWindowTitle(msg); + } + else + { + if (bExpertMode) + { + sprintf(msg, "Blast Viewer - Expert Mode"); + } + else + { + sprintf(msg, "Blast Viewer"); + } + AppMainWindow::Inst().setWindowTitle(msg); + } +} + +void LoadSamples(bool bNext) +{ + bUseOldLightCam = bUseOldSceneCam = false; + int prjCount = demoProjects.size(); + if(prjCount==0) + { + DisplayPreferencesPanel* pPanel = AppMainWindow::Inst().GetDisplayPreferencesPanel(); + if (pPanel) + { + pPanel->assignPlayPlaylistToGamepad(); + } + if (0) + { + static int iLimitSampleCount = 20; + QString appDir = strAppDir.c_str(); + QString projectPath; + // load from a specific file first + QString fn = appDir + "\\samples.txt"; + FILE* fp = fopen(fn.toUtf8().data(), "r"); + if (fp) + { + char Line[1024], FileName[2014]; + while (fgets(Line, sizeof(Line), fp) != NV_NULL) + { + QString t = QString(Line).trimmed(); + if (t.length() == 0) + continue; + QString fn = t.toLower(); + std::string strFN = fn.toUtf8().data(); + const char* ptest = strstr(strFN.c_str(), ".furproj"); + if (ptest) + { + const char* pchar = strchr(strFN.c_str(), ':'); + if (pchar) + { + demoProjects.append(fn); + } + else + { + const char* pFirst = strFN.c_str(); + if (pFirst[0] == '/' || pFirst[0] == '\\') + { + fn = appDir + fn; + demoProjects.append(fn); + } + else + { + fn = appDir + QString("/") + fn; + demoProjects.append(fn); + } + } + } + } + fclose(fp); + } + } + if(0) + { + QString appDir = strAppDir.c_str(); + QString projectPath; + // search some relative folders + QDir dirTmp(appDir); + if(dirTmp.cd("./media")) + projectPath = dirTmp.absolutePath(); + else if(dirTmp.cd("../media")) + projectPath = dirTmp.absolutePath(); + else if(dirTmp.cd("../../media")) + projectPath = dirTmp.absolutePath(); + else if(dirTmp.cd("../../media")) + projectPath = dirTmp.absolutePath(); + if(!projectPath.isEmpty()) + { + QStringList filters; + filters<<QString("*.furproj"); + QDirIterator dir_iterator(projectPath, filters, QDir::Files | QDir::NoSymLinks,QDirIterator::Subdirectories); + while(dir_iterator.hasNext()) + { + dir_iterator.next(); + QFileInfo file_info = dir_iterator.fileInfo(); + QString absolute_file_path = file_info.absoluteFilePath(); + demoProjects.append(absolute_file_path); + //if(demoProjects.size()>iLimitSampleCount) + // break; + } + } + else + { + const char* msg = "Fail to find any Blast projects!"; + viewer_msg(msg); + } + } + prjCount = demoProjects.size(); + } + if(prjCount) + { + if (bNext) + { + ++curentPrjIdx; + if (curentPrjIdx >= prjCount) + curentPrjIdx = 0; + } + else + { + --curentPrjIdx; + if (curentPrjIdx < 0) + curentPrjIdx = prjCount - 1; + } + // load sample + QString fn = demoProjects[curentPrjIdx]; + AppMainWindow::Inst().openProject(fn); + } + Gamepad::ShowProjectName(); +} + +void StartButtonPressed() +{ + Gamepad& gp = Gamepad::Instance(); + gp.ShowUsage(); +} + +void BackButtonPressed() +{ + Gamepad::DemoEscape(); + return; + + ++iQuitState; + switch(iQuitState) + { + case 0: + // do nothing + break; + case 1: + { + AppMainWindow::Inst().startProgress(); + AppMainWindow::Inst().setProgressMaximum(2); + AppMainWindow::Inst().setProgress("Press Back again to quit. Press other buttons to cancel it.", 1); + } + break; + case 2: + { + AppMainWindow::Inst().setProgress("Quitting...", 2); + //AppMainWindow::Inst().close(); + Gamepad::DemoEscape(); + } + break; + default: + iQuitState = 0; + break; + } +} + +void Gamepad::HandleJoySticks() +{ + int numJoysticks = SDL_NumJoysticks(); + int numUsedJoysticks = gHandlers.size(); + if (numUsedJoysticks != numJoysticks) + { + gHandlers.clear(); + } + if(numUsedJoysticks < 1) + { + //static int iSkipCount = 0; + //if (++iSkipCount >= 60) + //{ + // iSkipCount = 0; + static int iDoOnce = 1; + if (iDoOnce) + { + iDoOnce = 0; + + Initialize(); + numJoysticks = SDL_NumJoysticks(); + for (int i = 0; i < numJoysticks; ++i) + { + SDL_Joystick* joystick = SDL_JoystickOpen(i); + if (joystick) + { + numUsedJoysticks = gHandlers.size(); + gHandlers.resize(numUsedJoysticks + 1); + GamepadHandler& handler = gHandlers[numUsedJoysticks]; + handler.joystick = joystick; + handler.pjsName = SDL_JoystickName(joystick); + handler.numAxis = SDL_JoystickNumAxes(joystick); + handler.numTrackballs = SDL_JoystickNumBalls(joystick); + handler.numPov = SDL_JoystickNumHats(joystick); + handler.numButtons = SDL_JoystickNumButtons(joystick); + handler.jsGuid = SDL_JoystickGetGUID(joystick); + + LogAdd("Device Name: %s", handler.pjsName); + LogAdd("Num of Axis: %d", handler.numAxis); + LogAdd("Num of Trackballs: %d", handler.numTrackballs); + LogAdd("Num of POV: %d", handler.numPov); + LogAdd("Num of Buttons: %d", handler.numButtons); + LogAdd("Initial Axis States:"); + + handler.iAxisState.resize(handler.numAxis); + handler.iAxisStateAtBegin.resize(handler.numAxis); + handler.iAxisStateOld.resize(handler.numAxis); + + handler.iButtonState.resize(handler.numButtons); + handler.iButtonStateOld.resize(handler.numButtons); + + if (handler.numAxis == 6) + { + // XBOX 360 has 6 axis + AXIS_LS_X = 0; + AXIS_LS_Y = 1; + AXIS_RS_X = 2; + AXIS_RS_Y = 3; + AXIS_LT = 4; + AXIS_RT = 5; + + GAMEPAD_KEY_DPAD_UP = 0; + GAMEPAD_KEY_DPAD_DOWN = 1; + GAMEPAD_KEY_DPAD_LEFT = 2; + GAMEPAD_KEY_DPAD_RIGHT = 3; + GAMEPAD_KEY_START = 4; + GAMEPAD_KEY_BACK = 5; + GAMEPAD_KEY_LS = 6; + GAMEPAD_KEY_RS = 7; + GAMEPAD_KEY_LEFT_BUMP = 8; + GAMEPAD_KEY_RIGHT_BUMP = 9; + GAMEPAD_KEY_A = 10; + GAMEPAD_KEY_B = 11; + GAMEPAD_KEY_X = 12; + GAMEPAD_KEY_Y = 13; + } + else if (handler.numAxis == 5) + { + // Betop has 5 axis when xbox mode + AXIS_LS_X = 0; + AXIS_LS_Y = 1; + AXIS_RS_X = 3; + AXIS_RS_Y = 4; + AXIS_LT = 2; + AXIS_RT = 2; + + GAMEPAD_KEY_DPAD_UP = 10; // POV + GAMEPAD_KEY_DPAD_DOWN = 11; // POV + GAMEPAD_KEY_DPAD_LEFT = 12; // POV + GAMEPAD_KEY_DPAD_RIGHT = 13; // POV + GAMEPAD_KEY_START = 7; + GAMEPAD_KEY_BACK = 6; + GAMEPAD_KEY_LS = 8; + GAMEPAD_KEY_RS = 9; + GAMEPAD_KEY_LEFT_BUMP = 4; + GAMEPAD_KEY_RIGHT_BUMP = 5; + GAMEPAD_KEY_A = 0; + GAMEPAD_KEY_B = 1; + GAMEPAD_KEY_X = 2; + GAMEPAD_KEY_Y = 3; + + if (handler.numPov == 1) + { + // BETOP xbox mode + handler.iButtonState.resize(handler.numButtons + 4); // POV fake buttons + handler.iButtonStateOld.resize(handler.numButtons + 4); + for (int i = GAMEPAD_KEY_DPAD_UP; i <= GAMEPAD_KEY_DPAD_RIGHT; ++i) + { + handler.iButtonStateOld[i] = handler.iButtonState[i] = 0; + } + } + } + for (int i = 0; i < handler.numAxis; ++i) + { + int value = ClampAxis(SDL_JoystickGetAxis(handler.joystick, i)); + handler.iAxisStateAtBegin[i] = handler.iAxisStateOld[i] = handler.iAxisState[i] = value; + LogAdd("Axis %d State %d", i, value); + } + LogAdd("Initial Button States:"); + for (int i = 0; i < handler.numButtons; ++i) + { + int state = SDL_JoystickGetButton(handler.joystick, i); + handler.iButtonStateOld[i] = handler.iButtonState[i] = state; + LogAdd("Button %d State %d", i, state); + } + if (handler.numPov == 1) + { + LogAdd("Initial POV Button States:"); + Uint8 pov = SDL_JoystickGetHat(joystick, 0); + char msg[512]; + sprintf(msg, "POV State: %d", pov); + viewer_msg(msg); + LogAdd(msg); + // BETOP xbox mode + handler.iButtonState.resize(handler.numButtons + 4); // POV fake buttons + handler.iButtonStateOld.resize(handler.numButtons + 4); + for (int i = GAMEPAD_KEY_DPAD_UP; i <= GAMEPAD_KEY_DPAD_RIGHT; ++i) + { + handler.iButtonStateOld[i] = handler.iButtonState[i] = 0; + LogAdd("POV Button %d State %d", i, 0); + } + } + SDL_JoystickEventState(SDL_IGNORE); + } + } + } + } + else + { + ManualReadGamepad(); + } +} + +bool Gamepad::Initialize() +{ + if (strAppDir.size() < 1) + { + strAppDir = qApp->applicationDirPath().toUtf8().data(); + } + + SDL_Quit(); + // init SDL + // my Gamepad does not work with SDL_INIT_EVERYTHING. Just init the ones we use. + int ret = SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS); + return (ret == 0); +} + +void Gamepad::Free() +{ + if (bSaveLogToDisk) + { + SaveLog(); + } + + if(int count = gHandlers.size()) + { + for(int i = 0; i<count; ++i) + gHandlers[i].DisConnect(); + } + SDL_Quit(); +} + +void ShowUsageInViewport() +{ + bool bDemoMode = AppMainWindow::IsExpertMode(); + if(bDemoMode && bDefaultDemoMode) + { + int w = theScene->GetCamera()->GetWidth(); + int h = theScene->GetCamera()->GetHeight(); + //CDXUTTextHelper* pTxtHelper = theScene->GetRenderWindow()->GetTextHelper(); + + //pTxtHelper->Begin(); + //pTxtHelper->SetInsertionPos(w/5, h-80); + //pTxtHelper->SetForegroundColor(D3DXCOLOR(1.0f, 1.0f, 0.0f, 0.8f)); + + //pTxtHelper->DrawTextLine(L"Start: Load a sample Back: Quit Demo"); + //pTxtHelper->DrawTextLine(L"A: Stop/Restart Animation B: Pause/Continue Animation X: Start/Pause Simulation Y: Demo/Export Switch"); + //pTxtHelper->DrawTextLine(L"Left Stick: Zoom In/Out Right Stick: Control Camera Cross/Trigger: Scene HUD and Stats On/Off"); + //pTxtHelper->DrawTextLine(L"RB & LS: Wind Direction RB & RS: Wind Strength LB & LS: Light Control"); + //pTxtHelper->End(); + } +} + +void Gamepad::ShowUsage() +{ + viewer_msg("Start: Show Gamepad Usage"); + viewer_msg("Back: Quit the Blast Viewer"); + viewer_msg("LBump: Load previous demo RBump: Load next sample"); + viewer_msg("B: Reset Animation A: Play/Pause Animation"); + viewer_msg("Y: Demo View On/Off X: Show/Hide the selected Hair"); + viewer_msg("LStick: Zoom in and out RStick: Rotate the camera"); + viewer_msg("D-Pad Up: Show/Hide HUD D-Pad Left: Show/Hide Stats"); + viewer_msg("RTrigger & LStick: Wind Direction RTrigger & RStick: Wind Strength"); + viewer_msg("LTrigger & LStick: Move Light"); +} + + +void Gamepad::ResetScene() +{ +#ifndef NV_ARTISTTOOLS + BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar(); + + GlobalSettings::Inst().toggleSimulation(); + bool bSimulating = GlobalSettings::Inst().toggleSimulation(); // call it twice to get right state + if(bSimulating) + { + toolbar->on_btnEnableSimulation_clicked(); // stop simulation when stop animation + } + + DisplayFurVisualizersPanel* furPanel = AppMainWindow::Inst().GetFurVisualizersPanel(); + if(furPanel) + { + furPanel->on_btnShowHair_stateChanged(true); // show hair + furPanel->updateValues(); + } + + GlobalSettings::Inst().toggleAnimation(); + bool anim = GlobalSettings::Inst().toggleAnimation(); // call it twice to get right state + if(anim) + { + toolbar->on_btnPlayAnimation_clicked(); // stop animation + } + + toolbar->on_btnResetAnimation_clicked(); // reset animation + + toolbar->on_spinWindStrength_valueChanged(0.0f); + toolbar->updateValues(); +#else + CoreLib::Inst()->Gamepad_ResetScene(); +#endif // NV_ARTISTTOOLS + + Light* pLight = NV_NULL; + pLight = Light::GetFirstSelectedLight(); + + static Camera oldLightCam, oldSceneCam; + // restore old camera + if(bUseOldSceneCam) + { + *(theScene->GetCamera()) = oldSceneCam; + //theScene->FitCamera(); + } + else + { + oldSceneCam = *theScene->GetCamera(); + bUseOldSceneCam = true; + } + // restore light camera + if(pLight) + { + //pLight->FitBounds(true); + if(bUseOldLightCam) + { +// pLight->getCamera() = oldLightCam; + } + else + { +// oldLightCam = pLight->getCamera(); +// pLight->FitBounds(); + bUseOldLightCam = true; + } + } + theScene->SetProjectModified(true); +} + +bool Gamepad::IsDemoMode() +{ + return AppMainWindow::IsExpertMode(); +} + +void Gamepad::SetDemoProjects(QList<QString>& projects) +{ + demoProjects = projects; +} + +void Gamepad::Process() +{ + if (AppMainWindow::IsExpertMode() == false) + { + static bool bFirstTime = true; + if (bFirstTime) + { + bFirstTime = false; + DisplayPreferencesPanel* pPanel = AppMainWindow::Inst().GetDisplayPreferencesPanel(); + if (pPanel) + { + pPanel->runDemoCommandline(); + return; + } + } + } + + HandleJoySticks(); + + if (theScene == 0) + { + theScene = SimpleScene::Inst(); + return; + } + + //ShowUsageInViewport(); +} + + +void Gamepad::ManualReadGamepad() +{ + SDL_JoystickUpdate(); + if(int count = gHandlers.size()) + { + for(int i = 0; i < count; ++i) + gHandlers[i].Process(); + } +} + +void GamepadHandler::Process() +{ + for(int i = 0; i < numAxis; ++i) + { + int value = ClampAxis(SDL_JoystickGetAxis(joystick, i)); + iAxisState[i] = value; + if(iAxisStateOld[i] != value) + { + char msg[512]; + sprintf(msg, "Axis changes: %d %d", i, value); +#ifdef _DEBUG + viewer_msg(msg); +#endif + LogAdd(msg); + } + } + + bool bCancelQuit = false; + for(int i = 0; i < numButtons; ++i) + { + int state = SDL_JoystickGetButton(joystick, i); + iButtonState[i] = state; + if(iButtonStateOld[i] != state) + { + char msg[512]; + sprintf(msg, "Button changes: %d %d (%d)", i, state, iButtonStateOld[i]); +#ifdef _DEBUG + viewer_msg(msg); +#endif + LogAdd(msg); + } + if(i != GAMEPAD_KEY_BACK && ButtonState(i) == BUTTON_UP) + { + //bCancelQuit = true; + } + } + + if (numPov == 1) + { + // BETOP xbox mode + Uint8 pov = SDL_JoystickGetHat(joystick, 0); + switch (pov) + { + case SDL_HAT_UP: + iButtonState[GAMEPAD_KEY_DPAD_UP] = 1; + break; + case SDL_HAT_RIGHT: + iButtonState[GAMEPAD_KEY_DPAD_RIGHT] = 1; + break; + case SDL_HAT_DOWN: + iButtonState[GAMEPAD_KEY_DPAD_DOWN] = 1; + break; + case SDL_HAT_LEFT: + iButtonState[GAMEPAD_KEY_DPAD_LEFT] = 1; + break; + case SDL_HAT_RIGHTUP: + iButtonState[GAMEPAD_KEY_DPAD_RIGHT] = 1; + iButtonState[GAMEPAD_KEY_DPAD_UP] = 1; + break; + case SDL_HAT_RIGHTDOWN: + iButtonState[GAMEPAD_KEY_DPAD_RIGHT] = 1; + iButtonState[GAMEPAD_KEY_DPAD_DOWN] = 1; + break; + case SDL_HAT_LEFTUP: + iButtonState[GAMEPAD_KEY_DPAD_LEFT] = 1; + iButtonState[GAMEPAD_KEY_DPAD_UP] = 1; + break; + case SDL_HAT_LEFTDOWN: + iButtonState[GAMEPAD_KEY_DPAD_LEFT] = 1; + iButtonState[GAMEPAD_KEY_DPAD_DOWN] = 1; + break; + default: + for (int i = GAMEPAD_KEY_DPAD_UP; i <= GAMEPAD_KEY_DPAD_RIGHT; ++i) + { + iButtonState[i] = 0; + } + } + if (pov != SDL_HAT_CENTERED) + { + char msg[512]; + sprintf(msg, "POV State: %d", pov); + viewer_msg(msg); + LogAdd(msg); + for (int i = GAMEPAD_KEY_DPAD_UP; i <= GAMEPAD_KEY_DPAD_RIGHT; ++i) + { + if (ButtonState(i) == BUTTON_DOWN) + { + sprintf(msg, "POV Button Down: %d", i); + viewer_msg(msg); + LogAdd(msg); + } + } + } + } + + //bool bLeftBump = iButtonState[GAMEPAD_KEY_LEFT_BUMP], bRightBump = iButtonState[GAMEPAD_KEY_RIGHT_BUMP]; + bool bLeftTrigger = false, bRightTrigger = false; + double currentTime = GetSeconds(); // real elapsed frame time + static double lastJoyTime = currentTime; + + if(ButtonState(GAMEPAD_KEY_BACK) == BUTTON_UP) + { + BackButtonPressed(); + } + if(iQuitState && bCancelQuit) + { + AppMainWindow::Inst().setProgress("Cancel quitting.", 2); + iQuitState = 0; + } + else + { + bCancelQuit = false; + } + + if(!bCancelQuit) + { + if(ButtonState(GAMEPAD_KEY_START) == BUTTON_UP) + { + StartButtonPressed(); + } + if (ButtonState(GAMEPAD_KEY_RIGHT_BUMP) == BUTTON_UP) + { + // next proj + Gamepad::DemoNext(); + } + if (ButtonState(GAMEPAD_KEY_LEFT_BUMP) == BUTTON_UP) + { + // prev proj + Gamepad::DemoPrev(); + } + if (ButtonState(GAMEPAD_KEY_B) == BUTTON_UP) + { + viewer_msg("B Pressed"); + ButtonBPressed(); + } + if(ButtonState(GAMEPAD_KEY_A) == BUTTON_UP) + { + viewer_msg("A Pressed"); + ButtonAPressed(); + } + if (ButtonState(GAMEPAD_KEY_Y) == BUTTON_UP) + { + viewer_msg("Y Pressed"); + ChangeMode(); + } + if(ButtonState(GAMEPAD_KEY_X) == BUTTON_UP) + { + viewer_msg("X Pressed"); +#ifndef NV_ARTISTTOOLS + // Show/hide selected hair + bool v = false; + theScene->GetFurCharacter().GetHairParam(HAIR_PARAMS_DRAW_RENDER_HAIRS, &v); + DisplayFurVisualizersPanel* furPanel = AppMainWindow::Inst().GetFurVisualizersPanel(); + if (furPanel) + { + furPanel->on_btnShowHair_stateChanged(!v); + } +#else + CoreLib::Inst()->GamepadHandler_ShowHair(); +#endif // NV_ARTISTTOOLS + } + if(ButtonState(GAMEPAD_KEY_DPAD_LEFT) == BUTTON_DOWN) + { + // Show/Hide Stats + Gamepad::ShowHideStats(); + } + if(ButtonState(GAMEPAD_KEY_DPAD_RIGHT) == BUTTON_DOWN) + { + } + if(ButtonState(GAMEPAD_KEY_DPAD_UP) == BUTTON_DOWN) + { + // show/hide HUD + Gamepad::ShowHideHud(); + } + if(ButtonState(GAMEPAD_KEY_DPAD_DOWN) == BUTTON_DOWN) + { + } + } + + //const float g_dt = 1.0f/120.0f; // the time delta used for simulation + if (numAxis == 6) + { + // XBOX 360 has 6 axis + int iLTChange = AxisChange(AXIS_LT); + int iRTChange = AxisChange(AXIS_RT); + if (iLTChange > 30000) + { + bLeftTrigger = true; + } + if (iRTChange > 30000) + { + bRightTrigger = true; + } + } + else if(numAxis == 5) + { + // Betop has 5 axis when x360 mode + int iLTChange = AxisChange(AXIS_LT); + int iRTChange = AxisChange(AXIS_RT); + if (iLTChange>15000) + { + bLeftTrigger = true; + } + if (iRTChange < -15000) + { + bRightTrigger = true; + } + } + if (1) + { + static float zoomSpeed = 0.1f; + static float rotateSpeed = 2.5f; + + float deltaTime = (currentTime - lastJoyTime); + lastJoyTime = currentTime; + + const float jsFactor = 1.0f/32768.0f; + int iLSX = AxisChange(AXIS_LS_X); + int iLSY = AxisChange(AXIS_LS_Y); + if(iLSX != 0 || iLSY != 0) + { + // left stick + float forceLSX = iLSX * jsFactor; + float forceLSY = iLSY * jsFactor; + if(bLeftTrigger || bRightTrigger) + { + if(bRightTrigger) + { + // wind direction + atcore_float3 direct = gfsdk_makeFloat3(forceLSX, forceLSY, 0.1f); + gfsdk_normalize(direct); + + GlobalSettings::Inst().m_windDir = direct; + theScene->SetProjectModified(true); + } + if(bLeftTrigger) + { + // light direction + { + Light* pLight = Light::GetFirstSelectedLight(); + if (pLight) + { + atcore_float2 delta = gfsdk_makeFloat2(forceLSX, forceLSY); + delta = 10.0f * delta; + pLight->Orbit(delta); // unit is in degree(s) + theScene->SetProjectModified(true); + } + } + } + } + else + { + if(iLSY != 0) + { + // zoom in/out + theScene->GetCamera()->Dolly(zoomSpeed * forceLSY); + theScene->SetProjectModified(true); + } + } + } + int iRSX = AxisChange(AXIS_RS_X); + int iRSY = AxisChange(AXIS_RS_Y); + if(iRSX != 0 || iRSY != 0) + { + float forceX = iRSX * jsFactor; + float forceY = iRSY * jsFactor; + if(bRightTrigger) + { + if (iRSX != 0) + { + // wind strength, Press right to increase. Press left to decrease + static float windStrength = 0.0f; + static float fStep = 0.1f; + if (iRSX > 0) + windStrength += fStep; + else + windStrength -= fStep; + if (windStrength > 10.0f) + windStrength = 10.0f; + if (windStrength < 0.0f) + windStrength = 0.0f; + +#ifndef NV_ARTISTTOOLS + BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar(); + toolbar->on_spinWindStrength_valueChanged(windStrength); + toolbar->updateValues(); +#else + CoreLib::Inst()->GamepadHandler_SpinWindStrength(windStrength); +#endif // NV_ARTISTTOOLS + } + } + else + { + // rotate camera + atcore_float2 moveRightStick = gfsdk_makeFloat2(forceX, forceY); + theScene->GetCamera()->Orbit(moveRightStick*rotateSpeed); + theScene->SetProjectModified(true); + } + } + } + //if(numAxis>5) + //{ + //// XBOX 360 has 6 axis + //if((iAxisState[4]>=0) && (iAxisStateOld[4]<0)) + //{ + // bool bShow = ! GlobalSettings::Inst().m_showHUD; + // DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel(); + // if(pspanel) + // { + // pspanel->on_btnShowHUD_stateChanged(bShow); + // pspanel->on_btnComputeStats_stateChanged(false); + // } + //} + //if((iAxisState[5]>=0) && (iAxisStateOld[5]<0)) + //{ + // bool bShow = ! GlobalSettings::Inst().m_computeStatistics; + // DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel(); + // if(pspanel) + // { + // DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel(); + // if(pspanel) + // { + // // HUD controls stats + // pspanel->on_btnComputeStats_stateChanged(bShow); + // pspanel->on_btnShowHUD_stateChanged(bShow); + // } + // } + //} + //} + for(int i = 0; i < numAxis; ++i) + { + //if(iAxisStateOld[i] != iAxisState[i]) + //{ + // char msg[512]; + // sprintf(msg, "Axis: %d %d", i, iAxisState[i]); + // viewer_msg(msg); + //} + iAxisStateOld[i] = iAxisState[i]; + } + + for(int i = 0; i < numButtons; ++i) + { + iButtonStateOld[i] = iButtonState[i]; + } + + if (numPov == 1) + { + for (int i = GAMEPAD_KEY_DPAD_UP; i <= GAMEPAD_KEY_DPAD_RIGHT; ++i) + { + iButtonStateOld[i] = iButtonState[i]; + } + } +} + +//void Gamepad::ClearStates() +//{ +// for(int i = 0; i < iStateSize; ++i) +// { +// bKeyHolding[i] = 0; +// +// iAxisStateOld[i] = 0; +// iAxisState[i] = 0; +// iButtonStateOld[i] = 0; +// iButtonState[i] = 0; +// } +//} + +void Gamepad::ShowHideHud() +{ + static bool bShowHud = true; + DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel(); + if (pspanel) + { + // HUD controls stats + pspanel->on_btnShowHUD_stateChanged(bShowHud); + pspanel->on_btnComputeStats_stateChanged(false); + bShowHud = !bShowHud; + } +} + +void Gamepad::ShowHideStats() +{ + static bool bShowStats = true; + DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel(); + if (pspanel) + { + // HUD controls stats + pspanel->on_btnComputeStats_stateChanged(bShowStats); + pspanel->on_btnShowHUD_stateChanged(bShowStats); + bShowStats = !bShowStats; + } +} + +void Gamepad::QuitApp() +{ + AppMainWindow::Inst().close(); +} + +void Gamepad::ResetAnimation() +{ +#ifndef NV_ARTISTTOOLS + GlobalSettings::Inst().toggleSimulation(); + bool simulating = GlobalSettings::Inst().toggleSimulation(); // call it twice to get right state + + GlobalSettings::Inst().toggleAnimation(); + bool animating = GlobalSettings::Inst().toggleAnimation(); // call it twice to get right state + + BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar(); + if (!simulating) + { + toolbar->on_btnEnableSimulation_clicked(); + } + if (!animating) + { + toolbar->on_btnPlayAnimation_clicked(); + } + toolbar->on_btnResetAnimation_clicked(); +#else + CoreLib::Inst()->Gamepad_ResetAnimation(); +#endif // NV_ARTISTTOOLS +} + +void Gamepad::PlayPauseAnimation() +{ +#ifndef NV_ARTISTTOOLS + GlobalSettings::Inst().toggleSimulation(); + bool simulating = GlobalSettings::Inst().toggleSimulation(); // call it twice to get right state + + GlobalSettings::Inst().toggleAnimation(); + bool animating = GlobalSettings::Inst().toggleAnimation(); // call it twice to get right state + + BlastToolbar* toolbar = AppMainWindow::Inst().GetMainToolbar(); + if (simulating != animating) + { + toolbar->on_btnEnableSimulation_clicked(); + } + toolbar->on_btnEnableSimulation_clicked(); + toolbar->on_btnPlayAnimation_clicked(); +#else + CoreLib::Inst()->Gamepad_PlayPauseAnimation(); +#endif // NV_ARTISTTOOLS +} + +void Gamepad::DemoModeOnOff() +{ + ChangeMode(); +} + +void Gamepad::DemoNext() +{ + LoadSamples(true); + StartAnimation(); +} + +void Gamepad::DemoPrev() +{ + LoadSamples(false); + StartAnimation(); +} + +void Gamepad::SetDemoMode(bool onOff) +{ + //if (AppMainWindow::IsExpertMode() != onOff) + //{ + // ChangeMode(); + //} + if (onOff) + { + curentPrjIdx = -1; // make it start from first demo + DemoNext(); + + // turn off FPS display + GlobalSettings::Inst().m_showFPS = false; + } + else + { + ShowUsage(); + } + ChangeMode(); +} + +void Gamepad::DemoEscape() +{ + if (AppMainWindow::IsExpertMode()) + { + ChangeMode(); + // hide HUD if it is on. for GWDCC - 393 Blast Viewer - play list stats + DisplayScenePanel* pspanel = AppMainWindow::Inst().GetDisplayScenePanel(); + if (pspanel) + { + // HUD controls stats + pspanel->on_btnShowHUD_stateChanged(false); + pspanel->on_btnComputeStats_stateChanged(false); + } + } + //else + //{ + // QuitApp(); + //} +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Gamepad.h b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Gamepad.h new file mode 100644 index 0000000..46d45ba --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Gamepad.h @@ -0,0 +1,68 @@ +// 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-2015 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. +// + +#pragma once + +class SimpleScene; + +class Gamepad +{ +public: + Gamepad(); + ~Gamepad(); + + static Gamepad& Instance(); + + void Process(); + bool Initialize(); + void Free(); + + bool IsDemoMode(); + + void SetDemoProjects(QList<QString>& projects); + + static void DemoNext(); + static void DemoPrev(); + static void ShowProjectName(); + static void ShowHideHud(); + static void ShowHideStats(); + static void QuitApp(); + static void ResetAnimation(); + static void PlayPauseAnimation(); + static void DemoModeOnOff(); + static void DemoEscape(); + static void SetDemoMode(bool onOff); + static void ShowUsage(); + +private: + void ResetScene(); + void ManualReadGamepad(); + + void HandleJoySticks(); +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp new file mode 100644 index 0000000..42febc1 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.cpp @@ -0,0 +1,310 @@ +// 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. +// + +#include "GlobalSettings.h" +#include <QtCore/QTimer> +#include "Settings.h" + +static GlobalSettings g_settings; +static QTimer g_frameTimer(NV_NULL); + +//////////////////////////////////////////////////////////////////////////////////////////// +GlobalSettings::GlobalSettings() +{ + Init(); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +GlobalSettings& GlobalSettings::Inst() +{ + return g_settings; +} + +//////////////////////////////////////////////////////////////////////////////////////////// +QTimer& GlobalSettings::GetFrameTimer() +{ + return g_frameTimer; +} + +//////////////////////////////////////////////////////////////////////////////////////////// +void +GlobalSettings::Init() +{ + m_animate = false; + m_simulate = true; + m_simulateStep = false; + m_firstFrame = true; + m_resetAnimationOnLoop = true; + + m_animationFps = 24.0f; + m_repeatAnimation = true; + m_frameTime = 0.0f; + m_animationSpeed = 1.0f; + m_playStopped = false; + m_currentBoneIndex = 0; + + m_simulationFrameCalc.init(0, 1.0f / 60.0f); + m_simulationFps = 60.0f; + m_timeStep = 0.0f; + + m_visualizeWind = false; + m_showGraphicsMesh = true; + m_showWireframe = false; + m_showHUD = false; + m_visualizeBoneNames = false; + + m_computeStatistics = false; + m_computeProfile = false; + m_previewLOD = false; + m_renderStyle = MESH_RENDER_TEXTURED; + + m_sceneLoaded = false; + m_useDQ = false; + m_zup = false; + m_lhs = false; + + m_sceneUnitIndex = SCENE_UNIT_CENTIMETER; // default to use cm + + m_showGrid = true; + m_showAxis = true; + + m_fovAngle = 75.0f; + + m_loadTextures = true; + m_loadMaterials = true; + m_loadGroom = true; + m_loadCollision = true; + m_loadConstraints = true; + + m_msaaOption = 0; + + m_windDir.x = 0; + m_windDir.y = -1.0f; + m_windDir.z = 0.5f; + m_windStrength = 0.0f; + m_windNoise = 0.0f; + + m_frameStartTime = 0.0f; + m_frameEndTime = 100.0f; + + m_animationIndex = 0; + + m_lockRootBone = false; + + m_controlTextureOption = 0; + m_showSkinnedMeshOnly = false; + + m_useLighting = true; + m_showFPS = true; + + m_renderFrameCnt = 0; + m_renderFps = 60.0f; + + m_projectFileDir = ""; + m_projectFileName = ""; + m_backgroundTextureFilePath = ""; +} + +/////////////////////////////////////////////////////////////////////////////// +bool GlobalSettings::toggleSimulation() +{ + m_simulate = !m_simulate; + m_simulateStep = false; + + return m_simulate; +} + +/////////////////////////////////////////////////////////////////////////////// +void GlobalSettings::stepSimulation() +{ + m_simulateStep = true; +} + +////////////////////////////////////////////////////////////////////////////// +void GlobalSettings::setRenderFps(float fps) +{ + m_renderFps = fps; + + OptionValue* option = nullptr; + + option = AppSettings::Inst().GetOptionValue("User/PerfMode"); + if (option) + { + if (option->Value.Bool == OA_TRUE) + { + g_frameTimer.setInterval(0); + } + else + g_frameTimer.setInterval((int)(1000 / fps)); + } +} + +////////////////////////////////////////////////////////////////////////////// +void GlobalSettings::setSimulationFps(float fps) +{ + m_simulationFps = fps; + m_simulationFrameCalc.setTimeStep(1.0f/ fps); +} + +////////////////////////////////////////////////////////////////////////////// +void GlobalSettings::resetAnimation() +{ + m_frameTime = m_frameStartTime; + m_firstFrame = m_resetAnimationOnLoop ? true : false; + m_playStopped = false; + m_simulateStep = true; +} + +/////////////////////////////////////////////////////////////////////////////// +void GlobalSettings::toggleAnimationRepeat() +{ + m_repeatAnimation = !m_repeatAnimation; +} + +/////////////////////////////////////////////////////////////////////////////// +bool GlobalSettings::toggleAnimation() +{ + m_animate = !m_animate; + + if (m_animate && m_playStopped) + resetAnimation(); + + return m_animate; +} + +/////////////////////////////////////////////////////////////////////////////// +void GlobalSettings::stepAnimation() +{ + if (!m_sceneLoaded) + return; + + if (m_repeatAnimation) + m_playStopped = false; + + if (!m_playStopped) + m_frameTime += m_animationSpeed * m_animationFps * m_timeStep; + + if (m_frameTime > m_frameEndTime) + { + if (m_repeatAnimation) + resetAnimation(); + else + { + m_frameTime = m_frameEndTime; + m_playStopped = true; + m_animate = false; + } + } + + if (!m_animate) + { + stepSimulation(); + } +} + +/////////////////////////////////////////////////////////////////////////////// +void GlobalSettings::setSceneUnitIndex(int i) +{ + if (i < 0) + return; + + if (i >= SCENE_UNIT_END) + return; + + m_sceneUnitIndex = i; +} + + +/////////////////////////////////////////////////////////////////////////////// +float GlobalSettings::getSceneUnitInCentimeters() +{ + float unit = 1.0f; + + switch (m_sceneUnitIndex) + { + case SCENE_UNIT_CENTIMETER: + unit = 1.0f; + break; + case SCENE_UNIT_METER: + unit = 100.0f; + break; + case SCENE_UNIT_INCH: + unit = 2.54f; + break; + case SCENE_UNIT_DECIMETER: + unit = 10.0f; + break; + } + + return unit; +} + +/////////////////////////////////////////////////////////////////////////////// +atcore_float3 GlobalSettings::getGravityDir() +{ + atcore_float3 gravityDir; + + if (m_zup) + { + gravityDir.x = 0.0f; + gravityDir.y = 0.0f; + gravityDir.z = -1.0f; + } + else + { + gravityDir.x = 0.0f; + gravityDir.y = -1.0f; + gravityDir.z = 0.0f; + } + + return gravityDir; +} + +/////////////////////////////////////////////////////////////////////////////// +std::string GlobalSettings::getAbsoluteFilePath() +{ + return m_projectFileDir + "\\" + m_projectFileName; +} + +/////////////////////////////////////////////////////////////////////////////// +std::string GlobalSettings::getAbsoluteFilePath(const char* fileName) +{ + return m_projectFileDir + "\\" + fileName; +} + +#include <QtCore/QFileInfo> +#include <QtCore/QDir> + +/////////////////////////////////////////////////////////////////////////////// +std::string GlobalSettings::getRelativePath(const char* filePath) +{ + QDir projectDir(m_projectFileDir.c_str()); + QByteArray relPath = projectDir.relativeFilePath(filePath).toLocal8Bit(); + + return (const char*)relPath; +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h new file mode 100644 index 0000000..8a1ddec --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/GlobalSettings.h @@ -0,0 +1,172 @@ +// 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. +// + +#pragma once + +#include "MathUtil.h" +#include <string> + +#include <Nv/Common/Animation/NvCoFrameCalculator.h> + +class QTimer; + +enum +{ + MESH_RENDER_WIREFRAME, + MESH_RENDER_FLAT, + MESH_RENDER_SHADED, + MESH_RENDER_TEXTURED, + MESH_RENDER_END, +}; + +enum +{ + SCENE_UNIT_UNKNOWN, + SCENE_UNIT_CENTIMETER, + SCENE_UNIT_METER, + SCENE_UNIT_INCH, + SCENE_UNIT_DECIMETER, + SCENE_UNIT_END, +}; + +////////////////////////////////////////////////////////////////////////////////////// +// Placeholder for all the global settings used in hairworks viewer. +// This stores all simple options that are not part of hair instance descriptor +// such as animation logic in UI, scene settings, scene visualization options etc. +////////////////////////////////////////////////////////////////////////////////////// +class CORELIB_EXPORT GlobalSettings +{ +public: + GlobalSettings(); + + void Init(); + static GlobalSettings& Inst(); + static QTimer& GetFrameTimer(); + +public: + + // animation settings + bool m_animate; + float m_animationFps; + int m_animationIndex; + float m_animationSpeed; + int m_currentBoneIndex; + bool m_firstFrame; + float m_frameTime; + float m_frameStartTime; + float m_frameEndTime; + bool m_lockRootBone; + bool m_playStopped; + bool m_repeatAnimation; + bool m_resetAnimationOnLoop; + + bool m_simulate; + bool m_simulateStep; + + float m_timeStep; + NvCo::FrameCalculator m_simulationFrameCalc; + float m_simulationFps; + + // scene settings + bool m_useDQ; + bool m_zup; + bool m_lhs; + bool m_sceneLoaded; + int m_sceneUnitIndex; + std::string m_backgroundTextureFilePath; + + // statistics and profiling + bool m_computeStatistics; + bool m_computeProfile; + + // render option + float m_fovAngle; + bool m_useLighting; + int m_msaaOption; + int m_renderFrameCnt; + float m_renderFps; + + // viusialization + int m_controlTextureOption; + bool m_previewLOD; + int m_renderStyle; + bool m_showAxis; + bool m_showHUD; + bool m_showFPS; + bool m_showGraphicsMesh; + bool m_showGrid; + bool m_showWireframe; + bool m_showSkinnedMeshOnly; + bool m_visualizeShadowMap; + bool m_visualizeWind; + bool m_visualizeBoneNames; + + // global wind + atcore_float3 m_windDir; + float m_windStrength; + float m_windNoise; + + // import settings + bool m_loadTextures; + bool m_loadMaterials; + bool m_loadGroom; + bool m_loadCollision; + bool m_loadConstraints; + + // file path + std::string m_projectFileDir; + std::string m_projectFileName; + + // convenience access functions +public: + + bool isBindPose() { return m_animationIndex == 0; } + float getSceneUnitInCentimeters(); + void setSceneUnitIndex(int i); + + void setTimeStep(float timeStep) { m_timeStep = timeStep; } + + bool toggleSimulation(); + void stepSimulation(); + + void setRenderFps(float fps); + void setSimulationFps(float fps); + + void resetAnimation(); + void stepAnimation(); + bool toggleAnimation(); + void toggleAnimationRepeat(); + void getAnimationRange( float& start, float& end); + + std::string getAbsoluteFilePath(); + std::string getAbsoluteFilePath(const char* fileName); + std::string getRelativePath(const char* filePath); + + atcore_float3 getGravityDir(); +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Light.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Light.cpp new file mode 100644 index 0000000..e18314e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Light.cpp @@ -0,0 +1,744 @@ +// 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. +// +#include "Light.h" + +#include "GlobalSettings.h" +#include "ShadowMap.h" +#include "SimpleRenderable.h" +#include "MeshShaderParam.h" + +#include "RenderInterface.h" + +////////////////////////////////////////////////////////////////////////////// +inline int GetShadowMapResolution(int index) +{ + switch (index) + { + case 0: // default + return 2048; + break; + case 1: + return 4096; + break; + case 2: + return 1024; + break; + case 3: + return 512; + break; + case 4: + return 8192; + break; + case 5: + return 16384; + break; + } + + return 1024; +} + +namespace +{ + std::vector<Light> g_Lights; + static bool g_LinkLightOption = false; + std::string m_envTextureFilePath; + GPUShaderResource* m_pEnvTextureSRV; +} + +////////////////////////////////////////////////////////////////////////////// +Light::Light() +{ + m_enable = true; + m_useShadows = false; + m_visualize = false; + m_isEnvLight = false; + m_useEnvMap = false; + + m_selected = false; + + m_color = gfsdk_makeFloat3(1.0f, 1.0f, 1.0f); + m_intensity = 1.0f; + + m_pShadowMap = 0; +} + +////////////////////////////////////////////////////////////////////////////// +Light::~Light() +{ + if (m_pShadowMap) + { + delete m_pShadowMap; + m_pShadowMap = 0; + } +} + +////////////////////////////////////////////////////////////////////////////// +bool Light::UseLHS() const { + return m_lightCamera.UseLHS(); +} + +////////////////////////////////////////////////////////////////////////////// +GPUShaderResource* Light::GetShadowSRV() +{ + if (!m_pShadowMap) + return 0; + + return m_pShadowMap->GetShadowSRV(); +} + +////////////////////////////////////////////////////////////////////////////// +void Light::SetShadowMapResolution(int index) +{ + if (m_shadowMapResolutionIndex == index) + return; + + m_lightMapResolution = GetShadowMapResolution(index); + + if (m_pShadowMap) + { + m_pShadowMap->Release(); + delete m_pShadowMap; + } + + m_pShadowMap = ShadowMap::Create(m_lightMapResolution); + + float minZ = 1.0f; + float maxZ = 10000.0f; // should calculate dynamically + + m_lightCamera.Ortho(m_lightMapResolution, m_lightMapResolution, minZ, maxZ); + + m_shadowMapResolutionIndex = index; + + FitBounds(); +} + +////////////////////////////////////////////////////////////////////////////// +void Light::Init() +{ + m_shadowMapResolutionIndex = 2; + m_lightMapResolution = GetShadowMapResolution(m_shadowMapResolutionIndex); + + m_pShadowMap = ShadowMap::Create(m_lightMapResolution); +} + +////////////////////////////////////////////////////////////////////////////// +void Light::Release() +{ + if (m_pShadowMap) + { + delete m_pShadowMap; + m_pShadowMap = 0; + } +} + +////////////////////////////////////////////////////////////////////////////// +void Light::InitCamera(const atcore_float3& from, const atcore_float3& lookAt) +{ + m_lightCamera.Init(false, false); + +// atcore_float3 up = gfsdk_makeFloat3(0.0f, 1.0f, 0.0f); + atcore_float3 up = gfsdk_makeFloat3(0.0f, 0.0f, 1.0f); + + m_lightCamera.LookAt(from, lookAt, up); + + float minZ = 1.0f; + float maxZ = 10000.0f; // should calculate dynamically + + m_lightCamera.Ortho(m_lightMapResolution, m_lightMapResolution, minZ, maxZ); +} + +////////////////////////////////////////////////////////////////////////////// +atcore_float3 +Light::getLightDirection() const +{ + return (atcore_float3&)m_lightCamera.GetViewDirection(); +} + +////////////////////////////////////////////////////////////////////////////// +void Light::SetBounds(atcore_float3* bbCenter, atcore_float3* bbExtents) +{ + if (bbCenter) + m_bbCenter = *bbCenter; + if (bbExtents) + m_bbExtent = *bbExtents; +} + +////////////////////////////////////////////////////////////////////////////// +void Light::FitBounds(bool updateCenter) +{ + //////////////////////////////////////////////////////// + atcore_float3 bbCenter = m_bbCenter; + atcore_float3 bbExtents =m_bbExtent; + + //////////////////////////////////////////////////////////////////////// + if (updateCenter) + { + atcore_float3 lightPos = m_lightCamera.GetEye(); + atcore_float3 lightAt = m_lightCamera.GetAt(); + + atcore_float3 disp = bbCenter - lightAt; + + lightAt = lightAt + disp; + lightPos = lightPos + disp; + + m_lightCamera.SetEye(lightPos); + m_lightCamera.SetAt(lightAt); + m_lightCamera.BuildViewMatrix(); + } + + //////////////////////////////////////////////////////////////////////// + float size = bbExtents.x; + + size = max(size, bbExtents.y); + size = max(size, bbExtents.z); + + atcore_float4x4 view = m_lightCamera.GetViewMatrix(); + + atcore_float3 c = gfsdk_transformCoord(view, bbCenter); + + size *= 3.0f; + + float minZ = c.z - size; + float maxZ = c.z + size; + + float orthoW = size; + float orthoH = size; + + if (m_lightCamera.UseLHS()) + m_lightCamera.Ortho(orthoW, orthoH, minZ, maxZ); + else // rhs camera flips Z + m_lightCamera.Ortho(orthoW, orthoH, -maxZ, -minZ); + +} + +////////////////////////////////////////////////////////////////////////////// +void Light::resetUpDir(bool zup) +{ + m_lightCamera.ResetUpDir(zup); +} + +////////////////////////////////////////////////////////////////////////////// +void Light::resetLhs(bool lhs) +{ + m_lightCamera.ResetLhs(lhs); + FitBounds(); +} + +////////////////////////////////////////////////////////////////////////////// +void Light::Orbit(const atcore_float2& delta) +{ + m_lightCamera.OrbitLight(gfsdk_makeFloat2(-delta.x, delta.y)); + + FitBounds(); +} + +////////////////////////////////////////////////////////////////////////////// +void Light::Pan(const atcore_float2& delta, const atcore_float3& axisX, const atcore_float3& axisY) +{ + atcore_float3 lightPos = m_lightCamera.GetEye(); + atcore_float3 lightAt = m_lightCamera.GetAt(); + atcore_float3 lightDir = m_lightCamera.GetZAxis(); + + float depth = GetDistance(); + + atcore_float2 newDelta = depth * delta; + + atcore_float3 disp = -1.0f * axisY * newDelta.y + axisX * newDelta.x; + + lightAt = lightAt + disp; + lightPos = lightPos + disp; + + m_lightCamera.SetEye(lightPos); + m_lightCamera.SetAt(lightAt); + m_lightCamera.BuildViewMatrix(); + + FitBounds(); +} + +////////////////////////////////////////////////////////////////////////////// +float Light::GetDistance() const +{ + return m_lightCamera.GetLookDistance(); +} + +////////////////////////////////////////////////////////////////////////////// +bool Light::SetDistance(float newdistance) +{ + atcore_float3 lightPos = m_lightCamera.GetEye(); + atcore_float3 lightAt = m_lightCamera.GetAt(); + atcore_float3 lightDir = m_lightCamera.GetZAxis(); + + lightPos = lightAt + newdistance * lightDir; + + m_lightCamera.SetEye(lightPos); + m_lightCamera.BuildViewMatrix(); + + FitBounds(); + + return true; +} +////////////////////////////////////////////////////////////////////////////// +void Light::BeginShadowMapRendering() +{ + if (!m_pShadowMap) return; + + float clearDepth = m_lightCamera.UseLHS() ? FLT_MAX : -FLT_MAX; + m_pShadowMap->BeginRendering(clearDepth); +} + +////////////////////////////////////////////////////////////////////////////// +void Light::EndShadowMapRendering() +{ + if (!m_pShadowMap) return; + + m_pShadowMap->EndRendering(); +} + +////////////////////////////////////////////////////////////////////////////// +atcore_float4x4 Light::GetViewMatrix() const +{ + return m_lightCamera.GetViewMatrix(); +} + +////////////////////////////////////////////////////////////////////////////// +atcore_float4x4 Light::GetProjectionMatrix() const +{ + return m_lightCamera.GetProjectionMatrix(); +} + +////////////////////////////////////////////////////////////////////////////// +atcore_float4x4 Light::GetLightMatrix() const +{ + atcore_float4x4 view = m_lightCamera.GetViewMatrix(); + atcore_float4x4 projection = m_lightCamera.GetProjectionMatrix(); + + float mClip2Tex[] = { + 0.5, 0, 0, 0, + 0, -0.5, 0, 0, + 0, 0, 1, 0, + 0.5, 0.5, 0, 1 + }; + atcore_float4x4 clip2Tex = (atcore_float4x4&)mClip2Tex; + + atcore_float4x4 viewProjection = view * projection; + + atcore_float4x4 lightMatrix = viewProjection * clip2Tex; + + return lightMatrix; +} + +/////////////////////////////////////////////////////////////////////////////// +void Light::FillLightShaderParam(LightShaderParam ¶m) +{ + const std::vector<Light> &lights = g_Lights; + + for (int i = 0; i < lights.size(); i++) + { + if (i >= 4) + break; + + LightParam& lparam = param.m_lightParam[i]; + memset(&lparam, 0, sizeof(LightParam)); + + const Light& light= lights[i]; + + lparam.m_enable = light.m_enable; + lparam.m_useShadows = light.m_useShadows; + + lparam.m_dir = light.getLightDirection(); + lparam.m_intensity = light.m_intensity; + lparam.m_color = light.m_color; + lparam.m_isEnvLight = light.m_isEnvLight; + lparam.m_useEnvMap = light.m_isEnvLight && (m_pEnvTextureSRV != 0); + + float sceneUnit = GlobalSettings::Inst().getSceneUnitInCentimeters(); + lparam.m_depthBias = (sceneUnit > 0.0f) ? 1.0f / sceneUnit : 1.0f; + + if (light.UseLHS()) + { + lparam.m_depthBias *= -1.0f; + lparam.m_depthGain = -1.0f; + lparam.m_lhs = true; + } + else + { + lparam.m_depthGain = 1.0f; + lparam.m_lhs = false; + } + + lparam.m_viewMatrix = light.GetViewMatrix(); + lparam.m_lightMatrix = light.GetLightMatrix(); + } +} + +////////////////////////////////////////////////////////////////////////////// +void Light::draw(Camera* pCamera) +{ + atcore_float3 lightPos = m_lightCamera.GetEye(); + atcore_float3 lightAt = m_lightCamera.GetAt(); + + atcore_float4 color = gfsdk_makeFloat4(m_color.x, m_color.y, m_color.z, 1); + if (m_enable == false) + color = gfsdk_makeFloat4(0.5, 0.5, 0.5, 1); + + // draw light shape + atcore_float4x4 lightMat = gfsdk_transpose(m_lightCamera.GetViewMatrix()); + gfsdk_setPosition(lightMat, lightPos); + + SimpleShaderParam param; + { + param.world = lightMat; + param.view = pCamera->GetViewMatrix(); + param.projection = pCamera->GetProjectionMatrix(); + param.useVertexColor = false; + param.color = color; + } + + RenderInterface::CopyShaderParam(RenderInterface::SHADER_TYPE_SIMPLE_COLOR, + (void*)¶m, sizeof(SimpleShaderParam) ); + + SimpleRenderable::Draw(SimpleRenderable::LIGHT); + + // draw light ray + gfsdk_makeIdentity(param.world); + RenderInterface::CopyShaderParam(RenderInterface::SHADER_TYPE_SIMPLE_COLOR, + (void*)¶m, sizeof(SimpleShaderParam) ); + + SimpleRenderable::DrawLine(lightAt, lightPos); +} + +////////////////////////////////////////////////////////////////////////////// +bool Light::loadParameters(NvParameterized::Handle& handle) +{ +#ifndef NV_ARTISTTOOLS + NvParameterized::NvParameters* params = static_cast<NvParameterized::NvParameters*>(handle.getInterface()); + size_t offset = 0; + nvidia::parameterized::HairProjectParametersNS::Light_Type* param = nullptr; + params->getVarPtr(handle, (void*&)param, offset); + + m_enable = param->enable; + m_useShadows = param->useShadows; + m_visualize = param->visualize; + m_intensity = param->intensity; + + memcpy(&m_color, ¶m->color, sizeof(atcore_float3)); + + atcore_float3 axisX, axisY, axisZ, lightPos; + memcpy(&axisX, ¶m->lightAxisX, sizeof(atcore_float3)); + memcpy(&axisY, ¶m->lightAxisY, sizeof(atcore_float3)); + memcpy(&axisZ, ¶m->lightAxisZ, sizeof(atcore_float3)); + memcpy(&lightPos, ¶m->lightPos, sizeof(atcore_float3)); + + this->SetShadowMapResolution(param->shadowMapResolution); + + m_lightCamera.SetEye(lightPos); + m_lightCamera.SetViewMatrix(axisX, axisY, axisZ); + m_lightCamera.BuildViewMatrix(); +#else + CoreLib::Inst()->Light_loadParameters(handle, this); +#endif // NV_ARTISTTOOLS + + return true; +} + +////////////////////////////////////////////////////////////////////////////// +bool Light::saveParameters(NvParameterized::Handle& handle) +{ +#ifndef NV_ARTISTTOOLS + NvParameterized::NvParameters* params = static_cast<NvParameterized::NvParameters*>(handle.getInterface()); + size_t offset = 0; + nvidia::parameterized::HairProjectParametersNS::Light_Type* param = nullptr; + params->getVarPtr(handle, (void*&)param, offset); + + param->enable = m_enable; + param->useShadows = m_useShadows; + param->visualize = m_visualize; + param->intensity = m_intensity; + + param->shadowMapResolution = m_shadowMapResolutionIndex; + + memcpy(¶m->color, &m_color, sizeof(atcore_float3)); + + { + atcore_float3 axisX = m_lightCamera.GetXAxis(); + atcore_float3 axisY = m_lightCamera.GetYAxis(); + atcore_float3 axisZ = m_lightCamera.GetZAxis(); + atcore_float3 lightPos = m_lightCamera.GetEye(); + + memcpy(¶m->lightAxisX, &axisX, sizeof(atcore_float3)); + memcpy(¶m->lightAxisY, &axisY, sizeof(atcore_float3)); + memcpy(¶m->lightAxisZ, &axisZ, sizeof(atcore_float3)); + memcpy(¶m->lightPos, &lightPos, sizeof(atcore_float3)); + } +#else + CoreLib::Inst()->Light_saveParameters(handle, this); +#endif // NV_ARTISTTOOLS + + return true; +} + +////////////////////////////////////////////////////////////////////////////// +bool Light::SetEnvTextureFromFilePath(const char* textureFilePath) +{ + Light* pLight = Light::GetFirstSelectedLight(); + if (!pLight || !pLight->m_isEnvLight) + return false; + + m_envTextureFilePath = (textureFilePath) ? textureFilePath : ""; + + SAFE_RELEASE(m_pEnvTextureSRV); + if ((!textureFilePath) && (strlen(textureFilePath) > 0)) + m_pEnvTextureSRV = RenderInterface::CreateTextureResource(textureFilePath); + + return true; +} + +////////////////////////////////////////////////////////////////////////////// +const std::string& Light::GetEnvTextureFilePath() +{ + return m_envTextureFilePath; +} + +////////////////////////////////////////////////////////////////////////////// +GPUShaderResource* Light::GetEnvTextureSRV() +{ + return m_pEnvTextureSRV; +} + +////////////////////////////////////////////////////////////////////////////// +GPUShaderResource* Light::GetShadowSRV(int i) +{ + if ((i >= 3) || (i < 0)) + return 0; + + return g_Lights[i].GetShadowSRV(); +} + +bool Light::GetLinkLightOption() +{ + return g_LinkLightOption; +} + +void Light::SetLinkLightOption(bool val) +{ + g_LinkLightOption = val; +} + +////////////////////////////////////////////////////////////////////////////// +std::vector<Light>& Light::GetDefaultLights() +{ + return g_Lights; +} + +////////////////////////////////////////////////////////////////////////////// +Light* Light::GetFirstSelectedLight() +{ + for (int i = 0; i < g_Lights.size(); i++) + { + if (g_Lights[i].m_selected) + return &g_Lights[i]; + } + + return 0; +} + +////////////////////////////////////////////////////////////////////////////// +Light* Light::GetLight(int index) +{ + if (index < 0) + return 0; + if (index >= g_Lights.size()) + return 0; + + return &g_Lights[index]; +} + +////////////////////////////////////////////////////////////////////////////// +void Light::Initialize() +{ + g_Lights.resize(4); + + Light& keyLight = g_Lights[0]; + Light& fillLight = g_Lights[1]; + Light& rimLight = g_Lights[2]; + Light& envLight = g_Lights[3]; + + atcore_float3 lookAt = gfsdk_makeFloat3(0.0f, 0.0f, 0.0f); + + keyLight.m_selected = true; + keyLight.m_enable = true; + keyLight.m_color = gfsdk_makeFloat3(1, 1, 1); + keyLight.m_useShadows = true; + keyLight.m_isEnvLight = false; + keyLight.InitCamera(gfsdk_makeFloat3(100.0f, 25.0f, 0.0f), lookAt); + keyLight.m_name = "Key Light"; + + fillLight.m_enable = false; + fillLight.m_color = gfsdk_makeFloat3(0.5, 0.5, 0.5); + fillLight.m_useShadows = false; + fillLight.m_isEnvLight = false; + fillLight.InitCamera(gfsdk_makeFloat3(-100.0f, 0.0f, 25.0f), lookAt); + fillLight.m_name = "Fill Light"; + + rimLight.m_enable = false; + rimLight.m_color = gfsdk_makeFloat3(0.25, 0.25, 0.25); + rimLight.m_useShadows = false; + rimLight.m_isEnvLight = false; + rimLight.InitCamera(gfsdk_makeFloat3(0.0f, 100.0f, -25.0f), lookAt); + rimLight.m_name = "Rim Light"; + + envLight.m_enable = false; + envLight.m_color = gfsdk_makeFloat3(0.25, 0.25, 0.25); + envLight.m_useShadows = false; + envLight.m_isEnvLight = true; + envLight.InitCamera(gfsdk_makeFloat3(0.0f, 0.0f, 0.0f), lookAt); + envLight.m_name = "Env Light"; + + for (int i = 0; i < g_Lights.size(); i++) + g_Lights[i].Init(); + +} + +////////////////////////////////////////////////////////////////////////////// +void Light::Shutdown() +{ + for (int i = 0; i < g_Lights.size(); i++) + g_Lights[i].Release(); + + g_Lights.clear(); +} + +////////////////////////////////////////////////////////////////////////////// +void Light::FitLightCameras(atcore_float3& center, atcore_float3& extent) +{ + for (int i = 0; i < g_Lights.size(); i++) + { + if (g_LinkLightOption && (i == FILL_LIGHT || i == RIM_LIGHT)) + continue; + + Light& light = g_Lights[i]; + light.SetBounds(¢er, &extent); + light.FitBounds(true); + } +} + +////////////////////////////////////////////////////////////////////////////// +void Light::ResetUpDir(bool zup) +{ + for (int i = 0; i < g_Lights.size(); i++) + { + Light& li = g_Lights[i]; + li.resetUpDir(zup); + } +} + +////////////////////////////////////////////////////////////////////////////// +void Light::ResetLhs(bool lhs) +{ + for (int i = 0; i < g_Lights.size(); i++) + { + Light& li = g_Lights[i]; + li.resetLhs(lhs); + } +} + +////////////////////////////////////////////////////////////////////////////// +void Light::DrawLights(Camera* pCamera) +{ + for (int i = 0; i < g_Lights.size(); i++) + { + Light& light = g_Lights[i]; + if (light.m_visualize) + light.draw(pCamera); + } +} + +////////////////////////////////////////////////////////////////////////////// +void Light::RenderShadowMap() +{ + Light* pLight = Light::GetFirstSelectedLight(); + if (pLight) + { + float zNear = pLight->m_lightCamera.GetZNear(); + float zFar = pLight->m_lightCamera.GetZFar(); + + if (pLight->UseLHS()) + RenderInterface::RenderShadowMap(pLight->GetShadowSRV(), zNear, zFar); + else + RenderInterface::RenderShadowMap(pLight->GetShadowSRV(), -zFar, -zNear); + } +} + +////////////////////////////////////////////////////////////////////////////// +bool Light::LoadParameters(NvParameterized::Handle& handle) +{ + // load lights + NvParameterized::Handle lightsHandle(handle); + if (handle.getChildHandle(handle.getInterface(), "lights", lightsHandle) == NvParameterized::ERROR_NONE) + { + int numLights = 0; + lightsHandle.getArraySize(numLights); + if (numLights > g_Lights.size()) + numLights = g_Lights.size(); + + for (int idx = 0; idx < numLights; ++idx) + { + NvParameterized::Handle lightHandle(lightsHandle); + if (lightsHandle.getChildHandle(idx, lightHandle) == NvParameterized::ERROR_NONE) + { + g_Lights[idx].loadParameters(lightHandle); + } + } + } + return true; +} + +////////////////////////////////////////////////////////////////////////////// +bool Light::SaveParameters(NvParameterized::Handle& outHandle) +{ + NvParameterized::Handle lightsHandle(outHandle); + if (outHandle.getChildHandle(outHandle.getInterface(), "lights", lightsHandle) == NvParameterized::ERROR_NONE) + { + int numLights = (int)g_Lights.size(); + + lightsHandle.resizeArray(numLights); + + for (int idx = 0; idx < numLights; ++idx) + { + NvParameterized::Handle lightHandle(outHandle); + if (lightsHandle.getChildHandle(idx, lightHandle) == NvParameterized::ERROR_NONE) + { + g_Lights[idx].saveParameters(lightHandle); + } + } + } + return true; +} + +// END OF STATIC FUNCTIONS + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Light.h b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Light.h new file mode 100644 index 0000000..bbe4ef3 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Light.h @@ -0,0 +1,152 @@ +// 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-2015 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. +// + +#pragma once + +#include "MathUtil.h" +#ifndef NV_ARTISTTOOLS +#include "ProjectParams.h" +#else +#include "NvParametersTypes.h" +#ifndef NV_PARAMETERIZED_ONLY_LAYOUTS +#include "NvParameterized.h" +#include "NvParameters.h" +#include "NvParameterizedTraits.h" +#include "NvTraitsInternal.h" +#endif +#endif // NV_ARTISTTOOLS +#include "Camera.h" + +#include <string> +#include <vector> + +#include "LightShaderParam.h" + +class GPUShaderResource; +class ShadowMap; + +///////////////////////////////////////////////////////////////////////// +// Utility class for light object +///////////////////////////////////////////////////////////////////////// +class CORELIB_EXPORT Light +{ +public: + bool m_enable; + bool m_useShadows; + bool m_visualize; + bool m_isEnvLight; + bool m_useEnvMap; + + bool m_selected; + + float m_intensity; + atcore_float3 m_color; + + std::string m_name; + int m_shadowMapResolutionIndex; + int m_lightMapResolution; + + // public API to access 4 lights + static std::vector<Light>& GetDefaultLights(); + static Light* GetLight(int index); + static Light* GetFirstSelectedLight(); + + static void Initialize(); + static void Shutdown(); + static void FitLightCameras(atcore_float3& center, atcore_float3& extent); + static void ResetUpDir(bool zup); + static void ResetLhs(bool lhs); + static void DrawLights(Camera* pCamera); + static void FillLightShaderParam(LightShaderParam ¶m); + static bool LoadParameters(NvParameterized::Handle& handle); + static bool SaveParameters(NvParameterized::Handle& outHandle); + static void RenderShadowMap(); + + static bool SetEnvTextureFromFilePath(const char* textureFilePath); + static const std::string & GetEnvTextureFilePath(); + static GPUShaderResource* GetEnvTextureSRV(); + static GPUShaderResource* GetShadowSRV(int); + + static bool GetLinkLightOption(); + static void SetLinkLightOption(bool val); + +public: + Light(); + ~Light(); + + enum + { + KEY_LIGHT, + FILL_LIGHT, + RIM_LIGHT, + ENV_LIGHT, + }; + + void Orbit(const atcore_float2& delta); + void Pan(const atcore_float2& delta, const atcore_float3& axisX, const atcore_float3& axisY); + + bool UseLHS() const; + + float GetDistance() const; + bool SetDistance(float newdistsance); + + void SetShadowMapResolution(int option); + void BeginShadowMapRendering(); + void EndShadowMapRendering(); + + GPUShaderResource* GetShadowSRV(); + + atcore_float4x4 GetViewMatrix() const; + atcore_float4x4 GetProjectionMatrix() const; + atcore_float4x4 GetLightMatrix() const; + +protected: + void Init(); + void Release(); + + bool loadParameters(NvParameterized::Handle& handle); + bool saveParameters(NvParameterized::Handle& outHandle); + + void SetBounds(atcore_float3* center, atcore_float3* extents = 0); + void FitBounds(bool updateCenter = false); + + atcore_float3 getLightDirection() const; + void InitCamera(const atcore_float3& from, const atcore_float3& lookAt); + + void draw(Camera* pCamera); + void resetUpDir(bool zup); + void resetLhs(bool zup); + +public: + + Camera m_lightCamera; + ShadowMap* m_pShadowMap; + + atcore_float3 m_bbCenter; + atcore_float3 m_bbExtent; +}; diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/MeshData.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/MeshData.cpp new file mode 100644 index 0000000..295ac7f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/MeshData.cpp @@ -0,0 +1,108 @@ +// 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. +// +#include "MeshData.h" + +#include "AnimUtil.h" +#include "RenderResources.h" + +/////////////////////////////////////////////////////////////////////////////// +void CreateCPUResource(MeshData* pMeshData, const MeshDesc &meshDesc) +{ + if (!pMeshData) + return; + + pMeshData->m_NumVertices = meshDesc.m_NumVertices; + pMeshData->m_NumIndices = meshDesc.m_NumTriangles * 3; + + int numIndices = pMeshData->m_NumIndices; + + pMeshData->m_pIndices = new NvUInt32[numIndices]; + pMeshData->m_pMeshVertices = new MeshData::MeshVertex[numIndices]; + + NvUInt32* pVertUsed = new NvUInt32[meshDesc.m_NumVertices]; + memset(pVertUsed, meshDesc.m_NumVertices, sizeof(NvUInt32) * meshDesc.m_NumVertices); + for (NvUInt32 i = 0; i < numIndices; i++) + { + NvUInt32 vidx = pMeshData->m_pIndices[i] = meshDesc.m_pIndices[i]; + + MeshData::MeshVertex&v = pMeshData->m_pMeshVertices[i]; + + v.pos = meshDesc.m_pVertices[vidx]; + v.vertexNormal = meshDesc.m_pVertexNormals[i]; + v.faceNormal = meshDesc.m_pFaceNormals[i]; + v.tangent = meshDesc.m_pTangents[i]; + v.texcoord = meshDesc.m_pTexCoords[i]; + v.vertexId = (float)vidx; + pVertUsed[vidx] = i; + } + int numUniqueIndices = 0; + for (NvUInt32 i = 0; i < meshDesc.m_NumVertices; i++) + { + if (meshDesc.m_NumVertices != pVertUsed[i]) + ++numUniqueIndices; + } + pMeshData->m_NumUniqueIndices = numUniqueIndices; + pMeshData->m_pUniqueIndices = new NvUInt32[numUniqueIndices]; + for (NvUInt32 i = 0, idx = 0; i < meshDesc.m_NumVertices; i++) + { + if (meshDesc.m_NumVertices != pVertUsed[i]) + { + pMeshData->m_pUniqueIndices[idx++] = pVertUsed[i]; + } + } + delete[] pVertUsed; +} + +/////////////////////////////////////////////////////////////////////////////// +MeshData* MeshData::Create(MeshDesc &meshDesc, SkinData& skinData) +{ + MeshData* pMeshData = new MeshData; + + CreateCPUResource(pMeshData, meshDesc); + + pMeshData->m_GPUMeshResources = GPUMeshResources::Create(pMeshData, skinData); + + return pMeshData; +} + +/////////////////////////////////////////////////////////////////////////////// +void MeshData::Release() +{ + if (m_pMeshVertices) + delete [] m_pMeshVertices; + + if (m_pIndices) + delete [] m_pIndices; + + if (m_pUniqueIndices) + delete[] m_pUniqueIndices; + + m_GPUMeshResources->Release(); + delete m_GPUMeshResources; + m_GPUMeshResources = NULL; +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/MeshData.h b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/MeshData.h new file mode 100644 index 0000000..f05207e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/MeshData.h @@ -0,0 +1,74 @@ +// 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-2015 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. +// + +#pragma once + +#include "MathUtil.h" + +#include "RenderResources.h" + +class MeshDesc; +class SkinData; + +////////////////////////////////////////////////////////////////////////////////////// +// Helper for rendering graphics mesh +////////////////////////////////////////////////////////////////////////////////////// +class CORELIB_EXPORT MeshData +{ +public: + + struct MeshVertex + { + atcore_float3 pos; + atcore_float3 vertexNormal; + atcore_float3 faceNormal; + atcore_float3 tangent; + atcore_float2 texcoord; + float vertexId; + }; + +public: + static MeshData* Create(MeshDesc &meshDesc, SkinData& skinData); + void Release(); + +public: + int m_NumVertices; + int m_NumIndices; + + MeshVertex* m_pMeshVertices; + NvUInt32* m_pIndices; + + // m_pUniqueIndices and m_NumUniqueIndices are used to boost bounding calculation in FurMesh.cpp + NvUInt32* m_pUniqueIndices; + NvUInt32 m_NumUniqueIndices; + + // gpu resources + GPUMeshResources* m_GPUMeshResources; +}; + + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Mouse.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Mouse.cpp new file mode 100644 index 0000000..f321157 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Mouse.cpp @@ -0,0 +1,105 @@ + +// 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. + +#include "Mouse.h" + +//#include "windows.h" + +Mouse::Mouse() +{ +} + +Mouse::~Mouse() +{ + Free(); +} + +bool Mouse::Initialize(HINSTANCE hInstance, HWND hWnd) +{ + /* + if (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, + IID_IDirectInput8, reinterpret_cast<void**>(&_pDirectInput), 0))) + return false; + + if (FAILED(_pDirectInput->CreateDevice(GUID_SysMouse, &_pDevice, 0))) + return false; + + if (FAILED(_pDevice->SetDataFormat(&c_dfDIMouse))) + return false; + + if (FAILED(_pDevice->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE))) + return false; + + if (FAILED(_pDevice->Acquire())) + return false; + */ + return true; +} + +void Mouse::Free() +{ + /* + if (_pDevice) + { + _pDevice->Unacquire(); + _pDevice = NULL; + } + + _pDirectInput = NULL; + */ +} + +void Mouse::Update() +{ + /* + if (!_pDirectInput || !_pDevice) + { + return; + } + + HRESULT hr; + + while (true) + { + hr = _pDevice->GetDeviceState(sizeof(DIMOUSESTATE), &_mouseState); + + if (FAILED(hr)) + { + if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) + { + if (FAILED(_pDevice->Acquire())) + return; + } + } + else + { + break; + } + } + */ +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Mouse.h b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Mouse.h new file mode 100644 index 0000000..3cbd598 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/Mouse.h @@ -0,0 +1,103 @@ +// 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-2015 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. +// + +#pragma once +/* +#define DIRECTINPUT_VERSION 0x0800 +#include <dinput.h> +*/ +#include "windows.h" +#include "MathUtil.h" + +class Mouse +{ +public: + Mouse(); + ~Mouse(); + + /* + enum Button + { + LEFT = 0x00, + RIGHT = 0x01, + MIDDLE = 0x02 + }; + + bool IsButtonPressed(Button button) const + { + if (_mouseState.rgbButtons[button] & 0x80) + return true; + return false; + } + */ + void SetPosition(atcore_float2 position) + { + m_Position = position; + } + + atcore_float2 GetDelta() const + { + return m_Delta; + } + + void SetDelta(atcore_float2 position) + { + m_Delta = gfsdk_makeFloat2( + static_cast<float>(position.x - m_Position.x), + static_cast<float>(position.y - m_Position.y)); + m_Position = position; + } + + float GetDeltaWheel() const + { + if (m_DeltaWheel > 0) + return 1.0f; + else if (m_DeltaWheel < 0) + return -1.0f; + else + return 0.0f; + } + + void SetDeltaWheel(float deltaWheel) + { + m_DeltaWheel = deltaWheel; + } + + void Update(); + bool Initialize(HINSTANCE hInstance, HWND hWnd); + void Free(); + /* + IDirectInput8* _pDirectInput; + IDirectInputDevice8* _pDevice; + DIMOUSESTATE _mouseState; + */ + atcore_float2 m_Position; + atcore_float2 m_Delta; + float m_DeltaWheel; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp new file mode 100644 index 0000000..a633770 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.cpp @@ -0,0 +1,1312 @@ +// 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-2015 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. +// +#include "SimpleScene.h" + +#include "AppMainWindow.h" +#include "Automate.h" +#include "Backdoor.h" +#include "Gamepad.h" +#include "GlobalSettings.h" +#include "Light.h" +#include "Mouse.h" +#include "SimpleRenderable.h" +#include "Stats.h" +#include "CorelibUtils.h" +//#include "Timer.h" +#include "ViewerOutput.h" + +#include "FoundationHolder.h" + +#include <NvAllocatorCallback.h> +#include <NvErrorCallback.h> +#include <NsAlignedMalloc.h> +#include <NsVersionNumber.h> + +#include <Nv/Common/NvCoMemoryAllocator.h> + +#include "RenderInterface.h" +#include "DeviceManager.h" + +#ifndef NV_ARTISTTOOLS +#include "FurCharacter.h" +#include "FurRenderer.h" +#include "ProjectParams.h" +#include "HairInstance.h" +#include "HairSDK.h" + +namespace { // anonymous + +class ErrorCallback: public nvidia::NvErrorCallback +{ + public: + void reportError(nvidia::NvErrorCode::Enum code, const char* message, const char* file, int line) NV_OVERRIDE + { + if (code & (nvidia::NvErrorCode::eDEBUG_WARNING | nvidia::NvErrorCode::ePERF_WARNING)) + { + viewer_warn("%s", message); + return; + } + viewer_err("%s", message); + if (code != nvidia::NvErrorCode::eNO_ERROR) + { + viewer_err("%s", message); + } + } +}; + +class AllocatorCallback: public nvidia::NvAllocatorCallback +{ + public: + + void* allocate(size_t size, const char* typeName, const char* filename, int line) NV_OVERRIDE + { + return NvCo::MemoryAllocator::getInstance()->simpleAllocate(size); + } + + void deallocate(void* ptr) NV_OVERRIDE + { + NvCo::MemoryAllocator::getInstance()->simpleDeallocate(ptr); + } +}; + +} // namespace anonymous + +static AllocatorCallback s_allocator; +static ErrorCallback s_error; + +// global singletons (can't create more than one instance) +struct ProjectParamsContext* g_projectParamsContext = 0; + +class CustomLogger : public NvCo::Logger +{ +public: + virtual void log(NvCo::LogSeverity::Enum severity, const char* message, const char* functionName, const char* file, int line) NV_OVERRIDE + { + using namespace NvCo; + + switch (severity) + { + default: + case LogSeverity::FATAL_ERROR: + case LogSeverity::NON_FATAL_ERROR: + viewer_err("%s", message); + break; + case LogSeverity::WARNING: + viewer_warn("%s", message); + break; + case LogSeverity::INFO: + viewer_info("%s", message); + break; + case LogSeverity::DEBUG_INFO: + viewer_msg("%s", message); + break; + } + } + virtual void flush() NV_OVERRIDE {} +}; + +CustomLogger g_logHandler; +#else +#include "GPUProfiler.h" +#include "MeshShaderParam.h" +#include <Nv\Common\NvCoLogger.h> +#endif // NV_ARTISTTOOLS + +Gamepad& theGamepad = Gamepad::Instance(); +Mouse g_mouse; +Timer g_fpsTimer; +Backdoor* g_pBackdoor; + +/////////////////////////////////////////////////////////////////////////////// +SimpleScene* SimpleScene::Inst() +{ + static SimpleScene scene; + return &scene; +} + +/////////////////////////////////////////////////////////////////////////////// +SimpleScene::SimpleScene() + : + m_pCamera(0), + m_pWindCamera(0), + m_isProjectModified(false), + m_isFurModified(false), + m_isSceneLoading(false) +{ +#ifndef NV_ARTISTTOOLS + m_pFurCharacter = new FurCharacter; +#endif // NV_ARTISTTOOLS +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleScene::Initialize( HWND hWnd, int backdoor) +{ + g_fpsTimer.Start(); + + if(!InitCameraMouse(hWnd)) + return false; + +// if (!SimpleRenderable::Initialize()) +// return false; + + Light::Initialize(); + + //nvidia::shdfnd::initializeSharedFoundation(NV_FOUNDATION_VERSION, s_allocator, s_error); + + FoundationHolder::GetFoundation(); + + GPUProfiler_Initialize(); + + + if (backdoor == 1) // master mode + g_pBackdoor = createBackdoor("BACKDOOR_SERVER","BACKDOOR_CLIENT"); + + 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(); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleScene::Shutdown() +{ +#ifndef SAFE_DELETE +#define SAFE_DELETE(x) {if(x!=NV_NULL){delete x;x=NV_NULL;}} +#endif + + SAFE_DELETE(m_pCamera); + SAFE_DELETE(m_pWindCamera); + + GPUProfiler_Shutdown(); + + SimpleRenderable::Shutdown(); + Light::Shutdown(); + + if (g_pBackdoor) + { + g_pBackdoor->release(); + g_pBackdoor = nullptr; + } + +#ifndef NV_ARTISTTOOLS + GetFurCharacter().Clear(); + + ShutdownBlastSDK(); + + if (g_projectParamsContext) + { + ReleaseProjectParamsContext(g_projectParamsContext); + g_projectParamsContext = nullptr; + } +#else + CoreLib::Inst()->SimpleScene_Shutdown(); +#endif // NV_ARTISTTOOLS + + RenderInterface::Shutdown(); + + nvidia::shdfnd::terminateSharedFoundation(); +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleScene::Clear() +{ + GlobalSettings::Inst().m_sceneLoaded = false; + GlobalSettings::Inst().m_firstFrame = true; + +#ifndef NV_ARTISTTOOLS + GetFurCharacter().Clear(); +#else + CoreLib::Inst()->SimpleScene_Clear(); +#endif // NV_ARTISTTOOLS + + m_cameraBookmarks.clear(); + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleScene::InitCameraMouse(HWND hAppWnd) +{ + // default camera pose settings + m_pCamera = new Camera(GlobalSettings::Inst().m_zup, false); + m_pCamera->SetDefaults(); + + // init wind camera + { + m_pWindCamera = new Camera(false); + m_pWindCamera->SetDefaults(); + + GlobalSettings::Inst().m_windDir = m_pWindCamera->GetZAxis(); + } + + // init mouse + g_mouse.Initialize(::GetModuleHandle(NV_NULL), (HWND)hAppWnd/*_hWidget*/); + + theGamepad.Initialize(); + return true; +} + +float SimpleScene::NextTimeStep() +{ + static LONGLONG g_lastRenderTicks = 0; + + // Work out the timestep + LONGLONG ticks = g_fpsTimer.GetTicksElapsed(); + LONGLONG deltaTicks = ticks - g_lastRenderTicks; + g_lastRenderTicks = ticks; + + float timeStep = deltaTicks / float(g_fpsTimer.GetTicksPerSecond()); + + const float maxTimeStep = 0.1f; + + timeStep = (timeStep < 0.0f) ? 0.0f : timeStep; + timeStep = (timeStep > maxTimeStep) ? maxTimeStep : timeStep; + + return timeStep; +} + +Timer& SimpleScene::GetTimer() +{ + return g_fpsTimer; +} + +/////////////////////////////////////////////////////////////////////////////// +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; + + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + // draw background + RenderInterface::ClearRenderWindow(0.35f, 0.35f, 0.35f); + RenderInterface::RenderBackgroundTexture(); + + globalSettings.setTimeStep(NextTimeStep()); + //globalSettings.setTimeStep(1.0f/60.0f); + + // increment frame timer + if (globalSettings.m_animate) + { + globalSettings.stepAnimation(); + } + + if (globalSettings.m_playStopped) + AppMainWindow::Inst().updateMainToolbar(); + + // update camera + UpdateCamera(); + + // draw lights + Light::DrawLights(m_pCamera); + + // show ground grid + if (globalSettings.m_showGrid) + DrawGround(); + + // draw wind icon + if (globalSettings.m_visualizeWind) + DrawWind(); + + // draw axis lines + if (globalSettings.m_showAxis) + DrawAxis(); + + // handle game pad + theGamepad.Process(); + + // visualize shadow map + 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(); + + CoreLib::Inst()->SimpleScene_Draw_DX11(); + + RenderInterface::FlushDX11(); + +#endif // NV_ARTISTTOOLS + + // present current window + RenderInterface::PresentRenderWindow(); +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleScene::Timeout() +{ + if (m_pCamera == nullptr) + { + // this could be called when quiting. have to check nullptr + return; + } + + g_mouse.Update(); + + if (IsAutomateMode()) + { + AutomateRun(); + } + + Draw(); + + if (g_pBackdoor) + { + int argc; + const char **argv = g_pBackdoor->getInput(argc); + if (argc > 0) + { + char message[1024]; + strcpy(message,""); + for (int i = 0; i < argc; i++) + { + strcat(message, argv[i]); + strcat(message," "); + } + + viewer_info("Message received: %s", message); + } + } + +} + +#include <Shlwapi.h> +#include <FbxUtil.h> + +/////////////////////////////////////////////////////////////////////////////// +bool +SimpleScene::LoadSceneFromFbx(const char* dir, const char* fbxName) +{ + return CoreLib::Inst()->SimpleScene_LoadSceneFromFbx(dir, fbxName); + + /* + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + char fbxFilePath[MAX_PATH]; + + float sceneUnit = globalSettings.getSceneUnitInCentimeters(); + + PathCombineA(fbxFilePath, dir, fbxName); + + AppMainWindow::Inst().setProgress("Initializing FBX loader", 0); + FbxUtil::Initialize(fbxFilePath, sceneUnit); + + char rootBoneName[MAX_PATH]; + int upAxis = 0; + + FbxUtil::GetGlobalSettings( + &globalSettings.m_frameStartTime, + &globalSettings.m_frameEndTime, + &globalSettings.m_animationFps, + &upAxis, rootBoneName); + + if (upAxis == 1) + SimpleScene::Inst()->ResetUpDir(false); + else if (upAxis = 2) + SimpleScene::Inst()->ResetUpDir(true); + +#ifndef NV_ARTISTTOOLS + SimpleScene::Inst()->GetFurCharacter().LoadMeshFromFbx(dir, fbxName); +#else + CoreLib::Inst()->SimpleScene_LoadSceneFromFbx(dir, fbxName); +#endif // NV_ARTISTTOOLS + + FbxUtil::Release(); + + globalSettings.m_sceneLoaded = true; + globalSettings.m_animationIndex = 1; + globalSettings.m_firstFrame = true; + + //globalSettings.m_currentBoneIndex = findBoneByName(rootBoneName); + globalSettings.resetAnimation(); + + return true; + */ +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleScene::LoadProject(const char* dir, const char* file) +{ + 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); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleScene::LoadParameters(NvParameterized::Interface* iface) +{ + m_isSceneLoading = true; + + AppMainWindow::Inst().startProgress(); + +#ifndef NV_ARTISTTOOLS + nvidia::parameterized::HairProjectParameters* params = static_cast<nvidia::parameterized::HairProjectParameters*>(iface); + + nvidia::parameterized::HairProjectParametersNS::ParametersStruct& srcDesc = params->parameters(); + + if (m_pCamera) + { + m_pCamera->LoadParameters(&srcDesc.camera); + } + + LoadCameraBookmarks(iface); + + if (m_pWindCamera) + { + m_pWindCamera->LoadParameters(&srcDesc.windCamera); + } + + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + // Load scene settings + globalSettings.m_repeatAnimation = srcDesc.scene.repeatAnimation; + globalSettings.m_animationSpeed = srcDesc.scene.animationSpeed; + globalSettings.m_showGrid = srcDesc.scene.showGrid; + globalSettings.m_showAxis = srcDesc.scene.showAxis; + globalSettings.m_zup = srcDesc.scene.upAxis == 1; + globalSettings.m_sceneUnitIndex = srcDesc.scene.sceneUnitIndex; + + // Load renderer settings + NvParameterized::Handle handle(iface); + + // Load fbx paths + if (iface->getParameterHandle("fbxFilePaths", handle) == NvParameterized::ERROR_NONE) + { + int arraySize; + handle.getArraySize(arraySize); + char** strArray = new char*[arraySize]; + handle.getParamStringArray(strArray, arraySize); + for (int idx = 0; idx < arraySize; ++idx) + { + LoadSceneFromFbx( + globalSettings.m_projectFileDir.c_str(), + strArray[idx]); + } + delete [] strArray; + } + + // get general fur renderer settings + if (iface->getParameterHandle("renderer", handle) == NvParameterized::ERROR_NONE) + FurRenderer::LoadParameters(handle); + + // get fur character mesh setting + if (false == GetFurCharacter().LoadMeshParameters(handle)) + return false; + + // Load apx paths (hair instances) + if (iface->getParameterHandle("apxFilePaths", handle) == NvParameterized::ERROR_NONE) + { + if (false == GetFurCharacter().LoadHairParameters(handle)) + return false; + } +#else + CoreLib::Inst()->SimpleScene_LoadParameters(iface); +#endif // NV_ARTISTTOOLS + + m_isSceneLoading = false; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleScene::SaveProject(const char* dir, const char* file) +{ + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + globalSettings.m_projectFileDir = dir; + globalSettings.m_projectFileName = file; + + std::string saveFilePath = globalSettings.getAbsoluteFilePath(); + + std::string tempFilePath = utils::GetTempFilePath(); + +#ifndef NV_ARTISTTOOLS + if (ProjectParamsSave(g_projectParamsContext, tempFilePath.c_str(), this)) + { + if (!utils::RenameFile(tempFilePath.c_str(), saveFilePath.c_str(), true /* overwrite */)) + { + return false; + } + SetProjectModified(false); + return true; + } +#else + return CoreLib::Inst()->SimpleScene_SaveProject(dir, file); +#endif // NV_ARTISTTOOLS + + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleScene::LoadBackgroundTextureFile() +{ + QString texName = AppMainWindow::Inst().OpenTextureFile(); + + return RenderInterface::LoadBackgroundTexture(texName.toLocal8Bit()); +} + +////////////////////////////////////////////////////////////////////////// +void SimpleScene::ClearBackgroundTexture() +{ + RenderInterface::ClearBackgroundTexture(); +} + + +////////////////////////////////////////////////////////////////////////// +// slots and handlers / mouse / camera + +void SimpleScene::Resize( int w, int h ) +{ + RenderInterface::ResizeRenderWindow(w,h); + + m_pCamera->SetSize(w,h); + + UpdateCamera(); + + SetProjectModified(true); +} + +void SimpleScene::onMouseDown(atcore_float2 position) +{ + g_mouse.SetPosition(position); +} + +void SimpleScene::onMouseUp(atcore_float2 position) +{ +} + +void SimpleScene::onMouseMove(atcore_float2 position) +{ + g_mouse.SetDelta(position); +} + +void SimpleScene::onMouseWheel(float deltaWheel) +{ + g_mouse.SetDeltaWheel(deltaWheel); +} + +QString SimpleScene::createBookmark() +{ + QString bookmark = _generateBookmarkName(); + m_cameraBookmarks.append(CameraBookmark(bookmark, *m_pCamera)); + return bookmark; +} + +void SimpleScene::removeBookmark(const QString& name) +{ + int bookmarksCount = m_cameraBookmarks.size(); + for (int i = 0; i < bookmarksCount; ++i) + { + const CameraBookmark& bookmark = m_cameraBookmarks[i]; + if (bookmark.name == name) + { + m_cameraBookmarks.removeAt(i); + break; + } + } +} + +void SimpleScene::activateBookmark(const QString& name) +{ + int bookmarksCount = m_cameraBookmarks.size(); + for (int i = 0; i < bookmarksCount; ++i) + { + const CameraBookmark& bookmark = m_cameraBookmarks[i]; + if (bookmark.name == name) + { + *m_pCamera = bookmark.camera; + break; + } + } +} + +void SimpleScene::renameBookmark(const QString& oldName, const QString& newName) +{ + int bookmarksCount = m_cameraBookmarks.size(); + for (int i = 0; i < bookmarksCount; ++i) + { + CameraBookmark& bookmark = m_cameraBookmarks[i]; + if (bookmark.name == oldName) + { + bookmark.name = newName; + break; + } + } +} + +QList<QString> SimpleScene::getBookmarkNames() +{ + QList<QString> names; + int bookmarksCount = m_cameraBookmarks.size(); + for (int i = 0; i < bookmarksCount; ++i) + { + const CameraBookmark& bookmark = m_cameraBookmarks[i]; + names.append(bookmark.name); + } + + return names; +} + +void SimpleScene::Drag( char type ) +{ + g_mouse.Update(); + + switch(type) + { + case 'R': RotateCamera(); break; + case 'Z': ZoomCamera(); break; + case 'P': PanCamera(); break; + case 'L': RotateLightDirection(); break; + case 'W': RotateWindDirection(); break; + + case 'K': PanLight(); break; + } + SetProjectModified(true); +} + +void SimpleScene::WheelZoom() +{ + WheelZoomCamera(); + SetProjectModified(true); +} + +void SimpleScene::PanCamera() +{ + if (g_mouse.GetDelta().x != 0.0f || g_mouse.GetDelta().y != 0.0f) + { + int w = m_pCamera->GetWidth(); + int h = m_pCamera->GetHeight(); + + atcore_float2 delta = g_mouse.GetDelta() * 2.0f; + delta.x /= (float)(w); + delta.y /= (float)(h); + m_pCamera->Pan(delta); + } + SetProjectModified(true); +} + +void SimpleScene::ZoomCamera() +{ + float dz = (- g_mouse.GetDelta().y); + + if (dz != 0.0f) + { + dz *= 5.0f / m_pCamera->GetHeight(); + + m_pCamera->Dolly(dz); + } + SetProjectModified(true); +} + +void SimpleScene::WheelZoomCamera() +{ + float dz = - g_mouse.GetDeltaWheel() ; + + if (dz != 0.0f) + { + dz /= 5.0f; + + m_pCamera->Dolly(dz); + } + SetProjectModified(true); +} + +void SimpleScene::RotateCamera() +{ + if (g_mouse.GetDelta().x != 0.0f || g_mouse.GetDelta().y != 0.0f) + { + m_pCamera->Orbit(g_mouse.GetDelta() * 0.125f); + } + SetProjectModified(true); +} + +void SimpleScene::RotateLightDirection() +{ + if (g_mouse.GetDelta().x != 0.0f || g_mouse.GetDelta().y != 0.0f) + { + atcore_float2 delta = g_mouse.GetDelta() * 0.5f; + delta.y *= -1.0f; + + if (Light::GetLinkLightOption()) + { + Light* pKeyLight = Light::GetLight(Light::KEY_LIGHT); + Light* pFillLight = Light::GetLight(Light::FILL_LIGHT); + Light* pRimLight = Light::GetLight(Light::RIM_LIGHT); + if (pKeyLight->m_selected) + { + pKeyLight->Orbit(delta); + pFillLight->Orbit(delta); + pRimLight->Orbit(delta); + } + else + { + if (pFillLight->m_selected) + { + pFillLight->Orbit(delta); + } + + if (pRimLight->m_selected) + { + pRimLight->Orbit(delta); + } + } + + Light* pEnvLight = Light::GetLight(Light::ENV_LIGHT); + if (pEnvLight->m_selected) + { + pEnvLight->Orbit(delta); + } + } + else + { + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight) + continue; + + if (pLight->m_selected) + { + pLight->Orbit(delta); + } + } + } + } + SetProjectModified(true); +} + +void SimpleScene::PanLight() +{ + if (g_mouse.GetDelta().x != 0.0f || g_mouse.GetDelta().y != 0.0f) + { + int w = m_pCamera->GetWidth(); + int h = m_pCamera->GetHeight(); + + atcore_float2 delta = g_mouse.GetDelta() * 2.0f; + delta.x /= (float)(w); + delta.y /= (float)(h); + + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight) + continue; + + if (pLight->m_selected) + pLight->Pan(delta, m_pCamera->GetXAxis(), m_pCamera->GetYAxis()); + } + } + SetProjectModified(true); +} + +void SimpleScene::RotateWindDirection() +{ + if (g_mouse.GetDelta().x != 0.0f || g_mouse.GetDelta().y != 0.0f) + { + m_pWindCamera->Orbit(g_mouse.GetDelta() * 0.5f); + + GlobalSettings::Inst().m_windDir = m_pWindCamera->GetZAxis(); + } + + SetProjectModified(true); +} + +QString SimpleScene::_generateBookmarkName() +{ + QString name; + for (int i = 1; ; i++) + { + name = QString("View%1").arg(i, 2, 10, QChar('0')); + int found = -1; + int bookmarksCount = m_cameraBookmarks.size(); + for (int j = 0; j < bookmarksCount; ++j) + { + const CameraBookmark& bookmark = m_cameraBookmarks[j]; + if (bookmark.name == name) + { + found = j; + break; + } + } + + if (-1 == found) + break; + } + return name; +} + +void SimpleScene::UpdateCamera() +{ + if (!m_pCamera) + return; + + float sceneUnit = GlobalSettings::Inst().getSceneUnitInCentimeters() ; + float fov = (GlobalSettings::Inst().m_fovAngle / 360.0f) * 3.141592653589793; + + m_pCamera->SetFOV(fov); + + int w = m_pCamera->GetWidth(); + int h = m_pCamera->GetHeight(); + + float aspect = ((float)(w) / (float)(h)); + + 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(); +} + +void SimpleScene::FitCamera() +{ + if (!m_pCamera) + return; + + atcore_float3 center, extents; + +#ifndef NV_ARTISTTOOLS + if (m_pFurCharacter) + m_pFurCharacter->ComputeBounds(center, extents, false); +#else + CoreLib::Inst()->SimpleScene_FitCamera(center, extents); +#endif // NV_ARTISTTOOLS + + m_pCamera->FitBounds(center, extents); +} + +void SimpleScene::ResetUpDir(bool zup) +{ + m_pCamera->ResetUpDir(zup); + m_pWindCamera->ResetUpDir(zup); + Light::ResetUpDir(zup); + + GlobalSettings::Inst().m_zup = zup; + + SetProjectModified(true); +} + +void SimpleScene::ResetLhs(bool lhs) +{ + m_pCamera->ResetLhs(lhs); + m_pWindCamera->ResetLhs(lhs); + Light::ResetLhs(lhs); + + GlobalSettings::Inst().m_lhs = lhs; +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleScene::SaveParameters(NvParameterized::Interface* iface) +{ +#ifndef NV_ARTISTTOOLS + nvidia::parameterized::HairProjectParameters* params = static_cast<nvidia::parameterized::HairProjectParameters*>(iface); + nvidia::parameterized::HairProjectParametersNS::ParametersStruct& targetDesc = params->parameters(); + + if (m_pCamera) + m_pCamera->SaveParameters(&targetDesc.camera); + + SaveCameraBookmarks(iface); + + if (m_pWindCamera) + m_pWindCamera->SaveParameters(&targetDesc.windCamera); + + // Save scene settings + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + targetDesc.scene.repeatAnimation = globalSettings.m_repeatAnimation; + targetDesc.scene.animationSpeed = globalSettings.m_animationSpeed; + targetDesc.scene.showGrid = globalSettings.m_showGrid; + targetDesc.scene.showAxis = globalSettings.m_showAxis; + + targetDesc.scene.upAxis = (globalSettings.m_zup) ? 1 : 2; + targetDesc.scene.sceneUnitIndex = globalSettings.m_sceneUnitIndex; + + FurCharacter& character = GetFurCharacter(); + NvParameterized::Handle handle(iface); + + // Save renderer settings + if (iface->getParameterHandle("renderer", handle) == NvParameterized::ERROR_NONE) + { + FurRenderer::SaveParameters(handle); + character.SaveMeshParameters(handle); + } + + if (iface->getParameterHandle("renderer.textureFilePath", handle) == NvParameterized::ERROR_NONE) + { + std::string textureFilePath = globalSettings.getRelativePath(globalSettings.m_backgroundTextureFilePath.c_str()); + handle.setParamString(textureFilePath.c_str()); + } + + // save hair path + if (iface->getParameterHandle("apxFilePaths", handle) == NvParameterized::ERROR_NONE) + character.SaveHairParameters(handle); +#else + CoreLib::Inst()->SimpleScene_SaveParameters(iface); +#endif // NV_ARTISTTOOLS + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleScene::LoadCameraBookmarks(NvParameterized::Interface* iface) +{ +#ifndef NV_ARTISTTOOLS + nvidia::parameterized::HairProjectParameters* params = static_cast<nvidia::parameterized::HairProjectParameters*>(iface); + nvidia::parameterized::HairProjectParametersNS::ParametersStruct& srcDesc = params->parameters(); + nvidia::parameterized::HairProjectParametersNS::CameraBookmark_DynamicArray1D_Type& bookmarks = srcDesc.cameraBookmarks; + + NvParameterized::Handle cameraBookmarksHandle(iface); + if (iface->getParameterHandle("cameraBookmarks", cameraBookmarksHandle) != NvParameterized::ERROR_NONE) + return false; + + int numCameraBookmarks = 0; + cameraBookmarksHandle.getArraySize(numCameraBookmarks); + for (int idx = 0; idx < numCameraBookmarks; ++idx) + { + NvParameterized::Handle cameraBookmarkHandle(cameraBookmarksHandle); + if (cameraBookmarksHandle.getChildHandle(idx, cameraBookmarkHandle) == NvParameterized::ERROR_NONE) + { + CameraBookmark cameraBookmark; + cameraBookmark.camera.LoadParameters((void*)&(bookmarks.buf[idx].camera)); + cameraBookmark.camera.SetSize(m_pCamera->GetWidth(), m_pCamera->GetHeight()); + cameraBookmark.name = bookmarks.buf[idx].name.buf; + m_cameraBookmarks.append(cameraBookmark); + } + } +#else + CoreLib::Inst()->SimpleScene_LoadCameraBookmarks(iface); +#endif // NV_ARTISTTOOLS + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +bool SimpleScene::SaveCameraBookmarks(NvParameterized::Interface* iface) +{ +#ifndef NV_ARTISTTOOLS + nvidia::parameterized::HairProjectParameters* params = static_cast<nvidia::parameterized::HairProjectParameters*>(iface); + nvidia::parameterized::HairProjectParametersNS::ParametersStruct& srcDesc = params->parameters(); + nvidia::parameterized::HairProjectParametersNS::CameraBookmark_DynamicArray1D_Type& bookmarks = srcDesc.cameraBookmarks; + + NvParameterized::Handle cameraBookmarksHandle(iface); + if (iface->getParameterHandle("cameraBookmarks", cameraBookmarksHandle) != NvParameterized::ERROR_NONE) + return false; + + int numCameraBookmarks = m_cameraBookmarks.size(); + cameraBookmarksHandle.resizeArray(numCameraBookmarks); + + for (int idx = 0; idx < numCameraBookmarks; ++idx) + { + NvParameterized::Handle cameraBookmarkHandle(cameraBookmarksHandle); + if (cameraBookmarksHandle.getChildHandle(idx, cameraBookmarkHandle) == NvParameterized::ERROR_NONE) + { + NvParameterized::Handle tempHandle(cameraBookmarkHandle); + CameraBookmark& bookmark = m_cameraBookmarks[idx]; + + if (ParamGetChild(cameraBookmarkHandle, tempHandle, "name")) + { + tempHandle.setParamString(bookmark.name.toStdString().c_str()); + } + + bookmark.camera.SaveParameters((void*)&(bookmarks.buf[idx].camera)); + } + } +#else + CoreLib::Inst()->SimpleScene_SaveCameraBookmarks(iface); +#endif // NV_ARTISTTOOLS + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleScene::sendParam(const char *str, NvFloat32 v) +{ + if (g_pBackdoor) + { + char message[1024]; + sprintf(message, "%s %f", str, v); +// viewer_info(message); + g_pBackdoor->send("%s", message); + } +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleScene::sendParam(const char *str, NvUInt32 v) +{ + if (g_pBackdoor) + { + char message[1024]; + sprintf(message, "%s %d", str, v); +// viewer_info(message); + g_pBackdoor->send("%s", message); + } +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleScene::sendParam(const char *str, atcore_float3 v) +{ + if (g_pBackdoor) + { + char message[1024]; + sprintf(message, "%s %f %f %f", str, v.x, v.y, v.z); +// viewer_info(message); + g_pBackdoor->send("%s", message); + } +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleScene::sendParam(const char *str, atcore_float4 v) +{ + if (g_pBackdoor) + { + char message[1024]; + sprintf(message, "%s %f %f %f %f", str, v.x, v.y, v.z, v.w); +// viewer_info(message); + g_pBackdoor->send("%s", message); + } +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleScene::sendParam(const char *str, NvBoolean v) +{ + if (g_pBackdoor) + { + char message[1024]; + sprintf(message, "%s %d", str, int(v)); +// viewer_info(message); + g_pBackdoor->send("%s", message); + } +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleScene::DrawGround() +{ + bool zup = GlobalSettings::Inst().m_zup; + + SimpleShaderParam param; + { + param.useVertexColor = true; + gfsdk_makeIdentity(param.world); + param.view = m_pCamera->GetViewMatrix(); + param.projection = m_pCamera->GetProjectionMatrix(); + } + RenderInterface::CopyShaderParam(RenderInterface::SHADER_TYPE_SIMPLE_COLOR, + (void*)¶m, sizeof(SimpleShaderParam) ); + + SimpleRenderable::Draw( + zup ? SimpleRenderable::GROUND_ZUP : + SimpleRenderable::GROUND_YUP, false); +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleScene::DrawWind() +{ + // Convert camera axis into world matrix + atcore_float4x4 windMat = gfsdk_transpose(m_pWindCamera->GetViewMatrix()); + + // Extract rotation axis from the view matrix + atcore_float4x4 viewMat = m_pCamera->GetViewMatrix(); + if (m_pCamera->UseLHS()) + gfsdk_setPosition(viewMat, gfsdk_makeFloat3(0, 0, 80)); + else + gfsdk_setPosition(viewMat, gfsdk_makeFloat3(0, 0, -80)); + + SimpleShaderParam param; + { + param.useVertexColor = true; + param.world = windMat; + param.view = viewMat; + param.projection = m_pCamera->GetProjectionMatrix(); + } + RenderInterface::CopyShaderParam(RenderInterface::SHADER_TYPE_SIMPLE_COLOR, + (void*)¶m, sizeof(SimpleShaderParam) ); + + int targetWidth = m_pCamera->GetWidth(); + int targetHeight = m_pCamera->GetHeight(); + float aspectRatio = (float)targetWidth / (float)targetHeight; + + // Wind view size + const int srcHeight = 64; + const int srcWidth = aspectRatio*srcHeight; + const int originX = 64; + + RenderInterface::Viewport savedVP, vp; + RenderInterface::GetViewport(savedVP); + + // set the viewport transform + { + vp.TopLeftX = originX + ( (srcWidth > srcHeight) ? (srcHeight - srcWidth)/2.0f : 0); + vp.TopLeftY = targetHeight-srcHeight; + vp.Width = (float)srcWidth; + vp.Height = (float)srcHeight; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + } + + RenderInterface::SetViewport(vp); + + bool zUP = GlobalSettings::Inst().m_zup; + SimpleRenderable::Draw(zUP ? + SimpleRenderable::WIND_ZUP : + SimpleRenderable::WIND_YUP, false); + + // Restore states + RenderInterface::SetViewport(savedVP); +} + +/////////////////////////////////////////////////////////////////////////////// +void SimpleScene::DrawAxis() +{ + // Extract rotation axis from the view matrix + atcore_float4x4 viewMat = m_pCamera->GetViewMatrix(); + if (m_pCamera->UseLHS()) + gfsdk_setPosition(viewMat, gfsdk_makeFloat3(0, 0, 4)); + else + gfsdk_setPosition(viewMat, gfsdk_makeFloat3(0, 0, -4)); + + SimpleShaderParam param; + { + param.useVertexColor = true; + gfsdk_makeIdentity(param.world); + param.view = viewMat; + param.projection = m_pCamera->GetProjectionMatrix(); + } + RenderInterface::CopyShaderParam(RenderInterface::SHADER_TYPE_SIMPLE_COLOR, + (void*)¶m, sizeof(SimpleShaderParam) ); + + int targetWidth = m_pCamera->GetWidth(); + int targetHeight = m_pCamera->GetHeight(); + float aspectRatio = (float)targetWidth / (float)targetHeight; + + // Axis view size + const int srcHeight = 64; + const int srcWidth = aspectRatio*srcHeight; + + RenderInterface::Viewport savedVP, vp; + RenderInterface::GetViewport(savedVP); + + // set the viewport transform + { + vp.TopLeftX = (srcWidth > srcHeight) ? (srcHeight - srcWidth)/2.0f : 0; // To make it like a square view + vp.TopLeftY = targetHeight-srcHeight; + vp.Width = (float)srcWidth; + vp.Height = (float)srcHeight; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + } + + RenderInterface::SetViewport(vp); + + bool zUP = GlobalSettings::Inst().m_zup; + SimpleRenderable::Draw(zUP ? + SimpleRenderable::AXIS_ZUP : + SimpleRenderable::AXIS_YUP, false); + + RenderInterface::SetViewport(savedVP); +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h new file mode 100644 index 0000000..8d01970 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Scene/SimpleScene.h @@ -0,0 +1,184 @@ +// 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-2015 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. +// + +#pragma once + +#include <Windows.h> +#include "MathUtil.h" +#include <QtCore/QList> +#include <QtCore/QMap> +#include "Camera.h" +#include "Timer.h" +class FurCharacter; + +class DeviceManager; +class SampleManager; + +namespace NvParameterized +{ + class Interface; +} + +struct CameraBookmark +{ + CameraBookmark() + { + } + CameraBookmark(const QString& inName, const Camera& inCamera) + : name(inName) + , camera(inCamera) + { + } + QString name; + Camera camera; +}; + +////////////////////////////////////////////////////////////////////////////////////// +// This scene object does the followings +// - handles the overall project settings load/save +// - owns and calls FurRenderer's draw functions +// - owns and handle main camera and mouse callbacks +// - owns and handles backdoor communication with the SDK and game engines +////////////////////////////////////////////////////////////////////////////////////// +class CORELIB_EXPORT SimpleScene +{ +public: + SimpleScene(); + + static SimpleScene* Inst(); + + // prepare shaders, manage objects + bool Initialize(HWND hWnd, int backdoor = 0); + + bool LoadProject(const char* dir, const char* file); + bool SaveProject(const char* dir, const char* file); + bool LoadParameters(NvParameterized::Interface* iface); + bool SaveParameters(NvParameterized::Interface* iface); + bool LoadCameraBookmarks(NvParameterized::Interface* iface); + bool SaveCameraBookmarks(NvParameterized::Interface* iface); + bool Clear(); + + bool LoadSceneFromFbx(const char* dir, const char* fbxName); + + bool IsUpdatingUI() { return m_isUpdatingUI; } + void setIsUpdatingUI(bool b) { m_isUpdatingUI = b;} + bool IsSceneLoading() { return m_isSceneLoading; } + + Camera* GetCamera() { return m_pCamera; } + FurCharacter& GetFurCharacter() { return *m_pFurCharacter; } + void SetFurCharacter(FurCharacter* pFurCharacter) { m_pFurCharacter = pFurCharacter; } + + DeviceManager& GetDeviceManager() { return *m_pDeviceManager; } + void SetDeviceManager(DeviceManager* pDeviceManager) { m_pDeviceManager = pDeviceManager; } + SampleManager& GetSampleManager() { return *m_pSampleManager; } + void SetSampleManager(SampleManager* pSampleManager) { m_pSampleManager = pSampleManager; } + + void ResetUpDir(bool zup); + void ResetLhs(bool lhs); + + bool LoadBackgroundTextureFile(); + void ClearBackgroundTexture(); + + // backdoor + void sendParam(const char *str, NvFloat32 v); + void sendParam(const char *str, NvUInt32 v); + void sendParam(const char *str, atcore_float3 v); + void sendParam(const char *str, atcore_float4 v); + void sendParam(const char *str, NvBoolean v); + + bool IsFurModified() const { return m_isFurModified; } + bool IsProjectModified() const { return m_isProjectModified; } + void SetFurModified(bool isModified) { m_isFurModified = isModified; } + void SetProjectModified(bool isModified) { m_isProjectModified = isModified; } + + void UpdateCamera(); + void FitCamera(); + + void Draw(); + void Timeout(); + void Resize(int w, int h); + void Drag(char type); + void WheelZoom(); + void Shutdown(); + + void onMouseDown(atcore_float2 position); + void onMouseUp(atcore_float2 position); + void onMouseMove(atcore_float2 position); + void onMouseWheel(float deltaWheel); + + QString createBookmark(); + void removeBookmark(const QString& name); + void activateBookmark(const QString& name); + void renameBookmark(const QString& oldName, const QString& newName); + QList<QString> getBookmarkNames(); + + static float NextTimeStep(); + + Timer& GetTimer(); + +private: + // initialize scene components + bool InitCameraMouse(HWND hAppWnd); + bool InitFurSDK(); + + void DrawGround(); + void DrawAxis(); + void DrawHUD(); + void DrawWind(); + + // camera / mouse + void PanCamera(); + void ZoomCamera(); + void WheelZoomCamera(); + void RotateCamera(); + + void RotateLightDirection(); + void PanLight(); + + void RotateWindDirection(); + + QString _generateBookmarkName(); + +public: + + Camera* m_pCamera; + Camera* m_pWindCamera; + + QList<CameraBookmark> m_cameraBookmarks; + + FurCharacter* m_pFurCharacter; + + DeviceManager* m_pDeviceManager; + SampleManager* m_pSampleManager; + + bool m_isProjectModified; + bool m_isFurModified; + bool m_isSceneLoading; + bool m_isUpdatingUI; +}; + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Automate.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Automate.cpp new file mode 100644 index 0000000..6c7d551 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Automate.cpp @@ -0,0 +1,530 @@ +#include <windows.h> + +#include <QtWidgets/QApplication> + +#include "AppMainWindow.h" +//#include "SimpleScene.h" + +#include "OpenAutomate.h" +#include "Automate.h" +#include "Settings.h" + +//#define OPEN_CONSOLE +#ifdef OPEN_CONSOLE +#include <Windows.h> +#endif + +#include <cassert> +#include <string> + +#include <Nv/Common/NvCoCommon.h> + +#define KEYSTR ("Software\\OpenAutomate\\RegisteredApps\\NVIDIA\\FurViewer\\v1.0\\") + +const oaChar *Benchmarks[] = { + "HairBall", + "Teapot", + "Manjaladon", + "WitcherHorse", + NV_NULL +}; +oaInt NumBenchmarks = 1; + +static void ParseArgs(int argc, char *argv[]); + +static void OAMainLoop(const char *opt); +static bool RegisterAppItself(); +static int RunApp(QApplication& a); +static void GetAllOptions(void); +static void GetCurrentOptions(void); + +static bool g_isAutomateMode = false; +static int InstallModeFlag = 0; +static char *OAOpt = NV_NULL; + +bool AutomateInstallApp() +{ + return RegisterAppItself(); +} + +static bool RegisterAppItself() +{ + char exePath[MAX_PATH]; + if(!GetExePath(exePath)) + { + fprintf(stderr, "Cannot get exe path\r\n"); + return false; + } + + HKEY hKey; + DWORD dwRes = RegOpenKeyExA( + HKEY_LOCAL_MACHINE, + KEYSTR, + 0, + KEY_WRITE | KEY_READ, + &hKey); + + DWORD dwSize = MAX_PATH; + char buf[MAX_PATH]; + if(dwRes == ERROR_SUCCESS) + { + dwRes = RegQueryValueExA( + hKey, + "INSTALL_ROOT_PATH", + NV_NULL, + NV_NULL, + (LPBYTE)buf, + &dwSize); + if(dwRes == ERROR_SUCCESS && !lstrcmpiA(buf, exePath)) + { + RegCloseKey(hKey); + return true; + } + } + else + { + dwRes = RegCreateKeyExA( + HKEY_LOCAL_MACHINE, + KEYSTR, + 0, + NV_NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, NV_NULL, + &hKey, + &dwSize); + if(ERROR_SUCCESS != dwRes) + { + RegCloseKey(hKey); + return false; + } + } + + bool bRet = false; + do + { + dwRes = RegSetValueExA( + hKey, + "INSTALL_ROOT_PATH", + 0, + REG_SZ, + (BYTE*)exePath, + (DWORD)strlen(exePath)); + if(ERROR_SUCCESS != dwRes) + { + fprintf(stderr, "Write INSTALL_ROOT_PATH Failed\r\n"); + break; + } + +#ifdef _WIN64 +#ifdef _DEBUG + strcat(exePath, "FurViewer.win64.D.exe"); +#else + strcat(exePath, "FurViewer.win64.exe"); +#endif +#else +#ifdef _DEBUG + strcat(exePath, "FurViewer.win32.D.exe"); +#else + strcat(exePath, "FurViewer.win32.exe"); +#endif +#endif + + dwRes = RegSetValueExA( + hKey, + "ENTRY_EXE", + 0, + REG_SZ, + (BYTE*)exePath, + (DWORD)strlen(exePath)); + if(ERROR_SUCCESS != dwRes) + { + fprintf(stderr, "Write ENTRY_EXE Failed\r\n"); + break; + } + + ZeroMemory(buf, sizeof(buf)); + SYSTEMTIME tm; + GetLocalTime(&tm); + sprintf( + buf, + "%04d-%02d-%02d %02d:%02d:%02d", + tm.wYear, + tm.wMonth, + tm.wDay, + tm.wHour, + tm.wMinute, + tm.wSecond); + dwRes = RegSetValueExA( + hKey, + "INSTALL_DATETIME", + 0, + REG_SZ, + (BYTE*)buf, + (DWORD)strlen(buf)); + if(ERROR_SUCCESS != dwRes) + { + fprintf(stderr, "Write INSTALL_DATETIME Failed\r\n"); + break; + } + + dwRes = RegSetValueExA( + hKey, + "REGION", + 0, + REG_SZ, + (BYTE*)"en_US", + (DWORD)strlen("en_US")); + if(ERROR_SUCCESS != dwRes) + { + fprintf(stderr, "Write REGION Failed\r\n"); + break; + } + + bRet = true; + } while(0); + + RegCloseKey(hKey); + return bRet; +} + +static const char *FormatDataType(oaOptionDataType value_type) +{ + switch(value_type) + { + case OA_TYPE_STRING: + return "String"; + case OA_TYPE_INT: + return "Int"; + case OA_TYPE_FLOAT: + return "Float"; + case OA_TYPE_ENUM: + return "Enum"; + case OA_TYPE_BOOL: + return "Bool"; + default: + return "Unknown"; + } +} + +static const char *FormatCompareOp(oaComparisonOpType op_value) +{ + switch(op_value) + { + case OA_COMP_OP_EQUAL: + return "Equal"; + case OA_COMP_OP_NOT_EQUAL: + return "NotEqual"; + case OA_COMP_OP_GREATER: + return "Greater"; + case OA_COMP_OP_LESS: + return "Less"; + case OA_COMP_OP_GREATER_OR_EQUAL: + return "GreaterOrEqual"; + case OA_COMP_OP_LESS_OR_EQUAL: + return "LessOrEqual"; + default: + return "Unknown"; + } +} + +static void ConvertOAValue(oaOptionDataType value_type, + const oaValue *value, + char *result) +{ + switch(value_type) + { + case OA_TYPE_STRING: + case OA_TYPE_ENUM: + if (value->String) strcpy(result, value->String); + else result[0] = '\0'; + break; + case OA_TYPE_INT: + sprintf(result, "%d", value->Int); + break; + case OA_TYPE_FLOAT: + sprintf(result, "%f", value->Float); + break; + case OA_TYPE_BOOL: + sprintf(result, "%1d", value->Bool); + break; + default: + return; + } +} + +static void PrintOptions(const oaNamedOption *option) +{ + char buf[MAX_PATH]; + ConvertOAValue(option->DataType, &option->Value, buf); + + fprintf(stderr, "name=%s,type=%s,value=%s\r\n", option->Name, FormatDataType(option->DataType), buf); + if(option->MaxValue.Int && option->MinValue.Int) + { + fprintf(stderr," numsteps=%d", option->NumSteps); + ConvertOAValue(option->DataType, &option->MinValue, buf); + fprintf(stderr, "minvalue=%s", buf); + ConvertOAValue(option->DataType, &option->MaxValue, buf); + fprintf(stderr,"maxvalue=%s\r\n", buf); + } + + if(option->Dependency.ParentName) + { + ConvertOAValue(option->Dependency.ComparisonValType, &option->Dependency.ComparisonVal, buf); + fprintf(stderr, " parentname=%s,comparisionop=%s,comparisiontype=%s,comparisionvalue=%s\r\n", + option->Dependency.ParentName, + FormatCompareOp(option->Dependency.ComparisonOp), + FormatDataType(option->Dependency.ComparisonValType), + buf); + } +} + +#if (0) // Remove this! +int main(int argc, char *argv[]) +{ + SetConsoleTitleA("OA - simple application"); + ParseArgs(argc, argv); + + AppSettings::Inst().InitOptions(); + + if(InstallModeFlag) + { + InstallApp(); + } + else if(OAModeFlag) + { + OAMainLoop(OAOpt); + } + else + { + RunApp(); + } + + return(0); +} +#endif + +void GetAllOptions(void) +{ + fprintf(stderr, "All Options: \r\n"); + for(oaInt i=0; i < AppSettings::Inst().GetNumOptions(); ++i) + { + oaNamedOption* option = AppSettings::Inst().GetOption(i); + if (!strcmp(option->Name, "User/ProjectPath")) + continue; + if (!strcmp(option->Name, "User/FurAssetPath")) + continue; + PrintOptions(AppSettings::Inst().GetOption(i)); + oaAddOption(AppSettings::Inst().GetOption(i)); + } +} + +void GetCurrentOptions(void) +{ + fprintf(stderr, "Current Options: \r\n"); + + std::map<std::string, OptionValue>::const_iterator Iter = AppSettings::Inst().GetCurrentOptionMap()->begin(); + + oaNamedOption option; + oaInitOption(&option); + + for(; Iter != AppSettings::Inst().GetCurrentOptionMap()->end(); ++Iter) + { + if (!strcmp(Iter->second.Name, "User/ProjectPath")) + continue; + if (!strcmp(Iter->second.Name, "User/FurAssetPath")) + continue; + + option.Name = Iter->second.Name; + option.Value = Iter->second.Value; + option.DataType = Iter->second.Type; + PrintOptions(&option); + + oaAddOptionValue(Iter->second.Name, + Iter->second.Type, + &Iter->second.Value); + } +} + +void SetOptions(void) +{ + oaNamedOption *Option; + + fprintf(stderr, "Set Options: \r\n"); + while ((Option = oaGetNextOption()) != NV_NULL) + { + /* + * Set option value to persist for subsequent runs of the game + * to the given value. Option->Name will be the name of the value, + * and Option->Value will contain the appropriate value. + */ + PrintOptions(Option); + AppSettings::Inst().SetOptionValue(Option->Name, Option->DataType, &Option->Value); + } + + AppSettings::Inst().WriteOptionsFile(); +} + +void GetBenchmarks(void) +{ + /* foreach known available benchmark call oaAddBenchmark() with a unique string identifying it */ + for(oaInt i=0; i < NumBenchmarks; ++i) + oaAddBenchmark(Benchmarks[i]); +} + +void RunBenchmark(const oaChar *benchmark_name) +{ + oaValue Val; + int i; + + bool FoundBenchmark = false; + for(i=0; i < NumBenchmarks; ++i) + if(!strcmp(Benchmarks[i], benchmark_name)) + { + FoundBenchmark = true; + break; + } + + /* Check if the requested benchark is valid */ + if(!FoundBenchmark) + { + char Msg[1024]; + sprintf(Msg, "'%s' is not a valid benchmark.", benchmark_name); + OA_RAISE_ERROR(INVALID_BENCHMARK, benchmark_name); + } + + /* Setup everything to run the benchmark */ + + /* oaStartBenchmark() must be called right before the first frame */ + oaStartBenchmark(); + + /* + * Run the benchmark, and call oaDisplayFrame() right before the final + * present call for each frame + */ + //for(i=0; i < 50; ++i) + //{ + // SLEEP(20); + + // oaValue FrameValue; + // FrameValue.Int = i; + // oaValue OtherInt; + // OtherInt.Int = i+1000; + // oaChar str[100]; + // sprintf(str, "frame number: %d\00", i); + // oaValue Str; + // Str.String = str; + + // oaAddFrameValue("FrameCount", OA_TYPE_INT, &FrameValue); + // oaAddFrameValue("OtherInt", OA_TYPE_INT, &OtherInt); + // oaAddFrameValue("String", OA_TYPE_STRING, &Str); + + // oaDisplayFrame((oaFloat)(i * 20) / (oaFloat)1000); + //} + { +// SimpleScene* scene = SimpleScene::Inst(); + AppMainWindow::Inst().menu_clearScene(); + } + + /* Return some result values */ + Val.Int = 18249; + oaAddResultValue("Score", OA_TYPE_INT, &Val); + + Val.Float = 29.14; + oaAddResultValue("Some other score", OA_TYPE_FLOAT, &Val); + + /* oaStartBenchmark() must be called right after the last frame */ + oaEndBenchmark(); +} + +int AutomateInit(const char* opt) +{ + oaVersion Version; + if (!oaInit((const oaString)opt, &Version)) + { + Error("OA did not initialize properly."); + return 1; + } + g_isAutomateMode = true; + return 0; +} + +void AutomateRun() +{ + oaCommand Command; + + oaInitCommand(&Command); + switch(oaGetNextCommand(&Command)) + { + /* No more commands, exit program */ + case OA_CMD_EXIT: + AppMainWindow::Inst().close(); + return; + + /* Run as normal */ + case OA_CMD_RUN: + break; + + /* Enumerate all in-game options */ + case OA_CMD_GET_ALL_OPTIONS: + GetAllOptions(); + break; + + /* Return the option values currently set */ + case OA_CMD_GET_CURRENT_OPTIONS: + GetCurrentOptions(); + break; + + /* Set all in-game options */ + case OA_CMD_SET_OPTIONS: + SetOptions(); + break; + + /* Enumerate all known benchmarks */ + case OA_CMD_GET_BENCHMARKS: + GetBenchmarks(); + break; + + /* Run benchmark */ + case OA_CMD_RUN_BENCHMARK: + RunBenchmark(Command.BenchmarkName); + break; + } +} + +bool IsAutomateMode() +{ + return g_isAutomateMode; +} + +bool GetAutomateInstallModeOption(int argc, char* argv[]) +{ + for (int idx = 1; idx < argc; ++idx) + { + if (!strcmp(argv[idx], "-install")) + { + return true; + } + } + return false; +} + + +std::string GetAutomateOption(int argc, char* argv[]) +{ + for (int idx = 1; idx < argc; ++idx) + { + if (!strcmp(argv[idx], "-openautomate")) + { + if ((idx + 1) < argc) + { + return argv[idx+1]; + } + else + { + Error("-openautomate option must have an argument."); + return ""; + } + } + } + return ""; +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Automate.h b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Automate.h new file mode 100644 index 0000000..6f5de4f --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Automate.h @@ -0,0 +1,23 @@ + +// Wrapper functions for OpenAutomate + +// Add application info into registry key for Automate +// Return true if succeeded +bool AutomateInstallApp(); + +// Initialize OpenAutomate with its command line option. No need to cleanup +int AutomateInit(const char* opt); + +// Call this function when the application is idle when IsAutomateMode() is true +void AutomateRun(); + +// Returns true if automate mode is initialized by AutomateInit() call +bool IsAutomateMode(); + +// Utility function to parse the command line option for OpenAutomate +// Returns OpenAutomate option if it has. If not, returns empty string +std::string GetAutomateOption(int argc, char* argv[]); + +// Returns true if it has "-install" in the command line option +bool GetAutomateInstallModeOption(int argc, char* argv[]); + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/CoreLibUtils.h b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/CoreLibUtils.h new file mode 100644 index 0000000..6decd0c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/CoreLibUtils.h @@ -0,0 +1,65 @@ +// 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-2015 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. +// +#pragma once + +#include <QtCore/QFile> +#include <QtCore/QTemporaryFile> + +namespace utils { + +inline std::string GetTempFilePath() +{ + QByteArray tempFilePath; + QTemporaryFile tempFile; + // temp file will be automatically deleted after this function + tempFile.open(); + tempFilePath = tempFile.fileName().toLocal8Bit(); + return std::string(tempFilePath); +} + +inline bool RenameFile(const char* srcFilePath, const char* targetFilePath, bool isOvewrite = false) +{ + if (QFile::exists(targetFilePath)) + { + if (isOvewrite == false) return false; + if (!QFile::remove(targetFilePath)) return false; + } + return QFile::rename(srcFilePath, targetFilePath); +} + +inline bool CopyFile(const char* srcFilePath, const char* targetFilePath, bool isOverwrite = false) +{ + if (QFile::exists(targetFilePath)) + { + if (isOverwrite == false) return false; + if (!QFile::remove(targetFilePath)) return false; + } + return QFile::copy(srcFilePath, targetFilePath); +} + +} // end of utils diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/MathUtil.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/MathUtil.cpp new file mode 100644 index 0000000..bdb3a77 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/MathUtil.cpp @@ -0,0 +1,327 @@ +// 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. +// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// This file contains wrapper functions to make hair lib easy to setup and use +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "MathUtil.h" +#include <string.h> + +//////////////////////////////////////////////////////////////////////////////////////// +void gfsdk_makeIdentity(atcore_float4x4& transform) +{ + memset(&transform, 0, sizeof(atcore_float4x4)); + transform._11 = 1.0f; + transform._22 = 1.0f; + transform._33 = 1.0f; + transform._44 = 1.0f; +} + +//////////////////////////////////////////////////////////////////////////////////////// +void gfsdk_makeTranslation(atcore_float4x4& m, const atcore_float3& t) +{ + gfsdk_makeIdentity(m); + m._41 = t.x; + m._42 = t.y; + m._43 = t.z; +} + +//////////////////////////////////////////////////////////////////////////////////////// +void gfsdk_makeScale(atcore_float4x4& m, const atcore_float3& s) +{ + gfsdk_makeIdentity(m); + m._11 = s.x; + m._12 = s.y; + m._13 = s.z; +} + +//////////////////////////////////////////////////////////////////////////////// +void gfsdk_makeRotation(atcore_float4x4& m, const atcore_float4& q) +{ + gfsdk_makeIdentity(m); + + const float x = q.x; + const float y = q.y; + const float z = q.z; + const float w = q.w; + + const float x2 = x + x; + const float y2 = y + y; + const float z2 = z + z; + + const float xx = x2*x; + const float yy = y2*y; + const float zz = z2*z; + + const float xy = x2*y; + const float xz = x2*z; + const float xw = x2*w; + + const float yz = y2*z; + const float yw = y2*w; + const float zw = z2*w; + + m._11 = 1.0f - yy - zz; + m._12 = xy + zw; + m._13 = xz - yw; + + m._21 = xy - zw; + m._22 = 1.0f - xx - zz; + m._23 = yz + xw; + + m._31 = xz + yw; + m._32 = yz - xw; + m._33 = 1.0f - xx - yy; +} + +//////////////////////////////////////////////////////////////////////////////// +atcore_float4x4 gfsdk_makeTransform(const atcore_float4& q, const atcore_float3& t, const atcore_float3 &s) +{ + atcore_float4x4 m; + + gfsdk_makeRotation(m, q); + + m._11 *= s.x; m._12 *= s.x; m._13 *= s.x; + m._21 *= s.y; m._22 *= s.y; m._23 *= s.y; + m._31 *= s.z; m._32 *= s.z; m._33 *= s.z; + + m._41 = t.x; + m._42 = t.y; + m._43 = t.z; + + return m; +} + +//////////////////////////////////////////////////////////////////////////////// +atcore_float4 gfsdk_getRotation(const atcore_float4x4& sm) +{ + atcore_float4x4 m = sm; + + gfsdk_orthonormalize(m); + + atcore_float4 q; + + float x,y,z,w; + + float tr = m._11 + m._22 + m._33, h; + if(tr >= 0) + { + h = sqrt(tr +1); + w = float(0.5) * h; + h = float(0.5) / h; + + x = (m._23 - m._32) * h; + y = (m._31 - m._13) * h; + z = (m._12 - m._21) * h; + } + else + { + float max = m._11; + int i = 0; + if (m._22 > m._11) + { + i = 1; + max = m._22; + } + if (m._33 > max) + i = 2; + switch (i) + { + case 0: + h = sqrt((m._11 - (m._22 + m._33)) + 1); + x = float(0.5) * h; + h = float(0.5) / h; + + y = (m._21 + m._12) * h; + z = (m._13 + m._31) * h; + w = (m._23 - m._32) * h; + break; + case 1: + h = sqrt((m._22 - (m._33 + m._11)) + 1); + y = float(0.5) * h; + h = float(0.5) / h; + + z = (m._32 + m._23) * h; + x = (m._21 + m._12) * h; + w = (m._31 - m._13) * h; + break; + case 2: + h = sqrt((m._33 - (m._11 + m._22)) + 1); + z = float(0.5) * h; + h = float(0.5) / h; + + x = (m._13 + m._31) * h; + y = (m._32 + m._23) * h; + w = (m._12 - m._21) * h; + break; + default: // Make compiler happy + x = y = z = w = 0; + break; + } + } + + return gfsdk_makeFloat4(x,y,z,w); +} + +//////////////////////////////////////////////////////////////////////////////////////// +atcore_float4x4 gfsdk_lerp(atcore_float4x4& start, atcore_float4x4& end, float t) +{ + atcore_float4 sq = gfsdk_getRotation(start); + atcore_float4 eq = gfsdk_getRotation(end); + atcore_float3 st = gfsdk_getTranslation(start); + atcore_float3 et = gfsdk_getTranslation(end); + + atcore_float3 ss = gfsdk_getScale(start); + atcore_float3 es = gfsdk_getScale(end); + atcore_float3 s = gfsdk_lerp(ss, es, t); + + atcore_dualquaternion sdq = gfsdk_makeDQ(sq, st); + atcore_dualquaternion edq = gfsdk_makeDQ(eq, et); + + atcore_dualquaternion dq = gfsdk_lerp(sdq, edq, t); + + atcore_float4 gr = getRotation(dq); + atcore_float3 gt = getTranslation(dq); + + return gfsdk_makeTransform(gr, gt, s); +} + +//////////////////////////////////////////////////////////////////////////////// +atcore_float4x4 operator*(const atcore_float4x4& in1, const atcore_float4x4& in2) +{ +#define MATRIX_SUM(OUT, IN1, IN2, ROW, COL) OUT._##ROW##COL = IN1._##ROW##1 * IN2._1##COL + IN1._##ROW##2 * IN2._2##COL + IN1._##ROW##3 * IN2._3##COL + IN1._##ROW##4 * IN2._4##COL; + + atcore_float4x4 out; + + MATRIX_SUM(out, in1, in2, 1, 1); + MATRIX_SUM(out, in1, in2, 1, 2); + MATRIX_SUM(out, in1, in2, 1, 3); + MATRIX_SUM(out, in1, in2, 1, 4); + + MATRIX_SUM(out, in1, in2, 2, 1); + MATRIX_SUM(out, in1, in2, 2, 2); + MATRIX_SUM(out, in1, in2, 2, 3); + MATRIX_SUM(out, in1, in2, 2, 4); + + MATRIX_SUM(out, in1, in2, 3, 1); + MATRIX_SUM(out, in1, in2, 3, 2); + MATRIX_SUM(out, in1, in2, 3, 3); + MATRIX_SUM(out, in1, in2, 3, 4); + + MATRIX_SUM(out, in1, in2, 4, 1); + MATRIX_SUM(out, in1, in2, 4, 2); + MATRIX_SUM(out, in1, in2, 4, 3); + MATRIX_SUM(out, in1, in2, 4, 4); + +#undef MATRIX_SUM + + return out; +} + +//////////////////////////////////////////////////////////////////////////////// +float +gfsdk_getDeterminant(const atcore_float4x4& m) +{ + const float* matrix = (const float*)&m; + + atcore_float3 p0 = gfsdk_makeFloat3(matrix[0*4+0], matrix[0*4+1], matrix[0*4+2]); + atcore_float3 p1 = gfsdk_makeFloat3(matrix[1*4+0], matrix[1*4+1], matrix[1*4+2]); + atcore_float3 p2 = gfsdk_makeFloat3(matrix[2*4+0], matrix[2*4+1], matrix[2*4+2]); + + atcore_float3 tempv = gfsdk_cross(p1,p2); + + return gfsdk_dot(p0, tempv); +} + +//////////////////////////////////////////////////////////////////////////////// +atcore_float4x4 +gfsdk_getSubMatrix(int ki,int kj, const atcore_float4x4& m) +{ + atcore_float4x4 out; + gfsdk_makeIdentity(out); + + float* pDst = (float*)&out; + const float* matrix = (const float*)&m; + + int row, col; + int dstCol = 0, dstRow = 0; + + for ( col = 0; col < 4; col++ ) + { + if ( col == kj ) + { + continue; + } + for ( dstRow = 0, row = 0; row < 4; row++ ) + { + if ( row == ki ) + { + continue; + } + pDst[dstCol*4+dstRow] = matrix[col*4+row]; + dstRow++; + } + dstCol++; + } + + return out; +} + +//////////////////////////////////////////////////////////////////////////////// +atcore_float4x4 gfsdk_inverse(const atcore_float4x4& m) +{ + atcore_float4x4 im; + + float* inverse_matrix = (float*)&im; + + float det = gfsdk_getDeterminant(m); + det = 1.0f / det; + for (int i = 0; i < 4; i++ ) + { + for (int j = 0; j < 4; j++ ) + { + int sign = 1 - ( ( i + j ) % 2 ) * 2; + + atcore_float4x4 subMat = gfsdk_getSubMatrix(i, j, m); + float subDeterminant = gfsdk_getDeterminant(subMat); + + inverse_matrix[i*4+j] = ( subDeterminant * sign ) * det; + } + } + + return im; +} + +//////////////////////////////////////////////////////////////////////////////// +atcore_dualquaternion gfsdk_makeDQ(const atcore_float4x4& m) +{ + atcore_float4 q = gfsdk_getRotation(m); + atcore_float3 t = gfsdk_getTranslation(m); + + return gfsdk_makeDQ(q, t); +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/MathUtil.h b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/MathUtil.h new file mode 100644 index 0000000..7b7a2a5 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/MathUtil.h @@ -0,0 +1,557 @@ +// 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. +// +#pragma once + +#include "corelib_global.h" +#include "CoreLib.h" +#include "math.h" +#include "float.h" + +//////////////////////////////////////////////////////////////////////////////////////// +inline float gfsdk_lerp(float v1, float v2, float t) +{ + return (1.0f - t) * v1 + t * v2; +} + +inline float gfsdk_min(float x, float y) { + return (x < y) ? x : y; +} + +inline float gfsdk_max(float x, float y) { + return (x > y) ? x : y; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float2 gfsdk_makeFloat2(float x, float y) +{ + atcore_float2 v; + v.x = x; + v.y = y; + return v; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float2 operator*(float s, const atcore_float2 &p) +{ + return gfsdk_makeFloat2(s * p.x, s * p.y); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float2 operator*(const atcore_float2 &p, float s) +{ + return gfsdk_makeFloat2(s * p.x, s * p.y); +} + + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 gfsdk_makeFloat3(float x, float y, float z) +{ + atcore_float3 v; + v.x = x; + v.y = y; + v.z = z; + return v; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 operator+(const atcore_float3 &p0, const atcore_float3 &p1) +{ + return gfsdk_makeFloat3(p0.x + p1.x, p0.y + p1.y, p0.z + p1.z); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float3& operator+=(atcore_float3 &v, const atcore_float3 & v1) +{ + v.x += v1.x; v.y += v1.y; v.z += v1.z; + return v; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 operator-(const atcore_float3 &p0, const atcore_float3 &p1) +{ + return gfsdk_makeFloat3(p0.x - p1.x, p0.y - p1.y, p0.z - p1.z); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float3& operator-=(atcore_float3 &v, const atcore_float3 & v1) +{ + v.x -= v1.x; v.y -= v1.y; v.z -= v1.z; + return v; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 operator*(float s, const atcore_float3 &p) +{ + return gfsdk_makeFloat3(s * p.x, s * p.y, s * p.z); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 operator*(const atcore_float3 &p, float s) +{ + return gfsdk_makeFloat3(s * p.x, s * p.y, s * p.z); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline float gfsdk_dot(const atcore_float3& v0, const atcore_float3 &v1) { + return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline float gfsdk_lengthSquared(const atcore_float3& v) { + return gfsdk_dot(v,v); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline float gfsdk_length(const atcore_float3 &v) { + return sqrt(gfsdk_lengthSquared(v)); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline float gfsdk_distance(const atcore_float3 &v1, const atcore_float3 &v2) { + return gfsdk_length(v2-v1); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline const atcore_float3& gfsdk_normalize(atcore_float3 &v) { + float l = gfsdk_length(v); + if (l != 0) { v.x /= l; v.y /= l; v.z /= l; } + return v; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 gfsdk_cross(const atcore_float3& v1, const atcore_float3& v2) +{ + return gfsdk_makeFloat3( + v1.y * v2.z - v1.z * v2.y, + v1.z * v2.x - v1.x * v2.z, + v1.x * v2.y - v1.y * v2.x); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 gfsdk_lerp(const atcore_float3& v1, const atcore_float3& v2, float t) +{ + return gfsdk_makeFloat3(gfsdk_lerp(v1.x, v2.x, t), gfsdk_lerp(v1.y, v2.y, t), gfsdk_lerp(v1.z, v2.z, t)); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 gfsdk_min(const atcore_float3& v1, const atcore_float3 &v2) +{ + return gfsdk_makeFloat3( + gfsdk_min(v1.x, v2.x), + gfsdk_min(v1.y, v2.y), + gfsdk_min(v1.z, v2.z) + ); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 gfsdk_max(const atcore_float3& v1, const atcore_float3 &v2) +{ + return gfsdk_makeFloat3( + gfsdk_max(v1.x, v2.x), + gfsdk_max(v1.y, v2.y), + gfsdk_max(v1.z, v2.z) + ); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline float gfsdk_min(const atcore_float3 &v) +{ + return gfsdk_min(gfsdk_min(v.x, v.y), v.z); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline float gfsdk_max(const atcore_float3 &v) +{ + return gfsdk_max(gfsdk_max(v.x, v.y), v.z); +} + +//////////////////////////////////////////////////////////////////////////////// +// float4 +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float4 gfsdk_makeFloat4(float x = 0.0f, float y = 0.0f, float z = 0.0f, float w = 0.0f) +{ + atcore_float4 v; + v.x = x; + v.y = y; + v.z = z; + v.w = w; + return v; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float4 gfsdk_makeFloat4(const atcore_float3& v, float w) +{ + return gfsdk_makeFloat4(v.x, v.y, v.z, w); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float4& operator+=(atcore_float4 &v, const atcore_float4 & v1) +{ + v.x += v1.x; v.y += v1.y; v.z += v1.z; v.w += v1.w; + return v; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float4 operator*(float s, const atcore_float4 &p) +{ + return gfsdk_makeFloat4(s * p.x, s * p.y, s * p.z, s * p.w); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float4 operator*(const atcore_float4 &p, float s) +{ + return gfsdk_makeFloat4(s * p.x, s * p.y, s * p.z, s * p.w); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline float gfsdk_dot(const atcore_float4& v0, const atcore_float4 &v1) { + return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z + v0.w * v1.w; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline float gfsdk_lengthSquared(const atcore_float4& v) { + return gfsdk_dot(v,v); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline float gfsdk_length(const atcore_float4 &v) { + return sqrt(gfsdk_lengthSquared(v)); +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline const atcore_float4 gfsdk_normalize(const atcore_float4 &v) { + atcore_float4 nv = v; + + float l = gfsdk_length(nv); + if (l > FLT_EPSILON) + { + const float s = 1.0f / l; + + nv.x *= s; + nv.y *= s; + nv.z *= s; + nv.w *= s; + } + + return nv; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float4 gfsdk_lerp(const atcore_float4& v1, const atcore_float4& v2, float t) +{ + return gfsdk_makeFloat4( + gfsdk_lerp(v1.x, v2.x, t), + gfsdk_lerp(v1.y, v2.y, t), + gfsdk_lerp(v1.z, v2.z, t), + gfsdk_lerp(v1.w, v2.w, t) + ); +} + +//////////////////////////////////////////////////////////////////////////////// +// quaternion +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +inline atcore_float4 gfsdk_quaternionConjugate(const atcore_float4& in) +{ + return gfsdk_makeFloat4(-in.x, -in.y, -in.z, in.w); +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_float4 gfsdk_quaternionMultiply(const atcore_float4& q0, const atcore_float4& q1) +{ + atcore_float4 q; + + const float tx = q0.w * q1.x + q0.x * q1.w + q0.y * q1.z - q0.z * q1.y; + const float ty = q0.w * q1.y + q0.y * q1.w + q0.z * q1.x - q0.x * q1.z; + const float tz = q0.w * q1.z + q0.z * q1.w + q0.x * q1.y - q0.y * q1.x; + + q.w = q0.w * q1.w - q0.x * q1.x - q0.y * q1.y - q0.z * q1.z; + q.x = tx; + q.y = ty; + q.z = tz; + + return q; +} + +//////////////////////////////////////////////////////////////////////////////// +// 4x4 matrix +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////// +CORELIB_EXPORT void gfsdk_makeIdentity(atcore_float4x4& transform); +CORELIB_EXPORT void gfsdk_makeTranslation(atcore_float4x4& m, const atcore_float3& t); +CORELIB_EXPORT void gfsdk_makeScale(atcore_float4x4& m, const atcore_float3& s); +CORELIB_EXPORT void gfsdk_makeRotation(atcore_float4x4& m, const atcore_float4& q); + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float4x4& operator*=(atcore_float4x4& m, float s) +{ + float* data = (float*)&m; + for (int i = 0; i < 16; i++) + data[i] *= s; + + return m; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline void gfsdk_setPosition(atcore_float4x4&m, const atcore_float3& v) +{ + m._41 = v.x; + m._42 = v.y; + m._43 = v.z; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float4x4 gfsdk_transpose(const atcore_float4x4& m) +{ + atcore_float4x4 om; + + om._11 = m._11; om._12 = m._21; om._13 = m._31; om._14 = m._41; + om._21 = m._12; om._22 = m._22; om._23 = m._32; om._24 = m._42; + om._31 = m._13; om._32 = m._23; om._33 = m._33; om._34 = m._43; + om._41 = m._14; om._42 = m._24; om._43 = m._34; om._44 = m._44; + + return om; +} + +//////////////////////////////////////////////////////////////////////////////////////// +inline atcore_float4x4& operator+=(atcore_float4x4& m1, const atcore_float4x4& m2) +{ + float* data1 = (float*)&m1; + float* data2 = (float*)&m2; + + for (int i = 0; i < 16; i++) + data1[i] += data2[i]; + + return m1; +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_float4 gfsdk_transform(const atcore_float4x4 &m, atcore_float4 op) +{ + atcore_float4 p; + + p.x = op.x * m._11 + op.y * m._21 + op.z * m._31 + op.w * m._41; + p.y = op.x * m._12 + op.y * m._22 + op.z * m._32 + op.w * m._42; + p.z = op.x * m._13 + op.y * m._23 + op.z * m._33 + op.w * m._43; + p.w = op.x * m._14 + op.y * m._24 + op.z * m._34 + op.w * m._44; + + return p; +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 gfsdk_transformCoord(const atcore_float4x4 &m, atcore_float3 op) +{ + atcore_float3 p; + + p.x = op.x * m._11 + op.y * m._21 + op.z * m._31 + m._41; + p.y = op.x * m._12 + op.y * m._22 + op.z * m._32 + m._42; + p.z = op.x * m._13 + op.y * m._23 + op.z * m._33 + m._43; + + return p; +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 gfsdk_transformVector(const atcore_float4x4 &m, atcore_float3 op) +{ + atcore_float3 p; + + p.x = op.x * m._11 + op.y * m._21 + op.z * m._31; + p.y = op.x * m._12 + op.y * m._22 + op.z * m._32; + p.z = op.x * m._13 + op.y * m._23 + op.z * m._33; + + return p; +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 gfsdk_getScale(const atcore_float4x4& m) +{ + atcore_float3 ax = gfsdk_makeFloat3(m._11, m._12, m._13); + atcore_float3 ay = gfsdk_makeFloat3(m._21, m._22, m._23); + atcore_float3 az = gfsdk_makeFloat3(m._31, m._32, m._33); + + return gfsdk_makeFloat3(gfsdk_length(ax), gfsdk_length(ay), gfsdk_length(az)); +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 gfsdk_getTranslation(const atcore_float4x4& m) +{ + return gfsdk_makeFloat3(m._41, m._42, m._43); +} + +//////////////////////////////////////////////////////////////////////////////// +inline void gfsdk_setTranslation(atcore_float4x4& m, const atcore_float3 &v) +{ + m._41 = v.x; + m._42 = v.y; + m._43 = v.z; +} + +//////////////////////////////////////////////////////////////////////////////// +inline const atcore_float4x4& gfsdk_orthonormalize(atcore_float4x4& m) +{ + atcore_float3 ax = gfsdk_makeFloat3(m._11, m._12, m._13); + atcore_float3 ay = gfsdk_makeFloat3(m._21, m._22, m._23); + atcore_float3 az = gfsdk_makeFloat3(m._31, m._32, m._33); + + gfsdk_normalize(ax); + gfsdk_normalize(ay); + gfsdk_normalize(az); + + m._11 = ax.x; m._12 = ax.y; m._13 = ax.z; + m._21 = ay.x; m._22 = ay.y; m._23 = ay.z; + m._31 = az.x; m._32 = az.y; m._33 = az.z; + + return m; +} + +//////////////////////////////////////////////////////////////////////////////// +CORELIB_EXPORT atcore_float4x4 gfsdk_lerp(atcore_float4x4& start, atcore_float4x4& end, float t); + +//////////////////////////////////////////////////////////////////////////////// +CORELIB_EXPORT atcore_float4 gfsdk_getRotation(const atcore_float4x4& m); + +//////////////////////////////////////////////////////////////////////////////// +CORELIB_EXPORT atcore_float4x4 gfsdk_makeTransform(const atcore_float4& q, const atcore_float3& t, const atcore_float3 &s); + +//////////////////////////////////////////////////////////////////////////////// +CORELIB_EXPORT atcore_float4x4 operator*(const atcore_float4x4& in1, const atcore_float4x4& in2); + +//////////////////////////////////////////////////////////////////////////////// +CORELIB_EXPORT atcore_float4x4 gfsdk_inverse(const atcore_float4x4& m); + +//////////////////////////////////////////////////////////////////////////////// +// dual quaternion +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +inline atcore_dualquaternion gfsdk_makeDQ(const atcore_float4& q, const atcore_float3& t) +{ + atcore_dualquaternion dq; + + dq.q0 = gfsdk_normalize(q); + dq.q1 = gfsdk_quaternionMultiply(gfsdk_makeFloat4(t, 0), dq.q0) * 0.5f; + + return dq; +} + +//////////////////////////////////////////////////////////////////////////////// +atcore_dualquaternion gfsdk_makeDQ(const atcore_float4x4& m); + +//////////////////////////////////////////////////////////////////////////////// +inline const atcore_dualquaternion& gfsdk_normalize(atcore_dualquaternion & dq) +{ + float mag = gfsdk_dot( dq.q0, dq.q0); + float deLen = 1.0f / sqrt(mag+FLT_EPSILON); + + dq.q0 = dq.q0 * deLen; + dq.q1 = dq.q1 * deLen; + + return dq; +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_dualquaternion operator*(float s, const atcore_dualquaternion & dq) +{ + return atcore_dualquaternion(s * dq.q0, s * dq.q1); +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_dualquaternion operator*(const atcore_dualquaternion & dq, float s) +{ + return atcore_dualquaternion(s * dq.q0, s * dq.q1); +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_dualquaternion& operator+=(atcore_dualquaternion &dq, const atcore_dualquaternion & dq2) +{ + // hemispherization + float sign = (gfsdk_dot(dq.q0, dq2.q0) < -FLT_EPSILON) ? -1.0f: 1.0f; + + dq.q0 += sign * dq2.q0; + dq.q1 += sign * dq2.q1; + + return dq; +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_dualquaternion gfsdk_lerp(const atcore_dualquaternion &dq1, const atcore_dualquaternion & dq2, float t) +{ + atcore_dualquaternion dq = dq1 * (1.0f - t); + + float sign = (gfsdk_dot(dq1.q0, dq2.q0) < -FLT_EPSILON) ? -1.0f: 1.0f; + + dq += (t * sign) * dq2; + gfsdk_normalize(dq); + + return dq; +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 gfsdk_transformCoord(const atcore_dualquaternion& dq, const atcore_float3 &vecIn) +{ + atcore_float3 d0 = gfsdk_makeFloat3(dq.q0.x, dq.q0.y, dq.q0.z); + atcore_float3 de = gfsdk_makeFloat3(dq.q1.x, dq.q1.y, dq.q1.z); + float a0 = dq.q0.w; + float ae = dq.q1.w; + + atcore_float3 temp = gfsdk_cross( d0, vecIn ) + a0 * vecIn; + atcore_float3 temp2 = 2.0f * (a0 * de - ae * d0 + gfsdk_cross(d0, de)); + + return vecIn + temp2 + 2.0f * gfsdk_cross( d0, temp); +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 gfsdk_transformVector(const atcore_dualquaternion& dq, const atcore_float3 &vecIn) +{ + atcore_float3 d0 = gfsdk_makeFloat3(dq.q0.x, dq.q0.y, dq.q0.z); + atcore_float3 de = gfsdk_makeFloat3(dq.q1.x, dq.q1.y, dq.q1.z); + float a0 = dq.q0.w; + float ae = dq.q1.w; + + atcore_float3 temp = gfsdk_cross( d0, vecIn ) + a0 * vecIn; + return vecIn + 2.0f * gfsdk_cross( d0, temp); +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_float4 getRotation(const atcore_dualquaternion& dq) +{ + return dq.q0; +} + +//////////////////////////////////////////////////////////////////////////////// +inline atcore_float3 getTranslation(const atcore_dualquaternion& dq) +{ + atcore_float4 dual = 2.0f * dq.q1; + atcore_float4 t = gfsdk_quaternionMultiply(dual, gfsdk_quaternionConjugate( dq.q0 )); + + return gfsdk_makeFloat3(t.x, t.y, t.z); +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Profiler.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Profiler.cpp new file mode 100644 index 0000000..aab4de3 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Profiler.cpp @@ -0,0 +1,82 @@ +// 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. +// + +#pragma once + +#include "nvToolsExt.h" +#include <stdlib.h> // for rand() + +void ProfilerRangePush(const char* name) { + unsigned int color = 0xFF000000 | ((rand()%256) << 16) | ((rand()%256) << 8) | (rand()%256); + // Zero the structure + nvtxEventAttributes_t event_attrib = {0}; + // Set the version and the size information + event_attrib.version = NVTX_VERSION; + event_attrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE; + // Configure the attributes. 0 is the default for all attributes + event_attrib.colorType = NVTX_COLOR_ARGB; + event_attrib.color = color; + event_attrib.messageType = NVTX_MESSAGE_TYPE_ASCII; + event_attrib.message.ascii = name; + nvtxRangePushEx(&event_attrib); +} + +void ProfilerRangePush(const char* name, unsigned int color) { + // Zero the structure + nvtxEventAttributes_t event_attrib = {0}; + // Set the version and the size information + event_attrib.version = NVTX_VERSION; + event_attrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE; + // Configure the attributes. 0 is the default for all attributes + event_attrib.colorType = NVTX_COLOR_ARGB; + event_attrib.color = color; + event_attrib.messageType = NVTX_MESSAGE_TYPE_ASCII; + event_attrib.message.ascii = name; + nvtxRangePushEx(&event_attrib); +} + +void ProfilerRangePop() { + nvtxRangePop(); +} + +#include "Profiler.h" + +ScopedProfiler::ScopedProfiler(const char* name) +{ + ProfilerRangePush(name); +} + +ScopedProfiler::ScopedProfiler(const char* name, unsigned int color) +{ + ProfilerRangePush(name, color); +} + +ScopedProfiler::~ScopedProfiler() +{ + ProfilerRangePop(); +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Profiler.h b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Profiler.h new file mode 100644 index 0000000..5f00175 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Profiler.h @@ -0,0 +1,51 @@ +// 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. +// + +#pragma once + +#include "corelib_global.h" + +// name - the name to be displayed +void ProfilerRangePush(const char* name); + +// name - the name to be displayed +// color - ARGB color. ex) 0xFFFF0000 = Red, 0xFF0000FF = Blue +void ProfilerRangePush(const char* name, unsigned int color); + +void ProfilerRangePop(); + +struct CORELIB_EXPORT ScopedProfiler +{ + ScopedProfiler(const char* name); + + ScopedProfiler(const char* name, unsigned int color); + + ~ScopedProfiler(); +}; + +#define FUNCTION_PROFILER() ScopedProfiler _scoped_function_profiler(__FUNCTION__); diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Settings.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Settings.cpp new file mode 100644 index 0000000..5445bef --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Settings.cpp @@ -0,0 +1,767 @@ +/******************************************************************************* +* NVIDIA Corporation +* Software License Agreement - OpenAutomate SDK +* +* IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING +* Do not use or load the OpenAutomate SDK and any associated materials +* provided by NVIDIA on NVIDIA�s website (collectively, the "Software") +* until You have carefully read the following terms and conditions. By +* loading or using the Software, You agree to fully comply with the terms +* and conditions of this Software License Agreement ("Agreement") by and +* between NVIDIA Corporation, a Delaware corporation with its principal +* place of business at 2701 San Tomas Expressway, Santa Clara, California +* 95050 U.S.A. ("NVIDIA"), and You. If You do not wish to so agree, do not +* install or use the Software. +* +* For the purposes of this Agreement: +* +* "Licensee," "You" and/or "Your" shall mean, collectively and +* individually, Original Equipment Manufacturers, Independent Hardware +* Vendors, Independent Software Vendors, and End-Users of the Software +* pursuant to the terms and conditions of this Agreement. +* +* "Derivative Works" shall mean derivatives of the Software created by You +* or a third party on Your behalf, which term shall include: (a) for +* copyrightable or copyrighted material, any translation, abridgement, +* revision or other form in which an existing work may be recast, +* transformed or adapted; (b) for work protected by topography or mask +* right, any translation, abridgement, revision or other form in which an +* existing work may be recast, transformed or adapted; (c) for patentable +* or patented material, any Improvement; and (d) for material protected by +* trade secret, any new material derived from or employing such existing +* trade secret. +* +* "Excluded License" is any license that requires as a condition of use, +* modification and/or distribution of software subject to the Excluded +* License, that such software or other software distributed and/or +* combined with such software be (i) disclosed or distributed in source +* code form, (ii) licensed for the purpose of making derivative works, or +* (iii) redistributable at no charge. +* +* SECTION 1 - GRANT OF LICENSE. +* NVIDIA agrees to provide the Software and any associated materials +* pursuant to the terms and conditions of this Agreement. Subject to the +* terms of this Agreement, NVIDIA grants to You a nonexclusive, +* transferable, worldwide, revocable, limited, royalty-free, fully paid-up +* license under NVIDIA�s copyrights to +* +* (a) install, deploy, use, have used execute, reproduce, display, +* perform, run, modify the source code of the Software, or to prepare and +* have prepared Derivative Works thereof the Software for Your own +* internal development, testing and maintenance purposes to incorporate +* the Software or Derivative Works thereof, in part or whole, into Your +* software applications; +* +* (b) to transfer, distribute and sublicense the Software (in its +* unmodified form as delivered to You by NVIDIA pursuant to this +* Agreement) in any medium or technology for Your sublicensees to +* incorporate the Software or Derivative Works thereof, in part or whole, +* into their respective software applications; and +* +* (c) to transfer, distribute and sublicense Derivative Works (in object +* code only) of the Software (i)_as incorporated in Your application +* software in any medium or technology; and (ii) certified as OpenAutomate +* Compatible Software. +* +* You may exercise your license rights pursuant to Subsection 1(b) and (c) +* above pursuant to the terms and conditions of any form of end-user +* software license agreement of Your choice, including but not limited to +* an Excluded License. +* +* In the event NVIDIA certifies Your application software, incorporating +* the Derivative Works (in object code only) of the Software, as +* OpenAutomate compatible ("OpenAutomate Compatible Software"), NVIDIA +* grants You a nonexclusive, worldwide, revocable, paid-up license to use +* the name and trademark to "OpenAutomate Compatible" solely for the +* purposes of identifying and/or marketing Your application software as +* OpenAutomate Compatible Software; provided that Licensee fully complies +* with the following: +* +* (x) Licensee agrees that it is strictly prohibited from using the name +* and trademark of "OpenAutomate Compatible" if Your application software +* is not OpenAutomate Compatible Software; +* +* (y) if NVIDIA objects to Your improper use of the "OpenAutomate +* Compatible" name and trademark, You will take all reasonable steps +* necessary to resolve NVIDIA�s objections. NVIDIA may reasonably monitor +* the quality of Your application software bearing the "OpenAutomate +* Compatible" name or trademark pursuant to this Agreement; and +* +* (z) any goodwill attached to NVIDIA�s trademarks, service marks, or +* trade names belong to NVIDIA and this Agreement does not grant You any +* right to use them. +* +* If You are not the final manufacturer or vendor of a computer system or +* software program incorporating the Software, or if Your Contractors (as +* defined below), affiliates or subsidiaries need to exercise any, some or +* all of the license grant described above herein to the Software on Your +* behalf, then You may transfer a copy of the Software, (and related +* end-user documentation) to such recipient for use in accordance with the +* terms of this Agreement, provided such recipient agrees to be fully +* bound by the terms hereof. Except as expressly permitted in this +* Agreement, Unless otherwise authorized in the Agreement, You shall not +* otherwise assign, sublicense, lease, or in any other way transfer or +* disclose Software to any third party. Unless otherwise authorized in the +* Agreement, You shall not reverse- compile, disassemble, +* reverse-engineer, or in any manner attempt to derive the source code of +* the Software from the object code portions of the Software. +* +* Except as expressly stated in this Agreement, no license or right is +* granted to You directly or by implication, inducement, estoppel or +* otherwise. NVIDIA shall have the right to inspect or have an independent +* auditor inspect Your relevant records to verify Your compliance with the +* terms and conditions of this Agreement. +* +* SECTION 2 - CONFIDENTIALITY. +* If applicable, any exchange of Confidential Information (as defined in +* the NDA) shall be made pursuant to the terms and conditions of a +* separately signed Non-Disclosure Agreement ("NDA") by and between NVIDIA +* and You. For the sake of clarity, You agree that the Software is +* Confidential Information of NVIDIA. +* +* If You wish to have a third party consultant or subcontractor +* ("Contractor") perform work on Your behalf which involves access to or +* use of Software, You shall obtain a written confidentiality agreement +* from the Contractor which contains terms and obligations with respect to +* access to or use of Software no less restrictive than those set forth in +* this Agreement and excluding any distribution or sublicense rights, and +* use for any other purpose than permitted in this Agreement. Otherwise, +* You shall not disclose the terms or existence of this Agreement or use +* NVIDIA's name in any publications, advertisements, or other +* announcements without NVIDIA's prior written consent. Unless otherwise +* provided in this Agreement, You do not have any rights to use any NVIDIA +* trademarks or logos. +* +* SECTION 3 - OWNERSHIP OF SOFTWARE AND INTELLECTUAL PROPERTY RIGHTS. +* All rights, title and interest to all copies of the Software remain with +* NVIDIA, subsidiaries, licensors, or its suppliers. The Software is +* copyrighted and protected by the laws of the United States and other +* countries, and international treaty provisions. You may not remove any +* copyright notices from the Software. NVIDIA may make changes to the +* Software, or to items referenced therein, at any time and without +* notice, but is not obligated to support or update the Software. Except +* as otherwise expressly provided, NVIDIA grants no express or implied +* right under any NVIDIA patents, copyrights, trademarks, or other +* intellectual property rights. +* +* All rights, title and interest in the Derivative Works of the Software +* remain with You subject to the underlying license from NVIDIA to the +* Software. In Your sole discretion, You may grant NVIDIA, upon NVIDIA�s +* request for such a license described herein, an irrevocable, perpetual, +* nonexclusive, worldwide, royalty-free paid-up license to make, have +* made, use, have used, sell, license, distribute, sublicense or otherwise +* transfer Derivative Works created by You that add functionality or +* improvement to the Software. +* +* You has no obligation to give NVIDIA any suggestions, comments or other +* feedback ("Feedback") relating to the Software. However, NVIDIA may use +* and include any Feedback that You voluntarily provide to improve the +* Software or other related NVIDIA technologies. Accordingly, if You +* provide Feedback, You agree NVIDIA and its licensees may freely use, +* reproduce, license, distribute, and otherwise commercialize the Feedback +* in the Software or other related technologies without the payment of any +* royalties or fees. +* +* You may transfer the Software only if the recipient agrees to be fully +* bound by these terms and conditions of this Agreement. +* +* SECTION 4 - NO WARRANTIES. +* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY +* OF ANY KIND, INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, +* OR FITNESS FOR A PARTICULAR PURPOSE. NVIDIA does not warrant or assume +* responsibility for the accuracy or completeness of any information, +* text, graphics, links or other items contained within the Software. +* NVIDIA does not represent that errors or other defects will be +* identified or corrected. +* +* SECTION 5 - LIMITATION OF LIABILITY. +* EXCEPT WITH RESPECT TO THE MISUSE OF THE OTHER PARTY�S INTELLECTUAL +* PROPERTY OR DISCLOSURE OF THE OTHER PARTY�S CONFIDENTIAL INFORMATION IN +* BREACH OF THIS AGREEMENT, IN NO EVENT SHALL NVIDIA, SUBSIDIARIES, +* LICENSORS, OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER +* (INCLUDING, WITHOUT LIMITATION, INDIRECT, LOST PROFITS, CONSEQUENTIAL, +* BUSINESS INTERRUPTION OR LOST INFORMATION) ARISING OUT OF THE USE OF OR +* INABILITY TO USE THE SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS PROHIBIT EXCLUSION OR +* LIMITATION OF LIABILITY FOR IMPLIED WARRANTIES OR CONSEQUENTIAL OR +* INCIDENTAL DAMAGES, SO THE ABOVE LIMITATION MAY NOT APPLY TO YOU. YOU +* MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY FROM JURISDICTION TO +* JURISDICTION. NOTWITHSTANDING THE FOREGOING, NVIDIA�S AGGREGATE +* LIABILITY ARISING OUT OF THIS AGREEMENT SHALL NOT EXCEED ONE HUNDRED +* UNITED STATES DOLLARS (USD$100). +* +* SECTION 6 - TERM. +* This Agreement and the licenses granted hereunder shall be effective as +* of the date You download the applicable Software ("Effective Date") and +* continue for a period of one (1) year ("Initial Term") respectively, +* unless terminated earlier in accordance with the "Termination" provision +* of this Agreement. Unless either party notifies the other party of its +* intent to terminate this Agreement at least three (3) months prior to +* the end of the Initial Term or the applicable renewal period, this +* Agreement will be automatically renewed for one (1) year renewal periods +* thereafter, unless terminated in accordance with the "Termination" +* provision of this Agreement. +* +* SECTION 7 - TERMINATION. +* NVIDIA may terminate this Agreement at any time if You violate its +* terms. Upon termination, You will immediately destroy the Software or +* return all copies of the Software to NVIDIA, and certify to NVIDIA in +* writing that such actions have been completed. Upon termination or +* expiration of this Agreement the license grants to Licensee shall +* terminate, except that sublicenses rightfully granted by Licensee under +* this Agreement in connection with Section 1(b) and (c) of this Agreement +* provided by Licensee prior to the termination or expiration of this +* Agreement shall survive in accordance with their respective form of +* license terms and conditions. +* +* SECTION 8 - MISCELLANEOUS. +* +* SECTION 8.1 - SURVIVAL. +* Those provisions in this Agreement, which by their nature need to +* survive the termination or expiration of this Agreement, shall survive +* termination or expiration of the Agreement, including but not limited to +* Sections 2, 3, 4, 5, 7, and 8. +* +* SECTION 8.2 - APPLICABLE LAWS. +* Claims arising under this Agreement shall be governed by the laws of +* Delaware, excluding its principles of conflict of laws and the United +* Nations Convention on Contracts for the Sale of Goods. The state and/or +* federal courts residing in Santa Clara County, California shall have +* exclusive jurisdiction over any dispute or claim arising out of this +* Agreement. You may not export the Software in violation of applicable +* export laws and regulations. +* +* SECTION 8.3 - AMENDMENT. +* The Agreement shall not be modified except by a written agreement that +* names this Agreement and any provision to be modified, is dated +* subsequent to the Effective Date, and is signed by duly authorized +* representatives of both parties. +* +* SECTION 8.4 - NO WAIVER. +* No failure or delay on the part of either party in the exercise of any +* right, power or remedy under this Agreement or under law, or to insist +* upon or enforce performance by the other party of any of the provisions +* of this Agreement or under law, shall operate as a waiver thereof, nor +* shall any single or partial exercise of any right, power or remedy +* preclude other or further exercise thereof, or the exercise of any other +* right, power or remedy; rather the provision, right, or remedy shall be +* and remain in full force and effect. +* +* SECTION 8.5 - NO ASSIGNMENT. +* This Agreement and Licensee�s rights and obligations herein, may not be +* assigned, subcontracted, delegated, or otherwise transferred by Licensee +* without NVIDIA�s prior written consent, and any attempted assignment, +* subcontract, delegation, or transfer in violation of the foregoing will +* be null and void. The terms of this Agreement shall be binding upon +* Licensee�s assignees. +* +* SECTION 8.6 - GOVERNMENT RESTRICTED RIGHTS. +* The parties acknowledge that the Software is subject to U.S. export +* control laws and regulations. The parties agree to comply with all +* applicable international and national laws that apply to the Software, +* including the U.S. Export Administration Regulations, as well as +* end-user, end-use and destination restrictions issued by U.S. and other +* governments. +* +* The Software has been developed entirely at private expense and is +* commercial computer software provided with RESTRICTED RIGHTS. Use, +* duplication or disclosure of the Software by the U.S. Government or a +* U.S. Government subcontractor is subject to the restrictions set forth +* in the Agreement under which the Software was obtained pursuant to DFARS +* 227.7202-3(a) or as set forth in subparagraphs (c)(1) and (2) of the +* Commercial Computer Software - Restricted Rights clause at FAR +* 52.227-19, as applicable. Contractor/manufacturer is NVIDIA, 2701 San +* Tomas Expressway, Santa Clara, CA 95050. Use of the Software by the +* Government constitutes acknowledgment of NVIDIA's proprietary rights +* therein. +* +* SECTION 8.7 - INDEPENDENT CONTRACTORS. +* Licensee�s relationship to NVIDIA is that of an independent contractor, +* and neither party is an agent or partner of the other. Licensee will +* not have, and will not represent to any third party that it has, any +* authority to act on behalf of NVIDIA. +* +* SECTION 8.8 - SEVERABILITY. +* If for any reason a court of competent jurisdiction finds any provision +* of this Agreement, or portion thereof, to be unenforceable, that +* provision of the Agreement will be enforced to the maximum extent +* permissible so as to affect the intent of the parties, and the remainder +* of this Agreement will continue in full force and effect. This Agreement +* has been negotiated by the parties and their respective counsel and will +* be interpreted fairly in accordance with its terms and without any +* strict construction in favor of or against either party. +* +* SECTION 8.9 - ENTIRE AGREEMENT. +* This Agreement and NDA constitute the entire agreement between the +* parties with respect to the subject matter contemplated herein, and +* merges all prior and contemporaneous communications. +* +******************************************************************************/ + + +#include "settings.h" +#include "Nv.h" + +char OptionsFileName[] = "FurViewerOptions.txt"; +//std::vector<void *> AllocBlocks; + +using namespace std; + +void Error(const char *fmt, ...); +static int HexCharToInt(unsigned char c); +bool GetExePath(char* exe_path); +static int Hex2BytesToInt(const unsigned char *buf); +static oaFloat StrToFloat(const char *buf); +static void WriteFloat(FILE *fp, oaFloat val); +static void StripNewLine(char *str); +void *Alloc(size_t n); +char *StrDup(const char *str); + +bool GetExePath(char* exe_path) +{ +#if WIN32 + char delim = '\\'; +#else + char delim = '/'; +#endif + + DWORD dwRet; + dwRet = GetModuleFileNameA(NV_NULL, exe_path, MAX_PATH); + if ( dwRet == 0 ) + { + exe_path[0] = '\0'; + return false; + } + + int i; + for ( i = dwRet; i > 0; i-- ) + { + if ( exe_path[i-1] == delim ) + break; + } + exe_path[i] = '\0'; + + return true; +} + +void Error(const char *fmt, ...) +{ + va_list AP; + va_start(AP, fmt); + + char msg[1024]; + //fprintf(msg, "ERROR: "); + //vfprintf(msg, fmt, AP); + //fprintf(msg, "\n"); + sprintf(msg, fmt, AP); + OutputDebugStringA(msg); + assert(0); +// exit(-1); +} + +static int HexCharToInt(unsigned char c) +{ + if(c >= '0' && c <= '9') + return((int)(c - '0')); + + c = tolower(c); + if(c >= 'a' && c <= 'f') + return((int)(c - 'a' + 10)); + + return(0); +} + +static int Hex2BytesToInt(const unsigned char *buf) +{ + return(HexCharToInt(buf[0]) << 4 | HexCharToInt(buf[1])); +} + +static oaFloat StrToFloat(const char *buf) +{ + size_t Len = strlen(buf); + if(Len != sizeof(oaFloat) * 2) + return(0.0); + + oaFloat Ret; + unsigned char *Buf = (unsigned char *)&Ret; + for(int i=0; i < sizeof(oaFloat); ++i) + { + Buf[i] = Hex2BytesToInt((const unsigned char *)buf); + buf += 2; + } + + return(Ret); +} + +static void WriteFloat(FILE *fp, oaFloat val) +{ + unsigned char *Buf = (unsigned char *)&val; + for(int i=0; i < sizeof(oaFloat); ++i) + fprintf(fp, "%02x", Buf[i]); +} + +static void StripNewLine(char *str) +{ + size_t StrLen = strlen(str); + if(StrLen == 0) + return; + + for(size_t i=StrLen-1; i >= 0; --i) + if(str[i] == '\n') + { + str[i] = 0; + break; + } +} + +void *Alloc(size_t n) +{ + void *Ret = malloc(n); + assert(n != 0); + + //AllocBlocks.push_back(Ret); + return(Ret); +} + +char *StrDup(const char *str) +{ + assert(str != NV_NULL); + char *Ret = strdup(str); + + //AllocBlocks.push_back(Ret); + return(Ret); +} + +AppSettings::AppSettings() +{ + int NumOptions = 0; +} + +AppSettings::~AppSettings() +{ + Cleanup(); +} + +void AppSettings::InitOptions(void) +{ + { + oaNamedOption *Option; + + // Resolution (enum) + Option = &Options[NumOptions++]; + oaInitOption(Option); + Option->Name = "User/Resolution"; + Option->DataType = OA_TYPE_ENUM; + Option->Value.Enum = "640x480"; + + Options[NumOptions] = *Option; + Option = &Options[NumOptions++]; + Option->Value.Enum = "1024x768"; + + Options[NumOptions] = *Option; + Option = &Options[NumOptions++]; + Option->Value.Enum = "1200x768"; + + Options[NumOptions] = *Option; + Option = &Options[NumOptions++]; + Option->Value.Enum = "1600x1200"; + + // AA (enum) + Option = &Options[NumOptions++]; + oaInitOption(Option); + + Option->Name = "User/AA"; + Option->DataType = OA_TYPE_ENUM; + Option->Value.Enum = "Off"; + + Options[NumOptions] = *Option; + Option = &Options[NumOptions++]; + Option->Value.Enum = "2X"; + + Options[NumOptions] = *Option; + Option = &Options[NumOptions++]; + Option->Value.Enum = "4X"; + + Options[NumOptions] = *Option; + Option = &Options[NumOptions++]; + Option->Value.Enum = "8X"; + + // device id (int) + Option = &Options[NumOptions++]; + oaInitOption(Option); + Option->Name = "User/Device"; + Option->DataType = OA_TYPE_INT; + + Option->Value.Int = -1; // when -1 to choose a good GPU + + //Backdoor (enum) + Option = &Options[NumOptions++]; + oaInitOption(Option); + Option->Name = "User/Backdoor"; + Option->DataType = OA_TYPE_STRING; + Option->Value.String = ""; + + // HideUI (bool) + Option = &Options[NumOptions++]; + oaInitOption(Option); + Option->Name = "User/HideUI"; + Option->DataType = OA_TYPE_BOOL; + + Option->Value.Bool = OA_FALSE; + + // Perf mode (bool) + Option = &Options[NumOptions++]; + oaInitOption(Option); + Option->Name = "User/PerfMode"; + Option->DataType = OA_TYPE_BOOL; + + Option->Value.Bool = OA_FALSE; + + // Play (bool) + Option = &Options[NumOptions++]; + oaInitOption(Option); + Option->Name = "User/Play"; + Option->DataType = OA_TYPE_BOOL; + + Option->Value.Bool = OA_FALSE; + + // ProjectPath (string) + Option = &Options[NumOptions++]; + oaInitOption(Option); + Option->Name = "User/ProjectPath"; + Option->DataType = OA_TYPE_STRING; + Option->Value.String = ""; + + // FurAssetPath (string) + Option = &Options[NumOptions++]; + oaInitOption(Option); + Option->Name = "User/FurAssetPath"; + Option->DataType = OA_TYPE_STRING; + Option->Value.String = ""; + + // FurDemoPlaylist (string) + Option = &Options[NumOptions++]; + oaInitOption(Option); + Option->Name = "User/FurDemoPlaylist"; + Option->DataType = OA_TYPE_STRING; + Option->Value.String = ""; + + //Option = &Options[NumOptions++]; + //oaInitOption(Option); + //Option->Name = "r2_slight_fade"; + //Option->DataType = OA_TYPE_FLOAT; + //Option->MinValue.Float = 0.0; + //Option->MaxValue.Float = 100.0; + //Option->NumSteps = 200; + } + + //**************************************************************************** + //*** Init OptionValues + //**************************************************************************** + + // Initialize default options + for(int i=0; i < NumOptions; ++i) + { + string Name(Options[i].Name); + OptionValueMap[Name].Name = Options[i].Name; + OptionValueMap[Name].Type = Options[i].DataType; + OptionValueMap[Name].Value = Options[i].Value; + } + + InitDefaultOptions(); + /////////////////////////////////////////////////////// + // Load any persistent options if they've been previously set + ReadOptionsFile(); +} + +void AppSettings::InitDefaultOptions(void) +{ + oaValue Value; + + Value.Enum = "1200x768"; + SetOptionValue("User/Resolution", OA_TYPE_ENUM, &Value); + + Value.Enum = "8X"; + SetOptionValue("User/AA", OA_TYPE_ENUM, &Value); +} + +void AppSettings::SetOptionValue(const char *name, + oaOptionDataType type, + const oaValue *value) +{ + string Name(name); + assert(OptionValueMap.find(Name) != OptionValueMap.end()); + assert(OptionValueMap[Name].Type == type); + + switch(type) + { + case OA_TYPE_STRING: + OptionValueMap[Name].Value.String = StrDup(value->String); + break; + + case OA_TYPE_ENUM: + OptionValueMap[Name].Value.Enum = StrDup(value->Enum); + break; + + default: + OptionValueMap[Name].Value = *value; + } +} + +void AppSettings::ReadOptionsFile(void) +{ + char optionFile[MAX_PATH] = ""; + if(!GetExePath(optionFile)) + { + fprintf(stderr, "Cannot get exe path\r\n"); + } + strcat(optionFile, OptionsFileName); + + + FILE *FP = fopen(optionFile, "rb"); + if(!FP) + return; + + fprintf(stderr, "FurViewer: Reading options file \"%s\".\n", + optionFile); + fflush(stderr); + + char Line[1024] = ""; + int LineNum = 1; + while (fgets(Line, sizeof(Line), FP) != NV_NULL) + { + StripNewLine(Line); + if(Line[0] == 0) + continue; + + char *Name = strtok(Line, "\t"); + char *Value = strtok(NV_NULL, ""); + + if(!Name || !Value) + { + //Error("Invalid format in options file \"%s\" on line %d\n", + //OptionsFileName, + //LineNum); + continue; + } + + map<string, OptionValue>::const_iterator OptVal = + OptionValueMap.find(string(Name)); + + if(OptVal == OptionValueMap.end()) + Error("Unknown option \"%s\" defined in options file \"%s\" on line %d.", + Name, + OptionsFileName, + LineNum); + + SetOptionValue(Name, OptVal->second.Type, Value); + + LineNum++; + } + + fclose(FP); +} + +void AppSettings::Cleanup(void) +{ + //vector<void *>::iterator Iter = AllocBlocks.begin(); + //for(; Iter != AllocBlocks.end(); Iter++) + // free(*Iter); + + //AllocBlocks.clear(); +} + + +void AppSettings::WriteOptionsFile(FILE *fp) +{ + map<string, OptionValue>::const_iterator Iter = OptionValueMap.begin(); + for(; Iter != OptionValueMap.end(); ++Iter) + { + fprintf(fp, "%s\t", Iter->second.Name); + switch(Iter->second.Type) + { + case OA_TYPE_INT: + fprintf(fp, "%d", Iter->second.Value.Int); + break; + + case OA_TYPE_BOOL: + fprintf(fp, "%d", (int)Iter->second.Value.Bool); + break; + + case OA_TYPE_FLOAT: + WriteFloat(fp, Iter->second.Value.Float); + break; + + case OA_TYPE_STRING: + fprintf(fp, "%s", Iter->second.Value.String); + break; + + case OA_TYPE_ENUM: + fprintf(fp, "%s", Iter->second.Value.Enum); + break; + + } + + fprintf(fp, "\n"); + } +} + +void AppSettings::WriteOptionsFile(void) +{ + char optionFile[MAX_PATH] = ""; + if(!GetExePath(optionFile)) + { + fprintf(stderr, "Cannot get exe path\r\n"); + } + strcat(optionFile, OptionsFileName); + + fprintf(stderr, "FurViewer: Writing options file \"%s\".\n", + optionFile); + fflush(stderr); + + FILE *FP = fopen(optionFile, "wb"); + if(!FP) + Error("Couldn't open \"%s\" for write.\n", optionFile); + + WriteOptionsFile(FP); + + fclose(FP); +} + +void AppSettings::SetOptionValue(const char *name, + oaOptionDataType type, + const char *value) +{ + assert(name != NV_NULL); + assert(type != OA_TYPE_INVALID); + assert(value != NV_NULL); + + oaValue Value; + switch(type) + { + case OA_TYPE_INT: + Value.Int = atoi(value); + break; + + case OA_TYPE_FLOAT: + Value.Float = StrToFloat(value); + break; + + case OA_TYPE_BOOL: + Value.Bool = atoi(value) ? OA_TRUE : OA_FALSE; + break; + + case OA_TYPE_STRING: + Value.String = (oaString)value; + break; + + case OA_TYPE_ENUM: + Value.Enum = (oaString)value; + break; + } + + SetOptionValue(name, type, &Value); +} + + + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Settings.h b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Settings.h new file mode 100644 index 0000000..a845732 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Settings.h @@ -0,0 +1,392 @@ +/******************************************************************************* +* NVIDIA Corporation +* Software License Agreement - OpenAutomate SDK +* +* IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING +* Do not use or load the OpenAutomate SDK and any associated materials +* provided by NVIDIA on NVIDIA�s website (collectively, the "Software") +* until You have carefully read the following terms and conditions. By +* loading or using the Software, You agree to fully comply with the terms +* and conditions of this Software License Agreement ("Agreement") by and +* between NVIDIA Corporation, a Delaware corporation with its principal +* place of business at 2701 San Tomas Expressway, Santa Clara, California +* 95050 U.S.A. ("NVIDIA"), and You. If You do not wish to so agree, do not +* install or use the Software. +* +* For the purposes of this Agreement: +* +* "Licensee," "You" and/or "Your" shall mean, collectively and +* individually, Original Equipment Manufacturers, Independent Hardware +* Vendors, Independent Software Vendors, and End-Users of the Software +* pursuant to the terms and conditions of this Agreement. +* +* "Derivative Works" shall mean derivatives of the Software created by You +* or a third party on Your behalf, which term shall include: (a) for +* copyrightable or copyrighted material, any translation, abridgement, +* revision or other form in which an existing work may be recast, +* transformed or adapted; (b) for work protected by topography or mask +* right, any translation, abridgement, revision or other form in which an +* existing work may be recast, transformed or adapted; (c) for patentable +* or patented material, any Improvement; and (d) for material protected by +* trade secret, any new material derived from or employing such existing +* trade secret. +* +* "Excluded License" is any license that requires as a condition of use, +* modification and/or distribution of software subject to the Excluded +* License, that such software or other software distributed and/or +* combined with such software be (i) disclosed or distributed in source +* code form, (ii) licensed for the purpose of making derivative works, or +* (iii) redistributable at no charge. +* +* SECTION 1 - GRANT OF LICENSE. +* NVIDIA agrees to provide the Software and any associated materials +* pursuant to the terms and conditions of this Agreement. Subject to the +* terms of this Agreement, NVIDIA grants to You a nonexclusive, +* transferable, worldwide, revocable, limited, royalty-free, fully paid-up +* license under NVIDIA�s copyrights to +* +* (a) install, deploy, use, have used execute, reproduce, display, +* perform, run, modify the source code of the Software, or to prepare and +* have prepared Derivative Works thereof the Software for Your own +* internal development, testing and maintenance purposes to incorporate +* the Software or Derivative Works thereof, in part or whole, into Your +* software applications; +* +* (b) to transfer, distribute and sublicense the Software (in its +* unmodified form as delivered to You by NVIDIA pursuant to this +* Agreement) in any medium or technology for Your sublicensees to +* incorporate the Software or Derivative Works thereof, in part or whole, +* into their respective software applications; and +* +* (c) to transfer, distribute and sublicense Derivative Works (in object +* code only) of the Software (i)_as incorporated in Your application +* software in any medium or technology; and (ii) certified as OpenAutomate +* Compatible Software. +* +* You may exercise your license rights pursuant to Subsection 1(b) and (c) +* above pursuant to the terms and conditions of any form of end-user +* software license agreement of Your choice, including but not limited to +* an Excluded License. +* +* In the event NVIDIA certifies Your application software, incorporating +* the Derivative Works (in object code only) of the Software, as +* OpenAutomate compatible ("OpenAutomate Compatible Software"), NVIDIA +* grants You a nonexclusive, worldwide, revocable, paid-up license to use +* the name and trademark to "OpenAutomate Compatible" solely for the +* purposes of identifying and/or marketing Your application software as +* OpenAutomate Compatible Software; provided that Licensee fully complies +* with the following: +* +* (x) Licensee agrees that it is strictly prohibited from using the name +* and trademark of "OpenAutomate Compatible" if Your application software +* is not OpenAutomate Compatible Software; +* +* (y) if NVIDIA objects to Your improper use of the "OpenAutomate +* Compatible" name and trademark, You will take all reasonable steps +* necessary to resolve NVIDIA�s objections. NVIDIA may reasonably monitor +* the quality of Your application software bearing the "OpenAutomate +* Compatible" name or trademark pursuant to this Agreement; and +* +* (z) any goodwill attached to NVIDIA�s trademarks, service marks, or +* trade names belong to NVIDIA and this Agreement does not grant You any +* right to use them. +* +* If You are not the final manufacturer or vendor of a computer system or +* software program incorporating the Software, or if Your Contractors (as +* defined below), affiliates or subsidiaries need to exercise any, some or +* all of the license grant described above herein to the Software on Your +* behalf, then You may transfer a copy of the Software, (and related +* end-user documentation) to such recipient for use in accordance with the +* terms of this Agreement, provided such recipient agrees to be fully +* bound by the terms hereof. Except as expressly permitted in this +* Agreement, Unless otherwise authorized in the Agreement, You shall not +* otherwise assign, sublicense, lease, or in any other way transfer or +* disclose Software to any third party. Unless otherwise authorized in the +* Agreement, You shall not reverse- compile, disassemble, +* reverse-engineer, or in any manner attempt to derive the source code of +* the Software from the object code portions of the Software. +* +* Except as expressly stated in this Agreement, no license or right is +* granted to You directly or by implication, inducement, estoppel or +* otherwise. NVIDIA shall have the right to inspect or have an independent +* auditor inspect Your relevant records to verify Your compliance with the +* terms and conditions of this Agreement. +* +* SECTION 2 - CONFIDENTIALITY. +* If applicable, any exchange of Confidential Information (as defined in +* the NDA) shall be made pursuant to the terms and conditions of a +* separately signed Non-Disclosure Agreement ("NDA") by and between NVIDIA +* and You. For the sake of clarity, You agree that the Software is +* Confidential Information of NVIDIA. +* +* If You wish to have a third party consultant or subcontractor +* ("Contractor") perform work on Your behalf which involves access to or +* use of Software, You shall obtain a written confidentiality agreement +* from the Contractor which contains terms and obligations with respect to +* access to or use of Software no less restrictive than those set forth in +* this Agreement and excluding any distribution or sublicense rights, and +* use for any other purpose than permitted in this Agreement. Otherwise, +* You shall not disclose the terms or existence of this Agreement or use +* NVIDIA's name in any publications, advertisements, or other +* announcements without NVIDIA's prior written consent. Unless otherwise +* provided in this Agreement, You do not have any rights to use any NVIDIA +* trademarks or logos. +* +* SECTION 3 - OWNERSHIP OF SOFTWARE AND INTELLECTUAL PROPERTY RIGHTS. +* All rights, title and interest to all copies of the Software remain with +* NVIDIA, subsidiaries, licensors, or its suppliers. The Software is +* copyrighted and protected by the laws of the United States and other +* countries, and international treaty provisions. You may not remove any +* copyright notices from the Software. NVIDIA may make changes to the +* Software, or to items referenced therein, at any time and without +* notice, but is not obligated to support or update the Software. Except +* as otherwise expressly provided, NVIDIA grants no express or implied +* right under any NVIDIA patents, copyrights, trademarks, or other +* intellectual property rights. +* +* All rights, title and interest in the Derivative Works of the Software +* remain with You subject to the underlying license from NVIDIA to the +* Software. In Your sole discretion, You may grant NVIDIA, upon NVIDIA�s +* request for such a license described herein, an irrevocable, perpetual, +* nonexclusive, worldwide, royalty-free paid-up license to make, have +* made, use, have used, sell, license, distribute, sublicense or otherwise +* transfer Derivative Works created by You that add functionality or +* improvement to the Software. +* +* You has no obligation to give NVIDIA any suggestions, comments or other +* feedback ("Feedback") relating to the Software. However, NVIDIA may use +* and include any Feedback that You voluntarily provide to improve the +* Software or other related NVIDIA technologies. Accordingly, if You +* provide Feedback, You agree NVIDIA and its licensees may freely use, +* reproduce, license, distribute, and otherwise commercialize the Feedback +* in the Software or other related technologies without the payment of any +* royalties or fees. +* +* You may transfer the Software only if the recipient agrees to be fully +* bound by these terms and conditions of this Agreement. +* +* SECTION 4 - NO WARRANTIES. +* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY +* OF ANY KIND, INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, +* OR FITNESS FOR A PARTICULAR PURPOSE. NVIDIA does not warrant or assume +* responsibility for the accuracy or completeness of any information, +* text, graphics, links or other items contained within the Software. +* NVIDIA does not represent that errors or other defects will be +* identified or corrected. +* +* SECTION 5 - LIMITATION OF LIABILITY. +* EXCEPT WITH RESPECT TO THE MISUSE OF THE OTHER PARTY�S INTELLECTUAL +* PROPERTY OR DISCLOSURE OF THE OTHER PARTY�S CONFIDENTIAL INFORMATION IN +* BREACH OF THIS AGREEMENT, IN NO EVENT SHALL NVIDIA, SUBSIDIARIES, +* LICENSORS, OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER +* (INCLUDING, WITHOUT LIMITATION, INDIRECT, LOST PROFITS, CONSEQUENTIAL, +* BUSINESS INTERRUPTION OR LOST INFORMATION) ARISING OUT OF THE USE OF OR +* INABILITY TO USE THE SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS PROHIBIT EXCLUSION OR +* LIMITATION OF LIABILITY FOR IMPLIED WARRANTIES OR CONSEQUENTIAL OR +* INCIDENTAL DAMAGES, SO THE ABOVE LIMITATION MAY NOT APPLY TO YOU. YOU +* MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY FROM JURISDICTION TO +* JURISDICTION. NOTWITHSTANDING THE FOREGOING, NVIDIA�S AGGREGATE +* LIABILITY ARISING OUT OF THIS AGREEMENT SHALL NOT EXCEED ONE HUNDRED +* UNITED STATES DOLLARS (USD$100). +* +* SECTION 6 - TERM. +* This Agreement and the licenses granted hereunder shall be effective as +* of the date You download the applicable Software ("Effective Date") and +* continue for a period of one (1) year ("Initial Term") respectively, +* unless terminated earlier in accordance with the "Termination" provision +* of this Agreement. Unless either party notifies the other party of its +* intent to terminate this Agreement at least three (3) months prior to +* the end of the Initial Term or the applicable renewal period, this +* Agreement will be automatically renewed for one (1) year renewal periods +* thereafter, unless terminated in accordance with the "Termination" +* provision of this Agreement. +* +* SECTION 7 - TERMINATION. +* NVIDIA may terminate this Agreement at any time if You violate its +* terms. Upon termination, You will immediately destroy the Software or +* return all copies of the Software to NVIDIA, and certify to NVIDIA in +* writing that such actions have been completed. Upon termination or +* expiration of this Agreement the license grants to Licensee shall +* terminate, except that sublicenses rightfully granted by Licensee under +* this Agreement in connection with Section 1(b) and (c) of this Agreement +* provided by Licensee prior to the termination or expiration of this +* Agreement shall survive in accordance with their respective form of +* license terms and conditions. +* +* SECTION 8 - MISCELLANEOUS. +* +* SECTION 8.1 - SURVIVAL. +* Those provisions in this Agreement, which by their nature need to +* survive the termination or expiration of this Agreement, shall survive +* termination or expiration of the Agreement, including but not limited to +* Sections 2, 3, 4, 5, 7, and 8. +* +* SECTION 8.2 - APPLICABLE LAWS. +* Claims arising under this Agreement shall be governed by the laws of +* Delaware, excluding its principles of conflict of laws and the United +* Nations Convention on Contracts for the Sale of Goods. The state and/or +* federal courts residing in Santa Clara County, California shall have +* exclusive jurisdiction over any dispute or claim arising out of this +* Agreement. You may not export the Software in violation of applicable +* export laws and regulations. +* +* SECTION 8.3 - AMENDMENT. +* The Agreement shall not be modified except by a written agreement that +* names this Agreement and any provision to be modified, is dated +* subsequent to the Effective Date, and is signed by duly authorized +* representatives of both parties. +* +* SECTION 8.4 - NO WAIVER. +* No failure or delay on the part of either party in the exercise of any +* right, power or remedy under this Agreement or under law, or to insist +* upon or enforce performance by the other party of any of the provisions +* of this Agreement or under law, shall operate as a waiver thereof, nor +* shall any single or partial exercise of any right, power or remedy +* preclude other or further exercise thereof, or the exercise of any other +* right, power or remedy; rather the provision, right, or remedy shall be +* and remain in full force and effect. +* +* SECTION 8.5 - NO ASSIGNMENT. +* This Agreement and Licensee�s rights and obligations herein, may not be +* assigned, subcontracted, delegated, or otherwise transferred by Licensee +* without NVIDIA�s prior written consent, and any attempted assignment, +* subcontract, delegation, or transfer in violation of the foregoing will +* be null and void. The terms of this Agreement shall be binding upon +* Licensee�s assignees. +* +* SECTION 8.6 - GOVERNMENT RESTRICTED RIGHTS. +* The parties acknowledge that the Software is subject to U.S. export +* control laws and regulations. The parties agree to comply with all +* applicable international and national laws that apply to the Software, +* including the U.S. Export Administration Regulations, as well as +* end-user, end-use and destination restrictions issued by U.S. and other +* governments. +* +* The Software has been developed entirely at private expense and is +* commercial computer software provided with RESTRICTED RIGHTS. Use, +* duplication or disclosure of the Software by the U.S. Government or a +* U.S. Government subcontractor is subject to the restrictions set forth +* in the Agreement under which the Software was obtained pursuant to DFARS +* 227.7202-3(a) or as set forth in subparagraphs (c)(1) and (2) of the +* Commercial Computer Software - Restricted Rights clause at FAR +* 52.227-19, as applicable. Contractor/manufacturer is NVIDIA, 2701 San +* Tomas Expressway, Santa Clara, CA 95050. Use of the Software by the +* Government constitutes acknowledgment of NVIDIA's proprietary rights +* therein. +* +* SECTION 8.7 - INDEPENDENT CONTRACTORS. +* Licensee�s relationship to NVIDIA is that of an independent contractor, +* and neither party is an agent or partner of the other. Licensee will +* not have, and will not represent to any third party that it has, any +* authority to act on behalf of NVIDIA. +* +* SECTION 8.8 - SEVERABILITY. +* If for any reason a court of competent jurisdiction finds any provision +* of this Agreement, or portion thereof, to be unenforceable, that +* provision of the Agreement will be enforced to the maximum extent +* permissible so as to affect the intent of the parties, and the remainder +* of this Agreement will continue in full force and effect. This Agreement +* has been negotiated by the parties and their respective counsel and will +* be interpreted fairly in accordance with its terms and without any +* strict construction in favor of or against either party. +* +* SECTION 8.9 - ENTIRE AGREEMENT. +* This Agreement and NDA constitute the entire agreement between the +* parties with respect to the subject matter contemplated herein, and +* merges all prior and contemporaneous communications. +* +******************************************************************************/ + + +#ifndef _SETTINGS_H +#define _SETTINGS_H + +#include <assert.h> +#include <ctype.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <vector> +#include <map> +#include <string> +#include <conio.h> +#include <OpenAutomate.h> + +#include "corelib_global.h" + +#if WIN32 +# include <windows.h> +# define SLEEP(ms) Sleep(ms) +#else +# include <unistd.h> +# define SLEEP(ms) usleep(1000 * (ms)) +#endif + +void Error(const char *fmt, ...); +bool GetExePath(char* exe_path); + +struct OptionValue +{ + const char *Name; + oaOptionDataType Type; + oaValue Value; +}; + +class CORELIB_EXPORT AppSettings +{ +public: + AppSettings(); + ~AppSettings(); + + static AppSettings& Inst() + { + static AppSettings s_inst; + return s_inst; + } + + void InitOptions(); + + void WriteOptionsFile(); + + void SetOptionValue(const char *name, + oaOptionDataType type, + const oaValue *value); + + int GetNumOptions(){return NumOptions;} + + oaNamedOption* GetOption(int i){return &Options[i];} + + OptionValue* GetOptionValue(char* opt_name) + { + return &OptionValueMap[opt_name]; + } + + std::map<std::string, OptionValue>* GetCurrentOptionMap() + { + return &OptionValueMap; + } + +private: + + void Cleanup(); + + void InitDefaultOptions(); + + void ReadOptionsFile(); + + void WriteOptionsFile(FILE *fp); + + void SetOptionValue(const char *name, + oaOptionDataType type, + const char *value); + + oaNamedOption Options[128]; + std::map<std::string, OptionValue> OptionValueMap; + + int NumOptions; +}; + +#endif
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Stats.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Stats.cpp new file mode 100644 index 0000000..d52aa14 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Stats.cpp @@ -0,0 +1,76 @@ +// 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. +// +/////////////////////////////////////////////////////////////////////////////// +#include "Stats.h" + +void Stats::reset() +{ + m_totalRenderTime = 0.0f; + m_shadowRenderTime = 0.0f; + m_meshRenderTime = 0.0f; + m_hairRenderTime = 0.0f; + m_hairStatsTime = 0.0f; + m_totalUpdateTime = 0.0f; + m_meshSkinningTime = 0.0f; + m_hairSkinningTime = 0.0f; + m_hairSimulationTime = 0.0f; + m_queryTime = 0.0f; +} + +/////////////////////////////////////////////////////////////////////////////// +void Stats::add(const Stats& toAdd) +{ + m_totalRenderTime += toAdd.m_totalRenderTime; + m_shadowRenderTime += toAdd.m_shadowRenderTime; + m_meshRenderTime += toAdd.m_meshRenderTime; + m_hairRenderTime += toAdd.m_hairRenderTime; + m_hairStatsTime += toAdd.m_hairStatsTime; + + m_totalUpdateTime += toAdd.m_totalUpdateTime; + m_meshSkinningTime += toAdd.m_meshSkinningTime; + m_hairSkinningTime += toAdd.m_hairSkinningTime; + m_hairSimulationTime += toAdd.m_hairSimulationTime; + + m_queryTime += toAdd.m_queryTime; +} + +/////////////////////////////////////////////////////////////////////////////// +void Stats::average(float numFrames) +{ + m_totalRenderTime /= numFrames; + m_shadowRenderTime /= numFrames; + m_meshRenderTime /= numFrames; + m_hairRenderTime /= numFrames; + m_hairStatsTime /= numFrames; + m_totalUpdateTime /= numFrames; + m_meshSkinningTime /= numFrames; + m_hairSkinningTime /= numFrames; + m_hairSimulationTime /= numFrames; + m_queryTime /= numFrames; +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Stats.h b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Stats.h new file mode 100644 index 0000000..fb22e57 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Stats.h @@ -0,0 +1,54 @@ +// 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. +// + +#pragma once + +#include "corelib_global.h" + +// scene statistics +struct CORELIB_EXPORT Stats +{ + double m_totalRenderTime; + double m_shadowRenderTime; + double m_meshRenderTime; + double m_hairRenderTime; + double m_hairStatsTime; + + double m_totalUpdateTime; + double m_meshSkinningTime; + double m_hairSkinningTime; + double m_hairSimulationTime; + + double m_queryTime; + + Stats() { reset(); } + + void reset(); + void add(const Stats& toAdd); + void average(float numFrames); +};
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Timer.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Timer.cpp new file mode 100644 index 0000000..2161989 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Timer.cpp @@ -0,0 +1,80 @@ +// 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. +// + +#include "Timer.h" + +Timer::Timer(bool isStartNow) +{ + ::QueryPerformanceFrequency(&m_ticksPerSecond); + Reset(isStartNow); +} + +void Timer::Reset(bool isStartNow) +{ + m_isPaused = true; + m_totalPausedTime.QuadPart = 0; + m_lastPausedTime.QuadPart = 0; + if (isStartNow) + { + Start(); + } +} + +void Timer::Start() +{ + if (m_isPaused) + { + LARGE_INTEGER timeNow; + ::QueryPerformanceCounter(&timeNow); + m_totalPausedTime.QuadPart += timeNow.QuadPart - m_lastPausedTime.QuadPart; + m_isPaused = false; + } +} + +void Timer::Pause() +{ + if (!m_isPaused) + { + m_isPaused = true; + ::QueryPerformanceCounter(&m_lastPausedTime); + } +} + +LONGLONG Timer::GetTicksElapsed() const +{ + LARGE_INTEGER timeNow; + if (m_isPaused) + { + timeNow = m_lastPausedTime; + } + else + { + ::QueryPerformanceCounter(&timeNow); + } + return (timeNow.QuadPart - m_totalPausedTime.QuadPart); +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Timer.h b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Timer.h new file mode 100644 index 0000000..c14ff97 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/Timer.h @@ -0,0 +1,68 @@ +// 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. +// + +#pragma once + +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> + +#include "corelib_global.h" + +class CORELIB_EXPORT Timer +{ +public: + Timer(bool isStartNow = false); + void Start(); + void Reset(bool isStartNow = false); + void Pause(); + bool IsRunning() const + { + return !m_isPaused; + } + double GetTimeInMilliSeconds() const + { + return double(GetTicksElapsed()*1000.0) / GetTicksPerSecond(); + } + double GetTimeInSeconds() const + { + return double(GetTicksElapsed()) / GetTicksPerSecond(); + } + +public: + bool m_isPaused; + + // Get time ticks elapsed + LONGLONG GetTicksElapsed() const; + // Get the timer frequency. Time tick count per second + LONGLONG GetTicksPerSecond() const { + return m_ticksPerSecond.QuadPart; + } + LARGE_INTEGER m_ticksPerSecond; + LARGE_INTEGER m_lastPausedTime; + LARGE_INTEGER m_totalPausedTime; +}; diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.cpp new file mode 100644 index 0000000..d5486bc --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.cpp @@ -0,0 +1,75 @@ +#include <windows.h> +#include "ViewerOutput.h" + +ViewerOutput& ViewerOutput::Inst() +{ + static ViewerOutput inst; + return inst; +} + +void ViewerOutput::RegisterPrinter( FrontPrinter* printer ) +{ + if(!printer) return; + + _printers.insert(printer); +} + +void ViewerOutput::UnRegisterPrinter( FrontPrinter* printer ) +{ + if(!printer) return; + + auto itr = _printers.find(printer); + if(itr != _printers.end()) + _printers.erase(itr); +} + +void ViewerOutput::print( FrontPrinter::Effect e, unsigned long color, const char* fmt, ... ) +{ + va_list args; + va_start(args, fmt); + + vsprintf_s(_buf, MAX_BUFFER_SIZE, fmt, args); + + va_end(args); + + for (auto itr = _printers.begin(); itr != _printers.end(); ++itr) + { + (*itr)->print(_buf, color, e); + } +} + +////////////////////////////////////////////////////////////////////////// +ViewerStream::~ViewerStream() +{ + flush(); +} + +ViewerStream& ViewerStream::flush() +{ + this->std::ostream::flush(); + + if(_buffer.size() == 0) + return (*this); + + ViewerOutput::Inst().print(_effect, _color, _buffer.buf); + _buffer.reset(); + + return (*this); +} + +ViewerStream::ViewerStreamBuf::ViewerStreamBuf() +{ + reset(); +} + +std::streamsize ViewerStream::ViewerStreamBuf::size() +{ + return (pptr() - pbase()); +} + +void ViewerStream::ViewerStreamBuf::reset() +{ + memset(buf, 0, sizeof(buf)); + setp(buf, buf + FURVIEWER_MAX_OUTPUT_CHAR); +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.h b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.h new file mode 100644 index 0000000..b1fb9f7 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Utils/ViewerOutput.h @@ -0,0 +1,136 @@ +// 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-2015 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. +// + +#pragma once + +#include <set> + +#include "corelib_global.h" + +/* + * !! CAUSION: + * Not thread safe, should only output messages in the MAIN thread! + * Otherwise, cannot guarantee the Qt Gui behavior. + */ + +// DON'T TRY TO WRITE CHARS MORE THAN THE FURVIEWER_MAX_OUTPUT_CHAR +#define FURVIEWER_MAX_OUTPUT_CHAR 2048 + +// c-style print +#define viewer_msg(fmt, ...) ViewerOutput::Inst().print(FrontPrinter::NONE, 0, fmt, ##__VA_ARGS__) +#define viewer_warn(fmt, ...) ViewerOutput::Inst().print(FrontPrinter::NONE, RGB(255,200,020), fmt, ##__VA_ARGS__) +#define viewer_info(fmt, ...) ViewerOutput::Inst().print(FrontPrinter::NONE, RGB(118,185,000), fmt, ##__VA_ARGS__) +#define viewer_err(fmt, ...) ViewerOutput::Inst().print(FrontPrinter::NONE, RGB(255,000,000), fmt, ##__VA_ARGS__) +#define viewer_fatal(fmt, ...) ViewerOutput::Inst().print(FrontPrinter::BOLD, RGB(255,000,000), fmt, ##__VA_ARGS__) + +// c++ style output stream +#define viewer_stream_msg ViewerStream(FrontPrinter::NONE, 0) +#define viewer_stream_warn ViewerStream(FrontPrinter::NONE, RGB(255,200,020)) +#define viewer_stream_info ViewerStream(FrontPrinter::NONE, RGB(118,185,000)) +#define viewer_stream_err ViewerStream(FrontPrinter::NONE, RGB(255,000,000)) +#define viewer_stream_fatal ViewerStream(FrontPrinter::NONE, RGB(255,000,000)) + + +////////////////////////////////////////////////////////////////////////// +// implementation +////////////////////////////////////////////////////////////////////////// +class FrontPrinter +{ +public: + enum Effect + { + NONE = 0x0, + BOLD = 0x1, + ITALIC = 0x2, + UNDERLINE = 0x4 + }; + + virtual void print(const char* txt, unsigned long color = 0, Effect e = NONE) = 0; +}; + +class CORELIB_EXPORT ViewerOutput +{ +public: + static ViewerOutput& Inst(); + + void RegisterPrinter(FrontPrinter* printer); + void UnRegisterPrinter(FrontPrinter* printer); + + void print(FrontPrinter::Effect e, unsigned long color, const char* fmt, ...); + +private: + enum {MAX_BUFFER_SIZE = FURVIEWER_MAX_OUTPUT_CHAR + 1}; + + char _buf[MAX_BUFFER_SIZE]; + + std::set<FrontPrinter*> _printers; +}; + + +////////////////////////////////////////////////////////////////////////// +// stream to support c++ style output + +#include <streambuf> +#include <sstream> + +class ViewerStream : public std::ostream +{ +public: + explicit ViewerStream(FrontPrinter::Effect e, unsigned long color) + : std::ostream(&_buffer) + , _effect(e) + , _color(color) + {} + + ~ViewerStream(); + + ViewerStream& flush(); + +private: + + class ViewerStreamBuf : public std::streambuf + { + public: + enum + { + STATIC_BUFFER_SIZE = FURVIEWER_MAX_OUTPUT_CHAR + 1, + }; + + ViewerStreamBuf(); + + void reset(); + std::streamsize size(); + + // fixed stack buffer + char buf[STATIC_BUFFER_SIZE]; + }; + + ViewerStreamBuf _buffer; + FrontPrinter::Effect _effect; + unsigned long _color; +}; diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp new file mode 100644 index 0000000..3a85d8b --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp @@ -0,0 +1,1448 @@ +#include <QtWidgets/QShortcut> +#include <QtWidgets/QAction> +#include <QtWidgets/QMenu> +#include <QtWidgets/QFileDialog> +#include <QtWidgets/QMessageBox> +#include <QtGui/QDesktopServices> +#include <QtWidgets/QScrollBar> +#include <QtWidgets/QGraphicsEllipseItem> +#include <QtWidgets/QGraphicsView> +#include <QtWidgets/QProgressDialog> + +#include <Windows.h> + +#include "AppMainWindow.h" +#include "ExpandablePanel.h" + +#include "D3DWidget.h" + +#include "DisplayMeshesPanel.h" + +#include "DisplayPreferencesPanel.h" +#include "DisplayScenePanel.h" +#include "DisplayLightPanel.h" +#include "ui_DisplayPreferencesPanel.h" +#include "ui_DisplayScenePanel.h" +#include "ui_DisplayLightPanel.h" +#include "CameraBookmarksDialog.h" + +#include "SimpleScene.h" +#include "GlobalSettings.h" + +#include "ViewerOutput.h" +#include "Gamepad.h" +#if USE_CURVE_EDITOR +#include "CurveEditorMainWindow.h" +#endif +#ifndef NV_ARTISTTOOLS +#include "ui_AppMainToolbar.h" +#include "ui_AssetControlPanel.h" +#include "ui_GeneralAttributesPanel.h" +#include "ui_PhysicalMaterialsPanel.h" +#include "ui_StyleMaterialsPanel.h" +#include "ui_GraphicalMaterialsPanel.h" +#include "BlastToolbar.h" +#include "AssetControlPanel.h" +#include "GraphicalMaterialPanel.h" +#include "PhysicalMaterialPanel.h" +#include "StyleMaterialPanel.h" +#include "GeneralAttributePanel.h" +#include "MaterialSetPanel.h" +#include "LodPanel.h" +#include "DisplayVisualizersPanel.h" +#include "ui_DisplayVisualizersPanel.h" +#include "DisplayMeshMaterialsPanel.h" +#include "FurCharacter.h" +#include "HairParams.h" +#include "AboutDialog.h" +#else +#endif // NV_ARTISTTOOLS + +class MsgPrinter : public FrontPrinter +{ +public: + MsgPrinter(QTextBrowser* browser):_browser(browser) + { + + } + + void print(const char* txt, unsigned long color /* = 0 */, Effect e /* = NONE */) + { + if(color == 0 && e == FrontPrinter::NONE) + { + _browser->insertPlainText(QString(txt)+"\n"); + } + else + { + // output html text + QString surfix; + QString postfix; + surfix.reserve(64); + postfix.reserve(64); + if(e & FrontPrinter::BOLD) + { + surfix = surfix + "<b>"; + postfix= postfix + "</b>"; + } + else if(e & FrontPrinter::UNDERLINE) + { + surfix = surfix + "<u>"; + postfix= QString("</u>") + postfix; + } + else if(e & FrontPrinter::ITALIC) + { + surfix = surfix + "<i>"; + postfix= QString("</i>") + postfix; + } + + if(color != 0) + { + int r = GetRValue(color); + int g = GetGValue(color); + int b = GetBValue(color); + + surfix = QString("<div style=\"color:rgb(%1,%2,%3);\">").arg(r).arg(g).arg(b) + surfix; + postfix= postfix + QString("</div><br />"); + } + + QString html = surfix + QString(txt) + postfix; + _browser->insertHtml(html); + } + // auto scroll to the bottom + QScrollBar *sb = _browser->verticalScrollBar(); + if (sb) sb->setValue(sb->maximum()); + } + +private: + QTextBrowser* _browser; +}; + +int AppMainWindow::_connectionMode = 0; +bool AppMainWindow::_expertMode = false; +AppMainWindow* gAppMainWindow = NV_NULL; + +void CreateAppMainWindow() +{ + gAppMainWindow = new AppMainWindow; +} + +void ReleaseAppMainWindow() +{ + delete gAppMainWindow; + gAppMainWindow = NV_NULL; +} + +AppMainWindow& AppMainWindow::Inst() +{ + return *gAppMainWindow; +} + +AppMainWindow::AppMainWindow(QWidget *parent, Qt::WindowFlags flags) + : QMainWindow(parent, flags) + , _bookmarksMenu(0) + ,_displayMeshesPanel(0) + , _displayPreferencesPanel(0) + , _displayScenePanel(0) + ,_displayLightPanel(0) +#if USE_CURVE_EDITOR + ,_curveEditorInitizlized(false) + , _curveEditorMainWindow(nullptr) +#endif + ,_bookmarkActionGroup(0) + ,_actionAddBookmark(0) + ,_actionEditBookmarks(0) +{ + setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); + setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); + + ui.setupUi(this); + //ui.dockOutputWindow->hide(); + +#ifndef NV_ARTISTTOOLS + _mainToolbar = 0; + _physicalMaterialPanel = 0; + _styleMaterialPanel = 0; + _graphicalMaterialPanel = 0; + _displayFurVisualizersPanel = 0; + _assetControlPanel = 0; + _generalAttributePanel = 0; + _lodPanel = 0; + _displayMeshMaterialsPanel; +#if USE_MATERIAL_SET + _materialSetPanel = 0; +#endif +#else + CoreLib::Inst()->AppMainWindow_AppMainWindow(); +#endif // NV_ARTISTTOOLS + + _progressDialog.close(); // prevent show one empty progress dialog when it runs. + + m_bGizmoWithLocal = false; +} + +void AppMainWindow::InitUI() +{ + _d3dWidget = new D3DWidget(this); + _d3dWidget->setMinimumSize(200, 200); + ui.renderLayout->addWidget(_d3dWidget); + + InitShortCuts(); + InitMenuItems(); + InitToolbar(); + InitPluginTab(); + InitMainTab(); + + InitMouseSchemes(); + + updateUI(); + + if (_connectionMode == 1) // master mode + ui.sideBarTab->removeTab(1); + + if (_connectionMode == 2) + ui.sideBarTab->removeTab(0); + + + QString defFilePath; + + QString appDir = qApp->applicationDirPath(); + QDir dir(appDir); + if (dir.cd("../../media")) + defFilePath = dir.absolutePath(); + + _lastFilePath = defFilePath; + + _navigationStyle = 0; + + // initialize the message printer + _printer = new MsgPrinter(this->ui.outputWindow); + ViewerOutput::Inst().RegisterPrinter(_printer); + +#ifndef NV_ARTISTTOOLS + + viewer_info( + "<a href=\"https://developer.nvidia.com/hairworks\" style=\"color:rgb(118,180,0);\">NVIDIA Blast Version v" + NV_HAIR_RELEASE_VERSION_STRING + "</a>"); + +#else + CoreLib::Inst()->AppMainWindow_InitUI(); +#endif // NV_ARTISTTOOLS +} + +AppMainWindow::~AppMainWindow() +{ +} + +void AppMainWindow::setConnectionMode(int m) +{ + _connectionMode = m; +} + +void AppMainWindow::startProgress() +{ + _progressDialog.setWindowModality(Qt::WindowModal); + _progressDialog.show(); +} + +void AppMainWindow::setProgress(const char* label, int progress) +{ + _progressDialog.setLabelText(label); + if (progress >= 0) + _progressDialog.setValue(progress); + + _progressDialog.update(); +} + +void AppMainWindow::endProgress() +{ + _progressDialog.close(); +} + +void AppMainWindow::quit() +{ + emit aboutToQuit(); +} + +void AppMainWindow::setProgressMaximum(int m) +{ + _progressDialog.setMaximum(m); +} + +void AppMainWindow::InitMenuItems() +{ + QMenuBar* menu = ui.menuBar; + QAction* act = NV_NULL; + + // file sub-menu + QMenu* fileMenu = menu->addMenu("&File"); + + if (_connectionMode != 1) + { + act = new QAction("Clear scene", this); + act->setShortcut(QKeySequence::New); + connect(act, SIGNAL(triggered()), this, SLOT(menu_clearScene())); + fileMenu->addAction(act); + + fileMenu->addSeparator(); + + act = new QAction("Open fbx file", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_openfbx())); + fileMenu->addAction(act); + + fileMenu->addSeparator(); + +#ifndef NV_ARTISTTOOLS + fileMenu->addSeparator(); + act = new QAction("Open project file", this); + act->setShortcut(QKeySequence::Open); + connect(act, SIGNAL(triggered()), this, SLOT(menu_openProject())); + fileMenu->addAction(act); + + act = new QAction("Save project file", this); + act->setShortcut(QKeySequence::Save); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveProject())); + fileMenu->addAction(act); + + act = new QAction("Save project file as...", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveProjectAs())); + fileMenu->addAction(act); + + fileMenu->addSeparator(); + + act = new QAction("&Open hair file", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_openHair())); + fileMenu->addAction(act); + + act = new QAction("&Save hair file", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveHair())); + fileMenu->addAction(act); + + act = new QAction("Save hair file as...", this); + act->setShortcut(QKeySequence::SaveAs); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveHairAs())); + fileMenu->addAction(act); + + act = new QAction("Save all hairs...", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveAllHairs())); + fileMenu->addAction(act); + + fileMenu->addSeparator(); +#else + CoreLib::Inst()->AppMainWindow_InitMenuItems(ui.menuBar); +#endif // NV_ARTISTTOOLS + } + + act = new QAction("E&xit", this); + act->setShortcut(QKeySequence::Quit); + connect(act, SIGNAL(triggered()), this, SLOT(close())); + fileMenu->addAction(act); + + // view submenu + QMenu* viewMenu = menu->addMenu("&View"); + act = new QAction("Bookmarks", this); + //connect(act, SIGNAL(triggered()), this, SLOT(menu_showOutput())); + viewMenu->addAction(act); + _bookmarksMenu = new QMenu("Bookmarks", this); + connect(_bookmarksMenu, SIGNAL(triggered(QAction*)), this, SLOT(menu_bookmarkTriggered(QAction*))); + act->setMenu(_bookmarksMenu); + act = new QAction("Add Bookmark", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_addBookmark())); + _bookmarksMenu->addAction(act); + _actionAddBookmark = act; + act = new QAction("Edit Bookmarks", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_editBookmarks())); + _bookmarksMenu->addAction(act); + _actionEditBookmarks = act; + _bookmarksMenu->addSeparator(); + _bookmarkActionGroup = new QActionGroup(this); + + // window submenu + QMenu* windowMenu = menu->addMenu("&Window"); + act = new QAction("Output", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_showOutput())); + windowMenu->addAction(act); + + act = new QAction("Attribute Editor", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_showAttributeEditor())); + windowMenu->addAction(act); + +#if USE_CURVE_EDITOR + act = new QAction("Curve Editor", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_showCurveEditor())); + windowMenu->addAction(act); +#endif + + // help submenu + QMenu* helpMenu = menu->addMenu("&Help"); + + act = new QAction("Documentation", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_opendoc())); + helpMenu->addAction(act); + + act = new QAction("&About", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_about())); + helpMenu->addAction(act); +} + +void AppMainWindow::InitToolbar() +{ + if (_connectionMode != 1) + { +#ifndef NV_ARTISTTOOLS + _mainToolbar = new BlastToolbar(ui.centralWidget); + ui.verticalLayout->insertWidget(0, _mainToolbar); + connect(_mainToolbar->getUI().btnFileOpen, SIGNAL(clicked()), this, SLOT(menu_openProject())); +#else + CoreLib::Inst()->AppMainWindow_InitToolbar(ui.centralWidget, ui.verticalLayout); +#endif // NV_ARTISTTOOLS + } +} + +void AppMainWindow::InitPluginTab() +{ +#ifndef NV_ARTISTTOOLS + QWidget *tabFur; + QGridLayout *gridLayout; + QFrame *furMaterialEditorArea; + QVBoxLayout *furMaterialEditorAreaLayout; + QScrollArea *furScrollArea; + QWidget *furScrollAreaContents; + QVBoxLayout *furScrollAreaLayout; + QSpacerItem *verticalSpacer; + + tabFur = new QWidget(); + tabFur->setObjectName(QStringLiteral("tabFur")); + gridLayout = new QGridLayout(tabFur); + gridLayout->setSpacing(6); + gridLayout->setContentsMargins(11, 11, 11, 11); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + gridLayout->setContentsMargins(0, 0, 0, 0); + furMaterialEditorArea = new QFrame(tabFur); + furMaterialEditorArea->setObjectName(QStringLiteral("furMaterialEditorArea")); + furMaterialEditorAreaLayout = new QVBoxLayout(furMaterialEditorArea); + furMaterialEditorAreaLayout->setSpacing(6); + furMaterialEditorAreaLayout->setContentsMargins(11, 11, 11, 11); + furMaterialEditorAreaLayout->setObjectName(QStringLiteral("furMaterialEditorAreaLayout")); + furMaterialEditorAreaLayout->setContentsMargins(2, 2, 2, 2); + + gridLayout->addWidget(furMaterialEditorArea, 1, 0, 1, 1); + + furScrollArea = new QScrollArea(tabFur); + furScrollArea->setObjectName(QStringLiteral("furScrollArea")); + furScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + furScrollArea->setWidgetResizable(true); + furScrollAreaContents = new QWidget(); + furScrollAreaContents->setObjectName(QStringLiteral("furScrollAreaContents")); + furScrollAreaContents->setGeometry(QRect(0, 0, 359, 481)); + furScrollAreaLayout = new QVBoxLayout(furScrollAreaContents); + furScrollAreaLayout->setSpacing(3); + furScrollAreaLayout->setContentsMargins(11, 11, 11, 11); + furScrollAreaLayout->setObjectName(QStringLiteral("furScrollAreaLayout")); + furScrollAreaLayout->setContentsMargins(2, 2, 2, 2); + verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + furScrollAreaLayout->addItem(verticalSpacer); + + furScrollArea->setWidget(furScrollAreaContents); + + gridLayout->addWidget(furScrollArea, 0, 0, 1, 1); + + ui.sideBarTab->addTab(tabFur, QString()); + + ui.sideBarTab->setTabText(ui.sideBarTab->indexOf(tabFur), QApplication::translate("AppMainWindowClass", "Hair", 0)); + + ExpandablePanel* panel = 0; + int pannelCnt = 0; + + if (_connectionMode == 0) + { + panel = new ExpandablePanel(furScrollAreaContents, false); + _generalAttributePanel = new GeneralAttributePanel(panel); + panel->AddContent(_generalAttributePanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Asset Selection"); + + panel = new ExpandablePanel(furScrollAreaContents, false); + _assetControlPanel = new AssetControlPanel(panel); + panel->AddContent(_assetControlPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("General Settings"); + + } + + panel = new ExpandablePanel(furScrollAreaContents); + _displayFurVisualizersPanel = new DisplayFurVisualizersPanel(panel); + panel->AddContent(_displayFurVisualizersPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Visualization"); + + panel = new ExpandablePanel(furScrollAreaContents); + _physicalMaterialPanel = new PhysicalMaterialPanel(panel); + panel->AddContent(_physicalMaterialPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Physical"); + + panel = new ExpandablePanel(furScrollAreaContents); + _styleMaterialPanel = new StyleMaterialPanel(panel); + panel->AddContent(_styleMaterialPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Style"); + + panel = new ExpandablePanel(furScrollAreaContents); + _graphicalMaterialPanel = new GraphicalMaterialPanel(panel); + panel->AddContent(_graphicalMaterialPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Graphics"); + + panel = new ExpandablePanel(furScrollAreaContents); + _lodPanel = new LodPanel(panel); + panel->AddContent(_lodPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Level Of Detail"); + +#if USE_MATERIAL_SET + panel = new ExpandablePanel(furScrollAreaContents); + _materialSetPanel = new MaterialSetPanel(panel); + panel->AddContent(_materialSetPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Control Texture Channels"); + //_materialSetPanel->hide(); + //panel->SetCollapsed(true); +#else + ui.furMaterialEditorAreaLayout->setEnabled(false); +#endif +#else + CoreLib::Inst()->AppMainWindow_InitPluginTab(ui.sideBarTab); +#endif // NV_ARTISTTOOLS + +#if USE_CURVE_EDITOR + _curveEditorMainWindow = new nvidia::CurveEditor::CurveEditorMainWindow( this);//nullptr); + _curveEditorMainWindow->setResampleEnabled(false); + ui.dockWidgetCurveEditor->setWidget(_curveEditorMainWindow); + ui.dockWidgetCurveEditor->setWindowTitle(tr("Curve Editor")); + + connect(_curveEditorMainWindow, SIGNAL(CurveAttributeChanged(nvidia::CurveEditor::CurveAttribute*)), this, SLOT(onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute*))); + connect(_curveEditorMainWindow, SIGNAL(ColorAttributeChanged(nvidia::CurveEditor::ColorAttribute*)), this, SLOT(onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute*))); + connect(_curveEditorMainWindow, SIGNAL(ReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute*, bool, int)), this, SLOT(onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute*, bool, int))); +//#else +// ui.furCurveEditorAreaLayout->setEnabled(false); +#endif +} + +void AppMainWindow::InitMainTab() +{ + int idx = 0; + + if (_connectionMode != 1) + { + ExpandablePanel* panel = new ExpandablePanel(ui.displayScrollAreaContents); + _displayPreferencesPanel = new DisplayPreferencesPanel(panel); + panel->AddContent(_displayPreferencesPanel); + ui.displayScrollAreaLayout->insertWidget(idx++, panel); + panel->SetTitle("Preferences"); + + panel = new ExpandablePanel(ui.displayScrollAreaContents); + _displayScenePanel = new DisplayScenePanel(panel); + panel->AddContent(_displayScenePanel); + ui.displayScrollAreaLayout->insertWidget(idx++, panel); + panel->SetTitle("Scene"); + + panel = new ExpandablePanel(ui.displayScrollAreaContents); + _displayLightPanel = new DisplayLightPanel(panel); + panel->AddContent(_displayLightPanel); + ui.displayScrollAreaLayout->insertWidget(idx++, panel); + panel->SetTitle("Light"); + + panel = new ExpandablePanel(ui.displayScrollAreaContents); + _displayMeshesPanel = new DisplayMeshesPanel(panel); + panel->AddContent(_displayMeshesPanel); + ui.displayScrollAreaLayout->insertWidget(idx++, panel); + panel->SetTitle("Display Meshes"); + } + + if (_connectionMode != 1) + { +#ifndef NV_ARTISTTOOLS + ExpandablePanel* panel = new ExpandablePanel(ui.displayScrollAreaContents); + _displayMeshMaterialsPanel = new DisplayMeshMaterialsPanel(panel); + panel->AddContent(_displayMeshMaterialsPanel); + ui.displayScrollAreaLayout->insertWidget(idx++, panel); + panel->SetTitle("Display Mesh Materials"); +#else + CoreLib::Inst()->AppMainWindow_InitMainTab(ui.displayScrollAreaContents, ui.displayScrollAreaLayout, idx); +#endif // NV_ARTISTTOOLS + } +} + +void AppMainWindow::InitShortCuts() +{ + QShortcut* shortCut; + shortCut = new QShortcut(QKeySequence(Qt::Key_F), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_frameall())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_H), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_hud())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_G), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_statistics())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_Space), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_pause())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_B), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_reset())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_Escape), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_escape())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_V), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_expert())); + + shortCut = new QShortcut(QKeySequence("Ctrl+X"), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_expert())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_D), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(demo_next())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_Right), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(demo_next())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_A), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(demo_prev())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_Left), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(demo_prev())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_F2), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_output())); + + shortCut = new QShortcut(QKeySequence("Ctrl+F"), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_fitcamera())); +} + +////////////////////////////////////////////////////////////////////////// +void AppMainWindow::updateBookmarkMenu() +{ + // clear old menu items of camera bookmarks + while (_bookmarkActionGroup->actions().size() > 0) + { + QAction* act = _bookmarkActionGroup->actions()[0]; + _bookmarkActionGroup->removeAction(act); + delete act; + } + _bookmarksMenu->clear(); + _bookmarksMenu->addAction(_actionAddBookmark); + _bookmarksMenu->addAction(_actionEditBookmarks); + _bookmarksMenu->addSeparator(); + + QList<QString> bookmarks = SimpleScene::Inst()->getBookmarkNames(); + int numBookmarks = bookmarks.size(); + for (int i = 0; i < numBookmarks; ++i) + { + QString bookmark = bookmarks[i]; + + QAction* act = new QAction(bookmark, this); + act->setCheckable(true); + _bookmarksMenu->addAction(act); + _bookmarkActionGroup->addAction(act); + } + +} + +////////////////////////////////////////////////////////////////////////// +void AppMainWindow::updateUI() +{ + if (_bookmarksMenu && _bookmarkActionGroup) + { + updateBookmarkMenu(); + } + +#ifndef NV_ARTISTTOOLS + if (_mainToolbar) + _mainToolbar->updateValues(); + + if (_graphicalMaterialPanel) + _graphicalMaterialPanel->updateValues(); + + if (_physicalMaterialPanel) + _physicalMaterialPanel->updateValues(); + + if (_styleMaterialPanel) + _styleMaterialPanel->updateValues(); + + if (_displayFurVisualizersPanel) + _displayFurVisualizersPanel->updateValues(); + + if (_lodPanel) + _lodPanel->updateValues(); + + if (_generalAttributePanel) + _generalAttributePanel->updateValues(); + + if (_assetControlPanel) + _assetControlPanel->updateValues(); + + if (_displayMeshMaterialsPanel) + _displayMeshMaterialsPanel->updateValues(); + +#if USE_MATERIAL_SET + if (_materialSetPanel) + _materialSetPanel->updateValues(); +#endif +#else + CoreLib::Inst()->AppMainWindow_updateUI(); +#endif // NV_ARTISTTOOLS + + if (_displayPreferencesPanel) + _displayPreferencesPanel->updateValues(); + + if (_displayScenePanel) + _displayScenePanel->updateValues(); + + if (_displayLightPanel) + _displayLightPanel->updateValues(); + + if (_displayMeshesPanel) + _displayMeshesPanel->updateValues(); + +#if USE_CURVE_EDITOR + if (_curveEditorMainWindow) + UpdateCurveEditor(); +#endif +} + +////////////////////////////////////////////////////////////////////////// +void AppMainWindow::updatePluginUI() +{ + SimpleScene::Inst()->setIsUpdatingUI(true); + +#ifndef NV_ARTISTTOOLS + if (_graphicalMaterialPanel) + _graphicalMaterialPanel->updateValues(); + + if (_physicalMaterialPanel) + _physicalMaterialPanel->updateValues(); + + if (_styleMaterialPanel) + _styleMaterialPanel->updateValues(); + + if (_lodPanel) + _lodPanel->updateValues(); + + if (_displayFurVisualizersPanel) + _displayFurVisualizersPanel->updateValues(); + + if (_generalAttributePanel) + _generalAttributePanel->updateValues(); + + if (_assetControlPanel) + _assetControlPanel->updateValues(); + +#if USE_MATERIAL_SET + if (_materialSetPanel) + _materialSetPanel->updateValues(); +#endif +#else + CoreLib::Inst()->AppMainWindow_updatePluginUI(); +#endif // NV_ARTISTTOOLS + +#if USE_CURVE_EDITOR + if (_curveEditorMainWindow) + UpdateCurveEditor(); +#endif + + SimpleScene::Inst()->setIsUpdatingUI(false); +} + + +////////////////////////////////////////////////////////////////////////// +// event handlers + + +////////////////////////////////////////////////////////////////////////// +// event handlers +bool AppMainWindow::openProject(QString fileName) +{ + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file= fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->LoadProject(dir, file) == false) + { + QMessageBox messageBox; + messageBox.critical(0,"Error","File open error!"); + messageBox.setFixedSize(500,200); + + AppMainWindow::Inst().endProgress(); + char message[1024]; + sprintf(message, "Failed to open project file(\"%s\")", (const char*)file); + viewer_err(message); + return false; + } + + AppMainWindow::Inst().endProgress(); + _lastFilePath = fileInfo.absoluteDir().absolutePath(); + + updateUI(); + return true; + } + return false; +} + +void AppMainWindow::processDragAndDrop(QString fname) +{ + openProject(fname); +} + +void AppMainWindow::removeBookmark(const QString& name) +{ + QList<QAction*> bookmarks = _bookmarkActionGroup->actions(); + int bookmarkCount = bookmarks.size(); + for (int i = 0; i < bookmarkCount; ++i) + { + QAction* act = bookmarks.at(i); + if (act->text() == name) + { + _bookmarkActionGroup->removeAction(act); + _bookmarksMenu->removeAction(act); + delete act; + } + } +} + +void AppMainWindow::renameBookmark(const QString& oldName, const QString& newName) +{ + QList<QAction*> bookmarks = _bookmarkActionGroup->actions(); + int bookmarkCount = bookmarks.size(); + for (int i = 0; i < bookmarkCount; ++i) + { + QAction* act = bookmarks.at(i); + if (act->text() == oldName) + { + act->setText(newName); + } + } +} + +#if USE_CURVE_EDITOR +void AppMainWindow::UpdateCurveEditor() +{ +#ifndef NV_ARTISTTOOLS + _curveEditorMainWindow->setCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetCurveAttributes()); + _curveEditorMainWindow->setColorCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetColorAttributes()); +#else + CoreLib::Inst()->AppMainWindow_UpdateCurveEditor(); +#endif // NV_ARTISTTOOLS + + _curveEditorMainWindow->update(); +} + +void AppMainWindow::ShowCurveEditor(int paramId) +{ +#ifndef NV_ARTISTTOOLS + _curveEditorMainWindow->setCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetCurveAttributes()); + _curveEditorMainWindow->setColorCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetColorAttributes()); + if (HAIR_PARAMS_ROOT_COLOR == paramId || HAIR_PARAMS_TIP_COLOR == paramId) + { + std::vector<nvidia::CurveEditor::ColorAttribute*> attributes = SimpleScene::Inst()->GetFurCharacter().GetColorAttributesByParamId(paramId); + _curveEditorMainWindow->setSelectedColorAttribute(attributes.size() > 0 ? attributes[0] : nullptr); + } + else + _curveEditorMainWindow->setSelectedCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetCurveAttributesByParamId(paramId)); + +#else + CoreLib::Inst()->AppMainWindow_ShowCurveEditor(paramId); +#endif // NV_ARTISTTOOLS + + _curveEditorMainWindow->update(); +} +#endif + +void AppMainWindow::menu_clearScene() +{ + SimpleScene::Inst()->Clear(); + updateUI(); +} + +bool AppMainWindow::menu_openfbx() +{ + /* + QString lastDir = _lastFilePath; + QString fileName = QFileDialog::getOpenFileName(this, "Open FBX File", lastDir, "FBX File (*.fbx)"); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file= fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->LoadSceneFromFbx(dir, file) == false) + { + QMessageBox messageBox; + messageBox.critical(0,"Error","File open error!"); + messageBox.setFixedSize(500,200); + + AppMainWindow::Inst().endProgress(); + + char message[1024]; + sprintf(message, "Failed to open fbx file(\"%s\")", (const char*)file); + viewer_err(message); + + return false; + } + + AppMainWindow::Inst().endProgress(); + + _lastFilePath = fileInfo.absoluteDir().absolutePath(); + + updateUI(); + + return true; + } + return true; + */ + + // dir and file will get in blast open asset dialog + return SimpleScene::Inst()->LoadSceneFromFbx("", ""); +} + +void AppMainWindow::menu_addBookmark() +{ + QString bookmark = SimpleScene::Inst()->createBookmark(); + + QAction* act = new QAction(bookmark, this); + act->setCheckable(true); + _bookmarksMenu->addAction(act); + _bookmarkActionGroup->addAction(act); + act->setChecked(true); +} + +void AppMainWindow::menu_editBookmarks() +{ + CameraBookmarksDialog dlg(this); + dlg.exec(); +} + +void AppMainWindow::menu_bookmarkTriggered(QAction* act) +{ + if (_actionAddBookmark != act && _actionEditBookmarks != act) + { + SimpleScene::Inst()->activateBookmark(act->text()); + } +} + +void AppMainWindow::menu_showOutput() +{ + bool bVisibal = ui.dockOutputWindow->isVisible(); + ui.dockOutputWindow->setVisible(!bVisibal); +} + +void AppMainWindow::menu_showAttributeEditor() +{ + bool bVisibal = ui.dockWidget->isVisible(); + ui.dockWidget->setVisible(!bVisibal); +} +#if USE_CURVE_EDITOR +void AppMainWindow::menu_showCurveEditor() +{ + bool bVisibal = ui.dockWidgetCurveEditor->isVisible(); + ui.dockWidgetCurveEditor->setVisible(!bVisibal); +} +#endif +void AppMainWindow::menu_about() +{ + qDebug("%s", __FUNCTION__); +#ifndef NV_ARTISTTOOLS + AboutDialog::ShowAboutDialog(); +#else + CoreLib::Inst()->AppMainWindow_menu_about(); +#endif // NV_ARTISTTOOLS +} + +void AppMainWindow::menu_opendoc() +{ + qDebug("%s", __FUNCTION__); + +#ifndef NV_ARTISTTOOLS + QString appDir = QApplication::applicationDirPath(); + QString docsFile = QFileInfo(appDir + "/../../docs/User_Guide/Nvidia Blast.chm").absoluteFilePath(); + + QUrl docsUrl = QUrl::fromLocalFile(docsFile); + QUrl url = QUrl::fromUserInput(QString("http://docs.nvidia.com/gameworks/content/artisttools/hairworks/index.html")); + QDesktopServices::openUrl(url); +#else + CoreLib::Inst()->AppMainWindow_menu_opendoc(); +#endif // NV_ARTISTTOOLS +} + +void AppMainWindow::shortcut_frameall() +{ + qDebug("ShortCut_F: frame all"); +} + +void AppMainWindow::shortcut_hud() +{ + Gamepad::ShowHideHud(); + qDebug("ShortCut_S: statistics on/off"); +} + +void AppMainWindow::shortcut_statistics() +{ + Gamepad::ShowHideStats(); + qDebug("ShortCut_S: statistics on/off"); +} + +void AppMainWindow::shortcut_reset() +{ + Gamepad::ResetAnimation(); +} + +void AppMainWindow::shortcut_pause() +{ + //_mainToolbar->on_btnPlayAnimation_clicked(); // this one has some delay + //qDebug("ShortCut_Space: play/pause simualtion"); + Gamepad::PlayPauseAnimation(); +} + +bool AppMainWindow::IsExpertMode() +{ + return _expertMode; +} + +void AppMainWindow::demo_next() +{ + Gamepad::DemoNext(); +} + +void AppMainWindow::demo_prev() +{ + Gamepad::DemoPrev(); +} + +void AppMainWindow::shortcut_escape() +{ + Gamepad::DemoEscape(); +} + +void AppMainWindow::shortcut_expert() +{ + qDebug("ShortCut_F: expert mode on/off"); + + _expertMode = !_expertMode; + bool mode = !_expertMode; + + ui.menuBar->setVisible(mode); + ui.dockWidget->setVisible(mode); + ui.dockOutputWindow->setVisible(mode); +#if USE_CURVE_EDITOR + ui.dockWidgetCurveEditor->setVisible(mode); +#endif + ui.statusBar->setVisible(mode); + +#ifndef NV_ARTISTTOOLS + if (_mainToolbar) + _mainToolbar->setVisible(mode); +#else + CoreLib::Inst()->AppMainWindow_shortcut_expert(mode); +#endif // NV_ARTISTTOOLS + + //bool bDemoMode = AppMainWindow::IsExpertMode(); + bool bMaxSized = AppMainWindow::Inst().isMaximized(); + if (!bMaxSized) + { + // resize before change to demo mode + AppMainWindow::Inst().showMaximized(); + } + + _d3dWidget->update(); + Gamepad::ShowProjectName(); +} + +void AppMainWindow::shortcut_output() +{ + ui.dockOutputWindow->show(); + _d3dWidget->update(); +} + +void AppMainWindow::shortcut_meshmat() +{ +} + +void AppMainWindow::shortcut_fitcamera() +{ + qDebug("ShortCut_Ctrl+F: fit camera"); + SimpleScene::Inst()->FitCamera(); +} + +#if USE_CURVE_EDITOR +void AppMainWindow::onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute) +{ +#ifndef NV_ARTISTTOOLS + SimpleScene::Inst()->GetFurCharacter().updateCurveAttribute(attribute); +#else + CoreLib::Inst()->AppMainWindow_onCurveAttributeChanged(attribute); +#endif // NV_ARTISTTOOLS +} + +void AppMainWindow::onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute) +{ +#ifndef NV_ARTISTTOOLS + SimpleScene::Inst()->GetFurCharacter().updateColorAttribute(attribute); + _graphicalMaterialPanel->updateValues(); +#else + CoreLib::Inst()->AppMainWindow_onColorAttributeChanged(attribute); +#endif // NV_ARTISTTOOLS +} + +void AppMainWindow::onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex) +{ +#ifndef NV_ARTISTTOOLS + SimpleScene::Inst()->GetFurCharacter().reloadColorAttributeTexture(attribute, reloadColorTex, selectedCtrlPntIndex); +#else + CoreLib::Inst()->AppMainWindow_onReloadColorAttributeTexture(attribute, reloadColorTex, selectedCtrlPntIndex); +#endif // NV_ARTISTTOOLS +} +#endif + +/* + Maya Scheme: + ALT + LMB -> Rotate + ALT + MMB -> Pan + ALT + RMB -> Zoom + + M-wheel -> Zoom + + 3dsMax Scheme: + ALT + MMB -> Rotate + N/A + MMB -> Pan + ALT + SHFT + MMB -> Zoom + + M-wheel -> Zoom +*/ + +void AppMainWindow::InitMouseSchemes() +{ + ShortCut alt_lmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier), Qt::MouseButtons(Qt::LeftButton)); + ShortCut alt_mmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier), Qt::MouseButtons(Qt::MiddleButton)); + ShortCut alt_rmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier), Qt::MouseButtons(Qt::RightButton)); + ShortCut non_mmb = qMakePair(Qt::KeyboardModifiers(Qt::NoModifier), Qt::MouseButtons(Qt::MiddleButton)); + ShortCut alt_shft_mmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier|Qt::ShiftModifier), Qt::MouseButtons(Qt::MiddleButton)); + + _mayaScheme[alt_lmb] = 'R'; + _mayaScheme[alt_mmb] = 'P'; + _mayaScheme[alt_rmb] = 'Z'; + + _maxScheme[alt_mmb] = 'R'; + _maxScheme[non_mmb] = 'P'; + _maxScheme[alt_shft_mmb] = 'Z'; +} + +char AppMainWindow::TestMouseScheme( Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons ) +{ + char op = TestDragCamera(modifiers, buttons); + + if (op != 0) + return op; + + if (modifiers == Qt::KeyboardModifier(Qt::ControlModifier)) + { + if (buttons == Qt::MouseButton(Qt::LeftButton)) + return 'L'; + else if (buttons == Qt::MouseButton(Qt::MiddleButton)) + return 'K'; + } + + if (modifiers == Qt::KeyboardModifier(Qt::ShiftModifier)) + return 'W'; + + return 0; +} + +char AppMainWindow::TestDragCamera( Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons ) +{ + if(modifiers != Qt::NoModifier && modifiers != Qt::AltModifier) return 0; + + ShortCut input = qMakePair(modifiers, buttons); + + int scheme = _navigationStyle; + + // !! MUST MATCH THE ORDER OF ITEMS IN 'cbNavigationStyle' + const int MAYA_SCHEME = 0; + const int MAX_SCHEME = 1; + if(scheme == MAYA_SCHEME) + { + auto itr = _mayaScheme.find(input); + if(itr != _mayaScheme.end()) return itr.value(); + } + else + { + auto itr = _maxScheme.find(input); + if(itr != _maxScheme.end()) return itr.value(); + } + return 0; +} + +QString AppMainWindow::OpenTextureFile(QString title) +{ + QString lastDir = _lastFilePath; + QString titleStr = "Open Texture File"; + if(!title.isEmpty()) + titleStr = title; + + QString fileName = QFileDialog::getOpenFileName(this, titleStr, lastDir, "Images (*.dds *.png *.bmp *.jpg *.tga)"); + if(!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + _lastFilePath = fileInfo.absoluteDir().absolutePath(); + } + + return fileName; +} + +void AppMainWindow::closeEvent (QCloseEvent *event) +{ + ViewerOutput::Inst().UnRegisterPrinter(_printer); + + if (1) + { +#if USE_CURVE_EDITOR + _curveEditorMainWindow->setParent(NULL); +#endif + event->accept(); + emit aboutToQuit(); + return; + } + if (SimpleScene::Inst()->IsProjectModified() || SimpleScene::Inst()->IsFurModified()) + { + QMessageBox::StandardButton resBtn = QMessageBox::warning( + this, tr("Blast Viewer"), + tr("Save changes?\n"), + QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes, + QMessageBox::Yes); + switch (resBtn) + { + case QMessageBox::Yes: +#ifndef NV_ARTISTTOOLS + if (!menu_saveHair()) + { + event->ignore(); + return; + } + if (!menu_saveProject()) + { + event->ignore(); + return; + } +#else + if (!CoreLib::Inst()->AppMainWindow_closeEvent(event)) + { + event->ignore(); + return; + } +#endif // NV_ARTISTTOOLS + break; + case QMessageBox::No: + break; + default: + event->ignore(); + return; + } + } + event->accept(); + emit aboutToQuit(); +} + +void AppMainWindow::updateMainToolbar() +{ +#ifndef NV_ARTISTTOOLS + if (_mainToolbar) + _mainToolbar->updateValues(); +#else + CoreLib::Inst()->AppMainWindow_updateMainToolbar(); +#endif // NV_ARTISTTOOLS +} + +#ifndef NV_ARTISTTOOLS +bool AppMainWindow::menu_openProject() +{ + QString lastDir = _lastFilePath; + QString fileName = QFileDialog::getOpenFileName(this, "Open Hair Project File", lastDir, "Hair Project File (*.furproj)"); + + return openProject(fileName); +} + +bool AppMainWindow::menu_saveProject() +{ + char message[1024]; + + std::string projectFilePath = GlobalSettings::Inst().getAbsoluteFilePath(); + if (projectFilePath != "") + { + if (SimpleScene::Inst()->SaveProject( + GlobalSettings::Inst().m_projectFileDir.c_str(), + GlobalSettings::Inst().m_projectFileName.c_str() + ) == false) + { + QMessageBox messageBox; + + sprintf(message, "Project file %s could not be saved!", (const char*)projectFilePath.c_str()); + messageBox.critical(0, "Error", message); + messageBox.setFixedSize(500, 200); + char message[1024]; + sprintf(message, "Failed to save project file(\"%s\")", (const char*)projectFilePath.c_str()); + viewer_err(message); + return false; + } + + sprintf(message, "Project file %s was saved.", (const char*)projectFilePath.c_str()); + + /* + QMessageBox messageBox; + messageBox.information(0, "Info", message); + messageBox.setFixedSize(500,200); + */ + viewer_msg(message); + return true; + } + else + { + return menu_saveProjectAs(); + } + return false; +} + +bool AppMainWindow::menu_saveProjectAs() +{ + char message[1024]; + + QString lastDir = _lastFilePath; + QString fileName = QFileDialog::getSaveFileName(this, "Save Hair Project File", lastDir, "Hair Project File (*.furproj)"); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file = fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->SaveProject(dir, file) == false) + { + QMessageBox messageBox; + sprintf(message, "Project file %s could not be saved!", (const char*)file); + messageBox.critical(0, "Error", message); + messageBox.setFixedSize(500, 200); + return false; + } + + sprintf(message, "Project file %s was saved.", (const char*)file); + + /* + QMessageBox messageBox; + messageBox.information(0, "Info", message); + messageBox.setFixedSize(500,200); + */ + + viewer_msg(message); + + _lastFilePath = fileInfo.absoluteDir().absolutePath(); + return true; + } + return false; +} + +bool AppMainWindow::menu_openHair() +{ + AppMainWindow& window = AppMainWindow::Inst(); + QString lastDir = window._lastFilePath; + QString fileName = QFileDialog::getOpenFileName(&window, "Open Hair File", lastDir, "Apex Hair File (*.apx;*.apb)"); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file = fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->GetFurCharacter().LoadHairAsset(dir, file) == false) + { + QMessageBox messageBox; + messageBox.critical(0, "Error", "File open error!"); + messageBox.setFixedSize(500, 200); + char message[1024]; + sprintf(message, "Failed to open hair file(\"%s\")", (const char*)file); + viewer_err(message); + return false; + } + + window._lastFilePath = fileInfo.absoluteDir().absolutePath(); + + window.updateUI(); + return true; + } + + return false; +} + +////////////////////////////////////////////////////////////////////////// +// event handlers +bool AppMainWindow::menu_importHair() +{ + AppMainWindow& window = AppMainWindow::Inst(); + QString lastDir = window._lastFilePath; + QString fileName = QFileDialog::getOpenFileName(&window, "Import Hair File", lastDir, "Apex Hair File (*.apx;*.apb)"); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file = fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->GetFurCharacter().ImportSelectedHairAsset(dir, file) == false) + { + QMessageBox messageBox; + messageBox.critical(0, "Error", "File open error!"); + messageBox.setFixedSize(500, 200); + char message[1024]; + sprintf(message, "Failed to import hair file(\"%s\")", (const char*)file); + viewer_err(message); + return false; + } + + window._lastFilePath = fileInfo.absoluteDir().absolutePath(); + + window.updateUI(); + return true; + } + return false; +} + + +bool AppMainWindow::menu_saveHair() +{ + return SimpleScene::Inst()->GetFurCharacter().SaveHairAsset(); +} + +bool AppMainWindow::menu_saveHairAs() +{ + AppMainWindow& window = AppMainWindow::Inst(); + QString lastDir = window._lastFilePath; + QString fileName = QFileDialog::getSaveFileName(&window, "Save as", lastDir, "Apex Hair File (*.apx;*.apb)"); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file = fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->GetFurCharacter().SaveHairAssetAs(dir, file)) + { + window.updateUI(); + } + + window._lastFilePath = fileInfo.absoluteDir().absolutePath(); + return true; + } + return false; +} + +bool AppMainWindow::menu_saveAllHairs() +{ + return SimpleScene::Inst()->GetFurCharacter().SaveAllHairs(); +} +#endif // NV_ARTISTTOOLS
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h new file mode 100644 index 0000000..4183fc2 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h @@ -0,0 +1,208 @@ +#ifndef APPMAINWINDOW_H +#define APPMAINWINDOW_H + +#include <QtWidgets/QMainWindow> +#include <QtWidgets/QProgressDialog> + +#include "ui_AppMainWindow.h" +#include "UIGlobal.h" + +class StyleMaterialPanel; +class AssetControlPanel; +class PhysicalMaterialPanel; +class GraphicalMaterialPanel; +class DisplayFurVisualizersPanel; +class GeneralAttributePanel; +class BlastToolbar; +class LodPanel; +class DisplayMeshesPanel; +class DisplayPreferencesPanel; +class DisplayScenePanel; +class DisplayLightPanel; +class DisplayMeshMaterialsPanel; + +#if USE_CURVE_EDITOR +namespace nvidia { +namespace CurveEditor { + +class CurveEditorMainWindow; +class CurveAttribute; +class ColorAttribute; + +} // namespace CurveEditor +} // namespace nvidia +#endif + +#if USE_MATERIAL_SET +class MaterialSetPanel; +#endif + +class D3DWidget; +class MsgPrinter; +class AppMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + AppMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); + ~AppMainWindow(); + + CORELIB_EXPORT static AppMainWindow& Inst(); + + CORELIB_EXPORT void InitUI(); + CORELIB_EXPORT void updateUI(); + CORELIB_EXPORT void updatePluginUI(); + + static bool IsExpertMode(); + + D3DWidget* GetRenderWidget() {return _d3dWidget;} + char TestMouseScheme(Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons); + + CORELIB_EXPORT QString OpenTextureFile(QString title = ""); + + void setNavigationStyle(int index) { _navigationStyle = index; } + int getNavigationStyle() { return _navigationStyle; } + + void closeEvent (QCloseEvent *event); + + CORELIB_EXPORT void startProgress(); + CORELIB_EXPORT void setProgressMaximum(int m); + CORELIB_EXPORT void setProgress(const char* label, int progress = -1); + CORELIB_EXPORT void endProgress(); + CORELIB_EXPORT void quit(); + + CORELIB_EXPORT void updateMainToolbar(); + CORELIB_EXPORT void processDragAndDrop(QString fname); + CORELIB_EXPORT bool openProject(QString fileName); + + CORELIB_EXPORT static void setConnectionMode(int); + + DisplayMeshesPanel* GetDisplayMeshesPanel() { return _displayMeshesPanel; } + DisplayPreferencesPanel* GetDisplayPreferencesPanel() { return _displayPreferencesPanel; } + DisplayScenePanel* GetDisplayScenePanel() { return _displayScenePanel; } + DisplayLightPanel* GetDisplayLightPanel() { return _displayLightPanel; } + + void removeBookmark(const QString& name); + void renameBookmark(const QString& oldName, const QString& newName); + +#if USE_CURVE_EDITOR + CORELIB_EXPORT nvidia::CurveEditor::CurveEditorMainWindow* GetCurveEditorMainWindow() { return _curveEditorMainWindow; } + CORELIB_EXPORT void UpdateCurveEditor(); + CORELIB_EXPORT void ShowCurveEditor(int paramId); +#endif + + inline QString GetFilePath() { return _lastFilePath; } +signals: + void aboutToQuit(); + + public slots: + CORELIB_EXPORT void menu_clearScene(); + CORELIB_EXPORT bool menu_openfbx(); + CORELIB_EXPORT void menu_addBookmark(); + CORELIB_EXPORT void menu_editBookmarks(); + CORELIB_EXPORT void menu_bookmarkTriggered(QAction* act); + CORELIB_EXPORT void menu_showOutput(); + CORELIB_EXPORT void menu_showAttributeEditor(); + CORELIB_EXPORT void menu_about(); + CORELIB_EXPORT void menu_opendoc(); + CORELIB_EXPORT void shortcut_frameall(); + CORELIB_EXPORT void shortcut_hud(); + CORELIB_EXPORT void shortcut_statistics(); + CORELIB_EXPORT void shortcut_pause(); + CORELIB_EXPORT void shortcut_reset(); + CORELIB_EXPORT void shortcut_escape(); + CORELIB_EXPORT void shortcut_expert(); + CORELIB_EXPORT void demo_next(); + CORELIB_EXPORT void demo_prev(); + CORELIB_EXPORT void shortcut_output(); + CORELIB_EXPORT void shortcut_meshmat(); + CORELIB_EXPORT void shortcut_fitcamera(); + +#if USE_CURVE_EDITOR + CORELIB_EXPORT void menu_showCurveEditor(); + CORELIB_EXPORT void onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute); + CORELIB_EXPORT void onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute); + CORELIB_EXPORT void onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex); +#endif + +private: + char TestDragCamera(Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons); + +public: + void InitMenuItems(); + void InitToolbar(); + void InitPluginTab(); + void InitMainTab(); + void InitMouseSchemes(); + void InitShortCuts(); + void updateBookmarkMenu(); + + Ui::AppMainWindowClass ui; + + D3DWidget* _d3dWidget; + QMenu* _bookmarksMenu; + + DisplayMeshesPanel* _displayMeshesPanel; + DisplayPreferencesPanel* _displayPreferencesPanel; + DisplayScenePanel* _displayScenePanel; + DisplayLightPanel* _displayLightPanel; + + +#if USE_CURVE_EDITOR + bool _curveEditorInitizlized; + nvidia::CurveEditor::CurveEditorMainWindow* _curveEditorMainWindow; +#endif + + typedef QPair<Qt::KeyboardModifiers, Qt::MouseButtons> ShortCut; + QMap<ShortCut, char> _mayaScheme; + QMap<ShortCut, char> _maxScheme; + QActionGroup* _bookmarkActionGroup; + QAction* _actionAddBookmark; + QAction* _actionEditBookmarks; + + QString _lastFilePath; + + int _navigationStyle; + + MsgPrinter* _printer; + + QProgressDialog _progressDialog; + + + static bool _expertMode; + + CORELIB_EXPORT static int _connectionMode; + +#ifndef NV_ARTISTTOOLS + BlastToolbar* GetMainToolbar() { return _mainToolbar; } + DisplayFurVisualizersPanel* GetFurVisualizersPanel() { return _displayFurVisualizersPanel; } + +public slots: + bool menu_openProject(); + bool menu_saveProject(); + bool menu_saveProjectAs(); + bool menu_openHair(); + bool menu_importHair(); + bool menu_saveHair(); + bool menu_saveHairAs(); + bool menu_saveAllHairs(); + +private: + BlastToolbar* _mainToolbar; + AssetControlPanel* _assetControlPanel; + GeneralAttributePanel* _generalAttributePanel; + DisplayFurVisualizersPanel* _displayFurVisualizersPanel; + StyleMaterialPanel* _styleMaterialPanel; + PhysicalMaterialPanel* _physicalMaterialPanel; + GraphicalMaterialPanel* _graphicalMaterialPanel; + LodPanel* _lodPanel; + DisplayMeshMaterialsPanel* _displayMeshMaterialsPanel; +#if USE_MATERIAL_SET + MaterialSetPanel* _materialSetPanel; +#endif +#endif // NV_ARTISTTOOLS + + bool m_bGizmoWithLocal; +}; + +#endif // APPMAINWINDOW_H diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.cpp new file mode 100644 index 0000000..445067a --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.cpp @@ -0,0 +1,106 @@ +#include "CameraBookmarksDialog.h" +#include "SimpleScene.h" +#include "AppMainWindow.h" +#include <QtWidgets/QMessageBox> + +CameraBookmarksDialog::CameraBookmarksDialog(QWidget *parent) + : QDialog(parent) +{ + ui.setupUi(this); + + ui.buttonBox->button(QDialogButtonBox::Ok)->setFixedWidth(64); + ui.buttonBox->button(QDialogButtonBox::Cancel)->setFixedWidth(64); + ui.buttonBox->button(QDialogButtonBox::Ok)->setFixedHeight(23); + ui.buttonBox->button(QDialogButtonBox::Cancel)->setFixedHeight(23); + setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint); + + QObject::connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); + QObject::connect(ui.buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); + + ui.editBookmarkName->setEnabled(false); + ui.btnRename->setEnabled(false); + ui.btnDelete->setEnabled(false); + + _fillListWidget(); +} + +CameraBookmarksDialog::~CameraBookmarksDialog() +{ + +} + +void CameraBookmarksDialog::on_listWidgetBookmarks_itemSelectionChanged() +{ + if (ui.listWidgetBookmarks->selectedItems().size() == 0) + { + ui.editBookmarkName->setEnabled(false); + ui.btnRename->setEnabled(false); + ui.btnDelete->setEnabled(false); + } + else + { + QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0); + ui.editBookmarkName->setEnabled(true); + ui.btnRename->setEnabled(true); + ui.btnDelete->setEnabled(true); + + ui.editBookmarkName->setText(item->text()); + } +} + +void CameraBookmarksDialog::on_editBookmarkName_textChanged(QString val) +{ + +} + +void CameraBookmarksDialog::on_btnRename_clicked() +{ + if (ui.editBookmarkName->text().isEmpty()) + { + QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0); + ui.editBookmarkName->setText(item->text()); + } + else + { + if (_isNameConflict(ui.editBookmarkName->text())) + { + QMessageBox::warning(this, tr("Warning"), tr("The new name is conflict with name of other camera bookmark!")); + return; + } + + QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0); + SimpleScene::Inst()->renameBookmark(item->text(), ui.editBookmarkName->text()); + AppMainWindow::Inst().renameBookmark(item->text(), ui.editBookmarkName->text()); + item->setText(ui.editBookmarkName->text()); + } + +} + +void CameraBookmarksDialog::on_btnDelete_clicked() +{ + QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0); + SimpleScene::Inst()->removeBookmark(item->text()); + AppMainWindow::Inst().removeBookmark(item->text()); + ui.listWidgetBookmarks->takeItem(ui.listWidgetBookmarks->row(item)); + delete item; + +} + +void CameraBookmarksDialog::_fillListWidget() +{ + QList<QString> bookmarks = SimpleScene::Inst()->getBookmarkNames(); + ui.listWidgetBookmarks->addItems(bookmarks); +} + +bool CameraBookmarksDialog::_isNameConflict(const QString& name) +{ + QList<QString> bookmarks = SimpleScene::Inst()->getBookmarkNames(); + int bookmarkCount = bookmarks.size(); + for (int i = 0; i < bookmarkCount; ++i) + { + if (bookmarks.at(i) == name) + return true; + } + + return false; +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.h new file mode 100644 index 0000000..13caa42 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.h @@ -0,0 +1,31 @@ +#ifndef CAMERABOOKMARKSDIALOG_H +#define CAMERABOOKMARKSDIALOG_H + +#include <QtWidgets/QDialog> +#include "ui_CameraBookmarksDialog.h" + +#include "corelib_global.h" + +class CameraBookmarksDialog : public QDialog +{ + Q_OBJECT + +public: + CameraBookmarksDialog(QWidget *parent = 0); + ~CameraBookmarksDialog(); + +private slots: +CORELIB_EXPORT void on_listWidgetBookmarks_itemSelectionChanged(); +CORELIB_EXPORT void on_editBookmarkName_textChanged(QString val); +CORELIB_EXPORT void on_btnRename_clicked(); +CORELIB_EXPORT void on_btnDelete_clicked(); + +private: + void _fillListWidget(); + bool _isNameConflict(const QString& name); + +private: + Ui::CameraBookmarksDialog ui; +}; + +#endif // CAMERABOOKMARKSDIALOG_H diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp new file mode 100644 index 0000000..69be706 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp @@ -0,0 +1,151 @@ +#include <QtGui/QResizeEvent> +#include <QtGui/QMouseEvent> +#include <QtCore/QTimer> +#include <QtCore/QMimeData> + +#include "D3DWidget.h" +#include "AppMainWindow.h" +#include "SimpleScene.h" + +D3DWidget::D3DWidget( QWidget* parent ) + : QWidget(parent, Qt::MSWindowsOwnDC) // Same settings as used in Qt's QGLWidget +{ + // same settings as used in QGLWidget to avoid 'white flickering' + setAttribute(Qt::WA_PaintOnScreen); + setAttribute(Qt::WA_NoSystemBackground); + + // to get rid of 'black flickering' + setAttribute(Qt::WA_OpaquePaintEvent, true); + + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + setSizePolicy(sizePolicy); + + _appWindow = qobject_cast<AppMainWindow*>(parent); + this->setAcceptDrops(true); + + setMouseTracking(true); +} + +void D3DWidget::dragEnterEvent(QDragEnterEvent *e) +{ + CoreLib::Inst()->D3DWidget_dragEnterEvent(e); + e->acceptProposedAction(); +} + +void D3DWidget::dragMoveEvent(QDragMoveEvent *e) +{ + CoreLib::Inst()->D3DWidget_dragMoveEvent(e); + e->acceptProposedAction(); +} + +void D3DWidget::dragLeaveEvent(QDragLeaveEvent *e) +{ + CoreLib::Inst()->D3DWidget_dragLeaveEvent(e); + //e->acceptProposedAction(); +} + +void D3DWidget::dropEvent(QDropEvent *e) +{ + CoreLib::Inst()->D3DWidget_dropEvent(e); + + const QMimeData* data = e->mimeData(); + QString name = data->objectName(); + + bool hasUrls = data->hasUrls(); + if (!hasUrls) + return; + + QList<QUrl> urlList = data->urls(); + QString text; + for (int i = 0; i < urlList.size() && i < 32; ++i) { + QString url = urlList.at(i).toLocalFile(); + text += url; + } + + e->acceptProposedAction(); + + AppMainWindow::Inst().processDragAndDrop(text); +} + +void D3DWidget::paintEvent( QPaintEvent* e ) +{ + CoreLib::Inst()->D3DWidget_paintEvent(e); + + SimpleScene::Inst()->Draw(); +} + +void D3DWidget::Shutdown() +{ + SimpleScene::Inst()->Shutdown(); +} + +void D3DWidget::Timeout() +{ + SimpleScene::Inst()->Timeout(); +} + +void D3DWidget::resizeEvent( QResizeEvent* e ) +{ + int w = e->size().width(); + int h = e->size().height(); + // resize calls D3D11RenderWindow::Resize + SimpleScene::Inst()->Resize(w,h); + // D3DWidget_resizeEvent calls resize in DeviceManager + CoreLib::Inst()->D3DWidget_resizeEvent(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()); + + 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(); +} + +void D3DWidget::mousePressEvent( QMouseEvent* e ) +{ + CoreLib::Inst()->D3DWidget_mousePressEvent(e); + + atcore_float2 pos = gfsdk_makeFloat2(e->x(), e->y()); + SimpleScene::Inst()->onMouseDown(pos); +} + +void D3DWidget::mouseReleaseEvent( QMouseEvent* e ) +{ + CoreLib::Inst()->D3DWidget_mouseReleaseEvent(e); + + atcore_float2 pos = gfsdk_makeFloat2(e->x(), e->y()); + SimpleScene::Inst()->onMouseUp(pos); +} + +void D3DWidget::keyPressEvent( QKeyEvent* e ) +{ + CoreLib::Inst()->D3DWidget_keyPressEvent(e); +} + +void D3DWidget::keyReleaseEvent( QKeyEvent* e ) +{ + CoreLib::Inst()->D3DWidget_keyReleaseEvent(e); +} + +void D3DWidget::contextMenuEvent(QContextMenuEvent *e) +{ + CoreLib::Inst()->D3DWidget_contextMenuEvent(e); +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/D3DWidget.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/D3DWidget.h new file mode 100644 index 0000000..0de9a1e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/D3DWidget.h @@ -0,0 +1,51 @@ +#ifndef D3DWidget_h__ +#define D3DWidget_h__ + +#include <QtWidgets/QWidget> +#include "Nv.h" + +#include "corelib_global.h" + +class AppMainWindow; +class D3DWidget : public QWidget +{ + Q_OBJECT + +public: + + D3DWidget(QWidget* parent); + virtual ~D3DWidget(){} + +signals: + void DropSignal(); + +public slots: +CORELIB_EXPORT void Timeout(); +CORELIB_EXPORT void Shutdown(); + +protected: + // return NULL to ignore system painter + virtual QPaintEngine *paintEngine() const { return NV_NULL; } + + // QWidget events + virtual void resizeEvent(QResizeEvent* e); + virtual void paintEvent(QPaintEvent* e); + virtual void mousePressEvent(QMouseEvent* e); + virtual void mouseReleaseEvent(QMouseEvent* e); + virtual void mouseMoveEvent(QMouseEvent* e); + virtual void wheelEvent ( QWheelEvent * e); + virtual void keyPressEvent(QKeyEvent* e); + virtual void keyReleaseEvent(QKeyEvent* e); + + virtual void dragEnterEvent(QDragEnterEvent *e); + virtual void dragMoveEvent(QDragMoveEvent *e); + virtual void dragLeaveEvent(QDragLeaveEvent *e); + virtual void dropEvent(QDropEvent *e); + + virtual void contextMenuEvent(QContextMenuEvent *e); + +private: + AppMainWindow* _appWindow; +}; + +#endif // D3DWidget_h__ diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.cpp new file mode 100644 index 0000000..ec267a3 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.cpp @@ -0,0 +1,263 @@ +#include "AppMainWindow.h" +#include "DisplayLightPanel.h" + +#include "Light.h" +#include "GlobalSettings.h" + +#include <QtWidgets/QColorDialog> +#include <QtCore/QFileInfo> + +DisplayLightPanel::DisplayLightPanel(QWidget* parent) + : + QWidget(parent) +{ + ui.setupUi(this); + _isUpdatingUI = false; + + ConfigSpinBox<SlideSpinBoxF>(ui.spinLightDistance, 0.0, 1000.0, 0.1); + ConfigSpinBox<SlideSpinBoxF>(ui.spinLightIntensity, 0.0, 5.0, 0.01); + + ui.btnLightColorTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + ui.btnLightColorTex->setIconSize(QSize(12,12)); + ui.btnLightColorTexReload->setIcon(QIcon(":/AppMainWindow/images/Refresh_icon.png")); + ui.btnLightColorTexClear->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); + + connect(ui.listSelectedLight, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged())); +} + +void DisplayLightPanel::onListSelectionChanged() +{ + if (_isUpdatingUI) + return; + + int numSelected = ui.listSelectedLight->selectedItems().count(); + + // change selection only when there is something selected + if (numSelected > 0) + { + int numItems = ui.listSelectedLight->count(); + { + for (int i = 0; i < numItems; i++) + { + bool selected = ui.listSelectedLight->item(i)->isSelected(); + Light::GetLight(i)->m_selected = selected; + } + } + } + + updateUI(); +} + +void DisplayLightPanel::on_cbShadowMapResolution_currentIndexChanged( int index ) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->SetShadowMapResolution(index); + } +} + +void DisplayLightPanel::on_btnLightUseShadow_stateChanged(int state) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->m_useShadows = state; + } +} + +void DisplayLightPanel::on_btnVisualizeLight_stateChanged(int state) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->m_visualize = state; + } +} + +void DisplayLightPanel::on_btnLightEnable_stateChanged(int state) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->m_enable = state; + } +} + +void DisplayLightPanel::on_btnLinkLightEnable_stateChanged(int state) +{ + Light::SetLinkLightOption(state != 0 ? true : false); +} + +void DisplayLightPanel::on_spinLightDistance_valueChanged(double v) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->SetDistance(v); + } +} + +void DisplayLightPanel::on_spinLightIntensity_valueChanged(double v) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->m_intensity = v; + } +} + +void DisplayLightPanel::on_btnVisualizeShadowMap_stateChanged(int state) +{ + GlobalSettings::Inst().m_visualizeShadowMap = state; +} + +void DisplayLightPanel::setButtonColor(QPushButton *button, float r, float g, float b) +{ + QColor specColor; + specColor.setRgbF(r,g,b); + QString specBtnStyle = QString("background-color: rgb(%1,%2,%3);") + .arg(specColor.red()) + .arg(specColor.green()) + .arg(specColor.blue()); + button->setStyleSheet(specBtnStyle); +} + + +static bool getNewColor(atcore_float3& color) +{ + QColor currentColor; + currentColor.setRgbF(color.x, color.y, color.z); + + QColor newColor = QColorDialog::getColor(currentColor, NV_NULL); + if(newColor.isValid()) + { + qreal r,g,b; + newColor.getRgbF(&r, &g, &b); + + color.x = r; + color.y = g; + color.z = b; + return true; + } + + return false; +} + +void DisplayLightPanel::on_btnLightColor_clicked() +{ + Light* pLight = Light::GetFirstSelectedLight(); + + atcore_float3 color = pLight->m_color; + + if (getNewColor(color)) + setButtonColor(ui.btnLightColor, color.x, color.y, color.z); + + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->m_color = color; + } +} + +inline void SetTextureIcon(QPushButton* pButton, bool enabled) +{ + if (enabled) + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + else + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png")); +} + +void DisplayLightPanel::on_btnLightColorTex_clicked() +{ + QString texName = AppMainWindow::Inst().OpenTextureFile(); + QFileInfo fileInfo(texName); + QByteArray ba = fileInfo.absoluteFilePath().toLocal8Bit(); + + if (Light::SetEnvTextureFromFilePath((const char*)ba)) + SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty()); +} + +void DisplayLightPanel::on_btnLightColorTexReload_clicked() +{ + std::string path = Light::GetEnvTextureFilePath(); + if (Light::SetEnvTextureFromFilePath(path.c_str())) + SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty()); +} + +void DisplayLightPanel::on_btnLightColorTexClear_clicked() +{ + Light::SetEnvTextureFromFilePath(nullptr); + SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty()); +} + +void DisplayLightPanel::updateUI() +{ + Light* pLight = Light::GetFirstSelectedLight(); + if (!pLight) + return; + + atcore_float3& color = pLight->m_color; + setButtonColor(ui.btnLightColor, color.x, color.y, color.z); + + ui.btnVisualizeLight->setChecked(pLight->m_visualize); + + ui.spinLightDistance->setValue(pLight->GetDistance()); + ui.spinLightIntensity->setValue(pLight->m_intensity); + + ui.btnLightUseShadow->setChecked(pLight->m_useShadows); + ui.btnLightEnable->setChecked(pLight->m_enable); + + ui.btnVisualizeShadowMap->setChecked(GlobalSettings::Inst().m_visualizeShadowMap); + + ui.cbShadowMapResolution->setCurrentIndex(pLight->m_shadowMapResolutionIndex); + + ui.btnLinkLightEnable->setChecked(Light::GetLinkLightOption()); + + SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty()); +} + +void DisplayLightPanel::updateValues() +{ + _isUpdatingUI = true; + + ui.listSelectedLight->clear(); + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight) + continue; + + const char* lightName = pLight->m_name.c_str(); + bool selected = pLight->m_selected; + + ui.listSelectedLight->addItem(lightName); + ui.listSelectedLight->item(i)->setSelected(selected); + } + ui.listSelectedLight->setSelectionMode(QAbstractItemView::ExtendedSelection); + + updateUI(); + + _isUpdatingUI = false; +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.h new file mode 100644 index 0000000..e22eae4 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.h @@ -0,0 +1,47 @@ +#ifndef DisplayLightPanel_h__ +#define DisplayLightPanel_h__ + +#include <QtWidgets/QWidget> +#include "ui_DisplayLightPanel.h" + +#include "corelib_global.h" + +class DisplayLightPanel : public QWidget +{ + Q_OBJECT + +public: + DisplayLightPanel(QWidget* parent); + + public: + CORELIB_EXPORT void updateValues(); + + public slots: + CORELIB_EXPORT void onListSelectionChanged(); + + CORELIB_EXPORT void on_spinLightDistance_valueChanged(double v); + CORELIB_EXPORT void on_spinLightIntensity_valueChanged(double v); + + CORELIB_EXPORT void on_btnLightUseShadow_stateChanged(int state); + CORELIB_EXPORT void on_btnVisualizeLight_stateChanged(int state); + CORELIB_EXPORT void on_btnLightEnable_stateChanged(int state); + CORELIB_EXPORT void on_btnLinkLightEnable_stateChanged(int state); + + CORELIB_EXPORT void on_btnLightColor_clicked(); + CORELIB_EXPORT void on_btnLightColorTex_clicked(); + CORELIB_EXPORT void on_btnLightColorTexReload_clicked(); + CORELIB_EXPORT void on_btnLightColorTexClear_clicked(); + + CORELIB_EXPORT void on_btnVisualizeShadowMap_stateChanged(int state); + + CORELIB_EXPORT void on_cbShadowMapResolution_currentIndexChanged(int index); + +private: + Ui::DisplayLightPanel ui; + bool _isUpdatingUI; + void setButtonColor(QPushButton *button, float r, float g, float b); + + void updateUI(); +}; + +#endif diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.cpp new file mode 100644 index 0000000..67ca141 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.cpp @@ -0,0 +1,177 @@ +#include "DisplayMeshesPanel.h" + +#include <QtWidgets/QGridLayout> +#include <QtWidgets/QHBoxLayout> +#include <QtWidgets/QPushButton> + +#include "AppMainWindow.h" + +#include "SimpleScene.h" + +#ifndef NV_ARTISTTOOLS +#include "FurCharacter.h" +#else +#endif // NV_ARTISTTOOLS + +////////////////////////////////////////////////////////////////////////// +// DisplayMeshItem + +StateViewItem::StateViewItem( QWidget* parent, unsigned int id, MeshViewState view /*= VS_VISIABLE*/ ) + : _id(id) +{ + static QIcon iconVisible(":/AppMainWindow/images/visibilityToggle_visible.png"); + static QIcon iconNotVisible(":/AppMainWindow/images/visibilityToggle_notVisible.png"); + + _parent = qobject_cast<DisplayMeshesPanel*>(parent); + + _layout = new QHBoxLayout(this); + _layout->setObjectName(QString::fromUtf8("boxLayout")); + _layout->setMargin(0); + + this->setLayout(_layout); + + _btn = new QPushButton(this); + + _btn->setObjectName(QString::fromUtf8("btnToggleView")); + QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Fixed); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(_btn->sizePolicy().hasHeightForWidth()); + _btn->setSizePolicy(sizePolicy1); + _btn->setMinimumSize(QSize(16, 16)); + _btn->setMaximumSize(QSize(16, 16)); + _btn->setAutoFillBackground(false); + _btn->setCheckable(true); + _btn->setChecked(view == VS_VISIABLE); + _btn->setIcon( (view == VS_VISIABLE) ? iconVisible : iconNotVisible); + + _layout->addWidget(_btn); + + _spacer = new QSpacerItem(20, 40, QSizePolicy::Expanding, QSizePolicy::Ignored); + _layout->addItem(_spacer); + + QMetaObject::connectSlotsByName(this); +} + +void StateViewItem::on_btnToggleView_clicked() +{ + static QIcon iconVisible(":/AppMainWindow/images/visibilityToggle_visible.png"); + static QIcon iconNotVisible(":/AppMainWindow/images/visibilityToggle_notVisible.png"); + + bool bVis = _btn->isChecked(); + _btn->setIcon(bVis ? iconVisible : iconNotVisible); + + _parent->EmitToggleSignal(_id, bVis); + + qDebug("%s", __FUNCTION__); +} + + +////////////////////////////////////////////////////////////////////////// +DisplayMeshesPanel::DisplayMeshesPanel( QWidget* parent ) + :QFrame(parent) +{ + _layout = new QGridLayout(this); + _layout->setObjectName(QString::fromUtf8("gridLayout")); + + this->setLayout(_layout); + + //QString styleSheet = + // "QPushButton#btnToggleView:checked {border:2px solid gray; background:rgb(118,180,0);} \n" \ + // "QPushButton#btnToggleView:pressed {border:2px solid gray; background:rgb(118,180,0);}"; + //setStyleSheet(styleSheet); +} + +///////////////////////////////////////////////////////////////////////////////////////// +void DisplayMeshesPanel::updateValues() +{ + ClearItems(); + +#ifndef NV_ARTISTTOOLS + FurCharacter& character = SimpleScene::Inst()->GetFurCharacter(); + int nMesh = character.GetMeshCount(); + for (int i = 0; i < nMesh; ++i) + { + bool used = character.GetMeshUsed(i); + if (!used) + continue; + + const char* name = character.GetMeshName(i); + bool visible = character.GetMeshVisible(i); + + StateViewItem::MeshViewState visState = visible ? StateViewItem::VS_VISIABLE : StateViewItem::VS_INVISIBLE; + + AddMeshItem(QString(name), i, visState); + } +#else + CoreLib::Inst()->DisplayMeshesPanel_updateValues(); +#endif // NV_ARTISTTOOLS +} + +///////////////////////////////////////////////////////////////////////////////////////// +void DisplayMeshesPanel::AddMeshItem( QString name, unsigned int id, StateViewItem::MeshViewState view ) +{ + StateViewItem* item; + item = new StateViewItem(this, id, view); + + QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Fixed); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + + QLabel* label = new QLabel(name, this); + label->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + label->setSizePolicy(sizePolicy1); + + int row = _items.size(); + _layout->addWidget(label, row, 0, 1, 1); + + _layout->addWidget(item, row, 1, 1, 1); + + Q_ASSERT(_items.find(id) == _items.end()); + + ItemUI ui; + ui.label = label; + ui.viewItem = item; + _items[id] = ui; +} + +///////////////////////////////////////////////////////////////////////////////////////// +void DisplayMeshesPanel::EmitToggleSignal( unsigned int id, bool visible ) +{ + emit MeshViewSignal(id, visible); + +#ifndef NV_ARTISTTOOLS + FurCharacter& character = SimpleScene::Inst()->GetFurCharacter(); + character.SetMeshVisible(id, visible); +#else + CoreLib::Inst()->DisplayMeshesPanel_EmitToggleSignal(id, visible); +#endif // NV_ARTISTTOOLS +} + +///////////////////////////////////////////////////////////////////////////////////////// +void DisplayMeshesPanel::RemoveMeshItem( unsigned int id ) +{ + if(_items.find(id) != _items.end()) + { + ItemUI ui = _items[id]; + delete ui.label; + delete ui.viewItem; + _items.remove(id); + } + else + { + Q_ASSERT("Mesh item doesn't exist!!"); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +void DisplayMeshesPanel::ClearItems() +{ + Q_FOREACH(ItemUI ui, _items) + { + delete ui.label; + delete ui.viewItem; + } + + _items.clear(); +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.h new file mode 100644 index 0000000..ecc5b49 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.h @@ -0,0 +1,80 @@ +#ifndef DisplayMeshesPanel_h__ +#define DisplayMeshesPanel_h__ + +#include <QtWidgets/QFrame> +#include <QtCore/QMap> +#ifndef NV_ARTISTTOOLS +#include "ui_LodPanel.h" +#else +#include <QtWidgets/QLabel> +#endif // NV_ARTISTTOOLS + +#include "corelib_global.h" + +class QPushButton; +class QGridLayout; +class QHBoxLayout; +class QSpacerItem; + +class DisplayMeshesPanel; +class StateViewItem : public QWidget +{ + Q_OBJECT + +public: + enum MeshViewState + { + VS_INVISIBLE = 0, + VS_VISIABLE = 1, + }; + + StateViewItem(QWidget* parent, unsigned int id, MeshViewState view = VS_VISIABLE); + + public slots: + CORELIB_EXPORT void on_btnToggleView_clicked(); + +private: + unsigned int _id; + + QHBoxLayout* _layout; + QPushButton* _btn; + QSpacerItem* _spacer; + + DisplayMeshesPanel* _parent; +}; + +class DisplayMeshesPanel : public QFrame +{ + Q_OBJECT + +public: + DisplayMeshesPanel(QWidget* parent); + + void updateValues(); + + // client code should make sure the 'id' is unique! + CORELIB_EXPORT void AddMeshItem(QString name, unsigned int id, StateViewItem::MeshViewState view = StateViewItem::VS_VISIABLE); + CORELIB_EXPORT void RemoveMeshItem(unsigned int id); + CORELIB_EXPORT void ClearItems(); + +signals: + void MeshViewSignal(unsigned int id, bool visible); + +protected: + virtual void EmitToggleSignal(unsigned int id, bool visible); + +private: + QGridLayout* _layout; + + struct ItemUI + { + StateViewItem* viewItem; + QLabel* label; + }; + + QMap<unsigned int, ItemUI> _items; + + friend class StateViewItem; +}; + +#endif // GraphicalMaterialPanel_h__ diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp new file mode 100644 index 0000000..fe4b808 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp @@ -0,0 +1,906 @@ +#include "DisplayPreferencesPanel.h" + +#include "AppMainWindow.h" + +#include "SimpleScene.h" +#include "GlobalSettings.h" +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QMessageBox> +#include <QtWidgets/QFileDialog> + +#include "PlaylistParams.h" +//#include <Nv/Blast/NvHairCommon.h> +#include "NvParameterized.h" +#include "XmlSerializer.h" +#include "NsFileBuffer.h" +#include "NvTraits.h" +#include "NsMemoryBuffer.h" +#include "ViewerOutput.h" +#include "Settings.h" + +#include "Gamepad.h" + +const QString sPlaylistExt = "plist"; +bool bRefreshingComboBox = false; + +DisplayPreferencesPanel::DisplayPreferencesPanel(QWidget* parent) + : + QWidget(parent) + , idxCurrentPlaylist(-1) + , idxCurrentProj(-1) + , playlistProjectsDirty(false) +{ + ui.setupUi(this); + + ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + ui.btnBackgroundTex->setIconSize(QSize(12,12)); + ui.btnBackgroundTexClear->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); + + ui.btnPlaylistsRename->setIcon(QIcon(":/AppMainWindow/images/EditWrench.png")); + ui.btnPlaylistsAdd->setIcon(QIcon(":/AppMainWindow/images/Add.png")); + ui.btnPlaylistsReload->setIcon(QIcon(":/AppMainWindow/images/refreshReload.png")); + ui.btnPlaylistsRemove->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); + + ui.btnPlaylistAddProj->setIcon(QIcon(":/AppMainWindow/images/Add.png")); + ui.btnPlaylistRemoveProj->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); + ui.btnPlaylistProjGoUp->setIcon(QIcon(":/AppMainWindow/images/Up.png")); + ui.btnPlaylistProjGoDown->setIcon(QIcon(":/AppMainWindow/images/Down.png")); + + ui.btnPlaylistsPlay->setIcon(QIcon(":/AppMainWindow/images/playlist.png")); + + //QObject::connect(ui.listWidgetPlaylist, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(playlistDoubleClicked(QListWidgetItem*))); + + ConfigSpinBox<SlideSpinBoxF>(ui.spinCameraFOV, 5.0, 180.0, 1.0); +} + +DisplayPreferencesPanel::~DisplayPreferencesPanel() +{ +} + +void DisplayPreferencesPanel::on_spinRenderPlayRateFPS_valueChanged(double v) +{ + GlobalSettings::Inst().setRenderFps((float)v); +} + +void DisplayPreferencesPanel::on_spinSimulationRateFPS_valueChanged(double v) +{ + GlobalSettings::Inst().setSimulationFps((float)v); +} + +void DisplayPreferencesPanel::on_spinCameraFOV_valueChanged(double v) +{ + GlobalSettings::Inst().m_fovAngle = v; +} + +void DisplayPreferencesPanel::on_cbAntialiasing_currentIndexChanged( int index ) +{ + GlobalSettings::Inst().m_msaaOption = index; +} + +void DisplayPreferencesPanel::on_cbUpAxis_currentIndexChanged( int index ) +{ + switch (index) + { + case 0: // y up + SimpleScene::Inst()->ResetUpDir(false); + break; + case 1: // z up + SimpleScene::Inst()->ResetUpDir(true); + break; + } + SimpleScene::Inst()->SetProjectModified(true); +} + +void DisplayPreferencesPanel::on_cbHandedness_currentIndexChanged( int index ) +{ + switch (index) + { + case 0: // rhs + SimpleScene::Inst()->ResetLhs(false); + break; + case 1: // lhs + SimpleScene::Inst()->ResetLhs(true); + break; + } + SimpleScene::Inst()->SetProjectModified(true); +} + +void DisplayPreferencesPanel::on_cbSceneUnit_currentIndexChanged( int index ) +{ + GlobalSettings::Inst().m_sceneUnitIndex = index; +} + +void DisplayPreferencesPanel::on_cbNavigationStyle_currentIndexChanged( int index ) +{ + AppMainWindow::Inst().setNavigationStyle(index); +} + +void DisplayPreferencesPanel::on_btnBackgroundTex_clicked() +{ + if (SimpleScene::Inst()->LoadBackgroundTextureFile()) + ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png")); + else + ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + + updateValues(); + SimpleScene::Inst()->SetProjectModified(true); +} + +void DisplayPreferencesPanel::on_btnBackgroundTexClear_clicked() +{ + SimpleScene::Inst()->ClearBackgroundTexture(); + ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + updateValues(); +} + +void DisplayPreferencesPanel::updateValues() +{ + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + ui.spinRenderPlayRateFPS->setValue(globalSettings.m_renderFps); + ui.spinSimulationRateFPS->setValue(globalSettings.m_simulationFps); + ui.cbUpAxis->setCurrentIndex(globalSettings.m_zup); + ui.cbHandedness->setCurrentIndex(globalSettings.m_lhs); + ui.spinCameraFOV->setValue(globalSettings.m_fovAngle); + ui.cbSceneUnit->setCurrentIndex(globalSettings.m_sceneUnitIndex); + ui.cbNavigationStyle->setCurrentIndex(AppMainWindow::Inst().getNavigationStyle()); + ui.cbAntialiasing->setCurrentIndex(globalSettings.m_msaaOption); + + savePlaylistProjects(); + reloadComboxBoxPlaylists(); + + //// sync playlist to gamepad + //static bool bOnce = true; + //if (bOnce) + //{ + // bOnce = false; + // assignPlayPlaylistToGamepad(0); + //} +} + +void DisplayPreferencesPanel::reloadComboxBoxPlaylists() +{ + playlistsLoader.loadPlaylistsFromMediaPath(); + // set playlist combo box + //idxCurrentPlaylist = ui.cbPlaylists->currentIndex(); + bRefreshingComboBox = true; + ui.cbPlaylists->clear(); + int count = playlistsLoader.playlists.size(); + for (int i = 0; i < count; ++i) + { + QFileInfo& fi = playlistsLoader.playlists[i]; + std::string fn = fi.fileName().toUtf8().data(); + ui.cbPlaylists->addItem(fi.fileName()); + } + bRefreshingComboBox = false; + if (idxCurrentPlaylist > count || idxCurrentPlaylist < 0) + idxCurrentPlaylist = 0; + + ui.cbPlaylists->setCurrentIndex(idxCurrentPlaylist); + + // refresh project list + reloadListboxPorjectsFromPlayist(); +} + +void DisplayPreferencesPanel::runDemoCommandline() +{ + // run demos if command line asks + static bool once = true; + if (once) + { + once = false; + std::string demoPlaylist = AppSettings::Inst().GetOptionValue("User/FurDemoPlaylist")->Value.String; + if (demoPlaylist.size() > 1) + { + QString demoList = QString(demoPlaylist.c_str()).toUpper(); + int count = playlistsLoader.playlists.size(); + for (int i = 0; i < count; ++i) + { + QFileInfo& fi = playlistsLoader.playlists[i]; + QString fname = fi.fileName().toUpper(); + if (fname == demoList) + { + idxCurrentPlaylist = i; + ui.cbPlaylists->setCurrentIndex(idxCurrentPlaylist); + playPlaylist(idxCurrentPlaylist); + return; + } + } + viewer_msg(QString("Cannot find playlist, " + demoList).toUtf8().data()); + } + } +} + +void DisplayPreferencesPanel::reloadListboxPorjectsFromPlayist() +{ + int count = playlistsLoader.getProjectsInPlaylist(idxCurrentPlaylist, playlistProjects); + refreshListboxPorjects(); +} + +void DisplayPreferencesPanel::savePlaylistProjects() +{ + if (playlistProjectsDirty) + { + playlistsLoader.saveProjectsInPlaylist(idxCurrentPlaylist, playlistProjects); + playlistProjectsDirty = false; + } +} + +void DisplayPreferencesPanel::refreshListboxPorjects() +{ + int count = playlistProjects.size(); + ui.listWidgetPlaylist->clear(); + ui.listWidgetPlaylist->setSortingEnabled(false); + ui.listWidgetPlaylist->setSelectionMode(QAbstractItemView::SingleSelection); + QStringList tips; + for (int i = 0; i < count; ++i) + { + QString fullName = playlistsLoader.convertToAbsoluteFilePath(playlistProjects[i]); + QFileInfo fi(fullName); + tips.append(fi.absoluteFilePath()); + std::string tmp = fi.absoluteFilePath().toUtf8().data(); + ui.listWidgetPlaylist->addItem(fi.fileName()); + } + ui.listWidgetPlaylist->setTips(tips); + if (idxCurrentProj > count || idxCurrentProj < 0) + { + idxCurrentProj = 0; + } + ui.listWidgetPlaylist->setCurrentRow(idxCurrentProj); +} + +void DisplayPreferencesPanel::SelectPlayList(QString& name) +{ + QString newName = name.toUpper(); + int count = playlistsLoader.playlists.size(); + for (int i = 0; i < count; ++i) + { + QFileInfo& fi = playlistsLoader.playlists[i]; + if (fi.baseName().toUpper() == newName) + { + ui.cbPlaylists->setCurrentIndex(i); + break; + } + } +} + +void DisplayPreferencesPanel::on_cbPlaylists_currentIndexChanged(int index) +{ + savePlaylistProjects(); + if (!bRefreshingComboBox) + { + idxCurrentPlaylist = ui.cbPlaylists->currentIndex(); + reloadListboxPorjectsFromPlayist(); + } +} + +void DisplayPreferencesPanel::SelectProject(QString& name) +{ + QString newName = name.toUpper(); + std::string strNew = newName.toUtf8().data(); + int count = playlistProjects.size(); + for (int i = 0; i < count; ++i) + { + QString& str = playlistProjects[i]; + //QFileInfo fi(str); + //std::string stmp = fi.absoluteFilePath().toUtf8().data(); + //if (fi.absoluteFilePath().toUpper() == newName) + if (str.toUpper() == newName) + { + ui.listWidgetPlaylist->setCurrentRow(i); + break; + } + } +} + +void DisplayPreferencesPanel::on_listWidgetPlaylist_itemSelectionChanged() +{ + idxCurrentProj = ui.listWidgetPlaylist->currentRow(); +} + +void DisplayPreferencesPanel::on_listWidgetPlaylist_itemDoubleClicked(QListWidgetItem* pItem) +{ + idxCurrentProj = ui.listWidgetPlaylist->currentRow(); + if (idxCurrentProj < 0) + return; + QString fn = playlistProjects[idxCurrentProj]; + QString fullname = PlaylistsLoader::convertToAbsoluteFilePath(fn); + AppMainWindow::Inst().openProject(fullname); + char msg[1024]; + sprintf(msg, "Blast Viewer - %s", fullname.toUtf8().data()); + AppMainWindow::Inst().setWindowTitle(msg); +} + +void DisplayPreferencesPanel::on_btnPlaylistsRename_clicked() +{ + idxCurrentPlaylist = ui.cbPlaylists->currentIndex(); + if (idxCurrentPlaylist < 0) + return; + + QFileInfo& fi = playlistsLoader.playlists[idxCurrentPlaylist]; + bool isOK = false; + QString newBaseName = QInputDialog::getText(NULL, "Rename Playlist - " + fi.fileName(), + "Input a new name for the playlist, " + fi.fileName(), QLineEdit::Normal, + fi.baseName(), &isOK); + if (isOK) + { + bool ok = playlistsLoader.rename(idxCurrentPlaylist, newBaseName); + if (ok) + { + reloadComboxBoxPlaylists(); + SelectPlayList(newBaseName); + } + else + { + QMessageBox::warning(this, "Fail to rename a playlist", + "Fail to rename a playlist. The failure could relate to name duplication or hardware failure.", + QMessageBox::Close); + } + } +} + +void DisplayPreferencesPanel::on_btnPlaylistsAdd_clicked() +{ + savePlaylistProjects(); + + bool isOK = false; + QString sInput = QInputDialog::getText(NULL, "Create New Playlist", "Input a name for the new playlist.", QLineEdit::Normal, "", &isOK); + if (isOK) + { + QString newName = sInput.trimmed(); + bool ok = playlistsLoader.add(newName); + if (ok) + { + reloadComboxBoxPlaylists(); + // select the new one + SelectPlayList(newName); + } + else + { + QMessageBox::warning(this, "Fail to add new playlist", + "Fail to add new playlist. The failure could relate to name duplication or hardware failure.", + QMessageBox::Close); + } + } +} + +void DisplayPreferencesPanel::on_btnPlaylistsReload_clicked() +{ + savePlaylistProjects(); + reloadComboxBoxPlaylists(); +} + +void DisplayPreferencesPanel::on_btnPlaylistsRemove_clicked() +{ + savePlaylistProjects(); + idxCurrentPlaylist = ui.cbPlaylists->currentIndex(); + if (idxCurrentPlaylist < 0) + return; + + bool ok = playlistsLoader.remove(idxCurrentPlaylist); + if (ok) + { + reloadComboxBoxPlaylists(); + } + else + { + QMessageBox::warning(this, "Fail to remove a playlist", + "Fail to remove a playlist. The failure could relate to hardware.", + QMessageBox::Close); + } +} + +void DisplayPreferencesPanel::on_btnPlaylistAddProj_clicked() +{ + static QString lastPath; + if (lastPath.size() < 1) + { + lastPath = PlaylistsLoader::mediaPath; + } + QString fileNameInput = QFileDialog::getOpenFileName(this, "Open Hair Project File", lastPath, "Hair Project File (*.furproj)"); + if (!QFile::exists(fileNameInput)) + return; + std::string tmp = fileNameInput.toUtf8().data(); + QString fileName = PlaylistsLoader::convertToSaveingFilePath(fileNameInput); + if (fileName.size() < 1) + { + return; + } + lastPath = QFileInfo(fileNameInput).absolutePath(); + std::string tmp2 = fileName.toUtf8().data(); + playlistProjects.append(fileName); + refreshListboxPorjects(); + //QFileInfo fi(fileName); + SelectProject(fileName);// fi.absoluteFilePath()); + playlistProjectsDirty = true; +} + +void DisplayPreferencesPanel::on_btnPlaylistProjGoUp_clicked() +{ + idxCurrentProj = ui.listWidgetPlaylist->currentRow(); + if (idxCurrentProj <= 0) + return; + + QString tmp = playlistProjects[idxCurrentProj]; + playlistProjects[idxCurrentProj] = playlistProjects[idxCurrentProj - 1]; + playlistProjects[idxCurrentProj - 1] = tmp; + + refreshListboxPorjects(); + SelectProject(tmp); + + playlistProjectsDirty = true; +} + +void DisplayPreferencesPanel::on_btnPlaylistProjGoDown_clicked() +{ + int count = playlistProjects.size(); + idxCurrentProj = ui.listWidgetPlaylist->currentRow(); + if (idxCurrentProj < 0 || idxCurrentProj>= count -1) + return; + + QString tmp = playlistProjects[idxCurrentProj]; + playlistProjects[idxCurrentProj] = playlistProjects[idxCurrentProj + 1]; + playlistProjects[idxCurrentProj + 1] = tmp; + + refreshListboxPorjects(); + SelectProject(tmp); + + playlistProjectsDirty = true; +} + +void DisplayPreferencesPanel::on_btnPlaylistRemoveProj_clicked() +{ + int count = playlistProjects.size(); + idxCurrentProj = ui.listWidgetPlaylist->currentRow(); + if (idxCurrentProj < 0 || idxCurrentProj >= count) + { + return; + } + + playlistProjects.removeAt(idxCurrentProj); + + refreshListboxPorjects(); + playlistProjectsDirty = true; +} + +void DisplayPreferencesPanel::assignPlayPlaylistToGamepad(int idx) +{ + if (idx == -1) + idx = idxCurrentPlaylist; + int count = playlistsLoader.getProjectsInPlaylist(idx, playlistProjects); + if (count < 1) + { + viewer_msg("Playlist is empty."); + return; + } + QList<QString> files; + for (int i = 0; i < count; ++i) + { + QString fname = PlaylistsLoader::convertToAbsoluteFilePath(playlistProjects[i]); + if (fname.size() > 0) + { + files.append(fname); + } + } + + Gamepad& theGamepad = Gamepad::Instance(); + theGamepad.SetDemoProjects(files); +} + +void DisplayPreferencesPanel::playPlaylist(int idx) +{ + assignPlayPlaylistToGamepad(idx); + Gamepad& theGamepad = Gamepad::Instance(); + theGamepad.SetDemoMode(true); +} + +void DisplayPreferencesPanel::on_btnPlaylistsPlay_clicked() +{ + savePlaylistProjects(); + + idxCurrentPlaylist = ui.cbPlaylists->currentIndex(); + if (idxCurrentPlaylist < 0) + { + viewer_msg("No available playlists."); + return; + } + playPlaylist(idxCurrentPlaylist); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +using namespace nvidia; +using namespace nvidia::parameterized; + +QString PlaylistsLoader::projectPath; +QString PlaylistsLoader::mediaPath; + +#include "FoundationHolder.h" + +struct PlaylistParamsContext +{ + //nvidia::NvFoundation* mFoundation; + NvParameterized::Traits* mTraits; + PlaylistParamsFactory* mPlaylistParamsFactory; +}; + +PlaylistsLoader::PlaylistsLoader() + :pContext(nullptr) +{ +} + +PlaylistsLoader::~PlaylistsLoader() +{ +} + +void PlaylistsLoader::CreatePlaylistParamsContext() +{ + if (pContext) + return; + + PlaylistParamsContext* context = new PlaylistParamsContext; + //context->mFoundation = FoundationHolder::GetFoundation(); + FoundationHolder::GetFoundation(); + //assert(context->mFoundation != NV_NULL); + + context->mTraits = NvParameterized::createTraits(); + context->mPlaylistParamsFactory = new PlaylistParamsFactory; + context->mTraits->registerFactory(*context->mPlaylistParamsFactory); + pContext = context; +} + +void PlaylistsLoader::ReleasePlaylistParamsContext() +{ + if (pContext) + { + pContext->mTraits->release(); + delete pContext->mPlaylistParamsFactory; + delete pContext; + pContext = nullptr; + } +} + +void PlaylistsLoader::loadPlaylistsFromMediaPath() +{ + if (projectPath.isEmpty()) + { + QString appDir = qApp->applicationDirPath(); + QDir dirTmp(appDir); + if (dirTmp.cd("./media/playlists")) + projectPath = dirTmp.absolutePath(); + else if (dirTmp.cd("../media/playlists")) + projectPath = dirTmp.absolutePath(); + else if (dirTmp.cd("../../media/playlists")) + projectPath = dirTmp.absolutePath(); + else if (dirTmp.cd("../../media")) + { + bool ok = dirTmp.mkdir("playlists"); + if (dirTmp.cd("playlists")) + { + projectPath = dirTmp.absolutePath(); + } + } + if (!projectPath.isEmpty()) + { + if (dirTmp.cd("..")) + { + mediaPath = dirTmp.absolutePath(); + } + else + { + mediaPath = projectPath + "/.."; + } + } + } + if (!projectPath.isEmpty()) + { + playlists.clear(); + + QStringList filters; + filters << (QString("*.") + sPlaylistExt); + QDirIterator dir_iterator(projectPath, filters, QDir::Files | QDir::NoSymLinks, QDirIterator::NoIteratorFlags); //QDirIterator::Subdirectories + while (dir_iterator.hasNext()) + { + dir_iterator.next(); + QFileInfo file_info = dir_iterator.fileInfo(); + std::string absolute_file_path = file_info.absoluteFilePath().toUtf8().data(); + playlists.append(file_info); + } + } +} + +bool PlaylistsLoader::rename(int idx, QString& newBaseName) +{ + int count = playlists.size(); + if (idx >= 0 && idx < count) + { + QFileInfo& finfo = playlists[idx]; + QString fn = finfo.baseName().toUpper(); + QString fnNew = newBaseName.toUpper(); + if (fn != fnNew) + { + QFileInfo nfi(projectPath, newBaseName + "." + sPlaylistExt); + QString fullNewName = nfi.absoluteFilePath(); + std::string fntmp = fullNewName.toUtf8().data(); + bool exist = QFile::exists(fullNewName); + if (exist) + { + return false; + } + bool ok = QFile::rename(finfo.absoluteFilePath(), fullNewName); + if (ok) + { + finfo.setFile(fullNewName); + exist = QFile::exists(fullNewName); + if (!exist) + { + return false; + } + } + return ok; + } + return true; + } + return false; +} + +bool PlaylistsLoader::remove(int idx) +{ + int count = playlists.size(); + if (idx >= 0 && idx < count) + { + QFileInfo& finfo = playlists[idx]; + std::string fn = finfo.fileName().toUtf8().data(); + bool ok = QFile::remove(finfo.absoluteFilePath()); + if (ok) + { + playlists.removeAt(idx); + } + return ok; + } + return false; +} + +bool PlaylistsLoader::saveProjectsInPlaylist(int idx, QList<QString>& projects) +{ + int count = playlists.size(); + if (idx < 0 || idx >= count) + return false; + + CreatePlaylistParamsContext(); + if (!pContext) + return false; + + std::string tempFilePath = playlists[idx].absoluteFilePath().toUtf8().data(); + NvParameterized::XmlSerializer serializer(pContext->mTraits); + NvFileBuf* stream = new NvFileBufferBase(tempFilePath.c_str(), NvFileBuf::OPEN_WRITE_ONLY); + if (!stream || !stream->isOpen()) + { + // file open error + if (stream) stream->release(); + return false; + } + NvParameterized::Traits* traits = pContext->mTraits; + int numObjects = 0; + const int kMaxObjects = 1; + NvParameterized::Interface* objects[kMaxObjects]; + + PlaylistParams* params = new PlaylistParams(traits); + objects[numObjects++] = params; + NvParameterized::Interface* iface = static_cast<NvParameterized::Interface*>(params); + + 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) + { + int num = projects.size(); + + std::vector<std::string> strArray; + const char** strOutput = new const char*[num]; + + for (int i = 0; i < num; i++) + { + std::string proj = projects[i].toUtf8().data(); + strArray.push_back(proj); + strOutput[i] = strArray[i].c_str(); + } + + handle.resizeArray(num); + handle.setParamStringArray(strOutput, num); + + delete[] strOutput; + } + } + + NV_ASSERT(numObjects <= kMaxObjects); + NvParameterized::Serializer::ErrorType serError = NvParameterized::Serializer::ERROR_NONE; + bool isUpdate = false; + serError = serializer.serialize(*stream, (const NvParameterized::Interface**)&objects[0], numObjects, isUpdate); + for (int idx = 0; idx < numObjects; ++idx) + { + delete objects[idx]; + } + stream->release(); + ReleasePlaylistParamsContext(); + return true; +} + +QString PlaylistsLoader::convertToAbsoluteFilePath(QString& filePath) +{ + QString fname; + bool bCanBeRelativePath = false; + bool bAbsPath = (filePath.indexOf(':') >= 0); + if (bAbsPath) + { + if (QFile::exists(filePath)) + { + fname = filePath; + } + else + { + viewer_msg(QString(filePath + " does not exist.").toUtf8().data()); + } + std::string tmp2 = fname.toUtf8().data(); + return fname; + } + else + { + QFileInfo fi(mediaPath + "/" + filePath); + fname = fi.absoluteFilePath(); + if (!QFile::exists(fname)) + { + viewer_msg(QString(filePath + " does not exist.").toUtf8().data()); + fname = ""; + } + std::string tmp2 = fname.toUtf8().data(); + return fname; + } +} + +QString PlaylistsLoader::convertToSaveingFilePath(QString& filePath) +{ + QString fname; + bool bCanBeRelativePath = false; + bool bAbsPath = (filePath.indexOf(':') >= 0); + if (bAbsPath) + { + if (QFile::exists(filePath)) + { + QFileInfo fi(filePath); + int pos = fi.absoluteFilePath().indexOf(mediaPath, Qt::CaseInsensitive); + if (pos >= 0) + { + // convert to relative path + fname = filePath.right(filePath.size() - (pos + mediaPath.size() + 1)); + } + else + { + fname = fi.absoluteFilePath(); + } + } + else + { + fname = ""; + viewer_msg(QString(filePath + " does not exist.").toUtf8().data()); + } + std::string tmp = fname.toUtf8().data(); + return fname; + } + // do more try + QString tag = "media"; + int pos = filePath.indexOf(tag, Qt::CaseInsensitive); + if (pos >= 0) + { + fname = filePath.right(filePath.size() - (pos + tag.size() + 1)); + } + else + { + fname = filePath; + } + QFileInfo fi(mediaPath + "/" + fname); + std::string tmp = fi.absoluteFilePath().toUtf8().data(); + if (!QFile::exists(fi.absoluteFilePath())) + { + viewer_msg(QString(filePath + " does not exist.").toUtf8().data()); + fname = ""; + } + std::string tmp2 = fname.toUtf8().data(); + return fname; +} + +int PlaylistsLoader::getProjectsInPlaylist(int idx, QList<QString>& projects) +{ + projects.clear(); + + int count = playlists.size(); + if (idx < 0 || idx >= count) + return 0; + + CreatePlaylistParamsContext(); + if (!pContext) + return 0; + + std::string tempFilePath = playlists[idx].absoluteFilePath().toUtf8().data(); + NvFileBuf* stream = new NvFileBufferBase(tempFilePath.c_str(), NvFileBuf::OPEN_READ_ONLY); + if (!stream || !stream->isOpen()) + { + // file open error + if (stream) + stream->release(); + return 0; + } + + NvParameterized::Serializer::DeserializedData data; + NvParameterized::Serializer::ErrorType serError = NvParameterized::Serializer::ERROR_NONE; + NvParameterized::XmlSerializer serializer(pContext->mTraits); + bool isUpdated = false; + serError = serializer.deserialize(*stream, data, isUpdated); + if (data.size() < 1) + { + if (stream) + stream->release(); + return 0; + } + + for (int idx = 0; idx < (int)data.size(); ++idx) + { + NvParameterized::Interface* iface = data[idx]; + if (::strcmp(iface->className(), PlaylistParams::staticClassName()) == 0) + { + 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) + { + int arraySize; + handle.getArraySize(arraySize); + char** strArray = new char*[arraySize]; + handle.getParamStringArray(strArray, arraySize); + for (int idx = 0; idx < arraySize; ++idx) + { + QString fileName = PlaylistsLoader::convertToSaveingFilePath(QString(strArray[idx])); + if (fileName.size() > 0) + { + std::string tmp = fileName.toUtf8().data(); + projects.append(fileName); + } + } + delete[] strArray; + } + } + } + stream->release(); + ReleasePlaylistParamsContext(); + return projects.size(); +} + +bool PlaylistsLoader::add(QString& name) +{ + int count = playlists.size(); + for (int i = 0; i < count; ++i) + { + QFileInfo& fi = playlists[i]; + if (fi.baseName().toUpper() == name.toUpper()) + { + return false; + } + } + QFileInfo nfi(projectPath, name + "." + sPlaylistExt); + QFile newFile(nfi.absoluteFilePath()); + if (newFile.exists()) + { + return false; + } + newFile.open(QIODevice::WriteOnly); + newFile.close(); + bool exist = QFile::exists(nfi.absoluteFilePath()); + if (!exist) + { + return false; + } + playlists.append(nfi); + return true; +}
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.h new file mode 100644 index 0000000..eb57b12 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.h @@ -0,0 +1,100 @@ +#ifndef DisplayPreferencesPanel_h__ +#define DisplayPreferencesPanel_h__ + +#include <QtWidgets/QWidget> +#include <QtCore/QDir> +#include <QtCore/QDirIterator> +#include "TipListView.h" +#include "ui_DisplayPreferencesPanel.h" + +#include "corelib_global.h" + +struct PlaylistParamsContext; + +class PlaylistsLoader +{ +public: + PlaylistsLoader(); + ~PlaylistsLoader(); + + void loadPlaylistsFromMediaPath(); + bool rename(int idx, QString& newName); + bool remove(int idx); + bool add(QString& name); + bool saveProjectsInPlaylist(int idx, QList<QString>& projects); + int getProjectsInPlaylist(int idx, QList<QString>& projects); + + static QString convertToSaveingFilePath(QString& filePath); + static QString convertToAbsoluteFilePath(QString& filePath); + + QList<QFileInfo> playlists; + static QString projectPath; + static QString mediaPath; + +private: + void CreatePlaylistParamsContext(); + void ReleasePlaylistParamsContext(); + PlaylistParamsContext* pContext; +}; + +class DisplayPreferencesPanel : public QWidget +{ + Q_OBJECT + +public: + DisplayPreferencesPanel(QWidget* parent); + ~DisplayPreferencesPanel(); + + public: + void updateValues(); + + public slots: + CORELIB_EXPORT void on_spinRenderPlayRateFPS_valueChanged(double v); + CORELIB_EXPORT void on_spinSimulationRateFPS_valueChanged(double v); + CORELIB_EXPORT void on_spinCameraFOV_valueChanged(double v); + + CORELIB_EXPORT void on_cbSceneUnit_currentIndexChanged(int index); + CORELIB_EXPORT void on_cbAntialiasing_currentIndexChanged(int index); + CORELIB_EXPORT void on_cbUpAxis_currentIndexChanged(int index); + CORELIB_EXPORT void on_cbHandedness_currentIndexChanged(int index); + CORELIB_EXPORT void on_cbNavigationStyle_currentIndexChanged(int index); + CORELIB_EXPORT void on_btnBackgroundTex_clicked(); + CORELIB_EXPORT void on_btnBackgroundTexClear_clicked(); + + CORELIB_EXPORT void on_cbPlaylists_currentIndexChanged(int index); + CORELIB_EXPORT void SelectPlayList(QString& name); + CORELIB_EXPORT void on_listWidgetPlaylist_itemSelectionChanged(); + CORELIB_EXPORT void on_listWidgetPlaylist_itemDoubleClicked(QListWidgetItem* pItem); + CORELIB_EXPORT void SelectProject(QString& name); + + CORELIB_EXPORT void on_btnPlaylistsRename_clicked(); + CORELIB_EXPORT void on_btnPlaylistsAdd_clicked(); + CORELIB_EXPORT void on_btnPlaylistsReload_clicked(); + CORELIB_EXPORT void on_btnPlaylistsRemove_clicked(); + + CORELIB_EXPORT void on_btnPlaylistAddProj_clicked(); + CORELIB_EXPORT void on_btnPlaylistProjGoUp_clicked(); + CORELIB_EXPORT void on_btnPlaylistProjGoDown_clicked(); + CORELIB_EXPORT void on_btnPlaylistRemoveProj_clicked(); + + CORELIB_EXPORT void on_btnPlaylistsPlay_clicked(); + CORELIB_EXPORT void assignPlayPlaylistToGamepad(int idx = -1); + CORELIB_EXPORT void playPlaylist(int idx); + + CORELIB_EXPORT void reloadComboxBoxPlaylists(); + CORELIB_EXPORT void refreshListboxPorjects(); + CORELIB_EXPORT void reloadListboxPorjectsFromPlayist(); + CORELIB_EXPORT void savePlaylistProjects(); + + CORELIB_EXPORT void runDemoCommandline(); + +private: + Ui::DisplayPreferencesPanel ui; + PlaylistsLoader playlistsLoader; + QList<QString> playlistProjects; + bool playlistProjectsDirty; + int idxCurrentPlaylist; + int idxCurrentProj; +}; + +#endif // DisplayScene_h__ diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp new file mode 100644 index 0000000..b118b6b --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp @@ -0,0 +1,93 @@ +#include "DisplayScenePanel.h" + +#include "AppMainWindow.h" + +#include "SimpleScene.h" +#include "GlobalSettings.h" + +DisplayScenePanel::DisplayScenePanel(QWidget* parent) + : + QWidget(parent) +{ + ui.setupUi(this); +} + +void DisplayScenePanel::on_btnVisualizeWind_stateChanged(int state) +{ + GlobalSettings::Inst().m_visualizeWind = state; +} + +void DisplayScenePanel::on_btnShowGrid_stateChanged(int state) +{ + GlobalSettings::Inst().m_showGrid = state; +} + +void DisplayScenePanel::on_btnShowAxis_stateChanged(int state) +{ + GlobalSettings::Inst().m_showAxis = state; +} + +void DisplayScenePanel::on_btnShowWireframe_stateChanged(int state) +{ + GlobalSettings::Inst().m_showWireframe = state; +} + +void DisplayScenePanel::on_btnUseLighting_stateChanged(int state) +{ + GlobalSettings::Inst().m_useLighting = state; +} + +void DisplayScenePanel::on_cbRenderType_currentIndexChanged(int index) +{ + GlobalSettings::Inst().m_renderStyle = index; +} + +void DisplayScenePanel::on_btnShowHUD_stateChanged(int state) +{ + GlobalSettings::Inst().m_showHUD = state; +} + +void DisplayScenePanel::on_btnComputeStats_stateChanged(int state) +{ + GlobalSettings::Inst().m_computeStatistics = state; +} + +void DisplayScenePanel::on_btnComputeProfile_stateChanged(int state) +{ + GlobalSettings::Inst().m_computeProfile = state; +} + +void DisplayScenePanel::on_btnShowGraphicsMesh_stateChanged(int state) +{ + GlobalSettings::Inst().m_showGraphicsMesh = state; +} + +void DisplayScenePanel::on_btnShowSkinnedOnly_stateChanged(int state) +{ + GlobalSettings::Inst().m_showSkinnedMeshOnly = state; + AppMainWindow::Inst().updateUI(); +} + +void DisplayScenePanel::on_btnSkinningDQ_stateChanged(int state) +{ + GlobalSettings::Inst().m_useDQ = state; +} + +void DisplayScenePanel::on_checkBoxGizmoWithLocal_stateChanged(int state) +{ + AppMainWindow::Inst().m_bGizmoWithLocal = state; +} + +void DisplayScenePanel::updateValues() +{ + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + ui.btnShowGrid->setChecked(globalSettings.m_showGrid); + ui.btnShowAxis->setChecked(globalSettings.m_showAxis); + ui.cbRenderType->setCurrentIndex(globalSettings.m_renderStyle); + ui.btnShowHUD->setChecked(globalSettings.m_showHUD); + ui.btnComputeStats->setChecked(globalSettings.m_computeStatistics); + ui.btnUseLighting->setChecked(globalSettings.m_useLighting); + ui.btnShowGraphicsMesh->setChecked( globalSettings.m_showGraphicsMesh); + ui.btnShowSkinnedOnly->setChecked( globalSettings.m_showSkinnedMeshOnly); +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h new file mode 100644 index 0000000..6614eca --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h @@ -0,0 +1,39 @@ +#ifndef DisplayScenePanel_h__ +#define DisplayScenePanel_h__ + +#include <QtWidgets/QWidget> +#include "ui_DisplayScenePanel.h" + +#include "corelib_global.h" + +class DisplayScenePanel : public QWidget +{ + Q_OBJECT + +public: + DisplayScenePanel(QWidget* parent); + + public: + void updateValues(); + + public slots: + CORELIB_EXPORT void on_btnVisualizeWind_stateChanged(int state); + CORELIB_EXPORT void on_btnShowGrid_stateChanged(int state); + CORELIB_EXPORT void on_btnShowAxis_stateChanged(int state); + CORELIB_EXPORT void on_cbRenderType_currentIndexChanged(int index); + CORELIB_EXPORT void on_btnShowWireframe_stateChanged(int state); + CORELIB_EXPORT void on_btnShowHUD_stateChanged(int state); + CORELIB_EXPORT void on_btnComputeStats_stateChanged(int state); + CORELIB_EXPORT void on_btnComputeProfile_stateChanged(int state); + CORELIB_EXPORT void on_btnUseLighting_stateChanged(int state); + CORELIB_EXPORT void on_btnShowGraphicsMesh_stateChanged(int state); + CORELIB_EXPORT void on_btnShowSkinnedOnly_stateChanged(int state); + CORELIB_EXPORT void on_btnSkinningDQ_stateChanged(int state); + CORELIB_EXPORT void on_checkBoxGizmoWithLocal_stateChanged(int state); + + +private: + Ui::DisplayScenePanel ui; +}; + +#endif // DisplayScene_h__ diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.cpp new file mode 100644 index 0000000..0fe96d1 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.cpp @@ -0,0 +1,190 @@ +#include <QtWidgets/QLabel> +#include <QtGui/QImage> +#include <QtWidgets/QVBoxLayout> +#include <QtGui/QMouseEvent> +#include <QtGui/QPaintEvent> +#include <QtGui/QPainter> +#include <QtGui/QPainterPath> +#include "ExpandablePanel.h" +#include "Nv.h" + +static QImage S_TriangleRight; +static QImage S_TriangleDown; + +void InitTriangleResources(int w, int h) +{ + S_TriangleRight = QImage(w, h, QImage::Format_ARGB32); + S_TriangleDown = QImage(w, h, QImage::Format_ARGB32); + + S_TriangleRight.fill(QColor(0, 0, 0, 0)); + S_TriangleDown.fill(QColor(0, 0, 0, 0)); + + QPainter painter(&S_TriangleRight); + painter.setRenderHints(QPainter::Antialiasing,true); + + QPainterPath path; + path.moveTo(0, 0); + path.lineTo(w, h>>1); + path.lineTo(0, h); + path.lineTo(0, 0); + painter.setPen(Qt::NoPen); + painter.fillPath(path, QBrush(QColor(50, 50, 50))); + + // a painter cannot switch device? + QPainter painter2(&S_TriangleDown); + painter2.setRenderHint(QPainter::Antialiasing,true); + path = QPainterPath(); // trick to clear up a path + path.moveTo(0, 0); + path.lineTo(w, 0); + path.lineTo(w>>1, h); + path.lineTo(0, 0); + painter2.setPen(Qt::NoPen); + painter2.fillPath(path, QBrush(QColor(50, 50, 50))); +} + +class TitleLabelImpl : public TitleLabel +{ + enum + { + IMAGE_H = 10, + IMAGE_W = 10, + FIXED_H = 20, + }; + +public: + TitleLabelImpl(QWidget* parent, bool collapsed) + : TitleLabel(parent) + , _collapsed(collapsed) + { + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(this->sizePolicy().hasHeightForWidth()); + this->setSizePolicy(sizePolicy); + this->setMinimumSize(QSize(0, FIXED_H)); + this->setMaximumSize(QSize(16777215, FIXED_H)); + //this->setStyleSheet(QString::fromUtf8("background:rgb(219,219,219);border:1px solid rgb(185,185,185);")); + this->setFrameShape(QFrame::NoFrame); + this->setFrameShadow(QFrame::Plain); + this->setTextFormat(Qt::AutoText); + this->setScaledContents(false); + this->setAlignment(Qt::AlignCenter); + + if(S_TriangleDown.isNull() || S_TriangleRight.isNull()) + InitTriangleResources(IMAGE_W, IMAGE_H); + } + + void paintEvent(QPaintEvent * e) + { + QLabel::paintEvent(e); + + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing,true); + + const int L = 10; + const int T = (FIXED_H - IMAGE_H)/2; + QRect rc(L, T, IMAGE_W, IMAGE_H); + + // [later] transform the painter should also work; + // but i don't get the expected results, so have to use two images + if(_collapsed) + painter.drawImage(rc, S_TriangleRight); + else + painter.drawImage(rc, S_TriangleDown); + + } + + bool Collapsed() {return _collapsed;} + void SetCollapsed(bool b) + { + _collapsed = b; + this->update(); + } + +protected: + virtual void mousePressEvent(QMouseEvent* e) + { + if(e->buttons() == Qt::LeftButton) + { + _collapsed = !_collapsed; + this->update(); + emit LPressSignal(); + } + } + +private: + bool _collapsed; +}; + +ExpandablePanel::ExpandablePanel(QWidget* parent, bool collapsed) + : QFrame(parent) + , _pContent(NV_NULL) +{ + //_pContent = new QWidget(this); + Init(collapsed); +} + +ExpandablePanel::ExpandablePanel( QWidget* content, QWidget* parent /*= 0*/ ) + : QFrame(parent) + , _pContent(content) +{ + Init(); +} + +ExpandablePanel::~ExpandablePanel() +{ + +} + +void ExpandablePanel::SetCollapsed(bool b) +{ + if (_pTitle) + _pTitle->SetCollapsed(b); +} + +void ExpandablePanel::Init(bool collapsed) +{ + setAutoFillBackground(true); + setFrameShape(QFrame::StyledPanel); + setFrameShadow(QFrame::Sunken); + _pMainLayout = new QVBoxLayout(this); + _pMainLayout->setSpacing(2); + _pMainLayout->setContentsMargins(0, 0, 0, 0); + _pMainLayout->setObjectName(QString::fromUtf8("mainLayout")); + + _pTitle = new TitleLabelImpl(this, collapsed); + _pTitle->setText("TitleLabel"); + _pMainLayout->addWidget(_pTitle); + + connect(_pTitle, SIGNAL(LPressSignal()), this, SLOT(TitlePress())); + + if(_pContent) + _pMainLayout->addWidget(_pContent); +} + +void ExpandablePanel::SetTitle( const QString& title ) +{ + _pTitle->setText(title); +} + +void ExpandablePanel::TitlePress() +{ + if(_pTitle->Collapsed()) + { + _pContent->hide(); + } + else // expanded + { + _pContent->show(); + } +} + +void ExpandablePanel::AddContent( QWidget* content ) +{ + // only support one widget as content right now + if (_pContent != NV_NULL) return; + + _pMainLayout->addWidget(content); + _pContent = content; +} + diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.h new file mode 100644 index 0000000..ba3018d --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.h @@ -0,0 +1,51 @@ +#ifndef ExpandablePanel_h__ +#define ExpandablePanel_h__ + +#include <QtWidgets/QWidget> +#include <QtWidgets/QFrame> +#include <QtWidgets/QLabel> + +#include "corelib_global.h" + +class TitleLabelImpl; +class QString; +class QVBoxLayout; + +class TitleLabel : public QLabel +{ + Q_OBJECT + +public: + TitleLabel(QWidget* parent):QLabel(parent){} + +signals: + void LPressSignal(); +}; + +class ExpandablePanel : public QFrame +{ + Q_OBJECT + +public: + CORELIB_EXPORT explicit ExpandablePanel(QWidget* parent, bool collapsed = false); + explicit ExpandablePanel(QWidget* content, QWidget* parent); + virtual ~ExpandablePanel(); + + CORELIB_EXPORT void SetTitle(const QString& title); + void SetCollapsed(bool b); + QWidget* Content() {return _pContent;} + CORELIB_EXPORT void AddContent(QWidget* content); + +public slots: +CORELIB_EXPORT void TitlePress(); + +private: + void Init(bool collapsed = false); + +private: + QVBoxLayout* _pMainLayout; + TitleLabelImpl* _pTitle; + QWidget* _pContent; +}; + +#endif // ExpandablePanel_h__ diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/OutputWindow.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Window/OutputWindow.cpp new file mode 100644 index 0000000..08867e3 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/OutputWindow.cpp @@ -0,0 +1,22 @@ +#include "AppMainWindow.h" +#include "OutputWindow.h" + +#include <QtGUI/QContextMenuEvent> + +OutputWindow::OutputWindow(QWidget* parent) + : + QTextBrowser(parent) +{ + ui.setupUi(this); +} + +void OutputWindow::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu *menu = createStandardContextMenu(); + + QAction* act = new QAction("&Clear All", this); + connect(act, SIGNAL(triggered()), this, SLOT(clear())); + menu->addAction(act); + menu->exec(event->globalPos()); + delete menu; +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/OutputWindow.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/OutputWindow.h new file mode 100644 index 0000000..5d19bb6 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/OutputWindow.h @@ -0,0 +1,22 @@ +#ifndef OutputWindow_h__ +#define OutputWindow_h__ + +#include <QtWidgets/QTextBrowser> +#include "ui_OutputWindow.h" + +#include "UIGlobal.h" + +class CORELIB_EXPORT OutputWindow : public QTextBrowser +{ + Q_OBJECT + +public: + OutputWindow(QWidget* parent); + + void contextMenuEvent(QContextMenuEvent *event); + +private: + Ui::OutputWindow ui; +}; + +#endif // DisplayScene_h__ diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.cpp new file mode 100644 index 0000000..b127f1c --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.cpp @@ -0,0 +1,17 @@ +#include "SlideSpinBox.h" + +void SlideSpinBoxSlots::timeout() +{ + //qDebug("%s", __FUNCTION__); + this->_cb->on_timeout(); +} + +void ConfigSpinBoxInt(SlideSpinBoxInt* spinBox, int minv, int maxv, int step) +{ + spinBox->blockSignals(true); + spinBox->setRange(minv, maxv); + spinBox->setSingleStep(step); + spinBox->AutoConfigDragRange(); + spinBox->setKeyboardTracking(false); + spinBox->blockSignals(false); +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.h new file mode 100644 index 0000000..eeb7626 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.h @@ -0,0 +1,284 @@ +#ifndef SlideSpinBox_h__ +#define SlideSpinBox_h__ + +#include <QtWidgets/QStyle> +#include <QtWidgets/QStyleOptionSpinBox> +#include <QtWidgets/QAbstractSpinBox> +#include <QtGui/QMouseEvent> +#include <QtCore/QTimer> +#include <QtWidgets/QDoubleSpinBox> +#include <QtWidgets/QSpinBox> + +#include "corelib_global.h" + +/* + A Lesson: never use a template to sub-class QWidgets! + Qt doesn't moc template widget classes; + So we have to use a specific 'slots-callback' pair to let the moc system work... + */ +class SlideSpinBoxCallback +{ +public: + virtual void on_timeout() = 0; +}; + +class SlideSpinBoxSlots : public QObject +{ + Q_OBJECT + +public: + SlideSpinBoxSlots(SlideSpinBoxCallback* cb) + : _cb (cb) + {} + + public slots: + CORELIB_EXPORT void timeout(); + +private: + SlideSpinBoxCallback* _cb; +}; + +template<typename SpinWidget, typename ValueType> +class SlideSpinBox : public SpinWidget, public SlideSpinBoxCallback +{ + +public: + void on_timeout() + { + //qDebug("%s", __FUNCTION__); + EmitDragValueChanged(); + } + +public: + typedef ValueType value_type; + + SlideSpinBox(QWidget* parent = 0) + : SpinWidget(parent) + , _dragRange(DEFAULT_DRAG_RANGE) + { + setAccelerated(true); + + ResetCustState(); + + _pSlots = new SlideSpinBoxSlots(this); + + _dragTimer.setParent(this); + _dragTimer.setInterval(DRAG_TIMER_INTERVAL); + _dragTimer.setSingleShot(true); + connect(&_dragTimer, SIGNAL(timeout()), _pSlots, SLOT(timeout())); + } + + ~SlideSpinBox() + { + delete _pSlots; + } + + void SetDragRange(int range) + { + if(range < MIN_DRAG_RANGE) + range = MIN_DRAG_RANGE; + else if(range > MAX_DRAG_RANGE) + range = MAX_DRAG_RANGE; + + _dragRange = range; + } + + void AutoConfigDragRange() + { + ValueType minv = this->minimum(); + ValueType maxv = this->maximum(); + + double vrange = maxv - minv; + double step = 1.0; + + if(vrange <= 1.0) + { + step = 0.01; + } + else if(vrange <= 10.0) + { + step = 0.1; + } + + double pixelError = 2.0; + double dragRange = vrange * pixelError / step; + + SetDragRange((int)dragRange); + } + +protected: + void mouseMoveEvent ( QMouseEvent * event ) + { + if(!_dragBegin) + { + QAbstractSpinBox::mouseMoveEvent(event); + return; + } + + if(!_dragging) + { + _dragging = true; + _cursor = this->cursor(); + + this->setCursor(Qt::SizeVerCursor); + } + + //if(_dragging) + //{ + // _dragTimer.start(); // always restart, we only need the timeout event; + //} + + event->accept(); + DragValue(event->pos()); + } + + void mousePressEvent( QMouseEvent * event ) + { + if(event->button() == Qt::LeftButton) + { + SetupCustState(event); + } + + if(_dragging) + blockSignals(true); + QAbstractSpinBox::mousePressEvent(event); + if(_dragging) + blockSignals(false); + } + + void mouseReleaseEvent( QMouseEvent * event ) + { + if(_dragging) + { + setCursor(_cursor); + _dragTimer.stop(); + } + + QAbstractSpinBox::mouseReleaseEvent(event); + //if(_dragBegin) + // EmitDragValueChanged(); + + ResetCustState(); + } + + void timerEvent(QTimerEvent *event) + { + if(_dragging) + { + // stop timer event to disable acceleration/auto-stepping + event->ignore(); + return; + } + + event->accept(); + + if(_dragBegin) blockSignals(true); + QAbstractSpinBox::timerEvent(event); + if(_dragBegin) blockSignals(false); + } + +private: + enum + { + MIN_DRAG_RANGE = 50, + MAX_DRAG_RANGE = 500, + + DEFAULT_DRAG_RANGE = 100, + + DRAG_TIMER_INTERVAL= 30, // in msec + }; + + bool SetupCustState(QMouseEvent* event) + { + QStyleOptionSpinBox opt; + this->initStyleOption(&opt); + QStyle::SubControl hitControl = this->style()->hitTestComplexControl(QStyle::CC_SpinBox, &opt, event->pos()); + if(hitControl != QStyle::SC_SpinBoxUp && hitControl != QStyle::SC_SpinBoxDown) + return false; + + _pressPosition = event->pos(); + _dragging = false; + _dragBegin = true; + _pressValue = this->value(); + _dragValue = this->value(); + + return true; + } + + void ResetCustState() + { + _dragBegin = false; + _dragging = false; + } + + void DragValue(const QPoint& pos) + { + ValueType valueRange = this->maximum() - this->minimum(); + + double dh = (double)(_pressPosition.y() - pos.y()); + double dv = valueRange * dh / (double)_dragRange; + ValueType v = _pressValue + (ValueType)dv; + + //blockSignals(true); + setValue(v); + //blockSignals(false); + } + + void EmitDragValueChanged() + { + //if(this->value() != _pressValue) // value are always bound by qt (and decimal settings) + if(this->value() != _dragValue) + { + _dragValue = this->value(); + emit valueChanged(this->value()); + } + } + + int _dragRange; + + QPoint _pressPosition; + ValueType _pressValue; + ValueType _dragValue; + + bool _dragging; + bool _dragBegin; + QCursor _cursor; + + QTimer _dragTimer; + SlideSpinBoxSlots* _pSlots; +}; + +typedef SlideSpinBox<QDoubleSpinBox, double> SlideSpinBoxF; +typedef SlideSpinBox<QSpinBox, int> SlideSpinBoxInt; + +template<typename CustSpinBox> +class ConfigSpinBox +{ +public: + typedef typename CustSpinBox::value_type ValueType; + + ConfigSpinBox(CustSpinBox* spinBox, ValueType minv, ValueType maxv, ValueType step = (ValueType)1) + { + spinBox->blockSignals(true); + spinBox->setRange(minv, maxv); + spinBox->setSingleStep(step); + spinBox->AutoConfigDragRange(); + spinBox->setKeyboardTracking(false); + SpecificConfig<ValueType>(spinBox); + spinBox->blockSignals(false); + } + + template<typename T> + void SpecificConfig(CustSpinBox* spinBox){} + + template<> + void SpecificConfig<double>(CustSpinBox* spinBox) + { + spinBox->setDecimals(2.0); + } +}; + +#include "corelib_global.h" +CORELIB_EXPORT void ConfigSpinBoxInt(SlideSpinBoxInt* spinBox, int minv, int maxv, int step = (int)1); + +#endif // SlideSpinBox_h__ diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/SlideSpinBoxInt.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/SlideSpinBoxInt.h new file mode 100644 index 0000000..393adee --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/SlideSpinBoxInt.h @@ -0,0 +1,15 @@ +#ifndef SlideSpinBoxInt_h__ +#define SlideSpinBoxInt_h__ + +#include <QtWidgets/QStyle> +#include <QtWidgets/QStyleOptionSpinBox> +#include <QtWidgets/QAbstractSpinBox> +#include <QtGui/QMouseEvent> +#include <QtCore/QTimer> +#include <QtWidgets/QDoubleSpinBox> +#include <QtWidgets/QSpinBox> +#include <SlideSpinBox.h> + +// use this header as a trick to make moc work right + +#endif // SlideSpinBoxInt_h__ diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/TipListView.cpp b/NvBlast/tools/ArtistTools/source/CoreLib/Window/TipListView.cpp new file mode 100644 index 0000000..b91fd3e --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/TipListView.cpp @@ -0,0 +1,42 @@ +#include "TipListView.h" +#include <QtWidgets/QToolTip> +#include <QtCore/QEvent> +#include <QtGUI/QEvent.h> + + +TipListView::TipListView(QWidget* parent) + :QListWidget(parent) +{ +} + +void TipListView::setTips(QStringList& tips) +{ + mTips = tips; +} + +bool TipListView::event(QEvent *evt) +{ + if (evt->type() == QEvent::ToolTip) + { + if (mTips.size() > 0) + { + QHelpEvent *helpEvent = (QHelpEvent *)(evt); + const QPoint& pos = helpEvent->pos(); + QListWidgetItem* pItem = itemAt(pos); + int index = 0, num = count(); + for (int i = 0; i < num; ++i) + { + QListWidgetItem* pi = item(i); + if (pi == pItem && mTips.size() > i) + { + QToolTip::showText(helpEvent->globalPos(), mTips[i]); + return true; + } + } + } + //QToolTip::hideText(); + //evt->ignore(); + //return true; + } + return QListWidget::event(evt); +} diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/TipListView.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/TipListView.h new file mode 100644 index 0000000..6913baa --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/TipListView.h @@ -0,0 +1,26 @@ +#ifndef TipListView_h__ +#define TipListView_h__ + +#include <QtWidgets/QWidget> +#include <QtWidgets/QListWidget> +#include <QtCore/QEvent> + +#include "corelib_global.h" + +class TipListView : public QListWidget +{ + Q_OBJECT + +public: + TipListView(QWidget* parent = 0); + + void setTips(QStringList& tips); + +protected: + bool event(QEvent *); +private: + + QStringList mTips; + +}; +#endif // TipListView_h__ diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/Window/UIGlobal.h b/NvBlast/tools/ArtistTools/source/CoreLib/Window/UIGlobal.h new file mode 100644 index 0000000..3d50132 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/Window/UIGlobal.h @@ -0,0 +1,37 @@ +// 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-2015 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. +// + +#pragma once + +#define USE_MATERIAL_SET 1 +#define USE_CURVE_EDITOR 0 +#define USE_TEXTURE_BRIGHTNESS 0 + +#define USE_INTERNAL_GRAPHICAL_MATERIAL 0 + +#include "corelib_global.h"
\ No newline at end of file diff --git a/NvBlast/tools/ArtistTools/source/CoreLib/corelib_global.h b/NvBlast/tools/ArtistTools/source/CoreLib/corelib_global.h new file mode 100644 index 0000000..b3c0016 --- /dev/null +++ b/NvBlast/tools/ArtistTools/source/CoreLib/corelib_global.h @@ -0,0 +1,20 @@ +#ifndef CORELIB_GLOBAL_H +#define CORELIB_GLOBAL_H + +#include <QtCore/qglobal.h> +#include <Nv/NvBlastCommon.h> + +#ifdef CORELIB_LIB +# define CORELIB_EXPORT Q_DECL_EXPORT +#else +# define CORELIB_EXPORT Q_DECL_IMPORT +#endif + +#pragma warning(disable:4018) +#pragma warning(disable:4099) +#pragma warning(disable:4101) +#pragma warning(disable:4267) +#pragma warning(disable:4273) +#pragma warning(disable:4996) + +#endif // CORELIB_GLOBAL_H |