diff options
| author | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
|---|---|---|
| committer | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
| commit | 236f03c0b9a4982328ed1201978f7f69d192d9b2 (patch) | |
| tree | e486f2fa39dba203563895541e92c60ed3e25759 /tools/ArtistTools/source/BlastPlugin/SampleBase/ui | |
| parent | Added screens to welcome page (diff) | |
| download | blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.tar.xz blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.zip | |
Blast 1.1 release (windows / linux)
see docs/release_notes.txt for details
Diffstat (limited to 'tools/ArtistTools/source/BlastPlugin/SampleBase/ui')
12 files changed, 1803 insertions, 829 deletions
diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp index e56a124..f9e218b 100644 --- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, related documentation -* and any modifications thereto. Any use, reproduction, disclosure or -* distribution of this software and related documentation without an express -* license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + #include "CommonUIController.h" diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h index da62674..4656203 100644 --- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/CommonUIController.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, related documentation -* and any modifications thereto. Any use, reproduction, disclosure or -* distribution of this software and related documentation without an express -* license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + #ifndef COMMON_UI_CONTROLLER_H #define COMMON_UI_CONTROLLER_H diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp index fba1227..7f426bd 100644 --- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, related documentation -* and any modifications thereto. Any use, reproduction, disclosure or -* distribution of this software and related documentation without an express -* license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + #include "DamageToolController.h" #include "RenderUtils.h" @@ -18,11 +36,16 @@ #include <imgui.h> #include "NvBlastTkActor.h" +#include "NvBlastTkFamily.h" #include "NvBlastExtDamageShaders.h" #include "NvBlastExtPxActor.h" #include "PxRigidDynamic.h" #include "PxScene.h" +#include "SimpleScene.h" +#include "BlastSceneTree.h" +#include "DefaultDamagePanel.h" +#include "ViewerOutput.h" using namespace Nv::Blast; @@ -32,44 +55,113 @@ using namespace physx; // Setup /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - const DirectX::XMFLOAT4 PICK_POINTER_ACTIVE_COLOR(1.0f, 0.f, 0.f, 0.6f); +static const PxVec3 WEAPON_POSITION_IN_VIEW(0, -7, 23); +static const float SEGMENT_DAMAGE_MAX_DISTANCE = 100.0f; + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - +DamageToolController* gDamageToolController = nullptr; +DamageToolController* DamageToolController::ins() +{ + return gDamageToolController; +} +void DamageToolController::setDamageAmount(float value) +{ + m_damage = value; +} +void DamageToolController::setExplosiveImpulse(float value) +{ + m_explosiveImpulse = value; +} +void DamageToolController::setStressForceFactor(float value) +{ + m_stressForceFactor = value; +} +void DamageToolController::setDamagerIndex(int index) +{ + m_damagerIndex = index; +} +void DamageToolController::setRadius(float value) +{ + m_damagers[m_damagerIndex].radius = value; +} +void DamageToolController::setDamageWhilePressed(bool value) +{ + m_damagers[m_damagerIndex].damageWhilePressed = value; +} DamageToolController::DamageToolController() - : m_damageRadius(5.0f), m_compressiveDamage(1.0f), m_pickPointerColor(1.0f, 1.0f, 1.0f, 0.4f), - m_pickPointerRenderMaterial(nullptr), m_pickPointerRenderable(nullptr), m_explosiveImpulse(100), m_damageProfile(0), m_stressForceFactor(1.0f) + : m_damage(100.0f), m_toolColor(1.0f, 1.0f, 1.0f, 0.4f), + m_toolRenderMaterial(nullptr), m_sphereToolRenderable(nullptr), m_lineToolRenderable(nullptr), + m_explosiveImpulse(100), m_damagerIndex(0), m_stressForceFactor(1.0f), m_isMousePressed(false), m_damageCountWhilePressed(0) { + // damage amount calc using NvBlastExtMaterial + auto getDamageAmountFn = [](const float damage, ExtPxActor* actor) + { + const void* material = actor->getTkActor().getFamily().getMaterial(); + return material ? reinterpret_cast<const NvBlastExtMaterial*>(material)->getNormalizedDamage(damage) : 0.f; + }; + // Damage functions - auto radialDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 position, PxVec3 normal) + auto radialDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal) { - NvBlastExtRadialDamageDesc desc = + const float damage = getDamageAmountFn(m_damage, actor); + if (damage > 0.f) { - m_compressiveDamage, - { position.x, position.y, position.z }, - m_damageRadius, - m_damageRadius + 2.0f - }; + NvBlastExtRadialDamageDesc desc = + { + damage, + { position.x, position.y, position.z }, + damager->radius, + damager->radius * 1.6f + }; - actor->getTkActor().damage(damager->program, &desc, sizeof(desc)); + actor->getTkActor().damage(damager->program, &desc, sizeof(desc)); + } }; - auto shearDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 position, PxVec3 normal) + auto lineSegmentDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal) { - PxVec3 force = -2 * normal; + const float damage = getDamageAmountFn(m_damage, actor); + if (damage > 0.f) + { + PxVec3 dir = (position - origin).getNormalized(); + PxVec3 farEnd = origin + dir * 10000.0f; - NvBlastExtShearDamageDesc desc = + NvBlastExtSegmentRadialDamageDesc desc = + { + damage, + { origin.x, origin.y, origin.z }, + { farEnd.x, farEnd.y, farEnd.z }, + damager->radius, + damager->radius * 1.6f + }; + + actor->getTkActor().damage(damager->program, &desc, sizeof(desc)); + } + }; + auto shearDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal) + { + const float damage = getDamageAmountFn(m_damage, actor); + if (damage > 0.f) { - { force.x, force.y, force.z }, - { position.x, position.y, position.z } - }; + PxVec3 impactNormal = -normal; - actor->getTkActor().damage(damager->program, &desc, sizeof(desc)); + NvBlastExtShearDamageDesc desc = + { + damage, + { impactNormal.x, impactNormal.y, impactNormal.z }, + { position.x, position.y, position.z }, + damager->radius, + damager->radius * 1.6f + }; + + actor->getTkActor().damage(damager->program, &desc, sizeof(desc)); + } }; - auto stressDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 position, PxVec3 normal) + auto stressDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal) { PxVec3 force = -m_stressForceFactor * normal * actor->getPhysXActor().getMass(); @@ -81,41 +173,96 @@ DamageToolController::DamageToolController() Damager dam; dam.uiName = "Radial Damage (Falloff)"; dam.program = NvBlastDamageProgram { NvBlastExtFalloffGraphShader, NvBlastExtFalloffSubgraphShader }; + dam.pointerType = Damager::PointerType::Sphere; dam.pointerColor = DirectX::XMFLOAT4(1.0f, 1.0f, 1.0f, 0.4f); dam.executeFunction = radialDamageExecute; - m_armory.push_back(dam); + m_damagers.push_back(dam); } { Damager dam; dam.uiName = "Radial Damage (Cutter)"; dam.program = NvBlastDamageProgram { NvBlastExtCutterGraphShader, NvBlastExtCutterSubgraphShader }; + dam.pointerType = Damager::PointerType::Sphere; dam.pointerColor = DirectX::XMFLOAT4(0.5f, 0.5f, 1.0f, 0.4f); dam.executeFunction = radialDamageExecute; - m_armory.push_back(dam); + m_damagers.push_back(dam); + } + + { + Damager dam; + dam.uiName = "Segment Damage (Falloff)"; + dam.program = NvBlastDamageProgram{ NvBlastExtSegmentFalloffGraphShader, NvBlastExtSegmentFalloffSubgraphShader }; + dam.pointerType = Damager::PointerType::Line; + dam.pointerColor = DirectX::XMFLOAT4(0.1f, 1.0f, 0.1f, 0.4f); + dam.executeFunction = lineSegmentDamageExecute; + dam.damageWhilePressed = true; + dam.radius = .2f; + dam.radiusLimit = 20.0f; + m_damagers.push_back(dam); } { Damager dam; dam.uiName = "Shear Damage"; dam.program = NvBlastDamageProgram { NvBlastExtShearGraphShader, NvBlastExtShearSubgraphShader }; + dam.pointerType = Damager::PointerType::Sphere; dam.pointerColor = DirectX::XMFLOAT4(0.5f, 1.0f, 0.5f, 0.4f); dam.executeFunction = shearDamageExecute; - m_armory.push_back(dam); + m_damagers.push_back(dam); } { Damager dam; dam.uiName = "Stress Damage"; dam.program = { nullptr, nullptr }; + dam.pointerType = Damager::PointerType::Sphere; dam.pointerColor = DirectX::XMFLOAT4(0.5f, 0.5f, 1.0f, 0.4f); dam.executeFunction = stressDamageExecute; - m_armory.push_back(dam); + m_damagers.push_back(dam); } - for (const Damager& d : m_armory) + // UI + DefaultDamagePanel* pDefaultDamagePanel = DefaultDamagePanel::ins(); + pDefaultDamagePanel->setUpdateData(false); + QComboBox* comboBoxDamageProfile = pDefaultDamagePanel->getDamageProfile(); + comboBoxDamageProfile->clear(); + + // project + BPPDefaultDamage& damage = BlastProject::ins().getParams().defaultDamage; + damage.damageAmount = m_damage; + damage.explosiveImpulse = m_explosiveImpulse; + damage.stressDamageForce = m_stressForceFactor; + int count = m_damagers.size(); + if (damage.damageStructs.buf != nullptr && damage.damageStructs.arraySizes[0] != count) + { + delete[] damage.damageStructs.buf; + damage.damageStructs.buf = nullptr; + damage.damageStructs.arraySizes[0] = 0; + } + if (damage.damageStructs.buf == nullptr) { - m_armoryNames.push_back(d.uiName); + damage.damageStructs.buf = new BPPDamageStruct[count]; + damage.damageStructs.arraySizes[0] = count; } + damage.damageProfile = 0; + int damageIndex = 0; + + for (const Damager& d : m_damagers) + { + m_damagerNames.push_back(d.uiName); + + // UI + comboBoxDamageProfile->addItem(d.uiName); + + // project + BPPDamageStruct& damageStruct = damage.damageStructs.buf[damageIndex++]; + damageStruct.damageRadius = d.radius; + damageStruct.continuously = d.damageWhilePressed; + } + + pDefaultDamagePanel->updateValues(); + + gDamageToolController = this; } DamageToolController::~DamageToolController() @@ -124,19 +271,22 @@ DamageToolController::~DamageToolController() void DamageToolController::onSampleStart() { - // pick pointer -// Add By Lixu Begin - m_pickPointerRenderMaterial = new RenderMaterial("", getRenderer().getResourceManager(), "physx_primitive_transparent", "", RenderMaterial::BLEND_ALPHA_BLENDING); -// Add By Lixu End - IRenderMesh* mesh = getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Sphere); - m_pickPointerRenderable = getRenderer().createRenderable(*mesh, *m_pickPointerRenderMaterial); - m_pickPointerRenderable->setScale(PxVec3(m_damageRadius)); + // damage tool pointer + m_toolRenderMaterial = new RenderMaterial("", getRenderer().getResourceManager(), "physx_primitive_transparent", "", RenderMaterial::BLEND_ALPHA_BLENDING); + { + IRenderMesh* mesh = getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Sphere); + m_sphereToolRenderable = getRenderer().createRenderable(*mesh, *m_toolRenderMaterial); + } + { + IRenderMesh* mesh = getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Box); + m_lineToolRenderable = getRenderer().createRenderable(*mesh, *m_toolRenderMaterial); + } // default tool - setDamageProfile(0); + m_damagerIndex = 0; // start with damage mode by default - setDamageMode(true); + setDamageMode(false); } void DamageToolController::onInitialize() @@ -146,64 +296,139 @@ void DamageToolController::onInitialize() void DamageToolController::onSampleStop() { - getRenderer().removeRenderable(m_pickPointerRenderable); - SAFE_DELETE(m_pickPointerRenderMaterial); + getRenderer().removeRenderable(m_sphereToolRenderable); + getRenderer().removeRenderable(m_lineToolRenderable); + SAFE_DELETE(m_toolRenderMaterial); } + void DamageToolController::Animate(double dt) { PROFILER_SCOPED_FUNCTION(); - m_pickPointerColor = XMFLOAT4Lerp(m_pickPointerColor, m_armory[m_damageProfile].pointerColor, dt * 5.0f); - m_pickPointerRenderable->setColor(m_pickPointerColor); -} + m_toolColor = XMFLOAT4Lerp(m_toolColor, m_damagers[m_damagerIndex].pointerColor, dt * 5.0f); + m_sphereToolRenderable->setHidden(true); + m_lineToolRenderable->setHidden(true); -LRESULT DamageToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - PROFILER_SCOPED_FUNCTION(); - - if (uMsg == WM_LBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP) + // damage mode + if (m_damageMode) { - float mouseX = (short)LOWORD(lParam) / getRenderer().getScreenWidth(); - float mouseY = (short)HIWORD(lParam) / getRenderer().getScreenHeight(); - bool press = uMsg == WM_LBUTTONDOWN; + // ray cast according to camera + mouse ray + PxVec3 eyePos, pickDir; + getPhysXController().getEyePoseAndPickDir(m_lastMousePos.x, m_lastMousePos.y, eyePos, pickDir); + pickDir = pickDir.getNormalized(); + + PxRaycastHit hit; hit.shape = NULL; + PxRaycastBuffer hit1; + getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL); + hit = hit1.block; - // damage mode - if (m_damageMode && m_pickPointerRenderable) + if (hit.shape) { - PxVec3 eyePos, pickDir; - getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); - pickDir = pickDir.getNormalized(); + PxMat44 cameraViewInv = XMMATRIXToPxMat44(getRenderer().getCamera().GetViewMatrix()).inverseRT(); + PxVec3 weaponOrigin = eyePos + cameraViewInv.rotate(WEAPON_POSITION_IN_VIEW); - PxRaycastHit hit; hit.shape = NULL; - PxRaycastBuffer hit1; - getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL); - hit = hit1.block; + // damage function + const Damager& damager = m_damagers[m_damagerIndex]; + auto damageFunction = [&](ExtPxActor* actor) + { + auto t0 = actor->getPhysXActor().getGlobalPose(); + PxTransform t(t0.getInverse()); + PxVec3 localNormal = t.rotate(hit.normal); + PxVec3 localPosition = t.transform(hit.position); + PxVec3 localOrigin = t.transform(weaponOrigin); + damager.executeFunction(&damager, actor, localOrigin, localPosition, localNormal); + }; + + // should damage? + bool shouldDamage = false; + if (m_isMousePressed) + { + shouldDamage = damager.damageWhilePressed || m_damageCountWhilePressed == 0; + m_damageCountWhilePressed++; + } + else + { + m_damageCountWhilePressed = 0; + } - if (hit.shape) + // Update tool pointer and do damage with specific overlap + if (damager.pointerType == Damager::Sphere) { - PxRigidActor* actor = hit.actor; - m_pickPointerRenderable->setHidden(false); - m_pickPointerRenderable->setTransform(PxTransform(hit.position)); + m_sphereToolRenderable->setHidden(false); + m_sphereToolRenderable->setColor(m_toolColor); + m_sphereToolRenderable->setScale(PxVec3(damager.radius)); + m_sphereToolRenderable->setTransform(PxTransform(hit.position)); - if (press) + if (shouldDamage) { - damage(hit.position, hit.normal); - m_pickPointerColor = PICK_POINTER_ACTIVE_COLOR; + if (getBlastController().overlap(PxSphereGeometry(damager.radius), PxTransform(hit.position), damageFunction)) + { + m_toolColor = PICK_POINTER_ACTIVE_COLOR; + } + getPhysXController().explodeDelayed(hit.position, damager.radius, m_explosiveImpulse); + } + } + else if (damager.pointerType == Damager::Line) + { + m_lineToolRenderable->setHidden(false); + m_lineToolRenderable->setColor(m_toolColor); + + PxVec3 scale(damager.radius, damager.radius, SEGMENT_DAMAGE_MAX_DISTANCE); + PxVec3 direction = (hit.position - weaponOrigin).getNormalized(); + PxVec3 position = weaponOrigin + direction * SEGMENT_DAMAGE_MAX_DISTANCE; + + m_lineToolRenderable->setScale(scale); + PxTransform t(position, quatLookAt(direction)); + m_lineToolRenderable->setTransform(t); + + if (shouldDamage) + { + if (this->getBlastController().overlap(PxBoxGeometry(scale), t, damageFunction)) + { + m_toolColor = PICK_POINTER_ACTIVE_COLOR; + } } } else { - m_pickPointerRenderable->setHidden(true); + PX_ASSERT(false); } } } +} + + +LRESULT DamageToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PROFILER_SCOPED_FUNCTION(); + + if (uMsg == WM_LBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP) + { + m_lastMousePos.x = (short)LOWORD(lParam) / getRenderer().getScreenWidth(); + if (!SimpleScene::Inst()->m_pCamera->_lhs) + { + m_lastMousePos.x = 1 - m_lastMousePos.x; + } + m_lastMousePos.y = (short)HIWORD(lParam) / getRenderer().getScreenHeight(); + } + + if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) + { + m_isMousePressed = (uMsg == WM_LBUTTONDOWN); + if (m_isMousePressed && !m_damageMode) + { + viewer_warn("damage mode is disable, please enable it first !"); + } + } if (uMsg == WM_MOUSEWHEEL) { + /* int delta = int((short)HIWORD(wParam)) / WHEEL_DELTA; changeDamageRadius(delta * 0.3f); + */ } if (uMsg == WM_KEYDOWN) @@ -219,14 +444,12 @@ LRESULT DamageToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } else if (iKeyPressed >= '1' && iKeyPressed <= '9') { - uint32_t num = PxClamp<uint32_t>(iKeyPressed - '1', 0, (uint32_t)m_armory.size() - 1); - setDamageProfile(num); + m_damagerIndex = PxClamp<uint32_t>(iKeyPressed - '1', 0, (uint32_t)m_damagers.size() - 1); } else if (iKeyPressed == VK_SPACE) { - setDamageMode(!isDamageMode()); + //setDamageMode(!isDamageMode()); } - } return 1; @@ -234,61 +457,36 @@ LRESULT DamageToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA void DamageToolController::drawUI() { - ImGui::DragFloat("Compressive Damage", &m_compressiveDamage, 0.05f); + ImGui::DragFloat("Damage Amount", &m_damage, 1.0f); ImGui::DragFloat("Explosive Impulse", &m_explosiveImpulse); - ImGui::DragFloat("Damage Radius (Mouse WH)", &m_damageRadius); ImGui::DragFloat("Stress Damage Force", &m_stressForceFactor); // - - - - - - - - ImGui::Spacing(); // Armory - if (ImGui::Combo("Damage Profile", (int*)&m_damageProfile, m_armoryNames.data(), (int)m_armoryNames.size(), -1)) - { - setDamageProfile(m_damageProfile); - } + ImGui::Combo("Damage Profile", (int*)&m_damagerIndex, m_damagerNames.data(), (int)m_damagerNames.size(), -1); + Damager& damager = m_damagers[m_damagerIndex]; + ImGui::DragFloat("Damage Radius (Mouse WH)", &damager.radius); + ImGui::Checkbox("Damage Continuously", &damager.damageWhilePressed); } - void DamageToolController::setDamageMode(bool enabled) { m_damageMode = enabled; - getPhysXController().setDraggingEnabled(!m_damageMode); + //getPhysXController().setDraggingEnabled(!m_damageMode); if (!m_damageMode) { - m_pickPointerRenderable->setHidden(true); + m_sphereToolRenderable->setHidden(true); + m_lineToolRenderable->setHidden(true); } } - -void DamageToolController::setDamageProfile(uint32_t profile) -{ - m_damageProfile = profile; -} - - void DamageToolController::changeDamageRadius(float dr) { - m_damageRadius += dr; - m_damageRadius = PxMax(1.0f, m_damageRadius); - m_pickPointerRenderable->setScale(PxVec3(m_damageRadius)); -} - - -void DamageToolController::damage(physx::PxVec3 position, physx::PxVec3 normal) -{ - auto damageFunction = [&](ExtPxActor* actor) - { - auto t0 = actor->getPhysXActor().getGlobalPose(); - PxTransform t(t0.getInverse()); - PxVec3 localNormal = t.rotate(normal); - PxVec3 localPosition = t.transform(position); - Damager& damager = m_armory[m_damageProfile]; - damager.execute(actor, localPosition, localNormal); - }; - - this->getBlastController().blast(position, m_damageRadius, m_explosiveImpulse, damageFunction); - + Damager& damager = m_damagers[m_damagerIndex]; + damager.radius += dr; + damager.radius = PxClamp<float>(damager.radius, 0.05f, damager.radiusLimit); } diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h index b6712f2..0aeb0d7 100644 --- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/DamageToolController.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, related documentation -* and any modifications thereto. Any use, reproduction, disclosure or -* distribution of this software and related documentation without an express -* license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + #ifndef DAMAGE_TOOL_CONTROLLER_H #define DAMAGE_TOOL_CONTROLLER_H @@ -15,6 +33,7 @@ #include "NvBlastTypes.h" #include <DirectXMath.h> #include <functional> +#include "PxVec2.h" #include "PxVec3.h" @@ -37,6 +56,14 @@ public: DamageToolController(); virtual ~DamageToolController(); + static DamageToolController* ins(); + void setDamageAmount(float value); + void setExplosiveImpulse(float value); + void setStressForceFactor(float value); + void setDamagerIndex(int index); + void setRadius(float value); + void setDamageWhilePressed(bool value); + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); virtual void Animate(double dt); void drawUI(); @@ -54,8 +81,10 @@ public: // Add By Lixu Begin Renderable* getPickPointer() { - return m_pickPointerRenderable; + return m_sphereToolRenderable; } + + void setDamageMode(bool enabled); // Add By Lixu End private: @@ -64,17 +93,9 @@ private: //////// private methods //////// - void damage(physx::PxVec3 position, physx::PxVec3 normal); - - void setDamageProfile(uint32_t profile); - uint32_t getDamageProfile() const - { - return m_damageProfile; - } - void changeDamageRadius(float dr); - void setDamageMode(bool enabled); + //////// used controllers //////// @@ -97,33 +118,48 @@ private: //////// internal data //////// - Renderable* m_pickPointerRenderable; - RenderMaterial* m_pickPointerRenderMaterial; - DirectX::XMFLOAT4 m_pickPointerColor; + RenderMaterial* m_toolRenderMaterial; + Renderable* m_sphereToolRenderable; + DirectX::XMFLOAT4 m_toolColor; + Renderable* m_lineToolRenderable; - float m_damageRadius; - float m_compressiveDamage; - float m_explosiveImpulse; - float m_stressForceFactor; - uint32_t m_damageProfile; + float m_damage; + float m_explosiveImpulse; + float m_stressForceFactor; struct Damager { - const char* uiName; - NvBlastDamageProgram program; - DirectX::XMFLOAT4 pointerColor; - std::function<void(const Damager* damager, Nv::Blast::ExtPxActor* actor, physx::PxVec3 position, physx::PxVec3 normal)> executeFunction; - - void execute(Nv::Blast::ExtPxActor* actor, physx::PxVec3 position, physx::PxVec3 normal) + Damager() : damageWhilePressed(false), radius(5.0f), radiusLimit(1000.0f) { - executeFunction(this, actor, position, normal); } + + enum PointerType + { + Sphere, + Line + }; + + typedef std::function<void(const Damager* damager, Nv::Blast::ExtPxActor* actor, physx::PxVec3 origin, physx::PxVec3 position, physx::PxVec3 normal)> ExecuteFn; + + const char* uiName; + NvBlastDamageProgram program; + PointerType pointerType; + DirectX::XMFLOAT4 pointerColor; + float radius; + float radiusLimit; + bool damageWhilePressed; + ExecuteFn executeFunction; }; - std::vector<Damager> m_armory; - std::vector<const char*> m_armoryNames; + std::vector<Damager> m_damagers; + std::vector<const char*> m_damagerNames; + uint32_t m_damagerIndex; + + bool m_damageMode; - bool m_damageMode; + physx::PxVec2 m_lastMousePos; + bool m_isMousePressed; + uint32_t m_damageCountWhilePressed; }; #endif
\ No newline at end of file diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp index 244f121..b2533a6 100644 --- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, related documentation -* and any modifications thereto. Any use, reproduction, disclosure or -* distribution of this software and related documentation without an express -* license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + #include "EditionToolController.h" #include "BlastController.h" @@ -76,7 +94,7 @@ LRESULT EditionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR PxRaycastHit hit; hit.shape = NULL; PxRaycastBuffer hit1; - getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL); + getPhysXController().getEditPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL); hit = hit1.block; PxRigidActor* actor = NULL; @@ -109,19 +127,8 @@ void EditionToolController::fracture(PxActor* actor) return; } - ExtPxActor* extActor = NULL; PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>(); - if (NULL != rigidDynamic) - { - extActor = blastController.getExtPxManager().getActorFromPhysXActor(*rigidDynamic); - } - if (NULL == extActor) - { - return; - } - - uint32_t chunkCount = extActor->getChunkCount(); - if (chunkCount <= 0) + if (NULL == rigidDynamic) { return; } @@ -131,7 +138,7 @@ void EditionToolController::fracture(PxActor* actor) for (; it != families.end(); it++) { BlastFamilyPtr f = *it; - if (f->find(extActor)) + if (f->find(*actor)) { pBlastFamily = f; break; @@ -142,17 +149,13 @@ void EditionToolController::fracture(PxActor* actor) return; } - const uint32_t* chunkIndices = extActor->getChunkIndices(); + const uint32_t chunkIndex = pBlastFamily->getChunkIndexByPxActor(*actor); const BlastAsset& blastAsset = pBlastFamily->getBlastAsset(); - const BlastAsset* pBlastAsset = &blastAsset; - - SceneController& sceneController = getManager()->getSceneController(); - AssetList::ModelAsset desc; - sceneController.GetAssetDesc(pBlastAsset, desc); + BlastAsset* pBlastAsset = (BlastAsset*)&blastAsset; - std::string assetname = desc.id; - GlobalSettings& globalSettings = GlobalSettings::Inst(); - getManager()->fractureAsset(globalSettings.m_projectFileDir, assetname, pBlastAsset, chunkIndices[0]); - getManager()->addModelAsset(globalSettings.m_projectFileDir, assetname, desc.isSkinned, desc.transform, false); + VoronoiFractureExecutor executor; + executor.setSourceAsset(pBlastAsset); + executor.setTargetChunk(chunkIndex); + executor.execute(); }
\ No newline at end of file diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h index b1e88d1..5f71b58 100644 --- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/EditionToolController.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, related documentation -* and any modifications thereto. Any use, reproduction, disclosure or -* distribution of this software and related documentation without an express -* license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + #ifndef EDITION_TOOL_CONTROLLER_H #define EDITION_TOOL_CONTROLLER_H diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.cpp new file mode 100644 index 0000000..28ac182 --- /dev/null +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.cpp @@ -0,0 +1,256 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + + +#include "ExplodeToolController.h" +#include "RenderUtils.h" +#include "BlastController.h" +#include "Renderer.h" +#include "PhysXController.h" +#include "SampleProfiler.h" +#include "GizmoToolController.h" + +#include <imgui.h> + +#include "NvBlastTkActor.h" +#include "NvBlastExtDamageShaders.h" + +#include "PxRigidDynamic.h" +#include "PxScene.h" +#include "BlastSceneTree.h" +#include "SimpleScene.h" +#include "ViewerOutput.h" + +using namespace Nv::Blast; +using namespace physx; + +const float EXPLODE_MIN = 0.0f; +const float EXPLODE_MAX = 2.0f; +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Setup +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +ExplodeToolController::ExplodeToolController() + : m_previousExplodeValue(0.0f) + , m_starDrag(false) +{ +} + +ExplodeToolController::~ExplodeToolController() +{ +} + +void ExplodeToolController::onSampleStart() +{ +} + +void ExplodeToolController::onInitialize() +{ + m_previousExplodeValue = 0.0f; +} + + +void ExplodeToolController::onSampleStop() +{ +} + +void ExplodeToolController::Animate(double dt) +{ + PROFILER_SCOPED_FUNCTION(); +} + + +LRESULT ExplodeToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PROFILER_SCOPED_FUNCTION(); + + SampleManager* pSampleManager = SampleManager::ins(); + if (pSampleManager->IsSimulating()) + { + return 1; + } + + if (uMsg == WM_LBUTTONDOWN) + { + m_mouseStartPoint.x = (short)LOWORD(lParam); + m_mouseStartPoint.y = (short)HIWORD(lParam); + m_starDrag = true; + } + else if (uMsg == WM_MOUSEMOVE) + { + if (!m_starDrag) + return 1; + + float theDragDistance = (short)LOWORD(lParam) - m_mouseStartPoint.x; + // ignore shorter mouse move + if (fabs(theDragDistance) <= 3.0) + return 1; + + theDragDistance /= getRenderer().getScreenWidth(); + theDragDistance *= EXPLODE_MAX; + float theNewExplodeValue = m_previousExplodeValue + (float)theDragDistance; + + if (theNewExplodeValue < 0) + theNewExplodeValue = 0; + else if (theNewExplodeValue > EXPLODE_MAX) + theNewExplodeValue = EXPLODE_MAX; + + _explode(theNewExplodeValue); + } + else if (uMsg == WM_LBUTTONUP) + { + m_previousExplodeValue = 0.0f; + m_starDrag = false; + } + return 1; +} + +void ExplodeToolController::drawUI() +{ +} + +void ExplodeToolController::_explode(float value) +{ + SampleManager* pSampleManager = SampleManager::ins(); + + BlastAsset* pBlastAsset = nullptr; + int nFamilyIndex = -1; + pSampleManager->getCurrentSelectedInstance(&pBlastAsset, nFamilyIndex); + if (pBlastAsset == nullptr) + { + std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = pSampleManager->getAssetDescMap(); + if (AssetDescMap.size() == 1) + { + std::map<BlastAsset*, AssetList::ModelAsset>::iterator itAssetDescMap = AssetDescMap.begin(); + pSampleManager->setCurrentSelectedInstance(itAssetDescMap->first, -1); + pBlastAsset = pSampleManager->getCurBlastAsset(); + viewer_msg("no asset selected, use the only one in current scene."); + } + } + if (pBlastAsset == nullptr) + { + viewer_msg("please select one asset before explode."); + return; + } + + std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = pSampleManager->getAssetFamiliesMap(); + std::map<BlastAsset*, std::vector<BlastFamily*>>::iterator itAFM = AssetFamiliesMap.find(pBlastAsset); + if (itAFM == AssetFamiliesMap.end()) + { + return; + } + + std::vector<BlastFamily*> families = itAFM->second; + int familySize = families.size(); + if (familySize == 0) + { + viewer_msg("no instance for current asset."); + return; + } + + if (nFamilyIndex == -1 || nFamilyIndex >= familySize) + { + nFamilyIndex = 0; + viewer_msg("no instance selected, use the first one of current asset."); + } + + BlastFamily* pFamily = families[nFamilyIndex]; + + PxScene& scene = pSampleManager->getPhysXController().getEditPhysXScene(); + const PxU32 actorsCountTotal = scene.getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC); + if (actorsCountTotal == 0) + { + return; + } + + std::vector<PxActor*> actorsTotal(actorsCountTotal); + PxU32 nbActors = scene.getActors(PxActorTypeFlag::eRIGID_DYNAMIC, &actorsTotal[0], actorsCountTotal, 0); + PX_ASSERT(actorsCountTotal == nbActors); + + std::vector<PxActor*> actors; + PxActor* pRootActor = nullptr; + for (int act = 0; act < actorsCountTotal; act++) + { + if (pFamily->find(*actorsTotal[act])) + { + if (pRootActor == nullptr) + { + uint32_t chunkIndex = pFamily->getChunkIndexByPxActor(*actorsTotal[act]); + std::vector<uint32_t> chunkIndexes; + chunkIndexes.push_back(chunkIndex); + std::vector<BlastChunkNode*> chunkNodes = BlastTreeData::ins().getChunkNodeByBlastChunk(pBlastAsset, chunkIndexes); + if (chunkNodes.size() > 0 && BlastTreeData::isRoot(chunkNodes[0])) + { + pRootActor = actorsTotal[act]; + } + else + { + actors.push_back(actorsTotal[act]); + } + } + else + { + actors.push_back(actorsTotal[act]); + } + } + } + + if (pRootActor == nullptr) + { + return; + } + + BlastController& blastController = pSampleManager->getBlastController(); + + PxVec3 origin = pRootActor->getWorldBounds().getCenter(); + + int actorsCount = actors.size(); + for (int ac = 0; ac < actorsCount; ac++) + { + PxActor* actor = actors[ac]; + PxRigidDynamic* dynamic = actor->is<PxRigidDynamic>(); + PX_ASSERT(dynamic != nullptr); + PxTransform transformOld = dynamic->getGlobalPose(); + PxTransform transformNew = transformOld; + + PxBounds3 bound = actor->getWorldBounds(); + PxVec3 target = bound.getCenter(); + + //PxVec3 tChange = (target - origin) * value; + //PxVec3 newTarget = target + tChange; + //transformNew.p = transformOld.p + tChange; + transformNew.p = (target - origin) * value; + + dynamic->setGlobalPose(transformNew); + blastController.updateActorRenderableTransform(*actor, transformNew, false); + } +} diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.h new file mode 100644 index 0000000..9a417ca --- /dev/null +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/ExplodeToolController.h @@ -0,0 +1,100 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + + +#ifndef EXPLODE_TOOL_CONTROLLER_H +#define EXPLODE_TOOL_CONTROLLER_H + +#include "SampleManager.h" +#include "PxVec2.h" +#include "PxVec3.h" +#include "DebugRenderBuffer.h" +#include "BlastFamily.h" +#include "NvBlastExtPxManager.h" +#include "BlastSceneTree.h" + +class Renderable; +class RenderMaterial; + +namespace Nv +{ +namespace Blast +{ +class ExtPxActor; +} +} + +namespace physx +{ + class PxScene; +} + +class ExplodeToolController : public ISampleController +{ +public: + ExplodeToolController(); + virtual ~ExplodeToolController(); + + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual void Animate(double dt); + void drawUI(); + + virtual void onInitialize(); + virtual void onSampleStart(); + virtual void onSampleStop(); + +private: + ExplodeToolController& operator= (ExplodeToolController&); + + //////// private methods //////// + + //////// used controllers //////// + + Renderer& getRenderer() const + { + return getManager()->getRenderer(); + } + + PhysXController& getPhysXController() const + { + return getManager()->getPhysXController(); + } + + BlastController& getBlastController() const + { + return getManager()->getBlastController(); + } + + void _explode(float value); + //////// internal data //////// + + float m_previousExplodeValue; + PxVec2 m_mouseStartPoint; + bool m_starDrag; +}; + +#endif // EXPLODE_TOOL_CONTROLLER_H
\ No newline at end of file diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp index ff0ffa9..ea91766 100644 --- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, related documentation -* and any modifications thereto. Any use, reproduction, disclosure or -* distribution of this software and related documentation without an express -* license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + #include "GizmoToolController.h" #include "RenderUtils.h" @@ -15,6 +33,7 @@ #include "Renderer.h" #include "PhysXController.h" #include "SampleProfiler.h" +#include "ViewerOutput.h" #include <imgui.h> @@ -23,9 +42,12 @@ #include "PxRigidDynamic.h" #include "PxScene.h" +#include "PxPhysics.h" +#include "cooking/PxCooking.h" +#include "NvBlastExtPxActor.h" #include <AppMainWindow.h> - - +#include "BlastSceneTree.h" +#include "SimpleScene.h" using namespace Nv::Blast; using namespace physx; @@ -43,65 +65,123 @@ const physx::PxU32 Y_DIRECTION_COLOR_U = XMFLOAT4ToU32Color(Y_DIRECTION_COLOR_F) const physx::PxU32 Z_DIRECTION_COLOR_U = XMFLOAT4ToU32Color(Z_DIRECTION_COLOR_F); const physx::PxU32 HIGHLIGHT_COLOR_U = XMFLOAT4ToU32Color(HIGHLIGHT_COLOR_F); -const float defaultAxisLength = 10.0; +float defaultAxisLength = 10.0; const float defaultAxisModifier = -1.0; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -GizmoToolController::GizmoToolController() +void modifyPxActorByLocalWay(PxScene& pxScene, PxRigidDynamic& actor, PxTransform& gp_old, PxTransform& gp_new) { - m_bGizmoFollowed = false; + uint32_t shapesCount = actor.getNbShapes(); + if (shapesCount > 0) + { + PxTransform gp_newInv = gp_new.getInverse(); - int segment = 36; - double span = PxTwoPi / segment; - PxVec3* vertex = new PxVec3[segment]; + PxTransform lp_old; + PxTransform lp_new; - for (int i = 0; i < segment; i++) - { - vertex[i].x = 0; - vertex[i].y = 10 * PxSin(i * span); - vertex[i].z = 10 * PxCos(i * span); - } - // x - for (int i = 0; i < segment - 1; i++) - { - m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], X_DIRECTION_COLOR_U)); - } - m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], X_DIRECTION_COLOR_U)); + std::vector<PxShape*> shapes(shapesCount); + actor.getShapes(&shapes[0], shapesCount); - for (int i = 0; i < segment; i++) - { - vertex[i].x = 10 * PxCos(i * span); - vertex[i].y = 0; - vertex[i].z = 10 * PxSin(i * span); - } - // y - for (int i = 0; i < segment - 1; i++) - { - m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], Y_DIRECTION_COLOR_U)); + pxScene.removeActor(actor); + for (uint32_t i = 0; i < shapesCount; i++) + { + PxShape* shape = shapes[i]; + + actor.detachShape(*shape); + + lp_old = shape->getLocalPose(); + lp_new = gp_newInv * gp_old * lp_old; + shape->setLocalPose(lp_new); + + actor.attachShape(*shape); + } + pxScene.addActor(actor); } - m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], Y_DIRECTION_COLOR_U)); +} - for (int i = 0; i < segment; i++) +void scalePxActor(PxScene& pxScene, PxRigidDynamic& actor, PxMat44& scale) +{ + uint32_t shapesCount = actor.getNbShapes(); + if (shapesCount == 0) { - vertex[i].x = 10 * PxCos(i * span); - vertex[i].y = 10 * PxSin(i * span); - vertex[i].z = 0; + return; } - // z - for (int i = 0; i < segment - 1; i++) + + std::vector<PxShape*> shapes(shapesCount); + actor.getShapes(&shapes[0], shapesCount); + + pxScene.removeActor(actor); + + for (uint32_t i = 0; i < shapesCount; i++) { - m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], Z_DIRECTION_COLOR_U)); + PxShape* shape = shapes[i]; + + PxConvexMeshGeometry mesh; + bool valid = shape->getConvexMeshGeometry(mesh); + if (!valid) + { + continue; + } + + PxConvexMesh* pMesh = mesh.convexMesh; + if (NULL == pMesh) + { + continue; + } + + PxU32 numVertex = pMesh->getNbVertices(); + if (numVertex == 0) + { + continue; + } + + const PxVec3* pVertex = pMesh->getVertices(); + PxVec3* pVertexNew = new PxVec3[numVertex]; + for (PxU32 v = 0; v < numVertex; v++) + { + pVertexNew[v] = scale.transform(pVertex[v]); + } + + PxConvexMeshDesc convexMeshDesc; + convexMeshDesc.points.count = numVertex; + convexMeshDesc.points.data = pVertexNew; + convexMeshDesc.points.stride = sizeof(PxVec3); + convexMeshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX; + SampleManager* manager = SampleManager::ins(); + PxPhysics& physics = manager->getPhysXController().getPhysics(); + PxCooking& cooking = manager->getPhysXController().getCooking(); + PxConvexMesh* convexMesh = cooking.createConvexMesh(convexMeshDesc, physics.getPhysicsInsertionCallback()); + if (NULL == convexMesh) + { + delete[] pVertexNew; + continue; + } + + mesh.convexMesh = convexMesh; + + actor.detachShape(*shape); + shape->setGeometry(mesh); + actor.attachShape(*shape); + + pMesh->release(); + delete[] pVertexNew; } - m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], Z_DIRECTION_COLOR_U)); - delete[] vertex; - vertex = NULL; + pxScene.addActor(actor); +} + +GizmoToolController::GizmoToolController() +{ + m_bGizmoFollowed = false; + + UpdateCircleRenderData(defaultAxisLength); resetPos(); + + BlastSceneTree::ins()->addObserver(this); } GizmoToolController::~GizmoToolController() @@ -154,6 +234,37 @@ void GizmoToolController::onSampleStop() { } +void GizmoToolController::dataSelected(std::vector<BlastNode*> selections) +{ + if (!IsEnabled()) + return; + + BlastController& blastController = getBlastController(); + std::vector<BlastFamilyPtr>& families = blastController.getFamilies(); + + std::set<PxActor*> selectedActors; + PxActor* targetActor = nullptr; + for (BlastFamily* family : families) + { + std::vector<uint32_t> selectedChunks = family->getSelectedChunks(); + for (uint32_t chunkIndex : selectedChunks) + { + PxActor* actor = nullptr; + family->getPxActorByChunkIndex(chunkIndex, &actor); + + if (actor) + { + selectedActors.insert(actor); + targetActor = actor; + } + } + } + + if (targetActor) + setTargetActor(targetActor); + getSelectionToolController().setTargetActors(selectedActors); +} + void GizmoToolController::Animate(double dt) { PROFILER_SCOPED_FUNCTION(); @@ -170,6 +281,9 @@ void GizmoToolController::Animate(double dt) return; } + m_TargetPos = m_CurrentActor->getGlobalPose().p; + m_bNeedResetPos = true; + bool isTranslation = m_GizmoToolMode == GTM_Translate; bool isScale = m_GizmoToolMode == GTM_Scale; bool isRotation = m_GizmoToolMode == GTM_Rotation; @@ -187,6 +301,8 @@ void GizmoToolController::Animate(double dt) m_AxisBoxRenderable[AT_Y]->setHidden(!isScale); m_AxisBoxRenderable[AT_Z]->setHidden(!isScale); + syncRenderableState(); + if (showLine) { if (m_bNeedResetPos) @@ -430,8 +546,6 @@ void GizmoToolController::Animate(double dt) m_bNeedResetColor = false; } -#include "PxPhysics.h" -#include "cooking/PxCooking.h" LRESULT GizmoToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PROFILER_SCOPED_FUNCTION(); @@ -439,297 +553,338 @@ LRESULT GizmoToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM if (uMsg == WM_LBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP) { float mouseX = (short)LOWORD(lParam) / getRenderer().getScreenWidth(); + if (!SimpleScene::Inst()->m_pCamera->_lhs) + { + mouseX = 1 - mouseX; + } float mouseY = (short)HIWORD(lParam) / getRenderer().getScreenHeight(); - bool press = uMsg == WM_LBUTTONDOWN; - if (m_GizmoToolMode == GTM_Translate) + PxVec3 eyePos, pickDir; + getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); + pickDir = pickDir.getNormalized(); + + if (uMsg == WM_LBUTTONDOWN) { - if (uMsg == WM_LBUTTONDOWN) + if (m_AxisSelected == AT_Num) { - if (m_AxisSelected == AT_Num) - { - PxVec3 eyePos, pickDir; - getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); - pickDir = pickDir.getNormalized(); + PxRaycastBufferN<32> hits; + GetPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hits, PxHitFlag::ePOSITION | PxHitFlag::eMESH_MULTIPLE); - PxRaycastHit hit; hit.shape = NULL; - PxRaycastBuffer hit1; - getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL); - hit = hit1.block; + PxU32 nbThouches = hits.getNbTouches(); + const PxRaycastHit* touches = hits.getTouches(); - if (hit.shape) + PxRigidActor* actor = NULL; + for (PxU32 u = 0; u < nbThouches; ++u) + { + const PxRaycastHit& t = touches[u]; + if (t.shape && getBlastController().isActorVisible(*(t.actor))) { - PxRigidActor* actor = hit.actor; - PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>(); - if (NULL != rigidDynamic) - { - m_CurrentActor = actor; - getSelectionToolController().pointSelect(m_CurrentActor); + actor = t.actor; + } + } - PxTransform gp = m_CurrentActor->getGlobalPose(); + if (actor) + { + PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>(); + if (NULL != rigidDynamic) + { + m_CurrentActor = rigidDynamic; + getSelectionToolController().pointSelect(m_CurrentActor); - m_TargetPos = gp.p; - m_Axis[AT_X] = gp.q.rotate(PxVec3(defaultAxisLength, 0, 0)); - m_Axis[AT_Y] = gp.q.rotate(PxVec3(0, defaultAxisLength, 0)); - m_Axis[AT_Z] = gp.q.rotate(PxVec3(0, 0, defaultAxisLength)); + PxTransform gp = m_CurrentActor->getGlobalPose(); - m_bNeedResetPos = true; - } - else - { - m_CurrentActor = NULL; - getSelectionToolController().clearSelect(); - } + m_TargetPos = gp.p; + m_Axis[AT_X] = gp.q.rotate(PxVec3(defaultAxisLength, 0, 0)); + m_Axis[AT_Y] = gp.q.rotate(PxVec3(0, defaultAxisLength, 0)); + m_Axis[AT_Z] = gp.q.rotate(PxVec3(0, 0, defaultAxisLength)); + + m_bNeedResetPos = true; + } + else + { + m_CurrentActor = NULL; + getSelectionToolController().clearSelect(); } } - else + } + else + { + m_bGizmoFollowed = (m_CurrentActor != NULL); + + if (m_GizmoToolMode == GTM_Scale) { - m_bGizmoFollowed = (m_CurrentActor != NULL); + m_LastAxis[AT_X] = m_Axis[AT_X].getNormalized(); + m_LastAxis[AT_Y] = m_Axis[AT_Y].getNormalized(); + m_LastAxis[AT_Z] = m_Axis[AT_Z].getNormalized(); } } - else if (uMsg == WM_MOUSEMOVE) + } + else if (uMsg == WM_MOUSEMOVE) + { + if (m_bGizmoFollowed) { - if (m_bGizmoFollowed) + switch (m_GizmoToolMode) { - PxVec3 eyePos, pickDir; - getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); - pickDir = pickDir.getNormalized(); - - PxVec3 axis = m_Axis[m_AxisSelected]; - axis = axis.getNormalized(); - PxVec3 samplepoint = eyePos + pickDir; - PxVec3 normal = m_LastEyeRay.cross(axis); - normal = normal.getNormalized(); - PxVec3 foot; - GetFootFromPointToPlane(samplepoint, eyePos, normal, foot); - PxVec3 direction = foot - eyePos; - direction = direction.getNormalized(); - PxVec3 target; - GetIntersectBetweenLines(m_LastFoot, axis, eyePos, direction, target); - PxVec3 delta = target - m_LastFoot; - - m_LastEyeRay = direction; - m_LastFoot = target; - - PxTransform gp_old = m_CurrentActor->getGlobalPose(); - PxTransform gp_new(gp_old.p + delta, gp_old.q);; - m_CurrentActor->setGlobalPose(gp_new); - - m_TargetPos = gp_new.p; - - bool local = AppMainWindow::Inst().m_bGizmoWithLocal; - if (local) + case GTM_Translate: { - uint32_t shapesCount = m_CurrentActor->getNbShapes(); - if (shapesCount > 0) + if (AppMainWindow::Inst().m_bGizmoWithLocal && !CanModifyLocal(m_CurrentActor)) { - PxTransform gp_newInv = gp_new.getInverse(); + char message[1024]; + sprintf(message, "Only unfractured model can be modify in local way in edit mode!"); + viewer_warn(message); + return 1; + } - PxTransform lp_old; - PxTransform lp_new; + PxVec3 axis = m_Axis[m_AxisSelected]; + axis = axis.getNormalized(); + PxVec3 samplepoint = eyePos + pickDir; + PxVec3 normal = m_LastEyeRay.cross(axis); + normal = normal.getNormalized(); + PxVec3 foot; + GetFootFromPointToPlane(samplepoint, eyePos, normal, foot); + PxVec3 direction = foot - eyePos; + direction = direction.getNormalized(); + PxVec3 target; + GetIntersectBetweenLines(m_LastFoot, axis, eyePos, direction, target); + PxVec3 delta = target - m_LastFoot; - std::vector<PxShape*> shapes(shapesCount); - m_CurrentActor->getShapes(&shapes[0], shapesCount); - getPhysXController().getPhysXScene().removeActor(*m_CurrentActor); - for (uint32_t i = 0; i < shapesCount; i++) - { - PxShape* shape = shapes[i]; + m_LastEyeRay = direction; + m_LastFoot = target; - m_CurrentActor->detachShape(*shape); + PxTransform gp_old = m_CurrentActor->getGlobalPose(); + PxTransform gp_new(gp_old.p + delta, gp_old.q); + m_CurrentActor->setGlobalPose(gp_new); - lp_old = shape->getLocalPose(); - lp_new = gp_newInv * gp_old * lp_old; - shape->setLocalPose(lp_new); + bool modifyLocal = AppMainWindow::Inst().m_bGizmoWithLocal && CanModifyLocal(m_CurrentActor); - m_CurrentActor->attachShape(*shape); - } - getPhysXController().getPhysXScene().addActor(*m_CurrentActor); + if (!SampleManager::ins()->IsSimulating()) + { + getBlastController().updateActorRenderableTransform(*m_CurrentActor, gp_new, modifyLocal); + if (CanMapToRootChunk(m_CurrentActor) && !modifyLocal) + UpdateAssetInstanceTransform(gp_new); } - } - m_bNeedResetPos = true; - m_bNeedResetColor = true; - } - else if(m_CurrentActor != NULL) - { - PxVec3 eyePos, pickDir; - getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); - pickDir = pickDir.getNormalized(); + m_TargetPos = gp_new.p; - m_LastEyeRay = pickDir; + if (modifyLocal) + { + modifyPxActorByLocalWay(GetPhysXScene(), *m_CurrentActor, gp_old, gp_new); + } - // get axis which intersect with this eye ray - AxisType as = AT_Num; + m_bNeedResetPos = true; + m_bNeedResetColor = true; + } + break; + case GTM_Scale: { - double distanceMin = PX_MAX_F32; - double tolerance = 1; - int line_index = -1; - PxVec3 foot; - std::vector<PxDebugLine>& lines = m_AxisRenderBuffer.m_lines; - int linesize = lines.size(); - for (int l = 0; l < linesize; l++) + if (AppMainWindow::Inst().m_bGizmoWithLocal && !CanModifyLocal(m_CurrentActor)) { - PxVec3 start = lines[l].pos0; - PxVec3 end = lines[l].pos1; - PxVec3 dir = end - start; - double length = dir.magnitude(); - // separate the line to 10 segment - double delta = length * 0.1; - for (int segment = 0; segment <= 10; segment++) - { - PxVec3 vertex = start + 0.1 * segment * dir; - double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot); + char message[1024]; + sprintf(message, "Only unfractured model can be modify in local way in edit mode!"); + viewer_warn(message); + return 1; + } - if (distance < distanceMin) - { - distanceMin = distance; - line_index = l; - m_LastFoot = foot; - } - } + PxVec3 axis = m_LastAxis[m_AxisSelected]; + PxVec3 samplepoint = eyePos + pickDir; + PxVec3 normal = m_LastEyeRay.cross(axis); + normal = normal.getNormalized(); + PxVec3 foot; + GetFootFromPointToPlane(samplepoint, eyePos, normal, foot); + PxVec3 direction = foot - eyePos; + direction = direction.getNormalized(); + PxVec3 target; + GetIntersectBetweenLines(m_LastFoot, axis, eyePos, direction, target); + PxVec3 delta = target - m_LastFoot; + + if (m_AxisSelected == AT_X) + { + delta *= defaultAxisModifier; } - if (distanceMin < tolerance) + m_Axis[m_AxisSelected] = m_LastAxis[m_AxisSelected] * defaultAxisLength + delta; + + bool isShift = (GetAsyncKeyState(VK_SHIFT) && 0x8000); + if (isShift) { - int axis_index = line_index * 3 / linesize; - as = (AxisType)axis_index; + float length = m_Axis[m_AxisSelected].magnitude(); + m_Axis[AT_X] = m_LastAxis[AT_X] * length; + m_Axis[AT_Y] = m_LastAxis[AT_Y] * length; + m_Axis[AT_Z] = m_LastAxis[AT_Z] * length; } - } - setAxisSelected(as); - } - } - else if (uMsg == WM_LBUTTONUP) - { - m_bNeedResetPos = true; - m_bNeedResetColor = true; - m_bGizmoFollowed = false; - } - } - else if (m_GizmoToolMode == GTM_Scale) - { - if (uMsg == WM_LBUTTONDOWN) - { - if (m_AxisSelected == AT_Num) - { - PxVec3 eyePos, pickDir; - getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); - pickDir = pickDir.getNormalized(); - PxRaycastHit hit; hit.shape = NULL; - PxRaycastBuffer hit1; - getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL); - hit = hit1.block; + ScaleActor(false); + + m_bNeedResetPos = true; + m_bNeedResetColor = true; + } + break; - if (hit.shape) + case GTM_Rotation: { - PxRigidActor* actor = hit.actor; - PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>(); - if (NULL != rigidDynamic) + if (AppMainWindow::Inst().m_bGizmoWithLocal && !CanModifyLocal(m_CurrentActor)) + { + char message[1024]; + sprintf(message, "Only unfractured model can be modify in local way in edit mode!"); + viewer_warn(message); + return 1; + } + + PxVec3 planenormal = m_Axis[m_AxisSelected]; + planenormal = planenormal.getNormalized(); + + PxVec3 from, to; + CalPlaneLineIntersectPoint(from, planenormal, m_TargetPos, m_LastEyeRay, eyePos); + CalPlaneLineIntersectPoint(to, planenormal, m_TargetPos, pickDir, eyePos); + from = from - m_TargetPos; + to = to - m_TargetPos; + from = from.getNormalized(); + to = to.getNormalized(); + float cosangle = from.dot(to); + float angle = PxAcos(cosangle); + PxVec3 cross = from.cross(to); + cross = cross.getNormalized(); + + PxQuat q(angle, cross); + if (m_AxisSelected == AT_X) + { + m_Axis[AT_Y] = q.rotate(m_Axis[AT_Y]); + m_Axis[AT_Z] = q.rotate(m_Axis[AT_Z]); + } + else if (m_AxisSelected == AT_Y) + { + m_Axis[AT_X] = q.rotate(m_Axis[AT_X]); + m_Axis[AT_Z] = q.rotate(m_Axis[AT_Z]); + } + else if (m_AxisSelected == AT_Z) { - m_CurrentActor = actor; - getSelectionToolController().pointSelect(m_CurrentActor); + m_Axis[AT_X] = q.rotate(m_Axis[AT_X]); + m_Axis[AT_Y] = q.rotate(m_Axis[AT_Y]); + } - PxTransform gp = m_CurrentActor->getGlobalPose(); + m_LastEyeRay = pickDir; - m_TargetPos = gp.p; - m_Axis[AT_X] = gp.q.rotate(PxVec3(defaultAxisLength, 0, 0)); - m_Axis[AT_Y] = gp.q.rotate(PxVec3(0, defaultAxisLength, 0)); - m_Axis[AT_Z] = gp.q.rotate(PxVec3(0, 0, defaultAxisLength)); + PxTransform gp_old = m_CurrentActor->getGlobalPose(); + PxTransform gp_new = PxTransform(gp_old.p, CalConvertQuat()); + m_CurrentActor->setGlobalPose(gp_new); + bool modifyLocal = AppMainWindow::Inst().m_bGizmoWithLocal && CanModifyLocal(m_CurrentActor); - m_bNeedResetPos = true; + if (!SampleManager::ins()->IsSimulating()) + { + getBlastController().updateActorRenderableTransform(*m_CurrentActor, gp_new, modifyLocal); + if (CanMapToRootChunk(m_CurrentActor)) + UpdateAssetInstanceTransform(gp_new); } - else + + if (modifyLocal) { - m_CurrentActor = NULL; - getSelectionToolController().clearSelect(); + modifyPxActorByLocalWay(GetPhysXScene(), *m_CurrentActor, gp_old, gp_new); } + + m_bNeedResetPos = true; + m_bNeedResetColor = true; } - } - else - { - m_bGizmoFollowed = (m_CurrentActor != NULL); - m_LastAxis[AT_X] = m_Axis[AT_X].getNormalized(); - m_LastAxis[AT_Y] = m_Axis[AT_Y].getNormalized(); - m_LastAxis[AT_Z] = m_Axis[AT_Z].getNormalized(); + break; } } - else if (uMsg == WM_MOUSEMOVE) + else if(m_CurrentActor != NULL) { - if (m_bGizmoFollowed) + m_LastEyeRay = pickDir; + + // get axis which intersect with this eye ray + AxisType as = AT_Num; { - PxVec3 eyePos, pickDir; - getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); - pickDir = pickDir.getNormalized(); - - PxVec3 axis = m_LastAxis[m_AxisSelected]; - PxVec3 samplepoint = eyePos + pickDir; - PxVec3 normal = m_LastEyeRay.cross(axis); - normal = normal.getNormalized(); + double distanceMin = PX_MAX_F32; + double tolerance = defaultAxisLength / 20.0f; + int line_index = -1; PxVec3 foot; - GetFootFromPointToPlane(samplepoint, eyePos, normal, foot); - PxVec3 direction = foot - eyePos; - direction = direction.getNormalized(); - PxVec3 target; - GetIntersectBetweenLines(m_LastFoot, axis, eyePos, direction, target); - PxVec3 delta = target - m_LastFoot; - - if (m_AxisSelected == AT_X) - { - delta *= defaultAxisModifier; - } - m_Axis[m_AxisSelected] = m_LastAxis[m_AxisSelected] * defaultAxisLength + delta; - - bool isShift = (GetAsyncKeyState(VK_SHIFT) && 0x8000); - if (isShift) + switch (m_GizmoToolMode) { - float length = m_Axis[m_AxisSelected].magnitude(); - m_Axis[AT_X] = m_LastAxis[AT_X] * length; - m_Axis[AT_Y] = m_LastAxis[AT_Y] * length; - m_Axis[AT_Z] = m_LastAxis[AT_Z] * length; - } - - ScaleActor(false); - - m_bNeedResetPos = true; - m_bNeedResetColor = true; - } - else if (m_CurrentActor != NULL) - { - PxVec3 eyePos, pickDir; - getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); - pickDir = pickDir.getNormalized(); - - m_LastEyeRay = pickDir; + case GTM_Translate: + { + std::vector<PxDebugLine>& lines = m_AxisRenderBuffer.m_lines; + int linesize = lines.size(); + for (int l = 0; l < linesize; l++) + { + PxVec3 start = lines[l].pos0; + PxVec3 end = lines[l].pos1; + PxVec3 dir = end - start; - // get axis which intersect with this eye ray - AxisType as = AT_Num; - { - double distanceMin = PX_MAX_F32; - double tolerance = 1; - int line_index = -1; - std::vector<PxDebugLine>& lines = m_AxisRenderBuffer.m_lines; - int linesize = lines.size(); - PxVec3 foot; - for (int l = 0; l < linesize; l++) + // separate the line to 10 segment + for (int segment = 0; segment <= 10; segment++) + { + PxVec3 vertex = start + 0.1 * segment * dir; + double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot); + + if (distance < distanceMin) + { + distanceMin = distance; + line_index = l; + m_LastFoot = foot; + } + } + } + if (distanceMin < tolerance) + { + int axis_index = line_index * 3 / linesize; + as = (AxisType)axis_index; + } + } + break; + case GTM_Scale: { - PxVec3 vertex = lines[l].pos1; - double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot); + std::vector<PxDebugLine>& lines = m_AxisRenderBuffer.m_lines; + int linesize = lines.size(); + for (int l = 0; l < linesize; l++) + { + PxVec3 vertex = lines[l].pos1; + double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot); - if (distance < distanceMin) + if (distance < distanceMin) + { + distanceMin = distance; + line_index = l; + m_LastFoot = foot; + } + } + if (distanceMin < tolerance) { - distanceMin = distance; - line_index = l; - m_LastFoot = foot; + as = (AxisType)line_index; } } - if (distanceMin < tolerance) + break; + case GTM_Rotation: { - as = (AxisType)line_index; + std::vector<PxDebugLine>& lines = m_CircleRenderBuffer.m_lines; + int linesize = lines.size(); + for (int l = 0; l < linesize; l++) + { + PxVec3 vertex = lines[l].pos0; + double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot); + + if (distance < distanceMin) + { + distanceMin = distance; + line_index = l; + m_LastFoot = foot; + } + } + if (distanceMin < tolerance) + { + int axis_index = line_index * 3 / linesize; + as = (AxisType)axis_index; + } } + break; + default: + break; } - setAxisSelected(as); } + setAxisSelected(as); } - else if (uMsg == WM_LBUTTONUP) + } + else if (uMsg == WM_LBUTTONUP) + { + if (m_GizmoToolMode == GTM_Scale) { if (m_AxisSelected != AT_Num) { @@ -742,180 +897,16 @@ LRESULT GizmoToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM m_Axis[AT_Y] = m_LastAxis[AT_Y] * defaultAxisLength; m_Axis[AT_Z] = m_LastAxis[AT_Z] * defaultAxisLength; } - - m_bNeedResetPos = true; - m_bNeedResetColor = true; - m_bGizmoFollowed = false; } - } - else if (m_GizmoToolMode == GTM_Rotation) - { - if (uMsg == WM_LBUTTONDOWN) - { - if (m_AxisSelected == AT_Num) - { - PxVec3 eyePos, pickDir; - getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); - pickDir = pickDir.getNormalized(); - - PxRaycastHit hit; hit.shape = NULL; - PxRaycastBuffer hit1; - getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL); - hit = hit1.block; - - if (hit.shape) - { - PxRigidActor* actor = hit.actor; - PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>(); - if (NULL != rigidDynamic) - { - m_CurrentActor = actor; - getSelectionToolController().pointSelect(m_CurrentActor); - PxTransform gp = m_CurrentActor->getGlobalPose(); - - m_TargetPos = gp.p; - m_Axis[AT_X] = gp.q.rotate(PxVec3(defaultAxisLength, 0, 0)); - m_Axis[AT_Y] = gp.q.rotate(PxVec3(0, defaultAxisLength, 0)); - m_Axis[AT_Z] = gp.q.rotate(PxVec3(0, 0, defaultAxisLength)); - - m_bNeedResetPos = true; - } - else - { - m_CurrentActor = NULL; - getSelectionToolController().clearSelect(); - } - } - } - else - { - m_bGizmoFollowed = (m_CurrentActor != NULL); - } - } - else if (uMsg == WM_MOUSEMOVE) + if (m_AxisSelected != AT_Num && AppMainWindow::Inst().m_bGizmoWithLocal) { - if (m_bGizmoFollowed) - { - PxVec3 eyePos, pickDir; - getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); - pickDir = pickDir.getNormalized(); - - PxVec3 planenormal = m_Axis[m_AxisSelected]; - planenormal = planenormal.getNormalized(); - - PxVec3 from, to; - CalPlaneLineIntersectPoint(from, planenormal, m_TargetPos, m_LastEyeRay, eyePos); - CalPlaneLineIntersectPoint(to, planenormal, m_TargetPos, pickDir, eyePos); - from = from - m_TargetPos; - to = to - m_TargetPos; - from = from.getNormalized(); - to = to.getNormalized(); - float cosangle = from.dot(to); - float angle = PxAcos(cosangle); - PxVec3 cross = from.cross(to); - cross = cross.getNormalized(); - - PxQuat q(angle, cross); - if (m_AxisSelected == AT_X) - { - m_Axis[AT_Y] = q.rotate(m_Axis[AT_Y]); - m_Axis[AT_Z] = q.rotate(m_Axis[AT_Z]); - } - else if (m_AxisSelected == AT_Y) - { - m_Axis[AT_X] = q.rotate(m_Axis[AT_X]); - m_Axis[AT_Z] = q.rotate(m_Axis[AT_Z]); - } - else if (m_AxisSelected == AT_Z) - { - m_Axis[AT_X] = q.rotate(m_Axis[AT_X]); - m_Axis[AT_Y] = q.rotate(m_Axis[AT_Y]); - } - - m_LastEyeRay = pickDir; - - PxTransform gp_old = m_CurrentActor->getGlobalPose(); - PxTransform gp_new = PxTransform(gp_old.p, CalConvertQuat()); - m_CurrentActor->setGlobalPose(gp_new); - - bool local = AppMainWindow::Inst().m_bGizmoWithLocal; - if (local) - { - uint32_t shapesCount = m_CurrentActor->getNbShapes(); - if (shapesCount > 0) - { - PxTransform gp_newInv = gp_new.getInverse(); - - PxTransform lp_old; - PxTransform lp_new; - - std::vector<PxShape*> shapes(shapesCount); - m_CurrentActor->getShapes(&shapes[0], shapesCount); - getPhysXController().getPhysXScene().removeActor(*m_CurrentActor); - for (uint32_t i = 0; i < shapesCount; i++) - { - PxShape* shape = shapes[i]; - - m_CurrentActor->detachShape(*shape); - - lp_old = shape->getLocalPose(); - lp_new = gp_newInv * gp_old * lp_old; - shape->setLocalPose(lp_new); - - m_CurrentActor->attachShape(*shape); - } - getPhysXController().getPhysXScene().addActor(*m_CurrentActor); - } - } - - m_bNeedResetPos = true; - m_bNeedResetColor = true; - } - else if (m_CurrentActor != NULL) - { - PxVec3 eyePos, pickDir; - getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); - pickDir = pickDir.getNormalized(); - - m_LastEyeRay = pickDir; - - // get axis which intersect with this eye ray - AxisType as = AT_Num; - { - double distanceMin = PX_MAX_F32; - double tolerance = 1; - int line_index = -1; - std::vector<PxDebugLine>& lines = m_CircleRenderBuffer.m_lines; - int linesize = lines.size(); - PxVec3 foot; - for (int l = 0; l < linesize; l++) - { - PxVec3 vertex = lines[l].pos0; - double distance = DistanceFromPointToLine(vertex, eyePos, pickDir, foot); - - if (distance < distanceMin) - { - distanceMin = distance; - line_index = l; - m_LastFoot = foot; - } - } - if (distanceMin < tolerance) - { - int axis_index = line_index * 3 / linesize; - as = (AxisType)axis_index; - } - } - setAxisSelected(as); - } - } - else if (uMsg == WM_LBUTTONUP) - { - m_bNeedResetPos = true; - m_bNeedResetColor = true; - m_bGizmoFollowed = false; + getBlastController().updateModelMeshToProjectParam(*m_CurrentActor); } + + m_bNeedResetPos = true; + m_bNeedResetColor = true; + m_bGizmoFollowed = false; } } @@ -937,6 +928,8 @@ void GizmoToolController::setGizmoToolMode(GizmoToolMode mode) m_bNeedResetPos = true; m_bNeedResetColor = true; + + showAxisRenderables(true); } void GizmoToolController::setAxisSelected(AxisType type) @@ -950,6 +943,23 @@ void GizmoToolController::setAxisSelected(AxisType type) m_bNeedResetColor = true; } +void GizmoToolController::setAxisLength(float axisLength) +{ + defaultAxisLength = axisLength; + UpdateCircleRenderData(axisLength); + + float scale = axisLength / 10.f * 0.2f; + m_AxisConeRenderable[AT_X]->setScale(PxVec3(scale, 2 * scale, scale)); + m_AxisConeRenderable[AT_Y]->setScale(PxVec3(scale, 2 * scale, scale)); + m_AxisConeRenderable[AT_Z]->setScale(PxVec3(scale, 2 * scale, scale)); + + m_AxisBoxRenderable[AT_X]->setScale(PxVec3(scale, scale, scale)); + m_AxisBoxRenderable[AT_Y]->setScale(PxVec3(scale, scale, scale)); + m_AxisBoxRenderable[AT_Z]->setScale(PxVec3(scale, scale, scale)); + + m_bNeedResetPos = true; +} + void GizmoToolController::showAxisRenderables(bool show) { bool isTranslate = m_GizmoToolMode == GTM_Translate; @@ -974,6 +984,98 @@ void GizmoToolController::resetPos() m_CurrentActor = NULL; } +void GizmoToolController::setTargetActor(PxActor* actor) +{ + m_bNeedResetPos = true; + m_CurrentActor = nullptr; + if (actor == nullptr) + { + return; + } + PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>(); + if (rigidDynamic == nullptr) + { + return; + } + + m_CurrentActor = rigidDynamic; + getSelectionToolController().pointSelect(m_CurrentActor); + + PxTransform gp = m_CurrentActor->getGlobalPose(); + + m_TargetPos = gp.p; + m_Axis[AT_X] = gp.q.rotate(PxVec3(defaultAxisLength, 0, 0)); + m_Axis[AT_Y] = gp.q.rotate(PxVec3(0, defaultAxisLength, 0)); + m_Axis[AT_Z] = gp.q.rotate(PxVec3(0, 0, defaultAxisLength)); +} + +PxActor* GizmoToolController::getTargetActor() +{ + return m_CurrentActor; +} + +physx::PxScene& GizmoToolController::GetPhysXScene() +{ + if (getManager()->IsSimulating()) + { + return getPhysXController().getPhysXScene(); + } + else + { + return getPhysXController().getEditPhysXScene(); + } +} + +void GizmoToolController::UpdateCircleRenderData(float axisLength) +{ + int segment = 36; + double span = PxTwoPi / segment; + PxVec3* vertex = new PxVec3[segment]; + m_CircleRenderData.clear(); + + for (int i = 0; i < segment; i++) + { + vertex[i].x = 0; + vertex[i].y = axisLength * PxSin(i * span); + vertex[i].z = axisLength * PxCos(i * span); + } + // x + for (int i = 0; i < segment - 1; i++) + { + m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], X_DIRECTION_COLOR_U)); + } + m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], X_DIRECTION_COLOR_U)); + + for (int i = 0; i < segment; i++) + { + vertex[i].x = axisLength * PxCos(i * span); + vertex[i].y = 0; + vertex[i].z = axisLength * PxSin(i * span); + } + // y + for (int i = 0; i < segment - 1; i++) + { + m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], Y_DIRECTION_COLOR_U)); + } + m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], Y_DIRECTION_COLOR_U)); + + for (int i = 0; i < segment; i++) + { + vertex[i].x = axisLength * PxCos(i * span); + vertex[i].y = axisLength * PxSin(i * span); + vertex[i].z = 0; + } + // z + for (int i = 0; i < segment - 1; i++) + { + m_CircleRenderData.push_back(PxDebugLine(vertex[i], vertex[i + 1], Z_DIRECTION_COLOR_U)); + } + m_CircleRenderData.push_back(PxDebugLine(vertex[segment - 1], vertex[0], Z_DIRECTION_COLOR_U)); + + delete[] vertex; + vertex = NULL; +} + bool GizmoToolController::CalPlaneLineIntersectPoint(PxVec3& result, PxVec3 planeNormal, PxVec3 planePoint, PxVec3 linedirection, PxVec3 linePoint) { float dot = planeNormal.dot(linedirection); @@ -1008,6 +1110,16 @@ bool GizmoToolController::GetFootFromPointToPlane(PxVec3& point, PxVec3& origin, bool GizmoToolController::GetIntersectBetweenLines(PxVec3& origin1, PxVec3& direction1, PxVec3& origin2, PxVec3& direction2, PxVec3& intersect) { + float test = ((origin2 - origin1).getNormalized()).dot(direction1.cross(direction2)); + if (direction1.cross(direction2).isZero()) + {// if two lines are parallel + return false; + } + else if (abs(test) >= 0.001) + {// if two lines aren't in the same plane + return false; + } + PxVec3 normal1 = direction1.cross(direction2); PxVec3 normal2 = normal1.cross(direction1); normal2 = normal2.getNormalized(); @@ -1062,38 +1174,22 @@ PxQuat GizmoToolController::CalConvertQuat() void GizmoToolController::ScaleActor(bool replace) { - if (NULL == m_CurrentActor) - { - return; - } - ExtPxActor* extActor = NULL; - PxRigidDynamic* rigidDynamic = m_CurrentActor->is<PxRigidDynamic>(); - if (NULL != rigidDynamic) - { - extActor = getBlastController().getExtPxManager().getActorFromPhysXActor(*rigidDynamic); - } - if (NULL == extActor) + if (nullptr == m_CurrentActor) { return; } - std::vector<BlastFamilyPtr>& families = getBlastController().getFamilies(); - if (families.size() == 0) + bool isLocal = AppMainWindow::Inst().m_bGizmoWithLocal; + + if (isLocal && !CanModifyLocal(m_CurrentActor)) { + char message[1024]; + sprintf(message, "Only unfractured model can be modify in local way in edit mode!"); + viewer_warn(message); return; } - BlastFamilyPtr pBlastFamily = NULL; - std::vector<BlastFamilyPtr>::iterator it = families.begin(); - for (; it != families.end(); it++) - { - BlastFamilyPtr f = *it; - if (f->find(extActor)) - { - pBlastFamily = f; - break; - } - } + BlastFamilyPtr pBlastFamily = getBlastController().getFamilyByPxActor(*m_CurrentActor); if (NULL == pBlastFamily) { return; @@ -1116,7 +1212,6 @@ void GizmoToolController::ScaleActor(bool replace) } PxMat44 scale = PxMat44(PxVec4(delta, 1)); - bool isLocal = AppMainWindow::Inst().m_bGizmoWithLocal; if (!isLocal) { PxTransform gp = m_CurrentActor->getGlobalPose(); @@ -1134,77 +1229,87 @@ void GizmoToolController::ScaleActor(bool replace) scale = world * scale * worldInv; } - pBlastFamily->setActorScale(*extActor, scale, replace); + pBlastFamily->setActorScale(*m_CurrentActor, scale, replace); if (!replace) { return; } - uint32_t shapesCount = m_CurrentActor->getNbShapes(); - if (shapesCount == 0) + scalePxActor(GetPhysXScene(), *m_CurrentActor, scale); +} + +bool GizmoToolController::CanMapToRootChunk(PxActor* actor) +{ + if (actor) { - return; + BlastFamily* family = getBlastController().getFamilyByPxActor(*actor); + if (family == nullptr) + return false; + + const BlastAsset& asset = family->getBlastAsset(); + uint32_t chunkIndex = family->getChunkIndexByPxActor(*actor); + + std::vector<uint32_t> chunkIndexes; + chunkIndexes.push_back(chunkIndex); + std::vector<BlastChunkNode*> chunkNodes = BlastTreeData::ins().getChunkNodeByBlastChunk(&asset, chunkIndexes); + if (chunkNodes.size() > 0) + return BlastTreeData::isRoot(chunkNodes[0]); } + return false; +} - std::vector<PxShape*> shapes(shapesCount); - m_CurrentActor->getShapes(&shapes[0], shapesCount); - - getPhysXController().getPhysXScene().removeActor(*m_CurrentActor); - - for (uint32_t i = 0; i < shapesCount; i++) +bool GizmoToolController::CanModifyLocal(PxActor* actor) +{ + if (nullptr != actor + && !SampleManager::ins()->IsSimulating() + && !getBlastController().isAssetFractrued(*actor)) { - PxShape* shape = shapes[i]; - - PxConvexMeshGeometry mesh; - bool valid = shape->getConvexMeshGeometry(mesh); - if (!valid) - { - continue; - } + return true; + } - PxConvexMesh* pMesh = mesh.convexMesh; - if (NULL == pMesh) - { - continue; - } + return false; +} - PxU32 numVertex = pMesh->getNbVertices(); - if (numVertex == 0) - { - continue; - } +void GizmoToolController::UpdateAssetInstanceTransform(const PxTransform& position) +{ + if (!m_CurrentActor) + return; - const PxVec3* pVertex = pMesh->getVertices(); - PxVec3* pVertexNew = new PxVec3[numVertex]; - for (PxU32 v = 0; v < numVertex; v++) - { - pVertexNew[v] = scale.transform(pVertex[v]); - } + BlastFamily* family = getBlastController().getFamilyByPxActor(*m_CurrentActor); + if (family) + { + BPPAssetInstance* bppInstance = SampleManager::ins()->getInstanceByFamily(family); - PxConvexMeshDesc convexMeshDesc; - convexMeshDesc.points.count = numVertex; - convexMeshDesc.points.data = pVertexNew; - convexMeshDesc.points.stride = sizeof(PxVec3); - convexMeshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX; - PxPhysics& physics = getManager()->getPhysXController().getPhysics(); - PxCooking& cooking = getManager()->getPhysXController().getCooking(); - PxConvexMesh* convexMesh = cooking.createConvexMesh(convexMeshDesc, physics.getPhysicsInsertionCallback()); - if (NULL == convexMesh) + if (bppInstance) { - delete[] pVertexNew; - continue; - } + bppInstance->transform.position = *((nvidia::NvVec3*)(&position.p)); + bppInstance->transform.rotation = *((nvidia::NvVec4*)(&position.q)); - mesh.convexMesh = convexMesh; + family->initTransform(position); + // modify corresponding asset's transform, it's need to modify in future + { + const BlastAsset& asset = family->getBlastAsset(); + SampleManager* sampleManager = SampleManager::ins(); + std::map<BlastAsset*, std::vector<BlastFamily*>>& AssetFamiliesMap = sampleManager->getAssetFamiliesMap(); + std::map<BlastAsset*, AssetList::ModelAsset>& AssetDescMap = sampleManager->getAssetDescMap(); - m_CurrentActor->detachShape(*shape); - shape->setGeometry(mesh); - m_CurrentActor->attachShape(*shape); + BlastAsset* pBlastAsset = (BlastAsset*)&asset; - pMesh->release(); - delete[] pVertexNew; + AssetList::ModelAsset& m = AssetDescMap[pBlastAsset]; + m.transform = position; + } + } } +} - getPhysXController().getPhysXScene().addActor(*m_CurrentActor); +void GizmoToolController::syncRenderableState() +{ + bool depthTest = AppMainWindow::Inst().m_bGizmoWithDepthTest; + m_AxisConeRenderable[AT_X]->setDepthTest(depthTest); + m_AxisConeRenderable[AT_Y]->setDepthTest(depthTest); + m_AxisConeRenderable[AT_Z]->setDepthTest(depthTest); + m_AxisBoxRenderable[AT_X]->setDepthTest(depthTest); + m_AxisBoxRenderable[AT_Y]->setDepthTest(depthTest); + m_AxisBoxRenderable[AT_Z]->setDepthTest(depthTest); }
\ No newline at end of file diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h index 215cde5..8586ad3 100644 --- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/GizmoToolController.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, related documentation -* and any modifications thereto. Any use, reproduction, disclosure or -* distribution of this software and related documentation without an express -* license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + #ifndef GIZMO_TOOL_CONTROLLER_H #define GIZMO_TOOL_CONTROLLER_H @@ -14,6 +32,7 @@ #include "SampleManager.h" #include "DebugRenderBuffer.h" #include "NvBlastExtPxManager.h" +#include "BlastSceneTree.h" class Renderable; class RenderMaterial; @@ -26,6 +45,11 @@ class ExtPhysicsActor; } } +namespace physx +{ + class PxScene; +} + enum AxisType { AT_X = 0, @@ -41,7 +65,10 @@ enum GizmoToolMode GTM_Rotation }; -class GizmoToolController : public ISampleController +void modifyPxActorByLocalWay(PxScene& pxScene, PxRigidDynamic& actor, PxTransform& gp_old, PxTransform& gp_new); +void scalePxActor(PxScene& pxScene, PxRigidDynamic& actor, PxMat44& scale); + +class GizmoToolController : public ISampleController, public ISceneObserver { public: GizmoToolController(); @@ -55,16 +82,26 @@ public: virtual void onSampleStart(); virtual void onSampleStop(); + virtual void dataSelected(std::vector<BlastNode*> selections); + void setGizmoToolMode(GizmoToolMode mode); + GizmoToolMode getGizmoToolMode() { return m_GizmoToolMode; } void setAxisSelected(AxisType type); + void setAxisLength(float axisLength); void showAxisRenderables(bool show); void resetPos(); + void setTargetActor(PxActor* actor); + PxActor* getTargetActor(); + void syncRenderableState(); + bool CanMapToRootChunk(PxActor* actor); private: GizmoToolController& operator= (GizmoToolController&); //////// private methods //////// + physx::PxScene& GetPhysXScene(); + void UpdateCircleRenderData(float axisLength); bool CalPlaneLineIntersectPoint(PxVec3& result, PxVec3 planeNormal, PxVec3 planePoint, PxVec3 linedirection, PxVec3 linePoint); float DistanceFromPointToLine(PxVec3& point, PxVec3& origin, PxVec3& direction, PxVec3& foot); bool GetFootFromPointToPlane(PxVec3& point, PxVec3& origin, PxVec3& normal, PxVec3& foot); @@ -72,6 +109,10 @@ private: PxQuat CalDirectionQuat(AxisType type); PxQuat CalConvertQuat(); void ScaleActor(bool replace); + + bool CanModifyLocal(PxActor* actor); + void UpdateAssetInstanceTransform(const PxTransform& position); + //////// used controllers //////// Renderer& getRenderer() const @@ -103,7 +144,7 @@ private: PxVec3 m_LastFoot; PxVec3 m_LastAxis[AT_Num]; - PxRigidActor* m_CurrentActor; + PxRigidDynamic* m_CurrentActor; bool m_bNeedResetPos; bool m_bNeedResetColor; @@ -119,6 +160,8 @@ private: std::vector<PxDebugLine> m_CircleRenderData; DebugRenderBuffer m_CircleRenderBuffer; + + std::vector<BlastAssetInstanceNode*> m_assetInstances; }; #endif // GIZMO_TOOL_CONTROLLER_H
\ No newline at end of file diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp index 02a511f..458aec3 100644 --- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.cpp @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, related documentation -* and any modifications thereto. Any use, reproduction, disclosure or -* distribution of this software and related documentation without an express -* license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + #include "SelectionToolController.h" #include "RenderUtils.h" @@ -14,6 +32,7 @@ #include "Renderer.h" #include "PhysXController.h" #include "SampleProfiler.h" +#include "GizmoToolController.h" #include <imgui.h> @@ -23,7 +42,7 @@ #include "PxRigidDynamic.h" #include "PxScene.h" #include "BlastSceneTree.h" - +#include "SimpleScene.h" using namespace Nv::Blast; using namespace physx; @@ -39,6 +58,9 @@ using namespace physx; SelectionToolController::SelectionToolController() { m_bRectSelecting = false; + m_bSelecting = false; + + BlastSceneTree::ins()->addObserver(this); } SelectionToolController::~SelectionToolController() @@ -58,6 +80,29 @@ void SelectionToolController::onSampleStop() { } +void SelectionToolController::dataSelected(std::vector<BlastNode*> selections) +{ + m_actorsSelected.clear(); + + BlastController& blastController = getBlastController(); + std::vector<BlastFamilyPtr>& families = blastController.getFamilies(); + + for (BlastFamily* family : families) + { + std::vector<uint32_t> selectedChunks = family->getSelectedChunks(); + for (uint32_t chunkIndex : selectedChunks) + { + PxActor* actor = nullptr; + family->getPxActorByChunkIndex(chunkIndex, &actor); + + if (actor) + { + m_actorsSelected.emplace(actor); + } + } + } +} + void SelectionToolController::Animate(double dt) { PROFILER_SCOPED_FUNCTION(); @@ -76,6 +121,10 @@ LRESULT SelectionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP) { float mouseX = (short)LOWORD(lParam) / getRenderer().getScreenWidth(); + if (!SimpleScene::Inst()->m_pCamera->_lhs) + { + mouseX = 1 - mouseX; + } float mouseY = (short)HIWORD(lParam) / getRenderer().getScreenHeight(); bool press = uMsg == WM_LBUTTONDOWN; @@ -89,7 +138,18 @@ LRESULT SelectionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP m_RectSelectSpaceDir = pickDir.getNormalized(); m_RectRenderBuffer.clear(); - m_bRectSelecting = true; + bool isCtrl = (GetAsyncKeyState(VK_CONTROL) && 0x8000); + bool isAlt = (GetAsyncKeyState(VK_MENU) && 0x8000); + bool isLight = (GetAsyncKeyState('L') && 0x8000); + // ctrl+leftbutton is used for light changing + // alt+leftbutton is used for camera rotate movement in AppMainWindow.cpp + // so, we use rect select when ctrl and alt off + m_bRectSelecting = !(isAlt || isLight);// !(isCtrl || isAlt); + if (isAlt || isLight) + { + m_RectRenderBuffer.clear(); + } + m_bSelecting = true; } else if (uMsg == WM_MOUSEMOVE) { @@ -161,8 +221,9 @@ LRESULT SelectionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP { return 1; } - - if (m_bRectSelecting) + bool isAlt = (GetAsyncKeyState(VK_MENU) && 0x8000); + bool isLight = (GetAsyncKeyState('L') && 0x8000); + if (m_bSelecting && !(isAlt || isLight)) { bool isShift = (GetAsyncKeyState(VK_SHIFT) && 0x8000); bool isCtrl = (GetAsyncKeyState(VK_CONTROL) && 0x8000); @@ -180,15 +241,18 @@ LRESULT SelectionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP { selectMode = SM_SUB; } - int width = getRenderer().getScreenWidth(); int height = getRenderer().getScreenHeight(); int deltaX = (mouseX - m_RectSelectScreenPos.x) * width; int deltaY = (mouseY - m_RectSelectScreenPos.y) * height; float distance = deltaX * deltaX + deltaY * deltaY; - // rect select mode - if (distance > 1) + if (distance < 1) + { + m_bRectSelecting = false; + } + if (m_bRectSelecting) { + // rect select mode PxVec3 eyePos, pickDir[3]; getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir[0]); getPhysXController().getEyePoseAndPickDir(m_RectSelectScreenPos.x, mouseY, eyePos, pickDir[1]); @@ -243,23 +307,35 @@ LRESULT SelectionToolController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP getPhysXController().getEyePoseAndPickDir(mouseX, mouseY, eyePos, pickDir); pickDir = pickDir.getNormalized(); - PxRaycastHit hit; hit.shape = NULL; - PxRaycastBuffer hit1; - getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL); - hit = hit1.block; + PxRaycastBufferN<32> hits; + + GetPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hits, PxHitFlag::eDEFAULT | PxHitFlag::eMESH_MULTIPLE); + + PxU32 nbThouches = hits.getNbTouches(); + const PxRaycastHit* touches = hits.getTouches(); PxRigidActor* actor = NULL; - if (hit.shape) + float fDistance = PX_MAX_F32; + for (PxU32 u = 0; u < nbThouches; ++u) { - actor = hit.actor; + const PxRaycastHit& t = touches[u]; + if (t.shape && getBlastController().isActorVisible(*(t.actor))) + { + if (fDistance > t.distance) + { + fDistance = t.distance; + actor = t.actor; + } + } } + pointSelect(actor, selectMode); } } - BlastSceneTree::ins()->updateChunkItemSelection(); m_RectRenderBuffer.clear(); m_bRectSelecting = false; + m_bSelecting = false; } } @@ -272,42 +348,35 @@ void SelectionToolController::drawUI() void SelectionToolController::pointSelect(PxActor* actor, SelectMode selectMode) { - ExtPxActor* extActor = NULL; - if (NULL != actor) - { - PxRigidDynamic* rigidDynamic = actor->is<PxRigidDynamic>(); - if (NULL != rigidDynamic) - { - extActor = getBlastController().getExtPxManager().getActorFromPhysXActor(*rigidDynamic); - } - } - if (selectMode == SM_RESET) { clearSelect(); - if (NULL != extActor) + if (NULL != actor) { - setActorSelected(*extActor, true); - m_actorsSelected.emplace(extActor); + setActorSelected(*actor, true); + m_actorsSelected.emplace(actor); } } else if (selectMode == SM_ADD) { - if (NULL != extActor) + if (NULL != actor) { - setActorSelected(*extActor, true); - m_actorsSelected.emplace(extActor); + setActorSelected(*actor, true); + m_actorsSelected.emplace(actor); } } else if (selectMode == SM_SUB) { - if (NULL != extActor) + if (NULL != actor) { - setActorSelected(*extActor, false); - m_actorsSelected.erase(extActor); + setActorSelected(*actor, false); + m_actorsSelected.erase(actor); } } + + BlastSceneTree::ins()->updateChunkItemSelection(); + trySelectAssetInstanceNode(m_actorsSelected); } #include "PxPhysics.h" @@ -316,8 +385,8 @@ void SelectionToolController::pointSelect(PxActor* actor, SelectMode selectMode) class RectSelectionCallback : public PxOverlapCallback { public: - RectSelectionCallback(ExtPxManager& physicsManager, std::set<ExtPxActor*>& actorBuffer) - : m_physicsManager(physicsManager), m_actorBuffer(actorBuffer), PxOverlapCallback(m_hitBuffer, sizeof(m_hitBuffer) / sizeof(m_hitBuffer[0])) {} + RectSelectionCallback(std::set<PxActor*>& actorBuffer) + :m_actorBuffer(actorBuffer), PxOverlapCallback(m_hitBuffer, sizeof(m_hitBuffer) / sizeof(m_hitBuffer[0])) {} PxAgain processTouches(const PxOverlapHit* buffer, PxU32 nbHits) { @@ -326,25 +395,20 @@ public: PxRigidDynamic* rigidDynamic = buffer[i].actor->is<PxRigidDynamic>(); if (rigidDynamic) { - ExtPxActor* actor = m_physicsManager.getActorFromPhysXActor(*rigidDynamic); - if (actor != nullptr) - { - m_actorBuffer.insert(actor); - } + m_actorBuffer.insert(rigidDynamic); } } return true; } private: - ExtPxManager& m_physicsManager; - std::set<ExtPxActor*>& m_actorBuffer; - PxOverlapHit m_hitBuffer[1000]; + std::set<PxActor*>& m_actorBuffer; + PxOverlapHit m_hitBuffer[1000]; }; void SelectionToolController::rectSelect(PxVec3 eyePos, PxVec3 lefttop, PxVec3 leftbottom, PxVec3 righttop, PxVec3 rightbottom, SelectMode selectMode) { - std::set<ExtPxActor*> actorsToSelect; + std::set<PxActor*> actorsToSelect; float nearClip = 1; PxVec3 nearlefttop = lefttop * nearClip; @@ -373,8 +437,8 @@ void SelectionToolController::rectSelect(PxVec3 eyePos, PxVec3 lefttop, PxVec3 l PxConvexMesh* convexMesh = cooking.createConvexMesh(convexMeshDesc, physics.getPhysicsInsertionCallback()); if (NULL != convexMesh) { - RectSelectionCallback overlapCallback(getBlastController().getExtPxManager(), actorsToSelect); - getManager()->getPhysXController().getPhysXScene().overlap(PxConvexMeshGeometry(convexMesh), PxTransform(eyePos), overlapCallback); + RectSelectionCallback overlapCallback(actorsToSelect); + GetPhysXScene().overlap(PxConvexMeshGeometry(convexMesh), PxTransform(eyePos), overlapCallback); convexMesh->release(); } @@ -382,33 +446,42 @@ void SelectionToolController::rectSelect(PxVec3 eyePos, PxVec3 lefttop, PxVec3 l { clearSelect(); - for (ExtPxActor* actor : actorsToSelect) + for (PxActor* actor : actorsToSelect) { - setActorSelected(*actor, true); - m_actorsSelected.emplace(actor); + if (getBlastController().isActorVisible(*actor)) + { + setActorSelected(*actor, true); + m_actorsSelected.emplace(actor); + } } } else if (selectMode == SM_ADD) { - for (ExtPxActor* actor : actorsToSelect) + for (PxActor* actor : actorsToSelect) { - setActorSelected(*actor, true); - m_actorsSelected.emplace(actor); + if (getBlastController().isActorVisible(*actor)) + { + setActorSelected(*actor, true); + m_actorsSelected.emplace(actor); + } } } else if (selectMode == SM_SUB) { - for (ExtPxActor* actor : actorsToSelect) + for (PxActor* actor : actorsToSelect) { setActorSelected(*actor, false); m_actorsSelected.erase(actor); } } + + BlastSceneTree::ins()->updateChunkItemSelection(); + trySelectAssetInstanceNode(m_actorsSelected); } void SelectionToolController::clearSelect() { - for (ExtPxActor* actor : m_actorsSelected) + for (PxActor* actor : m_actorsSelected) { setActorSelected(*actor, false); } @@ -417,7 +490,75 @@ void SelectionToolController::clearSelect() SampleManager::ins()->clearChunksSelected(); } -void SelectionToolController::setActorSelected(const ExtPxActor& actor, bool selected) +void SelectionToolController::setTargetActor(PxActor* actor) +{ + if (actor == nullptr) + { + return; + } + + setActorSelected(*actor, true); + m_actorsSelected.emplace(actor); + + BlastSceneTree::ins()->updateChunkItemSelection(); + trySelectAssetInstanceNode(m_actorsSelected); +} + +PxActor* SelectionToolController::getTargetActor() +{ + PxActor* targetActor = nullptr; + if (m_actorsSelected.size() > 0) + { + targetActor = *m_actorsSelected.begin(); + } + return targetActor; +} + +void SelectionToolController::setTargetActors(std::set<PxActor*>& actors) +{ + for (PxActor* actor : actors) + { + setActorSelected(*actor, true); + m_actorsSelected.emplace(actor); + } + + BlastSceneTree::ins()->updateChunkItemSelection(); + trySelectAssetInstanceNode(m_actorsSelected); +} + +std::set<PxActor*> SelectionToolController::getTargetActors() +{ + return m_actorsSelected; +} + +void SelectionToolController::trySelectAssetInstanceNode(std::set<PxActor*>& selectedActors) +{ + BlastController& blastController = getBlastController(); + GizmoToolController& gizmoToolController = getManager()->getGizmoToolController(); + + for (PxActor* actor : selectedActors) + { + if (gizmoToolController.CanMapToRootChunk(actor)) + { + BlastFamily* family = getBlastController().getFamilyByPxActor(*actor); + BlastSceneTree::ins()->selectTreeItem(family); + } + } +} + +physx::PxScene& SelectionToolController::GetPhysXScene() +{ + if (getManager()->IsSimulating()) + { + return getPhysXController().getPhysXScene(); + } + else + { + return getPhysXController().getEditPhysXScene(); + } +} + +void SelectionToolController::setActorSelected(const PxActor& actor, bool selected) { std::vector<BlastFamilyPtr>& families = getBlastController().getFamilies(); if (families.size() == 0) @@ -430,7 +571,7 @@ void SelectionToolController::setActorSelected(const ExtPxActor& actor, bool sel for (; it != families.end(); it++) { BlastFamilyPtr f = *it; - if (f->find((ExtPxActor*)&actor)) + if (f->find(actor)) { pBlastFamily = f; break; diff --git a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h index 5261b90..74220e7 100644 --- a/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h +++ b/tools/ArtistTools/source/BlastPlugin/SampleBase/ui/SelectionToolController.h @@ -1,12 +1,30 @@ -/* -* Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, related documentation -* and any modifications thereto. Any use, reproduction, disclosure or -* distribution of this software and related documentation without an express -* license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + #ifndef SELECTION_TOOL_CONTROLLER_H #define SELECTION_TOOL_CONTROLLER_H @@ -17,6 +35,8 @@ #include "DebugRenderBuffer.h" #include "BlastFamily.h" #include "NvBlastExtPxManager.h" +#include "BlastSceneTree.h" + class Renderable; class RenderMaterial; @@ -28,7 +48,12 @@ class ExtPxActor; } } -class SelectionToolController : public ISampleController +namespace physx +{ + class PxScene; +} + +class SelectionToolController : public ISampleController, public ISceneObserver { public: SelectionToolController(); @@ -42,15 +67,27 @@ public: virtual void onSampleStart(); virtual void onSampleStop(); + virtual void dataSelected(std::vector<BlastNode*> selections); + void pointSelect(PxActor* actor, SelectMode selectMode = SM_RESET); void rectSelect(PxVec3 eyePos, PxVec3 lefttop, PxVec3 leftbottom, PxVec3 righttop, PxVec3 rightbottom, SelectMode selectMode = SM_RESET); void clearSelect(); + void setTargetActor(PxActor* actor); + PxActor* getTargetActor(); + + void setTargetActors(std::set<PxActor*>& actors); + std::set<PxActor*> getTargetActors(); + + void trySelectAssetInstanceNode(std::set<PxActor*>& selectedActors); + private: SelectionToolController& operator= (SelectionToolController&); //////// private methods //////// + physx::PxScene& GetPhysXScene(); + //////// used controllers //////// Renderer& getRenderer() const @@ -73,10 +110,11 @@ private: PxVec2 m_RectSelectScreenPos; PxVec3 m_RectSelectSpaceDir; bool m_bRectSelecting; + bool m_bSelecting; DebugRenderBuffer m_RectRenderBuffer; - void setActorSelected(const ExtPxActor& actor, bool selected); - std::set<ExtPxActor*> m_actorsSelected; + void setActorSelected(const PxActor& actor, bool selected); + std::set<PxActor*> m_actorsSelected; }; #endif // SELECTION_TOOL_CONTROLLER_H
\ No newline at end of file |