diff options
| author | Marijn Tamis <[email protected]> | 2018-05-03 18:22:48 +0200 |
|---|---|---|
| committer | Marijn Tamis <[email protected]> | 2018-05-03 18:22:48 +0200 |
| commit | ca32c59a58d37c1822e185a2d5f3d0d3e8943593 (patch) | |
| tree | b06b9eec03f34344ef8fc31aa147b2714d3962ee /NvCloth/samples/SampleBase/scene | |
| parent | Forced rename of platform folders in cmake dir. Git didn't pick this up before. (diff) | |
| download | nvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.tar.xz nvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.zip | |
NvCloth 1.1.4 Release. (24070740)
Diffstat (limited to 'NvCloth/samples/SampleBase/scene')
15 files changed, 906 insertions, 31 deletions
diff --git a/NvCloth/samples/SampleBase/scene/Scene.cpp b/NvCloth/samples/SampleBase/scene/Scene.cpp index 00e23ae..183b146 100644 --- a/NvCloth/samples/SampleBase/scene/Scene.cpp +++ b/NvCloth/samples/SampleBase/scene/Scene.cpp @@ -19,7 +19,8 @@ #include <foundation/PxVec2.h> std::vector<SceneFactory> Scene::sSceneFactories; -unsigned int Scene::mDebugVisualizationFlags; +unsigned int Scene::mDebugVisualizationFlags = 0; +bool Scene::mDebugVisualizationUpdateRequested = true; Scene::SceneDebugRenderParams Scene::sSceneDebugRenderParams; Scene::~Scene() @@ -78,6 +79,13 @@ void Scene::UpdateParticleDragging(float dt) tmp = physx::PxMat44((float*)&tmp2.r); physx::PxMat44 invMatrix = tmp; + tmp = modelMatrix; + tmp2 = DirectX::XMMatrixInverse(nullptr, DirectX::XMMATRIX(tmp.front())); + tmp = physx::PxMat44((float*)&tmp2.r); + physx::PxMat44 invModelMatrix = tmp; + + float clothScale = modelMatrix.transform(physx::PxVec4(1.0f, 1.0f, 1.0f, 0)).magnitude()/ 1.732; + physx::PxVec3 particleWorld = modelMatrix.transform(particles[mDraggingParticle.mParticleIndex].getXYZ()); physx::PxVec4 mousePointWorldT = invMatrix.transform(physx::PxVec4(mousePoint.x, mousePoint.y, 1.0, 1.0)); physx::PxVec3 mousePointWorld = mousePointWorldT.getXYZ() / mousePointWorldT.w; @@ -91,14 +99,20 @@ void Scene::UpdateParticleDragging(float dt) if(offset.magnitudeSquared() > 2.5f*2.5f) offset = offset.getNormalized()*2.5f; + offset = invModelMatrix.transform(physx::PxVec4(offset,0.0f)).getXYZ(); + for(int i = 0; i < (int)particles.size(); i++) { - physx::PxVec4 p = particles[i]; + physx::PxVec4 p = modelMatrix.transform(particles[i]); float dist = (p.getXYZ() - particleWorld).magnitude(); if(p.w > 0.0f) //Only move dynamic points { - float weight = max(0.0,min(1.0,0.4-dist)); + const float softSelectionRadius = 0.4f; + const float maxWeight = 0.4f; + float weight = max(0.0,min(1.0,1.0f-(dist/softSelectionRadius)))*maxWeight; + if(weight <= 0.0f) + continue; physx::PxVec3 point0(prevParticles[i].x, prevParticles[i].y, prevParticles[i].z); point0 = point0 - weight*offset; point0 = point0*0.99f + p.getXYZ()*0.01f; @@ -112,6 +126,44 @@ void Scene::UpdateParticleDragging(float dt) bool Scene::HandleEvent(UINT uMsg, WPARAM wParam, LPARAM lParam) { + if (uMsg == WM_KEYDOWN) + { + int iKeyPressed = static_cast<int>(wParam); + + switch (iKeyPressed) + { + case 'T': + mDebugVisualizationFlags ^= DEBUG_VIS_TETHERS; + break; + case 'C': + mDebugVisualizationFlags ^= DEBUG_VIS_CONSTRAINTS; + break; + case 'F': + mDebugVisualizationFlags ^= DEBUG_VIS_CONSTRAINTS_STIFFNESS; + break; + case 'R': + mDebugVisualizationFlags ^= DEBUG_VIS_CONSTRAINT_ERROR; + break; + case 'X': + mDebugVisualizationFlags ^= DEBUG_VIS_BOUNDING_BOX; + break; + case 'Z': + mDebugVisualizationFlags ^= DEBUG_VIS_DISTANCE_CONSTRAINTS; + break; + case 'L': + mDebugVisualizationFlags ^= DEBUG_VIS_POSITION_DELTA; + break; + case 'N': + mDebugVisualizationFlags ^= DEBUG_VIS_NORMALS; + break; + default: + return false; + } + + mDebugVisualizationUpdateRequested = true; + return true; + } + auto camera = mSceneController->getRenderer().getCamera(); auto m1 = camera.GetViewMatrix(); auto m2 = camera.GetProjMatrix(); @@ -183,6 +235,7 @@ bool Scene::HandlePickingEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, physx::P { physx::PxVec4 p = particles[i]; physx::PxVec4 point(p.x, p.y, p.z, 1.0f); + point = modelMatrix.transform(point); float dist = mouseRayDir.dot(point.getXYZ() - mouseRayStart); float offset = (point.getXYZ() - (dist*mouseRayDir + mouseRayStart)).magnitude(); @@ -271,6 +324,38 @@ void Scene::drawUI() cloth->setLinearInertia(physx::PxVec3(f, f, f)); } { + physx::PxVec3 f3 = cloth->getAngularInertia(); + if(ImGui::DragFloat3("Angular Inertia", &f3.x, 0.02f, 0.0f, 1.0f, "%.2f")) + cloth->setAngularInertia(f3); + float f = f3.maxElement(); + if(ImGui::DragFloat("Angular Inertia xyz", &f, 0.02f, 0.0f, 1.0f, "%.2f")) + cloth->setAngularInertia(physx::PxVec3(f, f, f)); + } + { + physx::PxVec3 f3 = cloth->getCentrifugalInertia(); + if(ImGui::DragFloat3("Centrifugal Inertia", &f3.x, 0.02f, 0.0f, 1.0f, "%.2f")) + cloth->setCentrifugalInertia(f3); + float f = f3.maxElement(); + if(ImGui::DragFloat("Centrifugal Inertia xyz", &f, 0.02f, 0.0f, 1.0f, "%.2f")) + cloth->setCentrifugalInertia(physx::PxVec3(f, f, f)); + } + { + physx::PxVec3 f3 = cloth->getLinearDrag(); + if(ImGui::DragFloat3("Linear Drag", &f3.x, 0.02f, 0.0f, 1.0f, "%.2f")) + cloth->setLinearDrag(f3); + float f = f3.maxElement(); + if(ImGui::DragFloat("Linear Drag xyz", &f, 0.02f, 0.0f, 1.0f, "%.2f")) + cloth->setLinearDrag(physx::PxVec3(f, f, f)); + } + { + physx::PxVec3 f3 = cloth->getAngularDrag(); + if(ImGui::DragFloat3("Angular Drag", &f3.x, 0.02f, 0.0f, 1.0f, "%.2f")) + cloth->setAngularDrag(f3); + float f = f3.maxElement(); + if(ImGui::DragFloat("Angular Drag xyz", &f, 0.02f, 0.0f, 1.0f, "%.2f")) + cloth->setAngularDrag(physx::PxVec3(f, f, f)); + } + { float f = cloth->getMotionConstraintScale(); if(ImGui::DragFloat("Motion Constraint Scale", &f, 0.08f, 0.0f, 4.0f, "%.2f")) cloth->setMotionConstraintScaleBias(f, cloth->getMotionConstraintBias()); @@ -325,21 +410,23 @@ void Scene::drawUI() if(ImGui::TreeNode("Debug Visualization")) { - ImGui::CheckboxFlags("Tethers", &mDebugVisualizationFlags, DEBUG_VIS_TETHERS); - ImGui::CheckboxFlags("Constraints", &mDebugVisualizationFlags, DEBUG_VIS_CONSTRAINTS); + auto old = mDebugVisualizationFlags; + ImGui::CheckboxFlags("Tethers (T)", &mDebugVisualizationFlags, DEBUG_VIS_TETHERS); + ImGui::CheckboxFlags("Constraints (C)", &mDebugVisualizationFlags, DEBUG_VIS_CONSTRAINTS); if(mDebugVisualizationFlags&DEBUG_VIS_CONSTRAINTS) { ImGui::DragInt("Start Constraint Phase Range", &sSceneDebugRenderParams.mVisiblePhaseRangeBegin, 0.05, 0, 30); ImGui::DragInt("End", &sSceneDebugRenderParams.mVisiblePhaseRangeEnd, 0.05, 0, 30); } - ImGui::CheckboxFlags("Constraint Stiffness", &mDebugVisualizationFlags, DEBUG_VIS_CONSTRAINTS_STIFFNESS); - - ImGui::CheckboxFlags("Constraint Error", &mDebugVisualizationFlags, DEBUG_VIS_CONSTRAINT_ERROR); - ImGui::CheckboxFlags("Position Delta", &mDebugVisualizationFlags, DEBUG_VIS_POSITION_DELTA); - ImGui::CheckboxFlags("Bounding Box", &mDebugVisualizationFlags, DEBUG_VIS_BOUNDING_BOX); - ImGui::CheckboxFlags("Distance Constraints", &mDebugVisualizationFlags, DEBUG_VIS_DISTANCE_CONSTRAINTS); - + ImGui::CheckboxFlags("Constraint Stiffness (F)", &mDebugVisualizationFlags, DEBUG_VIS_CONSTRAINTS_STIFFNESS); + ImGui::CheckboxFlags("Constraint Error (R)", &mDebugVisualizationFlags, DEBUG_VIS_CONSTRAINT_ERROR); + ImGui::CheckboxFlags("Position Delta (L)", &mDebugVisualizationFlags, DEBUG_VIS_POSITION_DELTA); + ImGui::CheckboxFlags("Bounding Box (X)", &mDebugVisualizationFlags, DEBUG_VIS_BOUNDING_BOX); + ImGui::CheckboxFlags("Distance Constraints (Z)", &mDebugVisualizationFlags, DEBUG_VIS_DISTANCE_CONSTRAINTS); ImGui::TreePop(); + + if(old != mDebugVisualizationFlags) + mDebugVisualizationUpdateRequested = true; } static int activeSolver = 0; @@ -395,7 +482,13 @@ void Scene::drawDebugVisualization() DebugRenderBoundingBox(); if(mDebugVisualizationFlags & DEBUG_VIS_DISTANCE_CONSTRAINTS) DebugRenderDistanceConstraints(); - + + mDebugVisualizationUpdateRequested = false; +} + +bool Scene::debugVisualizationUpdateRequested() const +{ + return mDebugVisualizationUpdateRequested; } namespace @@ -478,6 +571,11 @@ void Scene::untrackRenderable(Renderable* renderable) untrackT(mRenderableList, renderable); } +void Scene::trackCleanupCallback(std::function<void(void)> cleanupCallback) +{ + trackT(mCleanupCallbackList, cleanupCallback); +} + void Scene::autoDeinitialize() { //Remove all cloths from solvers @@ -518,6 +616,13 @@ void Scene::autoDeinitialize() mSceneController->getRenderer().removeRenderable(it); } mRenderableList.clear(); + + //Run all cleanup callbacks + for(auto it : mCleanupCallbackList) + { + it(); + } + mCleanupCallbackList.clear(); } void Scene::doSimulationStep(float dt) @@ -892,4 +997,4 @@ void Scene::DebugRenderBoundingBox() dbl->addLine(transform,c - dy + dz + dx,c + dy - dz - dx, 0x007777); dbl->addLine(transform,c - dy + dz - dx,c + dy - dz + dx, 0x007777); } -}
\ No newline at end of file +} diff --git a/NvCloth/samples/SampleBase/scene/Scene.h b/NvCloth/samples/SampleBase/scene/Scene.h index 4ef2bed..be8b5a1 100644 --- a/NvCloth/samples/SampleBase/scene/Scene.h +++ b/NvCloth/samples/SampleBase/scene/Scene.h @@ -15,6 +15,7 @@ #include <map> #include "scene/SceneController.h" #include "foundation/PxMat44.h" +#include <functional> namespace nv { namespace cloth @@ -44,13 +45,15 @@ public: Scene(SceneController* sceneController):mSceneController(sceneController) {} virtual ~Scene(); - virtual void Animate(double dt) { doSimulationStep(dt); drawDebugVisualization(); } + virtual void Animate(double dt) { doSimulationStep(dt); } void UpdateParticleDragging(float dt); virtual bool HandleEvent(UINT uMsg, WPARAM wParam, LPARAM lParam); bool HandlePickingEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, physx::PxMat44 viewProjectionMatrix); virtual void drawUI(); + virtual bool drawSubScenes() { return false; } //returns true if scene needs to be reinitialized virtual void drawStatsUI() {} virtual void drawDebugVisualization(); + bool debugVisualizationUpdateRequested() const; virtual void onInitialize() = 0; virtual void onTerminate() { autoDeinitialize(); } @@ -82,6 +85,9 @@ protected: void trackRenderable(Renderable* renderMesh); void untrackRenderable(Renderable* renderMesh); + //add a callback that is run at the end of autoDeinitialize + void trackCleanupCallback(std::function<void(void)> cleanupCallback); + void autoDeinitialize(); @@ -111,6 +117,7 @@ private: std::vector<nv::cloth::Fabric*> mFabricList; std::map<ClothActor*, nv::cloth::Solver*> mClothSolverMap; std::vector<Renderable*> mRenderableList; + std::vector<std::function<void(void)>> mCleanupCallbackList; static std::vector<SceneFactory> sSceneFactories; @@ -131,6 +138,7 @@ private: }; static unsigned int mDebugVisualizationFlags; + static bool mDebugVisualizationUpdateRequested; struct SceneDebugRenderParams { diff --git a/NvCloth/samples/SampleBase/scene/SceneController.cpp b/NvCloth/samples/SampleBase/scene/SceneController.cpp index fa35d5d..2eedfe4 100644 --- a/NvCloth/samples/SampleBase/scene/SceneController.cpp +++ b/NvCloth/samples/SampleBase/scene/SceneController.cpp @@ -76,6 +76,8 @@ void SceneController::onSampleStart() mPhysXPrimitiveRenderMaterial = new RenderMaterial(getRenderer().getResourceManager(), "physx_primitive", ""); mPhysXPlaneRenderMaterial = new RenderMaterial(getRenderer().getResourceManager(), "physx_primitive_plane", ""); + mWeightedModelSkinRenderMaterial = new RenderMaterial(getRenderer().getResourceManager(), "weighted_model_skinned", ""); + /*{ IRenderMesh* mesh = getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Plane); @@ -184,13 +186,20 @@ void SceneController::changeScene(int index) mActiveScene = Scene::CreateScene(0, this); } mActiveScene->onInitialize(); + mDebugLineRenderBuffer->clear(); + mActiveScene->drawDebugVisualization(); } void SceneController::Animate(double dt) { if(mPaused && (mSingleStep <= 0)) { - //Re render debug lines from last frame + if(mActiveScene->debugVisualizationUpdateRequested()) + { + mDebugLineRenderBuffer->clear(); + mActiveScene->drawDebugVisualization(); + } + //else Re render debug lines from last frame getRenderer().queueRenderBuffer(mDebugLineRenderBuffer); return; } @@ -200,8 +209,6 @@ void SceneController::Animate(double dt) dt = 1.0 / 60.0; } - mDebugLineRenderBuffer->clear(); - mLeftOverTime += dt * mTimeScale; double simulationStep = 0.0; @@ -211,6 +218,8 @@ void SceneController::Animate(double dt) simulationStep = 1.0 / 60.0; mActiveScene->Animate(simulationStep); + mDebugLineRenderBuffer->clear(); + mActiveScene->drawDebugVisualization(); getRenderer().queueRenderBuffer(mDebugLineRenderBuffer); } @@ -267,6 +276,10 @@ void SceneController::drawUI() for(int i = 0; i < Scene::GetSceneCount(); i++) { pressed = pressed | ImGui::RadioButton(Scene::GetSceneName(i), &mActiveSceneIndex, i); + if(i == mActiveSceneIndex) + { + pressed = pressed | mActiveScene->drawSubScenes(); + } } if(pressed) changeScene(mActiveSceneIndex); diff --git a/NvCloth/samples/SampleBase/scene/SceneController.h b/NvCloth/samples/SampleBase/scene/SceneController.h index 9f4f428..d8042bb 100644 --- a/NvCloth/samples/SampleBase/scene/SceneController.h +++ b/NvCloth/samples/SampleBase/scene/SceneController.h @@ -92,6 +92,11 @@ public: return mPhysXPlaneRenderMaterial; } + RenderMaterial* getDefaultWeightedModelSkinMaterial() + { + return mWeightedModelSkinRenderMaterial; + } + DebugLineRenderBuffer* getDebugLineRenderBuffer() { return mDebugLineRenderBuffer; @@ -106,6 +111,7 @@ private: RenderMaterial* mPhysXPrimitiveRenderMaterial; RenderMaterial* mPhysXPlaneRenderMaterial; + RenderMaterial* mWeightedModelSkinRenderMaterial; Renderable* mPlane; std::vector<Renderable*> mBoxes; @@ -132,8 +138,7 @@ private: double mLeftOverTime; bool mPaused; - int mSingleStep; - + int mSingleStep; }; #endif
\ No newline at end of file diff --git a/NvCloth/samples/SampleBase/scene/scenes/CCDScene2.cpp b/NvCloth/samples/SampleBase/scene/scenes/CCDScene2.cpp new file mode 100644 index 0000000..ba50f1d --- /dev/null +++ b/NvCloth/samples/SampleBase/scene/scenes/CCDScene2.cpp @@ -0,0 +1,155 @@ +/* +* Copyright (c) 2008-2017, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "CCDScene2.h" +#include "scene/SceneController.h" +#include <NvClothExt/ClothFabricCooker.h> +#include "ClothMeshGenerator.h" +#include <NvCloth/Fabric.h> +#include <NvCloth/Solver.h> +#include <NvCloth/Cloth.h> +#include <NvCloth/Factory.h> +#include "Renderer.h" +#include "renderer/RenderUtils.h" +#include "windows.h" +#include "utils/MeshGenerator.h" + +DECLARE_SCENE_NAME(CCDScene2, "CCD Scene 2") + +void CCDScene2::Animate(double dt) +{ + static float time = 0.0f; + time += dt*1.5f; //19x + + physx::PxTransform invTranslation(-mOffset - physx::PxVec3(0.f, 10.f, -2.f)); + physx::PxTransform rotation(physx::PxQuat(cosf(time)*physx::PxHalfPi-physx::PxHalfPi,physx::PxVec3(0.0f,1.0f,0.0f))); + physx::PxTransform translation(mOffset + physx::PxVec3(0.f, 10.f, -2.f) + physx::PxVec3(0.0f,0.0f,10.0f*sinf(time))); + physx::PxTransform totalTransform = translation.transform(rotation.transform(invTranslation)); + + physx::PxVec4 spheres[2] = { + physx::PxVec4(totalTransform.transform(physx::PxVec3(-4.f,10.f,0.f) + mOffset),1.0), + physx::PxVec4(totalTransform.transform(physx::PxVec3( 4.f,10.f,0.f) + mOffset),0.5)}; + + mClothActor[0]->mCloth->setSpheres(nv::cloth::Range<physx::PxVec4>(spheres, spheres + 2), 0, mClothActor[0]->mCloth->getNumSpheres()); + + mCollisionMehs->setTransform(totalTransform); + + Scene::Animate(dt); +} + +void CCDScene2::initializeCloth(int index, physx::PxVec3 offset) +{ + mOffset = offset; + + /////////////////////////////////////////////////////////////////////// + ClothMeshData clothMesh; + + physx::PxMat44 transform = PxTransform(PxVec3(0.f, 13.f, 0.f)+ mOffset, PxQuat(0, PxVec3(1.f, 0.f, 0.f))); + clothMesh.GeneratePlaneCloth(5.f, 6.f, 69, 79, false, transform); + clothMesh.AttachClothPlaneByAngles(69, 79); + clothMesh.SetInvMasses(0.5f + (float)index * 2.0f); + + mClothActor[index] = new ClothActor; + nv::cloth::ClothMeshDesc meshDesc = clothMesh.GetClothMeshDesc(); + { + mClothActor[index]->mClothRenderMesh = new ClothRenderMesh(meshDesc); + mClothActor[index]->mClothRenderable = getSceneController()->getRenderer().createRenderable(*(static_cast<IRenderMesh*>(mClothActor[index]->mClothRenderMesh)), *getSceneController()->getDefaultMaterial()); + + float r, g, b; + r = index == 0 ? 1.0f : 0.3f; + g = index == 1 ? 1.0f : 0.3f; + b = index == 2 ? 1.0f : 0.3f; + + mClothActor[index]->mClothRenderable->setColor(DirectX::XMFLOAT4(r, g, b, 1.0f)); + } + + nv::cloth::Vector<int32_t>::Type phaseTypeInfo; + mFabric[index] = NvClothCookFabricFromMesh(getSceneController()->getFactory(), meshDesc, physx::PxVec3(0.0f, 0.0f, 1.0f), &phaseTypeInfo, false); + trackFabric(mFabric[index]); + + // Initialize start positions and masses for the actual cloth instance + // (note: the particle/vertex positions do not have to match the mesh description here. Set the positions to the initial shape of this cloth instance) + std::vector<physx::PxVec4> particlesCopy; + particlesCopy.resize(clothMesh.mVertices.size()); + + physx::PxVec3 clothOffset = transform.getPosition(); + for(int i = 0; i < (int)clothMesh.mVertices.size(); i++) + { + // To put attachment point closer to each other + if(clothMesh.mInvMasses[i] < 1e-6) + clothMesh.mVertices[i] = (clothMesh.mVertices[i] - clothOffset)*0.95f + clothOffset; + + particlesCopy[i] = physx::PxVec4(clothMesh.mVertices[i], clothMesh.mInvMasses[i]); // w component is 1/mass, or 0.0f for anchored/fixed particles + } + + // Create the cloth from the initial positions/masses and the fabric + mClothActor[index]->mCloth = getSceneController()->getFactory()->createCloth(nv::cloth::Range<physx::PxVec4>(&particlesCopy[0], &particlesCopy[0] + particlesCopy.size()), *mFabric[index]); + particlesCopy.clear(); particlesCopy.shrink_to_fit(); + + mClothActor[index]->mCloth->setGravity(physx::PxVec3(0.0f, -9.8f, 0.0f)); + mClothActor[index]->mCloth->setDamping(physx::PxVec3(0.1f, 0.1f, 0.1f)); + mClothActor[index]->mCloth->setSelfCollisionDistance(0.07f); + //mClothActor[index]->mCloth->enableContinuousCollision(true); + //mClothActor[index]->mCloth->setFriction(1.0f); + + + physx::PxVec4 spheres[2] = {physx::PxVec4(physx::PxVec3(-4.f,10.f,0.f) + mOffset,1.0), + physx::PxVec4(physx::PxVec3( 4.f,10.f,0.f) + mOffset,0.5)}; + + mClothActor[index]->mCloth->setSpheres(nv::cloth::Range<physx::PxVec4>(spheres, spheres + 2), 0, mClothActor[index]->mCloth->getNumSpheres()); + + uint32_t caps[4]; + caps[0] = 0; + caps[1] = 1; + + mClothActor[index]->mCloth->setCapsules(nv::cloth::Range<uint32_t>(caps, caps + 2), 0, mClothActor[index]->mCloth->getNumCapsules()); + + //create render mesh + auto mesh = MeshGenerator::generateCollisionCapsules(spheres,2,caps,2,-0.05f); + auto renderMesh = new MeshGenerator::MeshGeneratorRenderMesh(mesh); + mCollisionMehs = getSceneController()->getRenderer().createRenderable(*renderMesh, *getSceneController()->getDefaultMaterial()); + trackRenderable(mCollisionMehs); + + // Setup phase configs + std::vector<nv::cloth::PhaseConfig> phases(mFabric[index]->getNumPhases()); + for(int i = 0; i < (int)phases.size(); i++) + { + phases[i].mPhaseIndex = i; + phases[i].mStiffness = 1.0f; + phases[i].mStiffnessMultiplier = 1.0f; + phases[i].mCompressionLimit = 1.0f; + phases[i].mStretchLimit = 1.0f; + } + mClothActor[index]->mCloth->setPhaseConfig(nv::cloth::Range<nv::cloth::PhaseConfig>(&phases.front(), &phases.back())); + mClothActor[index]->mCloth->setDragCoefficient(0.5f); + mClothActor[index]->mCloth->setLiftCoefficient(0.6f); + mClothActor[index]->mCloth->setSolverFrequency(30); + + trackClothActor(mClothActor[index]); + + // Add the cloth to the solver for simulation + addClothToSolver(mClothActor[index], mSolver); +} + +void CCDScene2::onInitialize() +{ + mSolver = getSceneController()->getFactory()->createSolver(); + trackSolver(mSolver); + + initializeCloth(0, physx::PxVec3(0.0f, 0.0f, 0.0f)); + + { + IRenderMesh* mesh = getSceneController()->getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Plane); + Renderable* plane = getSceneController()->getRenderer().createRenderable(*mesh, *getSceneController()->getDefaultPlaneMaterial()); + plane->setTransform(PxTransform(PxVec3(0.f, 0.f, 0.f), PxQuat(PxPiDivTwo, PxVec3(0.f, 0.f, 1.f)))); + plane->setScale(PxVec3(1000.f)); + trackRenderable(plane); + } +} diff --git a/NvCloth/samples/SampleBase/scene/scenes/CCDScene2.h b/NvCloth/samples/SampleBase/scene/scenes/CCDScene2.h new file mode 100644 index 0000000..8c27a63 --- /dev/null +++ b/NvCloth/samples/SampleBase/scene/scenes/CCDScene2.h @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2008-2017, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef CCD_SCENE_H +#define CCD_SCENE_H + +#include "scene/Scene.h" +#include <foundation/PxVec3.h> + +class CCDScene2 : public Scene +{ +public: + + CCDScene2(SceneController* sceneController): Scene(sceneController) {} + + virtual void Animate(double dt) override; + void initializeCloth(int index, physx::PxVec3 offset); + virtual void onInitialize() override; + +private: + nv::cloth::Fabric* mFabric[1]; + nv::cloth::Solver* mSolver; + ClothActor* mClothActor[1]; + + physx::PxVec3 mOffset; + Renderable* mCollisionMehs; +}; + + +#endif
\ No newline at end of file diff --git a/NvCloth/samples/SampleBase/scene/scenes/InterCollisionScene.cpp b/NvCloth/samples/SampleBase/scene/scenes/InterCollisionScene.cpp index 0dd1aa7..12ff7ce 100644 --- a/NvCloth/samples/SampleBase/scene/scenes/InterCollisionScene.cpp +++ b/NvCloth/samples/SampleBase/scene/scenes/InterCollisionScene.cpp @@ -117,6 +117,8 @@ void InterCollisionScene::onInitialize() initializeCloth(0, posTrans); posTrans.setPosition(physx::PxVec3(0.0f, 0.8f, -1.2f)); initializeCloth(1, posTrans); + posTrans.setPosition(physx::PxVec3(0.0f, 1.6f, -1.4f)); + initializeCloth(2, posTrans); { IRenderMesh* mesh = getSceneController()->getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Plane); diff --git a/NvCloth/samples/SampleBase/scene/scenes/InterCollisionScene.h b/NvCloth/samples/SampleBase/scene/scenes/InterCollisionScene.h index 1ef0b45..98ea3ef 100644 --- a/NvCloth/samples/SampleBase/scene/scenes/InterCollisionScene.h +++ b/NvCloth/samples/SampleBase/scene/scenes/InterCollisionScene.h @@ -24,9 +24,9 @@ public: virtual void onInitialize() override; private: - nv::cloth::Fabric* mFabric[2]; + nv::cloth::Fabric* mFabric[3]; nv::cloth::Solver* mSolver; - ClothActor* mClothActor[2]; + ClothActor* mClothActor[3]; }; diff --git a/NvCloth/samples/SampleBase/scene/scenes/SelfCollisionScene.cpp b/NvCloth/samples/SampleBase/scene/scenes/SelfCollisionScene.cpp index 89fed39..f2c368e 100644 --- a/NvCloth/samples/SampleBase/scene/scenes/SelfCollisionScene.cpp +++ b/NvCloth/samples/SampleBase/scene/scenes/SelfCollisionScene.cpp @@ -61,7 +61,7 @@ void SelfCollisionScene::initializeCloth(int index, physx::PxMat44 transform) particlesCopy.resize(clothMesh.mVertices.size()); physx::PxVec3 clothOffset = transform.getPosition(); - for(int i = 0; i < (int)clothMesh.mVertices.size(); i++) + for (int i = 0; i < (int)clothMesh.mVertices.size(); i++) { // To put attachment point closer to each other if(clothMesh.mInvMasses[i] < 1e-6) @@ -79,9 +79,10 @@ void SelfCollisionScene::initializeCloth(int index, physx::PxMat44 transform) nv::cloth::Range<const physx::PxVec4> planesR(&planes[0], &planes[0] + planes.size()); mClothActor[index]->mCloth->setPlanes(planesR, 0, mClothActor[index]->mCloth->getNumPlanes()); + std::vector<uint32_t> indices; indices.resize(planes.size()); - for(int i = 0; i < (int)indices.size(); i++) + for (int i = 0; i < (int)indices.size(); i++) indices[i] = 1 << i; nv::cloth::Range<uint32_t> cind(&indices[0], &indices[0] + indices.size()); mClothActor[index]->mCloth->setConvexes(cind, 0, mClothActor[index]->mCloth->getNumConvexes()); @@ -97,20 +98,21 @@ void SelfCollisionScene::initializeCloth(int index, physx::PxMat44 transform) std::vector<uint32_t> selfCollisionIndices; //only enable every other particle for self collision - for(int y = 0; y < 5*h + 1; y++) - for(int x = 0; x < 5 * w + 1; x++) - if((x & 1) ^ (y & 1)) selfCollisionIndices.push_back(x + y*(5 * w + 1)); + for (int y = 0; y < 5*h + 1; y++) + for (int x = 0; x < 5 * w + 1; x++) + if ((x & 1) ^ (y & 1)) selfCollisionIndices.push_back(x + y*(5 * w + 1)); - for(int y = 0; y < 5 * h2 + 1; y++) - for(int x = 0; x < 5 * w2 + 1; x++) - if((x & 1) ^ (y & 1)) selfCollisionIndices.push_back(FirstParticleIndexCloth2 + x + y*(5 * w2 + 1)); + for (int y = 0; y < 5 * h2 + 1; y++) + for (int x = 0; x < 5 * w2 + 1; x++) + if ((x & 1) ^ (y & 1)) + selfCollisionIndices.push_back(FirstParticleIndexCloth2 + x + y*(5 * w2 + 1)); nv::cloth::Range<uint32_t> selfCollisionIndicesRange (&selfCollisionIndices[0], &selfCollisionIndices[0] + selfCollisionIndices.size()); mClothActor[index]->mCloth->setSelfCollisionIndices(selfCollisionIndicesRange); // Setup phase configs std::vector<nv::cloth::PhaseConfig> phases(mFabric[index]->getNumPhases()); - for(int i = 0; i < (int)phases.size(); i++) + for (int i = 0; i < (int)phases.size(); i++) { phases[i].mPhaseIndex = i; phases[i].mStiffness = 1.0f; @@ -137,6 +139,7 @@ void SelfCollisionScene::onInitialize() return true; } );*/ + trackSolver(mSolver); physx::PxMat44 posTrans(physx::PxIdentity); diff --git a/NvCloth/samples/SampleBase/scene/scenes/TeleportScene.cpp b/NvCloth/samples/SampleBase/scene/scenes/TeleportScene.cpp new file mode 100644 index 0000000..ed4d044 --- /dev/null +++ b/NvCloth/samples/SampleBase/scene/scenes/TeleportScene.cpp @@ -0,0 +1,148 @@ +/* +* Copyright (c) 2008-2017, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "TeleportScene.h" +#include "scene/SceneController.h" +#include <NvClothExt/ClothFabricCooker.h> +#include "ClothMeshGenerator.h" +#include <NvCloth/Fabric.h> +#include <NvCloth/Solver.h> +#include <NvCloth/Cloth.h> +#include <NvCloth/Factory.h> +#include "Renderer.h" +#include "renderer/RenderUtils.h" +#include "windows.h" + +DECLARE_SCENE_NAME(TeleportScene, "Teleport Scene") + +void TeleportScene::Animate(double dt) +{ + mTime += dt; + if(mTime > 4.0f) + { + TeleportScene::teleport(); + } + physx::PxVec3 position(0.0f,0.0f, mTime*-25.0f); + physx::PxQuat rotation(mTime * physx::PxPi * 0.5f, physx::PxVec3(0.0f, 1.0f, 0.0f)); + + mClothActor[0]->mCloth->setTranslation(position); + mClothActor[0]->mCloth->setRotation(rotation); + + //Disable setTransform on the renderable so we can clearly see any jumps and discontinuities from the teleport + //mClothActor[0]->mClothRenderable->setTransform(physx::PxTransform(position + physx::PxVec3(-4.f, 0.f, 0.f), rotation)); + + Scene::Animate(dt); +} + +void TeleportScene::teleport() +{ + mTime = 0.0f; + physx::PxVec3 position(0.0f, 0.0f, mTime*-10.0f); + physx::PxQuat rotation(mTime, physx::PxVec3(0.0f, 1.0f, 0.0f)); + + //mClothActor[0]->mCloth->teleport(-mClothActor[0]->mCloth->getTranslation()); + mClothActor[0]->mCloth->teleportToLocation(position, rotation); + //mClothActor[0]->mCloth->clearInertia(); + mClothActor[0]->mCloth->ignoreVelocityDiscontinuity(); +} + +void TeleportScene::initializeCloth(int index, physx::PxVec3 offset) +{ + /////////////////////////////////////////////////////////////////////// + ClothMeshData clothMesh; + + physx::PxMat44 transform = PxTransform(PxVec3(0.f, 13.f, 0.f)+ offset, PxQuat(PxPi / 2.0f, PxVec3(1.f, 0.f, 0.f))); + clothMesh.GeneratePlaneCloth(5.f, 6.f, 39, 49, false, transform); + clothMesh.AttachClothPlaneByAngles(39, 49); + clothMesh.SetInvMasses(0.5f + (float)index * 2.0f); + + mClothActor[index] = new ClothActor; + nv::cloth::ClothMeshDesc meshDesc = clothMesh.GetClothMeshDesc(); + { + mClothActor[index]->mClothRenderMesh = new ClothRenderMesh(meshDesc); + mClothActor[index]->mClothRenderable = getSceneController()->getRenderer().createRenderable(*(static_cast<IRenderMesh*>(mClothActor[index]->mClothRenderMesh)), *getSceneController()->getDefaultMaterial()); + + float r, g, b; + r = index == 0 ? 1.0f : 0.3f; + g = index == 1 ? 1.0f : 0.3f; + b = index == 2 ? 1.0f : 0.3f; + + mClothActor[index]->mClothRenderable->setColor(DirectX::XMFLOAT4(r, g, b, 1.0f)); + } + + nv::cloth::Vector<int32_t>::Type phaseTypeInfo; + mFabric[index] = NvClothCookFabricFromMesh(getSceneController()->getFactory(), meshDesc, physx::PxVec3(0.0f, 0.0f, 1.0f), &phaseTypeInfo, false); + trackFabric(mFabric[index]); + + // Initialize start positions and masses for the actual cloth instance + // (note: the particle/vertex positions do not have to match the mesh description here. Set the positions to the initial shape of this cloth instance) + std::vector<physx::PxVec4> particlesCopy; + particlesCopy.resize(clothMesh.mVertices.size()); + + physx::PxVec3 clothOffset = transform.getPosition(); + for (int i = 0; i < (int)clothMesh.mVertices.size(); i++) + { + // To put attachment point closer to each other + if(clothMesh.mInvMasses[i] < 1e-6) + clothMesh.mVertices[i] = (clothMesh.mVertices[i] - clothOffset)*0.95f + clothOffset; + + particlesCopy[i] = physx::PxVec4(clothMesh.mVertices[i], clothMesh.mInvMasses[i]); // w component is 1/mass, or 0.0f for anchored/fixed particles + } + + if(index == 1) + { + mAttachmentVertices[0] = 0; + mAttachmentVertices[1] = 39; + mAttachmentVertexOriginalPositions[0] = particlesCopy[mAttachmentVertices[0]]; + mAttachmentVertexOriginalPositions[1] = particlesCopy[mAttachmentVertices[1]]; + } + + // Create the cloth from the initial positions/masses and the fabric + mClothActor[index]->mCloth = getSceneController()->getFactory()->createCloth(nv::cloth::Range<physx::PxVec4>(&particlesCopy[0], &particlesCopy[0] + particlesCopy.size()), *mFabric[index]); + particlesCopy.clear(); particlesCopy.shrink_to_fit(); + + mClothActor[index]->mCloth->setGravity(physx::PxVec3(0.0f, -9.8f, 0.0f)); + + // Setup phase configs + std::vector<nv::cloth::PhaseConfig> phases(mFabric[index]->getNumPhases()); + for (int i = 0; i < (int)phases.size(); i++) + { + phases[i].mPhaseIndex = i; + phases[i].mStiffness = 1.0f; + phases[i].mStiffnessMultiplier = 1.0f; + phases[i].mCompressionLimit = 1.0f; + phases[i].mStretchLimit = 1.0f; + } + mClothActor[index]->mCloth->setPhaseConfig(nv::cloth::Range<nv::cloth::PhaseConfig>(&phases.front(), &phases.back())); + mClothActor[index]->mCloth->setDragCoefficient(0.1f); + mClothActor[index]->mCloth->setLiftCoefficient(0.2f); + + mSolver[index] = getSceneController()->getFactory()->createSolver(); + trackSolver(mSolver[index]); + trackClothActor(mClothActor[index]); + + // Add the cloth to the solver for simulation + addClothToSolver(mClothActor[index], mSolver[index]); +} + +void TeleportScene::onInitialize() +{ + initializeCloth(0, physx::PxVec3(0.0f, 0.0f, 0.0f)); + + mTime = 0.0f; + + { + IRenderMesh* mesh = getSceneController()->getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Plane); + Renderable* plane = getSceneController()->getRenderer().createRenderable(*mesh, *getSceneController()->getDefaultPlaneMaterial()); + plane->setTransform(PxTransform(PxVec3(0.f, 0.f, 0.f), PxQuat(PxPiDivTwo, PxVec3(0.f, 0.f, 1.f)))); + plane->setScale(PxVec3(1000.f)); + trackRenderable(plane); + } +} diff --git a/NvCloth/samples/SampleBase/scene/scenes/TeleportScene.h b/NvCloth/samples/SampleBase/scene/scenes/TeleportScene.h new file mode 100644 index 0000000..668dfb0 --- /dev/null +++ b/NvCloth/samples/SampleBase/scene/scenes/TeleportScene.h @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2008-2017, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef TELEPORT_SCENE_H +#define TELEPORT_SCENE_H + +#include "scene/Scene.h" +#include <foundation/PxVec3.h> + +class TeleportScene : public Scene +{ +public: + + TeleportScene(SceneController* sceneController): Scene(sceneController) {} + + virtual void Animate(double dt) override; + void initializeCloth(int index, physx::PxVec3 offset); + virtual void onInitialize() override; + void teleport(); + +private: + nv::cloth::Fabric* mFabric[1]; + nv::cloth::Solver* mSolver[1]; + ClothActor* mClothActor[1]; + + int mAttachmentVertices[1]; + physx::PxVec4 mAttachmentVertexOriginalPositions[1]; + + float mTime; + +}; + + +#endif
\ No newline at end of file diff --git a/NvCloth/samples/SampleBase/scene/scenes/TimeStepScene.cpp b/NvCloth/samples/SampleBase/scene/scenes/TimeStepScene.cpp new file mode 100644 index 0000000..82ac9fe --- /dev/null +++ b/NvCloth/samples/SampleBase/scene/scenes/TimeStepScene.cpp @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2008-2017, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "TimeStepScene.h" +#include "scene/SceneController.h" +#include <NvClothExt/ClothFabricCooker.h> +#include "ClothMeshGenerator.h" +#include <NvCloth/Fabric.h> +#include <NvCloth/Solver.h> +#include <NvCloth/Cloth.h> +#include <NvCloth/Factory.h> +#include "Renderer.h" +#include "renderer/RenderUtils.h" + +DECLARE_SCENE_NAME(TimeStepScene, "Time Step Scene") + +void TimeStepScene::initializeCloth(int index, physx::PxVec3 offset) +{ + ClothMeshData clothMesh; + + physx::PxMat44 transform = PxTransform(PxVec3(0.f, 13.f, 0.f) + offset, PxQuat(PxPi / 2.f, PxVec3(1.f, 0.f, 0.f))); + clothMesh.GeneratePlaneCloth(4.f, 4.f, 1, 1, false, transform); + clothMesh.AttachClothPlaneByAngles(1, 1); + + mClothActor[index] = new ClothActor; + nv::cloth::ClothMeshDesc meshDesc = clothMesh.GetClothMeshDesc(); + { + mClothActor[index]->mClothRenderMesh = new ClothRenderMesh(meshDesc); + mClothActor[index]->mClothRenderable = getSceneController()->getRenderer().createRenderable(*(static_cast<IRenderMesh*>(mClothActor[index]->mClothRenderMesh)), *getSceneController()->getDefaultMaterial()); + mClothActor[index]->mClothRenderable->setColor(getRandomPastelColor()); + } + + nv::cloth::Vector<int32_t>::Type phaseTypeInfo; + mFabric[index] = NvClothCookFabricFromMesh(getSceneController()->getFactory(), meshDesc, physx::PxVec3(0.0f, 0.0f, 1.0f), &phaseTypeInfo, false); + trackFabric(mFabric[index]); + + // Initialize start positions and masses for the actual cloth instance + // (note: the particle/vertex positions do not have to match the mesh description here. Set the positions to the initial shape of this cloth instance) + std::vector<physx::PxVec4> particlesCopy; + particlesCopy.resize(clothMesh.mVertices.size()); + + physx::PxVec3 clothOffset = transform.getPosition(); + for (int i = 0; i < (int)clothMesh.mVertices.size(); i++) + { + // To put attachment point closer to each other + if(clothMesh.mInvMasses[i] < 1e-6) + clothMesh.mVertices[i] = (clothMesh.mVertices[i] - clothOffset) * 1.0f + clothOffset; + + particlesCopy[i] = physx::PxVec4(clothMesh.mVertices[i], 0.5f * clothMesh.mInvMasses[i]); // w component is 1/mass, or 0.0f for anchored/fixed particles + } + + // Create the cloth from the initial positions/masses and the fabric + mClothActor[index]->mCloth = getSceneController()->getFactory()->createCloth(nv::cloth::Range<physx::PxVec4>(&particlesCopy[0], &particlesCopy[0] + particlesCopy.size()), *mFabric[index]); + particlesCopy.clear(); particlesCopy.shrink_to_fit(); + + mClothActor[index]->mCloth->setGravity(physx::PxVec3(0.0f, -9.8f*0.0f, 0.0f)); + mClothActor[index]->mCloth->setTetherConstraintStiffness(0.01); + mClothActor[index]->mCloth->setStiffnessFrequency(10); + mClothActor[index]->mCloth->setTetherConstraintScale(0.7); + if(index == 0) + { + mClothActor[index]->mCloth->setSolverFrequency(60); + } + else + { + mClothActor[index]->mCloth->setSolverFrequency(300); + } + + //actual spring frequency of the 300hz cloth should be about 2.25x faster instead + // of 4.5x if the stiffness compensation is used (Log stiffness). + + // Setup phase configs + std::vector<nv::cloth::PhaseConfig> phases(mFabric[index]->getNumPhases()); + for (int i = 0; i < (int)phases.size(); i++) + { + phases[i].mPhaseIndex = i; + phases[i].mStiffness = 0.0f; + phases[i].mStiffnessMultiplier = 1.0f; + phases[i].mCompressionLimit = 1.0f; + phases[i].mStretchLimit = 1.0f; + } + mClothActor[index]->mCloth->setPhaseConfig(nv::cloth::Range<nv::cloth::PhaseConfig>(&phases.front(), &phases.back())); + + trackClothActor(mClothActor[index]); + + // Add the cloth to the solver for simulation + addClothToSolver(mClothActor[index], mSolver); +} + +void TimeStepScene::onInitialize() +{ + mSolver = getSceneController()->getFactory()->createSolver(); + trackSolver(mSolver); + + initializeCloth(0,physx::PxVec3(-7.0f, 2.0f, 0.0f)); + initializeCloth(1, physx::PxVec3(2.0f, 2.0f, 0.0f)); + + mTime = 0.0f; + + { + IRenderMesh* mesh = getSceneController()->getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Plane); + Renderable* plane = getSceneController()->getRenderer().createRenderable(*mesh, *getSceneController()->getDefaultPlaneMaterial()); + plane->setTransform(PxTransform(PxVec3(0.f, 0.f, 0.f), PxQuat(PxPiDivTwo, PxVec3(0.f, 0.f, 1.f)))); + plane->setScale(PxVec3(1000.f)); + trackRenderable(plane); + } +} diff --git a/NvCloth/samples/SampleBase/scene/scenes/TimeStepScene.h b/NvCloth/samples/SampleBase/scene/scenes/TimeStepScene.h new file mode 100644 index 0000000..82b0034 --- /dev/null +++ b/NvCloth/samples/SampleBase/scene/scenes/TimeStepScene.h @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2008-2017, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef TETHER_SCENE_H +#define TETHER_SCENE_H + +#include "scene/Scene.h" +#include <foundation/PxVec3.h> + +class TimeStepScene : public Scene +{ +public: + + TimeStepScene(SceneController* sceneController): Scene(sceneController) {} + + void initializeCloth(int index, physx::PxVec3 offset); + virtual void onInitialize() override; + +private: + nv::cloth::Fabric* mFabric[2]; + nv::cloth::Solver* mSolver; + ClothActor* mClothActor[2]; + + float mTime; + +}; + + +#endif
\ No newline at end of file diff --git a/NvCloth/samples/SampleBase/scene/scenes/VirtualParticleScene.cpp b/NvCloth/samples/SampleBase/scene/scenes/VirtualParticleScene.cpp new file mode 100644 index 0000000..a2fa3a5 --- /dev/null +++ b/NvCloth/samples/SampleBase/scene/scenes/VirtualParticleScene.cpp @@ -0,0 +1,171 @@ +/* +* Copyright (c) 2008-2017, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "VirtualParticleScene.h" +#include "scene/SceneController.h" +#include <NvClothExt/ClothFabricCooker.h> +#include "ClothMeshGenerator.h" +#include <NvCloth/Fabric.h> +#include <NvCloth/Solver.h> +#include <NvCloth/Cloth.h> +#include <NvCloth/Factory.h> +#include "Renderer.h" +#include "renderer/RenderUtils.h" +#include "windows.h" +#include "utils/MeshGenerator.h" + +DECLARE_SCENE_NAME(VirtualParticleScene, "Virtual Particle Scene") + +void VirtualParticleScene::Animate(double dt) +{ + static float time = 0.0f; + time += dt*0.75; + + physx::PxTransform invTranslation(-mOffset - physx::PxVec3(0.f, 10.f, -2.f)); + physx::PxTransform rotation(physx::PxQuat(cosf(time)*physx::PxHalfPi-physx::PxHalfPi,physx::PxVec3(0.0f,1.0f,0.0f))); + physx::PxTransform translation(mOffset + physx::PxVec3(0.f, 10.f, -2.f) + physx::PxVec3(0.0f,0.0f,10.0f*sinf(time))); + physx::PxTransform totalTransform = translation.transform(rotation.transform(invTranslation)); + + physx::PxVec4 spheres[2] = { + physx::PxVec4(totalTransform.transform(physx::PxVec3(-4.f,10.f,0.f) + mOffset),1.5), + physx::PxVec4(totalTransform.transform(physx::PxVec3( 4.f,10.f,0.f) + mOffset),1.5)}; + + mClothActor[0]->mCloth->setSpheres(nv::cloth::Range<physx::PxVec4>(spheres, spheres + 2), 0, mClothActor[0]->mCloth->getNumSpheres()); + + mCollisionMehs->setTransform(totalTransform); + + Scene::Animate(dt); +} + +void VirtualParticleScene::initializeCloth(int index, physx::PxVec3 offset) +{ + mOffset = offset; + + /////////////////////////////////////////////////////////////////////// + ClothMeshData clothMesh; + + physx::PxMat44 transform = PxTransform(PxVec3(0.f, 13.f, 0.f)+ mOffset, PxQuat(0, PxVec3(1.f, 0.f, 0.f))); + clothMesh.GeneratePlaneCloth(5.f, 6.f, 9, 1, false, transform); + clothMesh.AttachClothPlaneByAngles(8, 1); + //clothMesh.SetInvMasses(0.5f + (float)index * 2.0f); + + mClothActor[index] = new ClothActor; + nv::cloth::ClothMeshDesc meshDesc = clothMesh.GetClothMeshDesc(); + { + mClothActor[index]->mClothRenderMesh = new ClothRenderMesh(meshDesc); + mClothActor[index]->mClothRenderable = getSceneController()->getRenderer().createRenderable(*(static_cast<IRenderMesh*>(mClothActor[index]->mClothRenderMesh)), *getSceneController()->getDefaultMaterial()); + + float r, g, b; + r = index == 0 ? 1.0f : 0.3f; + g = index == 1 ? 1.0f : 0.3f; + b = index == 2 ? 1.0f : 0.3f; + + mClothActor[index]->mClothRenderable->setColor(DirectX::XMFLOAT4(r, g, b, 1.0f)); + } + + nv::cloth::Vector<int32_t>::Type phaseTypeInfo; + mFabric[index] = NvClothCookFabricFromMesh(getSceneController()->getFactory(), meshDesc, physx::PxVec3(0.0f, 0.0f, 1.0f), &phaseTypeInfo, false); + trackFabric(mFabric[index]); + + // Initialize start positions and masses for the actual cloth instance + // (note: the particle/vertex positions do not have to match the mesh description here. Set the positions to the initial shape of this cloth instance) + std::vector<physx::PxVec4> particlesCopy; + particlesCopy.resize(clothMesh.mVertices.size()); + + physx::PxVec3 clothOffset = transform.getPosition(); + for(int i = 0; i < (int)clothMesh.mVertices.size(); i++) + { + // To put attachment point closer to each other + if(clothMesh.mInvMasses[i] < 1e-6) + clothMesh.mVertices[i] = (clothMesh.mVertices[i] - clothOffset)*0.95f + clothOffset; + + particlesCopy[i] = physx::PxVec4(clothMesh.mVertices[i], clothMesh.mInvMasses[i]); // w component is 1/mass, or 0.0f for anchored/fixed particles + } + + // Create the cloth from the initial positions/masses and the fabric + mClothActor[index]->mCloth = getSceneController()->getFactory()->createCloth(nv::cloth::Range<physx::PxVec4>(&particlesCopy[0], &particlesCopy[0] + particlesCopy.size()), *mFabric[index]); + particlesCopy.clear(); particlesCopy.shrink_to_fit(); + + mClothActor[index]->mCloth->setGravity(physx::PxVec3(0.0f, -50.0f, 0.0f)); + mClothActor[index]->mCloth->setDamping(physx::PxVec3(0.1f, 0.1f, 0.1f)); + //mClothActor[index]->mCloth->setSelfCollisionDistance(0.07f); + //mClothActor[index]->mCloth->enableContinuousCollision(true); + //mClothActor[index]->mCloth->setFriction(1.0f); + typedef uint32_t arraytype[4]; + + arraytype * virtualParticleIndices = new uint32_t[clothMesh.mTriangles.size()][4]; + for(int i = 0; i < (int)clothMesh.mTriangles.size(); i++) + { + virtualParticleIndices[i][0] = clothMesh.mTriangles[i].a; + virtualParticleIndices[i][1] = clothMesh.mTriangles[i].b; + virtualParticleIndices[i][2] = clothMesh.mTriangles[i].c; + virtualParticleIndices[i][3] = 0; + } + + physx::PxVec3 weights[1] = + { + physx::PxVec3(1.0f,1.0f,1.0f) / 3.0f + }; + + mClothActor[index]->mCloth->setVirtualParticles(nv::cloth::Range<const uint32_t[4]>(virtualParticleIndices, (virtualParticleIndices+ clothMesh.mTriangles.size())), nv::cloth::Range<physx::PxVec3>(weights, weights+1)); + + + physx::PxVec4 spheres[2] = {physx::PxVec4(physx::PxVec3(-4.f,10.f,0.f) + mOffset,1.5), + physx::PxVec4(physx::PxVec3( 4.f,10.f,0.f) + mOffset,1.5)}; + + mClothActor[index]->mCloth->setSpheres(nv::cloth::Range<physx::PxVec4>(spheres, spheres + 2), 0, mClothActor[index]->mCloth->getNumSpheres()); + + uint32_t caps[4]; + caps[0] = 0; + caps[1] = 1; + + mClothActor[index]->mCloth->setCapsules(nv::cloth::Range<uint32_t>(caps, caps + 2), 0, mClothActor[index]->mCloth->getNumCapsules()); + + //create render mesh + auto mesh = MeshGenerator::generateCollisionCapsules(spheres,2,caps,2,-0.05f); + auto renderMesh = new MeshGenerator::MeshGeneratorRenderMesh(mesh); + mCollisionMehs = getSceneController()->getRenderer().createRenderable(*renderMesh, *getSceneController()->getDefaultMaterial()); + trackRenderable(mCollisionMehs); + + // Setup phase configs + std::vector<nv::cloth::PhaseConfig> phases(mFabric[index]->getNumPhases()); + for(int i = 0; i < (int)phases.size(); i++) + { + phases[i].mPhaseIndex = i; + phases[i].mStiffness = 1.0f; + phases[i].mStiffnessMultiplier = 1.0f; + phases[i].mCompressionLimit = 1.0f; + phases[i].mStretchLimit = 1.0f; + } + mClothActor[index]->mCloth->setPhaseConfig(nv::cloth::Range<nv::cloth::PhaseConfig>(&phases.front(), &phases.back())); + mClothActor[index]->mCloth->setDragCoefficient(0.5f); + mClothActor[index]->mCloth->setLiftCoefficient(0.6f); + + trackClothActor(mClothActor[index]); + + // Add the cloth to the solver for simulation + addClothToSolver(mClothActor[index], mSolver); +} + +void VirtualParticleScene::onInitialize() +{ + mSolver = getSceneController()->getFactory()->createSolver(); + trackSolver(mSolver); + + initializeCloth(0, physx::PxVec3(0.0f, 0.0f, 0.0f)); + + { + IRenderMesh* mesh = getSceneController()->getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Plane); + Renderable* plane = getSceneController()->getRenderer().createRenderable(*mesh, *getSceneController()->getDefaultPlaneMaterial()); + plane->setTransform(PxTransform(PxVec3(0.f, 0.f, 0.f), PxQuat(PxPiDivTwo, PxVec3(0.f, 0.f, 1.f)))); + plane->setScale(PxVec3(1000.f)); + trackRenderable(plane); + } +} diff --git a/NvCloth/samples/SampleBase/scene/scenes/VirtualParticleScene.h b/NvCloth/samples/SampleBase/scene/scenes/VirtualParticleScene.h new file mode 100644 index 0000000..38fa66b --- /dev/null +++ b/NvCloth/samples/SampleBase/scene/scenes/VirtualParticleScene.h @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2008-2017, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#ifndef CCD_SCENE_H +#define CCD_SCENE_H + +#include "scene/Scene.h" +#include <foundation/PxVec3.h> + +class VirtualParticleScene : public Scene +{ +public: + + VirtualParticleScene(SceneController* sceneController): Scene(sceneController) {} + + virtual void Animate(double dt) override; + void initializeCloth(int index, physx::PxVec3 offset); + virtual void onInitialize() override; + +private: + nv::cloth::Fabric* mFabric[1]; + nv::cloth::Solver* mSolver; + ClothActor* mClothActor[1]; + + physx::PxVec3 mOffset; + Renderable* mCollisionMehs; +}; + + +#endif
\ No newline at end of file |