aboutsummaryrefslogtreecommitdiff
path: root/NvCloth/samples/SampleBase/scene
diff options
context:
space:
mode:
authorMarijn Tamis <[email protected]>2018-05-03 18:22:48 +0200
committerMarijn Tamis <[email protected]>2018-05-03 18:22:48 +0200
commitca32c59a58d37c1822e185a2d5f3d0d3e8943593 (patch)
treeb06b9eec03f34344ef8fc31aa147b2714d3962ee /NvCloth/samples/SampleBase/scene
parentForced rename of platform folders in cmake dir. Git didn't pick this up before. (diff)
downloadnvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.tar.xz
nvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.zip
NvCloth 1.1.4 Release. (24070740)
Diffstat (limited to 'NvCloth/samples/SampleBase/scene')
-rw-r--r--NvCloth/samples/SampleBase/scene/Scene.cpp133
-rw-r--r--NvCloth/samples/SampleBase/scene/Scene.h10
-rw-r--r--NvCloth/samples/SampleBase/scene/SceneController.cpp19
-rw-r--r--NvCloth/samples/SampleBase/scene/SceneController.h9
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/CCDScene2.cpp155
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/CCDScene2.h37
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/InterCollisionScene.cpp2
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/InterCollisionScene.h4
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/SelfCollisionScene.cpp21
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/TeleportScene.cpp148
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/TeleportScene.h41
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/TimeStepScene.cpp114
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/TimeStepScene.h36
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/VirtualParticleScene.cpp171
-rw-r--r--NvCloth/samples/SampleBase/scene/scenes/VirtualParticleScene.h37
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