aboutsummaryrefslogtreecommitdiff
path: root/NvCloth/samples/SampleBase/scene
diff options
context:
space:
mode:
authormtamis <[email protected]>2017-02-28 18:24:59 +0100
committermtamis <[email protected]>2017-02-28 18:24:59 +0100
commit5581909a4d19db97304449f66404ff99a0429d3f (patch)
treea90f7eb85c095a8aba45cf5e909c82c1cdbed77d /NvCloth/samples/SampleBase/scene
parentFix cmake visual studio project generation (locate_gw_root.bat) (diff)
downloadnvcloth-5581909a4d19db97304449f66404ff99a0429d3f.tar.xz
nvcloth-5581909a4d19db97304449f66404ff99a0429d3f.zip
Add visual samples.
Diffstat (limited to 'NvCloth/samples/SampleBase/scene')
-rw-r--r--NvCloth/samples/SampleBase/scene/Scene.cpp162
-rw-r--r--NvCloth/samples/SampleBase/scene/Scene.h104
-rw-r--r--NvCloth/samples/SampleBase/scene/SceneController.cpp250
-rw-r--r--NvCloth/samples/SampleBase/scene/SceneController.h128
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/FreeFallScene.cpp116
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/FreeFallScene.h33
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/FrictionScene.cpp119
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/FrictionScene.h33
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/SimpleScene.cpp94
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/SimpleScene.h32
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/TetherScene.cpp103
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/TetherScene.h36
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/WindScene.cpp124
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/WindScene.h37
14 files changed, 1371 insertions, 0 deletions
diff --git a/NvCloth/samples/SampleBase/scene/Scene.cpp b/NvCloth/samples/SampleBase/scene/Scene.cpp
new file mode 100644
index 0000000..130dad3
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/Scene.cpp
@@ -0,0 +1,162 @@
+/*
+* 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 "Scene.h"
+#include <NvCloth/Cloth.h>
+#include <NvCloth/Solver.h>
+#include <NvCloth/Fabric.h>
+#include "Renderer.h"
+
+std::vector<SceneFactory> Scene::sSceneFactories;
+
+Scene::~Scene()
+{
+
+}
+
+namespace
+{
+template <typename T> void trackT(std::vector<T>& list, T object)
+{
+ list.push_back(object);
+}
+
+template <typename T> void untrackT(std::vector<T>& list, T object)
+{
+ for(auto it = list.begin(); it != list.end(); ++it)
+ {
+ if(*it == object)
+ {
+ list.erase(it);
+ break;
+ }
+ }
+}
+}
+void Scene::trackClothActor(ClothActor* clothActor)
+{
+ trackT(mClothList, clothActor);
+}
+void Scene::untrackClothActor(ClothActor* clothActor)
+{
+ untrackT(mClothList, clothActor);
+}
+void Scene::trackSolver(nv::cloth::Solver* solver)
+{
+ trackT(mSolverList, solver);
+ mSolverHelpers[solver].Initialize(solver, mSceneController->getJobManager());
+}
+void Scene::untrackSolver(nv::cloth::Solver* solver)
+{
+ untrackT(mSolverList, solver);
+ mSolverHelpers.erase(solver);
+}
+void Scene::trackFabric(nv::cloth::Fabric* fabric)
+{
+ trackT(mFabricList, fabric);
+}
+void Scene::untrackFabric(nv::cloth::Fabric* fabric)
+{
+ untrackT(mFabricList, fabric);
+}
+
+void Scene::addClothToSolver(ClothActor* clothActor, nv::cloth::Solver* solver)
+{
+ solver->addCloth(clothActor->mCloth);
+ assert(mClothSolverMap.find(clothActor) == mClothSolverMap.end());
+ mClothSolverMap[clothActor] = solver;
+}
+
+void Scene::trackRenderable(Renderable* renderable)
+{
+ trackT(mRenderableList, renderable);
+}
+void Scene::untrackRenderable(Renderable* renderable)
+{
+ untrackT(mRenderableList, renderable);
+}
+
+void Scene::autoDeinitialize()
+{
+ //Remove all cloths from solvers
+ for (auto it : mClothSolverMap)
+ {
+ it.second->removeCloth(it.first->mCloth);
+ }
+ mClothSolverMap.clear();
+
+ //Destroy all solvers
+ for (auto it : mSolverList)
+ {
+ delete it;
+ }
+ mSolverList.clear();
+ mSolverHelpers.clear();
+
+ //Destroy all cloths
+ for (auto it : mClothList)
+ {
+ delete it->mCloth;
+ mSceneController->getRenderer().removeRenderable(it->mClothRenderable);
+ delete it->mClothRenderMesh;
+ delete it;
+ }
+ mClothList.clear();
+
+ //Destroy all fabrics
+ for (auto it : mFabricList)
+ {
+ it->decRefCount();
+ }
+ mFabricList.clear();
+
+ //Destroy all renderables
+ for(auto it : mRenderableList)
+ {
+ mSceneController->getRenderer().removeRenderable(it);
+ }
+ mRenderableList.clear();
+}
+
+void Scene::doSimulationStep(float dt)
+{
+ startSimulationStep(dt);
+ waitForSimulationStep();
+ updateSimulationGraphics();
+}
+
+void Scene::startSimulationStep(float dt)
+{
+ for(auto it = mSolverHelpers.begin(); it != mSolverHelpers.end(); ++it)
+ {
+ it->second.StartSimulation(dt);
+ }
+}
+void Scene::waitForSimulationStep()
+{
+ for(auto it = mSolverHelpers.begin(); it != mSolverHelpers.end(); ++it)
+ {
+ it->second.WaitForSimulation();
+ }
+}
+
+void Scene::updateSimulationGraphics()
+{
+ for each (auto actor in mClothList)
+ {
+ nv::cloth::MappedRange<physx::PxVec4> particles = actor->mCloth->getCurrentParticles();
+ std::vector<PxVec3> particles3(particles.size());
+ for(uint32_t i = 0; i < particles.size(); ++i)
+ particles3[i] = particles[i].getXYZ();
+
+ actor->mClothRenderMesh->update(particles3.data(), particles.size());
+ }
+}
+
diff --git a/NvCloth/samples/SampleBase/scene/Scene.h b/NvCloth/samples/SampleBase/scene/Scene.h
new file mode 100644
index 0000000..3a11ec7
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/Scene.h
@@ -0,0 +1,104 @@
+/*
+* 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 SCENE_H
+#define SCENE_H
+
+#include <vector>
+#include <map>
+#include "scene/SceneController.h"
+namespace nv
+{
+ namespace cloth
+ {
+ class Factory;
+ class Solver;
+ class Cloth;
+ class Fabric;
+ }
+}
+
+class Scene;
+struct SceneFactory
+{
+ SceneFactory(Scene* (*create)(SceneController*), const char* name):Create(create), mName(name) {}
+ Scene* (*Create)(SceneController*);
+ const char* mName;
+};
+
+#define DECLARE_SCENE_NAME(classname, name) static int classname##id = Scene::AddSceneFactory([](SceneController* c) {return (Scene*)new classname(c); }, name);
+#define DECLARE_SCENE(classname) DECLARE_SCENE_NAME(classname,#classname)
+
+class Scene
+{
+public:
+
+ Scene(SceneController* sceneController):mSceneController(sceneController) {}
+ virtual ~Scene();
+
+ virtual void Animate(double dt) { doSimulationStep(dt); }
+ virtual void drawUI() {}
+ virtual void drawStatsUI() {}
+
+ virtual void onInitialize() = 0;
+ virtual void onTerminate() { autoDeinitialize(); }
+
+ SceneController* getSceneController() { return mSceneController; }
+
+ static int AddSceneFactory(Scene* (*create)(SceneController*), const char* name) { sSceneFactories.push_back(SceneFactory(create, name)); return (int)sSceneFactories.size(); }
+ static Scene* CreateScene(int index, SceneController* controller) { return sSceneFactories[index].Create(controller); }
+ static const char* GetSceneName(int index) { return sSceneFactories[index].mName; }
+ static int GetSceneCount() { return (int)sSceneFactories.size(); }
+
+protected:
+ //Helper functions to enable automatic deinitialize
+ //Tracking an object will delete it when autoDeinitialize is called
+ //Untracking can be used if you delete it sooner than autoDeinitialize
+ void trackClothActor(ClothActor* clothActor);
+ void untrackClothActor(ClothActor* clothActor);
+
+ void trackSolver(nv::cloth::Solver* solver);
+ void untrackSolver(nv::cloth::Solver* solver);
+
+ void trackFabric(nv::cloth::Fabric* fabric);
+ void untrackFabric(nv::cloth::Fabric* fabric);
+
+ void addClothToSolver(ClothActor* clothActor, nv::cloth::Solver* solver); //Helps to detach cloths from solver at AutoDeinit.
+
+ void trackRenderable(Renderable* renderMesh);
+ void untrackRenderable(Renderable* renderMesh);
+
+ void autoDeinitialize();
+
+
+ void doSimulationStep(float dt);
+ void startSimulationStep(float dt);
+ void waitForSimulationStep();
+ void updateSimulationGraphics();
+
+private:
+ Scene& operator= (Scene&); // not implemented
+
+private:
+ SceneController* mSceneController;
+
+ std::vector<ClothActor*> mClothList;
+ std::vector<nv::cloth::Solver*> mSolverList;
+ std::map<nv::cloth::Solver*, MultithreadedSolverHelper> mSolverHelpers;
+ std::vector<nv::cloth::Fabric*> mFabricList;
+ std::map<ClothActor*, nv::cloth::Solver*> mClothSolverMap;
+ std::vector<Renderable*> mRenderableList;
+
+ static std::vector<SceneFactory> sSceneFactories;
+
+};
+
+
+#endif \ No newline at end of file
diff --git a/NvCloth/samples/SampleBase/scene/SceneController.cpp b/NvCloth/samples/SampleBase/scene/SceneController.cpp
new file mode 100644
index 0000000..90b499c
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/SceneController.cpp
@@ -0,0 +1,250 @@
+/*
+* 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 "SceneController.h"
+#include "RenderUtils.h"
+#include "Utils.h"
+
+#include "Renderer.h"
+
+#include "CommonUIController.h"
+
+// initialization of NvCloth dll
+#include <NvCloth/Callbacks.h>
+
+// example allocator callbacks
+#include "CallbackImplementations.h"
+
+// low level cloth
+//#include <NvCloth/Factory.h>
+#include <NvCloth/Fabric.h>
+#include <NvCloth/Cloth.h>
+#include <NvCloth/Solver.h>
+
+#include <NvClothExt/ClothFabricCooker.h>
+#include "ClothMeshGenerator.h"
+
+#include <algorithm>
+#include <imgui.h>
+#include <sstream>
+#include <tuple>
+
+#include "scene/Scene.h"
+#include "scene/scenes/SimpleScene.h"
+#include "scene/scenes/WindScene.h"
+
+JobManager SceneController::sJobManager;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Controller
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SceneController::SceneController() : mTimeScale(1.0f), mStartDelay(0.f)
+{
+ mActivePlatform = (int)nv::cloth::Platform::CPU;
+ mCUDAInitialized = false;
+ mDXInitialized = false;
+}
+
+SceneController::~SceneController()
+{
+}
+
+void SceneController::onSampleStart()
+{
+ // setup camera
+ CFirstPersonCamera* camera = &getRenderer().getCamera();
+ DirectX::XMVECTORF32 lookAtPt = { 0, 10, 0, 0 };
+ DirectX::XMVECTORF32 eyePt = { 0, 15, 25, 0 };
+ camera->SetViewParams(eyePt, lookAtPt);
+ camera->SetRotateButtons(false, false, true, false);
+ camera->SetEnablePositionMovement(true);
+
+ mStartDelay = 3.f;
+
+ mPhysXPrimitiveRenderMaterial = new RenderMaterial(getRenderer().getResourceManager(), "physx_primitive", "");
+ mPhysXPlaneRenderMaterial = new RenderMaterial(getRenderer().getResourceManager(), "physx_primitive_plane", "");
+
+ /*{
+ IRenderMesh* mesh = getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Plane);
+ mPlane = getRenderer().createRenderable(*mesh, *mPhysXPlaneRenderMaterial);
+ mPlane->setTransform(PxTransform(PxVec3(0.f, 0.f, 0.f), PxQuat(PxPiDivTwo, PxVec3(0.f, 0.f, 1.f))));
+ mPlane->setScale(PxVec3(1000.f));
+ }*/
+
+ for (uint32_t i = 0; i < 0; ++i)
+ {
+ IRenderMesh* mesh = getRenderer().getPrimitiveRenderMesh(PrimitiveRenderMeshType::Box);
+ auto box = getRenderer().createRenderable(*mesh, *mPhysXPrimitiveRenderMaterial);
+ box->setColor(getRandomPastelColor());
+ box->setScale(PxVec3(0.2f));
+ mBoxes.push_back(box);
+ }
+
+
+ ///
+
+ mActiveScene = new SimpleScene(this);
+ mActiveScene->onInitialize();
+ mActiveSceneIndex = 0;
+}
+
+void SceneController::onInitialize()
+{
+ NvClothEnvironment::AllocateEnv();
+
+ mFactories[(int)nv::cloth::Platform::CPU] = NvClothCreateFactoryCPU();
+ mFactories[(int)nv::cloth::Platform::CUDA] = nullptr;
+ mFactories[(int)nv::cloth::Platform::DX11] = nullptr;
+
+ //CUDA
+ do
+ {
+ assert(mCUDAInitialized == false);
+ cuInit(0);
+ int deviceCount = 0;
+ mCUDAInitialized = true;
+ mCUDAInitialized = (cuDeviceGetCount(&deviceCount) == CUDA_SUCCESS);
+ mCUDAInitialized &= deviceCount >= 1;
+ if(!mCUDAInitialized)
+ break;
+ mCUDAInitialized = cuCtxCreate(&mCUDAContext, 0, 0) == CUDA_SUCCESS;
+ if(!mCUDAInitialized)
+ break;
+
+ mFactories[(int)nv::cloth::Platform::CUDA] = NvClothCreateFactoryCUDA(mCUDAContext);
+ } while(false);
+
+ //DX11
+ do
+ {
+ assert(mDXInitialized == false);
+ mDXInitialized = true;
+ mDXDevice = GetDeviceManager()->GetDevice();
+
+ mGraphicsContextManager = new DxContextManagerCallbackImpl(mDXDevice);
+ mDXInitialized &= mGraphicsContextManager != nullptr;
+ if(!mDXInitialized)
+ break;
+
+ mFactories[(int)nv::cloth::Platform::DX11] = NvClothCreateFactoryDX11(mGraphicsContextManager);
+ mDXInitialized &= mFactories[(int)nv::cloth::Platform::DX11] != nullptr;
+ } while(false);
+}
+
+void SceneController::onSampleStop()
+{
+ mActiveScene->onTerminate();
+ delete mActiveScene;
+
+ for (auto b : mBoxes)
+ SAFE_DELETE(b);
+
+ mBoxes.clear();
+
+ NvClothDestroyFactory(mFactories[(int)nv::cloth::Platform::CPU]);
+ NvClothDestroyFactory(mFactories[(int)nv::cloth::Platform::CUDA]);
+ NvClothDestroyFactory(mFactories[(int)nv::cloth::Platform::DX11]);
+
+ //SAFE_DELETE(mPlane);
+ SAFE_DELETE(mPhysXPlaneRenderMaterial);
+ SAFE_DELETE(mPhysXPrimitiveRenderMaterial);
+}
+
+void SceneController::onTerminate()
+{
+}
+
+void SceneController::changeScene(int index)
+{
+ mActiveScene->onTerminate();
+ delete mActiveScene;
+
+ mActiveSceneIndex = index;
+
+ if(index < Scene::GetSceneCount())
+ mActiveScene = Scene::CreateScene(index, this);
+ else
+ {
+ mActiveSceneIndex = 0;
+ mActiveScene = Scene::CreateScene(0, this);
+ }
+ mActiveScene->onInitialize();
+}
+
+void SceneController::Animate(double dt)
+{
+ double simulationStep = dt * mTimeScale;
+ if(simulationStep > 1.0 / 60.0)
+ simulationStep = 1.0 / 60.0;
+
+ mActiveScene->Animate(simulationStep);
+
+}
+
+LRESULT SceneController::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg == WM_KEYDOWN)
+ {
+ int iKeyPressed = static_cast<int>(wParam);
+
+ if(iKeyPressed >= '1' && iKeyPressed <= '9')
+ {
+ changeScene(iKeyPressed - '1');
+ }
+
+ switch (iKeyPressed)
+ {
+ case 'R':
+ return 0;
+ case 'F':
+ return 0;
+ default:
+ break;
+ }
+ }
+
+ return 1;
+}
+
+void SceneController::drawUI()
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Cube
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ {
+ ImGui::Text("Time Scale");
+ ImGui::DragFloat("Scale", &mTimeScale, 0.1f, 0.0f, 100.0f);
+ }
+
+ bool pressed = false;
+
+ pressed = pressed | ImGui::RadioButton("CPU", &mActivePlatform, (int)nv::cloth::Platform::CPU); ImGui::SameLine();
+ pressed = pressed | ImGui::RadioButton("DX11", &mActivePlatform, (int)nv::cloth::Platform::DX11); ImGui::SameLine();
+ pressed = pressed | ImGui::RadioButton("CUDA", &mActivePlatform, (int)nv::cloth::Platform::CUDA);
+
+ if(!getFactory())
+ mActivePlatform = (int)nv::cloth::Platform::CPU;
+
+ for(int i = 0; i < Scene::GetSceneCount(); i++)
+ {
+ pressed = pressed | ImGui::RadioButton(Scene::GetSceneName(i), &mActiveSceneIndex, i);
+ }
+ if(pressed)
+ changeScene(mActiveSceneIndex);
+
+ mActiveScene->drawUI();
+}
+
+void SceneController::drawStatsUI()
+{
+ mActiveScene->drawStatsUI();
+}
+
diff --git a/NvCloth/samples/SampleBase/scene/SceneController.h b/NvCloth/samples/SampleBase/scene/SceneController.h
new file mode 100644
index 0000000..d527597
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/SceneController.h
@@ -0,0 +1,128 @@
+/*
+* 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 SCENE_CONTROLLER_H
+#define SCENE_CONTROLLER_H
+
+
+#include "SampleManager.h"
+#include <map>
+#include <vector>
+
+#include <NvCloth/Factory.h>
+#include "JobManager.h"
+
+#include "ClothRenderMesh.h"
+#include <cuda.h>
+#include "CallbackImplementations.h"
+
+namespace nv
+{
+ namespace cloth
+ {
+ class Factory;
+ class Solver;
+ class Cloth;
+ class Fabric;
+ class DxContextManagerCallback;
+ }
+}
+
+class RenderMaterial;
+class Renderable;
+
+struct ClothActor
+{
+ Renderable* mClothRenderable;
+ ClothRenderMesh* mClothRenderMesh;
+ nv::cloth::Cloth* mCloth;
+};
+
+class Scene;
+
+class SceneController : public ISampleController
+{
+public:
+
+ SceneController();
+ virtual ~SceneController();
+
+ virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual void Animate(double dt);
+ void drawUI();
+ void drawStatsUI();
+
+ virtual void onInitialize();
+ virtual void onSampleStart();
+ virtual void onSampleStop();
+ virtual void onTerminate();
+
+ JobManager* getJobManager() { return &sJobManager; }
+ nv::cloth::Factory* getFactory() { return mFactories[mActivePlatform]; }
+
+ static JobManager sJobManager;
+
+ //////// used controllers ////////
+
+ Renderer& getRenderer() const
+ {
+ return getManager()->getRenderer();
+ }
+
+ CommonUIController& getCommonUIController() const
+ {
+ return getManager()->getCommonUIController();
+ }
+
+ RenderMaterial* getDefaultMaterial()
+ {
+ return mPhysXPrimitiveRenderMaterial;
+ }
+
+ RenderMaterial* getDefaultPlaneMaterial()
+ {
+ return mPhysXPlaneRenderMaterial;
+ }
+
+
+private:
+ SceneController& operator= (SceneController&); // not implemented
+
+ void changeScene(int index);
+
+ //////// internal data ////////
+
+ RenderMaterial* mPhysXPrimitiveRenderMaterial;
+ RenderMaterial* mPhysXPlaneRenderMaterial;
+
+ Renderable* mPlane;
+ std::vector<Renderable*> mBoxes;
+
+ float mTimeScale;
+ float mStartDelay;
+
+ // NvCloth
+ CpuDispatcher mDispatcher;
+ physx::PxTaskManager* mTaskManager;
+
+ nv::cloth::Factory* mFactories[3];
+ int mActivePlatform;
+ bool mCUDAInitialized;
+ CUcontext mCUDAContext;
+ bool mDXInitialized;
+ ID3D11Device* mDXDevice;
+ ID3D11DeviceContext* mDXDeviceContext;
+ nv::cloth::DxContextManagerCallback* mGraphicsContextManager;
+
+ Scene* mActiveScene;
+ int mActiveSceneIndex;
+};
+
+#endif \ No newline at end of file
diff --git a/NvCloth/samples/SampleBase/scene/scenes/FreeFallScene.cpp b/NvCloth/samples/SampleBase/scene/scenes/FreeFallScene.cpp
new file mode 100644
index 0000000..c1f6a00
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/scenes/FreeFallScene.cpp
@@ -0,0 +1,116 @@
+/*
+* 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 "FreeFallScene.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(FreeFallScene, "Free Fall Scene")
+
+void FreeFallScene::initializeCloth(int index, physx::PxVec3 offset)
+{
+ ///////////////////////////////////////////////////////////////////////
+ ClothMeshData clothMesh;
+
+ physx::PxMat44 transform = PxTransform(PxVec3(0.f, 13.f, 0.f)+ offset, PxQuat(PxPi, PxVec3(1.f, 0.f, 0.f)));
+ clothMesh.GeneratePlaneCloth(1.f * (1 << index), 1.f * (1 << index), int(2.0f*(1 << index)), int(2.0f*(1 << index)), false, transform);
+
+ 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)*0.9f + 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();
+
+ std::vector<physx::PxVec4> planes;
+ planes.push_back(physx::PxVec4(physx::PxVec3(0.0f, 1.f, 0.0f), -0.01f));
+
+ 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++)
+ 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());
+
+ mClothActor[index]->mCloth->setGravity(physx::PxVec3(0.0f, -1.0f, 0.0f));
+ mClothActor[index]->mCloth->setFriction(0.1);
+ mClothActor[index]->mCloth->setDragCoefficient(0.5);
+ mClothActor[index]->mCloth->setLiftCoefficient(0.0);
+
+ // 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()));
+
+ mSolver = getSceneController()->getFactory()->createSolver();
+ trackSolver(mSolver);
+ trackClothActor(mClothActor[index]);
+
+ // Add the cloth to the solver for simulation
+ addClothToSolver(mClothActor[index], mSolver);
+}
+
+void FreeFallScene::onInitialize()
+{
+ float spaceX = -1.5f;
+
+ for(int i = 0; i < 4; ++i)
+ {
+ initializeCloth(i, physx::PxVec3(16.f + float((i+1)*(i+1)) * spaceX, 2.f, -7.f));
+ }
+
+ {
+ 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/FreeFallScene.h b/NvCloth/samples/SampleBase/scene/scenes/FreeFallScene.h
new file mode 100644
index 0000000..3cab456
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/scenes/FreeFallScene.h
@@ -0,0 +1,33 @@
+/*
+* 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 FREE_FALL_SCENE_H
+#define FREE_FALL_SCENE_H
+
+#include "scene/Scene.h"
+#include <foundation/PxVec3.h>
+
+class FreeFallScene : public Scene
+{
+public:
+
+ FreeFallScene(SceneController* sceneController): Scene(sceneController) {}
+
+ void initializeCloth(int index, physx::PxVec3 offset);
+ virtual void onInitialize() override;
+
+private:
+ nv::cloth::Fabric* mFabric[4];
+ nv::cloth::Solver* mSolver;
+ ClothActor* mClothActor[4];
+};
+
+
+#endif \ No newline at end of file
diff --git a/NvCloth/samples/SampleBase/scene/scenes/FrictionScene.cpp b/NvCloth/samples/SampleBase/scene/scenes/FrictionScene.cpp
new file mode 100644
index 0000000..3c181ea
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/scenes/FrictionScene.cpp
@@ -0,0 +1,119 @@
+/*
+* 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 "FrictionScene.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(FrictionScene, "Friction Scene")
+
+void FrictionScene::initializeCloth(int index, physx::PxVec3 offset, float frictionCoef)
+{
+ ///////////////////////////////////////////////////////////////////////
+ ClothMeshData clothMesh;
+
+ physx::PxMat44 transform = PxTransform(PxVec3(0.f, 13.f, 0.f)+ offset, PxQuat(PxPi / 6.f, PxVec3(1.f, 0.f, 0.f)));
+ clothMesh.GeneratePlaneCloth(3.f, 3.f, 29, 29, false, transform);
+
+ 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)*0.9f + 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();
+
+ std::vector<physx::PxVec4> planes;
+ planes.push_back(physx::PxVec4(PxQuat(PxPiDivFour*0.5f, PxVec3(1.f, 0.f, 0.f)).rotate(physx::PxVec3(0.0f, 1.f, 0.0f)), -0.01f));
+
+ 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++)
+ 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());
+
+ 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->setFriction(frictionCoef);
+
+ mSolver = getSceneController()->getFactory()->createSolver();
+ trackSolver(mSolver);
+ trackClothActor(mClothActor[index]);
+
+ // Add the cloth to the solver for simulation
+ addClothToSolver(mClothActor[index], mSolver);
+}
+
+void FrictionScene::onInitialize()
+{
+
+
+ float spaceX = -4.f;
+ float frictionDelta = 0.2f;
+
+ for(int i = 0; i < 4; ++i)
+ {
+ float friction = i > 0 ? float(i) * frictionDelta : 0.f; // 0.0, 0.2, 0.4, 0.6
+
+ initializeCloth(i, physx::PxVec3(4.f + float(i) * spaceX, 4.f, -18.f), friction);
+ }
+
+ {
+ 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(PxPiDivFour*0.5f, PxVec3(1.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/FrictionScene.h b/NvCloth/samples/SampleBase/scene/scenes/FrictionScene.h
new file mode 100644
index 0000000..4173e09
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/scenes/FrictionScene.h
@@ -0,0 +1,33 @@
+/*
+* 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 FRICTION_SCENE_H
+#define FRICTION_SCENE_H
+
+#include "scene/Scene.h"
+#include <foundation/PxVec3.h>
+
+class FrictionScene : public Scene
+{
+public:
+
+ FrictionScene(SceneController* sceneController): Scene(sceneController) {}
+
+ void initializeCloth(int index, physx::PxVec3 offset, float frictionCoef);
+ virtual void onInitialize() override;
+
+private:
+ nv::cloth::Fabric* mFabric[4];
+ nv::cloth::Solver* mSolver;
+ ClothActor* mClothActor[4];
+};
+
+
+#endif \ No newline at end of file
diff --git a/NvCloth/samples/SampleBase/scene/scenes/SimpleScene.cpp b/NvCloth/samples/SampleBase/scene/scenes/SimpleScene.cpp
new file mode 100644
index 0000000..68bb96b
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/scenes/SimpleScene.cpp
@@ -0,0 +1,94 @@
+/*
+* 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 "SimpleScene.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(SimpleScene,"Simple Scene")
+
+void SimpleScene::onInitialize()
+{
+ ///////////////////////////////////////////////////////////////////////
+ ClothMeshData clothMesh;
+
+ physx::PxMat44 transform = PxTransform(PxVec3(0.f, 13.f, 0.f), PxQuat(PxPi / 6.f, PxVec3(1.f, 0.f, 0.f)));
+ clothMesh.GeneratePlaneCloth(6.f, 7.f, 59, 69, false, transform);
+ clothMesh.AttachClothPlaneByAngles(59, 69);
+
+ mClothActor = new ClothActor;
+ nv::cloth::ClothMeshDesc meshDesc = clothMesh.GetClothMeshDesc();
+ {
+ mClothActor->mClothRenderMesh = new ClothRenderMesh(meshDesc);
+ mClothActor->mClothRenderable = getSceneController()->getRenderer().createRenderable(*(static_cast<IRenderMesh*>(mClothActor->mClothRenderMesh)), *getSceneController()->getDefaultMaterial());
+ mClothActor->mClothRenderable->setColor(getRandomPastelColor());
+ }
+
+ nv::cloth::Vector<int32_t>::Type phaseTypeInfo;
+ mFabric = NvClothCookFabricFromMesh(getSceneController()->getFactory(), meshDesc, physx::PxVec3(0.0f, -9.8f, 0.0f), &phaseTypeInfo, false);
+ trackFabric(mFabric);
+
+ // 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 center = transform.transform(physx::PxVec3(0.0f, 0.0f, 0.0f));
+ 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] - center)*0.85f + center;
+
+ 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->mCloth = getSceneController()->getFactory()->createCloth(nv::cloth::Range<physx::PxVec4>(&particlesCopy[0], &particlesCopy[0] + particlesCopy.size()), *mFabric);
+ particlesCopy.clear(); particlesCopy.shrink_to_fit();
+
+ mClothActor->mCloth->setGravity(physx::PxVec3(0.0f, -9.8f, 0.0f));
+
+ // Setup phase configs
+ std::vector<nv::cloth::PhaseConfig> phases(mFabric->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->mCloth->setPhaseConfig(nv::cloth::Range<nv::cloth::PhaseConfig>(&phases.front(), &phases.back()));
+ mClothActor->mCloth->setDragCoefficient(0.5f);
+ mClothActor->mCloth->setDragCoefficient(0.5f);
+
+ mSolver = getSceneController()->getFactory()->createSolver();
+ trackSolver(mSolver);
+ trackClothActor(mClothActor);
+
+ // Add the cloth to the solver for simulation
+ addClothToSolver(mClothActor, mSolver);
+
+ {
+ 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/SimpleScene.h b/NvCloth/samples/SampleBase/scene/scenes/SimpleScene.h
new file mode 100644
index 0000000..2ee17c1
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/scenes/SimpleScene.h
@@ -0,0 +1,32 @@
+/*
+* 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 SIMPLE_SCENE_H
+#define SIMPLE_SCENE_H
+
+#include "scene/Scene.h"
+
+class SimpleScene : public Scene
+{
+public:
+
+ SimpleScene(SceneController* sceneController):Scene(sceneController) {}
+
+ virtual void onInitialize() override;
+
+private:
+ nv::cloth::Fabric* mFabric;
+ nv::cloth::Solver* mSolver;
+ ClothActor* mClothActor;
+
+};
+
+
+#endif \ No newline at end of file
diff --git a/NvCloth/samples/SampleBase/scene/scenes/TetherScene.cpp b/NvCloth/samples/SampleBase/scene/scenes/TetherScene.cpp
new file mode 100644
index 0000000..b818d9d
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/scenes/TetherScene.cpp
@@ -0,0 +1,103 @@
+/*
+* 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 "TetherScene.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(TetherScene, "Tether Scene")
+
+void TetherScene::initializeCloth(int index, physx::PxVec3 offset, float tetherStiffness)
+{
+ ///////////////////////////////////////////////////////////////////////
+ ClothMeshData clothMesh;
+
+ physx::PxMat44 transform = PxTransform(PxVec3(0.f, 13.f, 0.f)+ offset, PxQuat(PxPi / 6.f, PxVec3(1.f, 0.f, 0.f)));
+ clothMesh.GeneratePlaneCloth(6.f, 7.5f, 39, 59, false, transform);
+ clothMesh.AttachClothPlaneByAngles(39, 59);
+
+ 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)*0.8f + 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->setTetherConstraintStiffness(tetherStiffness);
+
+ // 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()));
+
+
+ mSolver = getSceneController()->getFactory()->createSolver();
+ trackSolver(mSolver);
+ trackClothActor(mClothActor[index]);
+
+ // Add the cloth to the solver for simulation
+ addClothToSolver(mClothActor[index], mSolver);
+}
+
+void TetherScene::onInitialize()
+{
+
+ initializeCloth(0,physx::PxVec3(-5.0f,0.0f,0.0f),0);
+ initializeCloth(1, physx::PxVec3(4.0f, 0.0f, 0.0f),1);
+
+ 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/TetherScene.h b/NvCloth/samples/SampleBase/scene/scenes/TetherScene.h
new file mode 100644
index 0000000..728286b
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/scenes/TetherScene.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 TetherScene : public Scene
+{
+public:
+
+ TetherScene(SceneController* sceneController): Scene(sceneController) {}
+
+ void initializeCloth(int index, physx::PxVec3 offset, float tetherStiffness);
+ 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/WindScene.cpp b/NvCloth/samples/SampleBase/scene/scenes/WindScene.cpp
new file mode 100644
index 0000000..51cec1d
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/scenes/WindScene.cpp
@@ -0,0 +1,124 @@
+/*
+* 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 "WindScene.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(WindScene, "Wind Scene")
+
+void WindScene::Animate(double dt)
+{
+ mTime += dt;
+
+ if(mTime > 3.7f)
+ {
+ float dvx = 3.f * cos(25.f * mTime);
+ float vy = max(0.f, 0.9f * cos(11.f * mTime));
+ float dvz = 1.5f * sin(19.f * mTime);
+ for(int i = 0; i < 3; i++)
+ {
+ physx::PxVec3 wind = physx::PxVec3(2.5f + dvx, vy, 15.f + dvz);
+ mClothActor[i]->mCloth->setWindVelocity(wind);
+ }
+ }
+
+ doSimulationStep(dt);
+}
+
+void WindScene::initializeCloth(int index, physx::PxVec3 offset)
+{
+ ///////////////////////////////////////////////////////////////////////
+ ClothMeshData clothMesh;
+
+ physx::PxMat44 transform = PxTransform(PxVec3(0.f, 13.f, 0.f)+ offset, PxQuat(PxPi / 6.f, PxVec3(1.f, 0.f, 0.f)));
+ clothMesh.GeneratePlaneCloth(5.f, 6.f, 49, 59, false, transform);
+ clothMesh.AttachClothPlaneByAngles(49, 59);
+ clothMesh.SetInvMasses(0.2f + (float)index * 1.4f);
+
+ 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)*0.9f + 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));
+
+ // 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);
+
+ mSolver = getSceneController()->getFactory()->createSolver();
+ trackSolver(mSolver);
+ trackClothActor(mClothActor[index]);
+
+ // Add the cloth to the solver for simulation
+ addClothToSolver(mClothActor[index], mSolver);
+}
+
+void WindScene::onInitialize()
+{
+
+ initializeCloth(2,physx::PxVec3(-9.0f,0.0f,0.0f));
+ initializeCloth(1, physx::PxVec3(-2.0f, 0.0f, 0.0f));
+ initializeCloth(0, physx::PxVec3(5.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/WindScene.h b/NvCloth/samples/SampleBase/scene/scenes/WindScene.h
new file mode 100644
index 0000000..d637bed
--- /dev/null
+++ b/NvCloth/samples/SampleBase/scene/scenes/WindScene.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 WIND_SCENE_H
+#define WIND_SCENE_H
+
+#include "scene/Scene.h"
+#include <foundation/PxVec3.h>
+
+class WindScene : public Scene
+{
+public:
+
+ WindScene(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[3];
+ nv::cloth::Solver* mSolver;
+ ClothActor* mClothActor[3];
+
+ float mTime;
+
+};
+
+
+#endif \ No newline at end of file