aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Samples/SampleCharacterCloth
diff options
context:
space:
mode:
Diffstat (limited to 'PhysX_3.4/Samples/SampleCharacterCloth')
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth.h189
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothCameraController.cpp259
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothCameraController.h78
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothFlag.cpp201
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothFlag.h63
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothInputEventIds.h45
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothJump.cpp83
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothJump.h58
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothPlatform.h80
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothSettings.h39
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_CCT.cpp201
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_ClothController.cpp452
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_FilterShader.cpp52
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_Main.cpp441
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_Platform.cpp120
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_PlatformBuilder.cpp201
-rw-r--r--PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_TerrainBuilder.cpp268
17 files changed, 2830 insertions, 0 deletions
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth.h b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth.h
new file mode 100644
index 00000000..95e33d41
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth.h
@@ -0,0 +1,189 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SAMPLE_CHARACTER_CLOTH_H
+#define SAMPLE_CHARACTER_CLOTH_H
+
+#include "PhysXSample.h"
+#include "PxSimulationEventCallback.h"
+#include "characterkinematic/PxController.h"
+#include "characterkinematic/PxControllerBehavior.h"
+#include "PxShape.h"
+
+#include "SampleCharacterHelpers.h"
+#include "SampleCharacterClothJump.h"
+#include "SampleCharacterClothPlatform.h"
+
+namespace physx
+{
+ class PxCapsuleController;
+ class PxControllerManager;
+}
+
+ class SampleCharacterClothFlag;
+ class SampleCharacterClothCameraController;
+ class ControlledActor;
+
+ class SampleCharacterCloth : public PhysXSample, public PxUserControllerHitReport, public PxControllerBehaviorCallback
+ {
+ public:
+ SampleCharacterCloth(PhysXSampleApplication& app);
+ virtual ~SampleCharacterCloth();
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Implements SampleApplication
+ virtual void onInit();
+ virtual void onInit(bool restart) { onInit(); }
+ virtual void onShutdown();
+ virtual void onSubstep(float dtime);
+ virtual void onTickPreRender(float dtime);
+ virtual void onTickPostRender(float dtime);
+ virtual void onPointerInputEvent(const SampleFramework::InputEvent& ie, physx::PxU32 x, physx::PxU32 y, physx::PxReal dx, physx::PxReal dy, bool val);
+ virtual void onDigitalInputEvent(const SampleFramework::InputEvent& , bool val);
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Implements PhysXSampleApplication
+ virtual void helpRender(PxU32 x, PxU32 y, PxU8 textAlpha);
+ virtual void descriptionRender(PxU32 x, PxU32 y, PxU8 textAlpha);
+ virtual void customizeRender();
+ virtual void customizeSample(SampleSetup&);
+ virtual void customizeSceneDesc(PxSceneDesc&);
+ virtual void collectInputEvents(std::vector<const SampleFramework::InputEvent*>& inputEvents);
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Implements PxUserControllerHitReport
+ virtual void onShapeHit(const PxControllerShapeHit& hit);
+ virtual void onControllerHit(const PxControllersHit& hit);
+ virtual void onObstacleHit(const PxControllerObstacleHit& hit);
+
+ // Implements PxControllerBehaviorCallback
+ virtual PxControllerBehaviorFlags getBehaviorFlags(const PxShape&, const PxActor&);
+ virtual PxControllerBehaviorFlags getBehaviorFlags(const PxController&);
+ virtual PxControllerBehaviorFlags getBehaviorFlags(const PxObstacle&);
+
+ ///////////////////////////////////////////////////////////////////////////////
+ protected:
+ // non-dynamic environment
+ PxRigidStatic* buildHeightField();
+ void createLandscape(PxReal* heightmap, PxU32 size, PxReal scale, PxReal* outVerts, PxReal* outNorms, PxU32* outTris);
+ PxRigidStatic* createHeightField(PxReal* heightmap, PxReal scale, PxU32 size);
+ SampleCharacterClothPlatform* createPlatform(const PxTransform &pose, const PxGeometry &geom, PxReal travelTime, const PxVec3 &offset, RenderMaterial *renderMaterial);
+ void createPlatforms();
+ void updatePlatforms(float dtime);
+
+ // cct control
+ void bufferCCTMotion(const PxVec3& disp, PxReal dtime);
+ void createCCTController();
+ void updateCCT(float dtime);
+
+ // cloth and character
+ void createCharacter();
+ void createCape();
+ void createFlags();
+ void releaseFlags();
+
+ void resetCape();
+ void resetCharacter();
+ void resetScene();
+
+ void updateCape(float dtime);
+ void updateCharacter(float dtime);
+ void updateFlags(float dtime);
+
+ void createRenderMaterials();
+#if PX_SUPPORT_GPU_PHYSX || PX_XBOXONE
+ void toggleGPU();
+#endif
+
+ private:
+ ///////////////////////////////////////////////////////////////////////////////
+ // Landscape
+ PxTransform mHFPose;
+ PxU32 mNbVerts;
+ PxU32 mNbTris;
+ PxReal* mVerts;
+ PxU32* mTris;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // Camera and Controller
+ SampleCharacterClothCameraController* mCCTCamera;
+ PxCapsuleController* mController;
+ PxControllerManager* mControllerManager;
+ PxVec3 mControllerInitialPosition;
+ bool mCCTActive;
+ PxVec3 mCCTDisplacement;
+ PxVec3 mCCTDisplacementPrevStep;
+ PxReal mCCTTimeStep;
+ SampleCharacterClothJump mJump;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // rendering
+ RenderMaterial* mSnowMaterial;
+ RenderMaterial* mPlatformMaterial;
+ RenderMaterial* mRockMaterial;
+ RenderMaterial* mWoodMaterial;
+ RenderMaterial* mFlagMaterial;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // cloth
+ PxCloth* mCape;
+ SampleArray<SampleCharacterClothFlag*> mFlags;
+#if PX_SUPPORT_GPU_PHYSX || PX_XBOXONE
+ bool mUseGPU;
+#endif
+ PxU32 mClothFlagCountIndex;
+ PxU32 mClothFlagCountIndexMax;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // character motion
+ Character mCharacter;
+ Skin mSkin;
+ int mMotionHandleWalk;
+ int mMotionHandleRun;
+ int mMotionHandleJump;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // simulation stats
+ shdfnd::Time mTimer;
+ PxReal mAccumulatedSimulationTime;
+ PxReal mAverageSimulationTime;
+ PxU32 mFrameCount;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // platform levels
+ SampleArray<SampleCharacterClothPlatform*> mPlatforms;
+
+ friend class SampleCharacterClothCameraController;
+ friend class SampleCharacterClothFlag;
+ };
+
+#endif
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothCameraController.cpp b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothCameraController.cpp
new file mode 100644
index 00000000..a30d150f
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothCameraController.cpp
@@ -0,0 +1,259 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "PxPhysXConfig.h"
+
+#if PX_USE_CLOTH_API
+
+#include "PhysXSample.h"
+
+#include "SampleCharacterClothCameraController.h"
+
+#include "SampleCharacterCloth.h"
+#include "SampleCharacterClothInputEventIds.h"
+#include "SampleUtils.h"
+
+#include "PxRigidDynamic.h"
+#include "foundation/PxMath.h"
+#include <SampleBaseInputEventIds.h>
+#include <SamplePlatform.h>
+#include <SampleUserInput.h>
+#include <SampleUserInputIds.h>
+#include <SampleUserInputDefines.h>
+
+using namespace physx;
+using namespace SampleRenderer;
+using namespace SampleFramework;
+
+///////////////////////////////////////////////////////////////////////////////
+SampleCharacterClothCameraController::SampleCharacterClothCameraController(PxController& controlled, SampleCharacterCloth& base) :
+ mCamera (NULL),
+ mController (controlled),
+ mSample (base),
+ mTargetYaw (0.0f-PxPi/2),
+ mTargetPitch (0.0f),
+ mPitchMin (-PxHalfPi),
+ mPitchMax (PxHalfPi),
+ mGamepadPitchInc (0.0f),
+ mGamepadYawInc (0.0f),
+ mGamepadForwardInc (0.0f),
+ mGamepadLateralInc (0.0f),
+ mSensibility (0.01f),
+ mFwd (false),
+ mBwd (false),
+ mLeft (false),
+ mRight (false),
+ mKeyShiftDown (false),
+ mRunningSpeed (8.0f),
+ mWalkingSpeed (4.0f)
+{
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+void SampleCharacterClothCameraController::collectInputEvents(std::vector<const SampleFramework::InputEvent*>& inputEvents)
+{
+ //digital keyboard events
+ DIGITAL_INPUT_EVENT_DEF(CAMERA_MOVE_FORWARD, SCAN_CODE_FORWARD, XKEY_W, X1KEY_W, PS3KEY_W, PS4KEY_W, AKEY_UNKNOWN, SCAN_CODE_FORWARD, IKEY_UNKNOWN, SCAN_CODE_FORWARD, WIIUKEY_UNKNOWN);
+ DIGITAL_INPUT_EVENT_DEF(CAMERA_MOVE_BACKWARD, SCAN_CODE_BACKWARD, XKEY_S, X1KEY_S, PS3KEY_S, PS4KEY_S, AKEY_UNKNOWN, SCAN_CODE_BACKWARD, IKEY_UNKNOWN, SCAN_CODE_BACKWARD, WIIUKEY_UNKNOWN);
+ DIGITAL_INPUT_EVENT_DEF(CAMERA_MOVE_LEFT, SCAN_CODE_LEFT, XKEY_A, X1KEY_A, PS3KEY_A, PS4KEY_A, AKEY_UNKNOWN, SCAN_CODE_LEFT, IKEY_UNKNOWN, SCAN_CODE_LEFT, WIIUKEY_UNKNOWN);
+ DIGITAL_INPUT_EVENT_DEF(CAMERA_MOVE_RIGHT, SCAN_CODE_RIGHT, XKEY_D, X1KEY_D, PS3KEY_D, PS4KEY_D, AKEY_UNKNOWN, SCAN_CODE_RIGHT, IKEY_UNKNOWN, SCAN_CODE_RIGHT, WIIUKEY_UNKNOWN);
+ DIGITAL_INPUT_EVENT_DEF(CAMERA_SHIFT_SPEED, SCAN_CODE_LEFT_SHIFT, XKEY_SHIFT, X1KEY_SHIFT, PS3KEY_SHIFT, PS4KEY_SHIFT, AKEY_UNKNOWN, OSXKEY_SHIFT, IKEY_UNKNOWN, LINUXKEY_SHIFT, WIIUKEY_UNKNOWN);
+ DIGITAL_INPUT_EVENT_DEF(CAMERA_JUMP, SCAN_CODE_SPACE, XKEY_SPACE, X1KEY_SPACE, PS3KEY_SPACE, PS4KEY_SPACE, AKEY_UNKNOWN, OSXKEY_SPACE, IKEY_UNKNOWN, LINUXKEY_SPACE, WIIUKEY_UNKNOWN);
+
+ //digital gamepad events
+ DIGITAL_INPUT_EVENT_DEF(CAMERA_JUMP, GAMEPAD_SOUTH, GAMEPAD_SOUTH, GAMEPAD_SOUTH, GAMEPAD_SOUTH, GAMEPAD_SOUTH, AKEY_UNKNOWN, GAMEPAD_SOUTH, IKEY_UNKNOWN, LINUXKEY_UNKNOWN, GAMEPAD_SOUTH);
+
+ //analog gamepad events
+ ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_ROTATE_LEFT_RIGHT,GAMEPAD_ROTATE_SENSITIVITY, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, LINUXKEY_UNKNOWN, GAMEPAD_RIGHT_STICK_X);
+ ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_ROTATE_UP_DOWN,GAMEPAD_ROTATE_SENSITIVITY, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, LINUXKEY_UNKNOWN, GAMEPAD_RIGHT_STICK_Y);
+ ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_MOVE_LEFT_RIGHT,GAMEPAD_DEFAULT_SENSITIVITY, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, LINUXKEY_UNKNOWN, GAMEPAD_LEFT_STICK_X);
+ ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_MOVE_FORWARD_BACK,GAMEPAD_DEFAULT_SENSITIVITY, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, LINUXKEY_UNKNOWN, GAMEPAD_LEFT_STICK_Y);
+
+ //touch events
+ TOUCH_INPUT_EVENT_DEF(CAMERA_JUMP, "Jump", AQUICK_BUTTON_1, IQUICK_BUTTON_1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterClothCameraController::onDigitalInputEvent(const SampleFramework::InputEvent& ie, bool val)
+{
+ switch (ie.m_Id)
+ {
+ case CAMERA_MOVE_FORWARD:
+ {
+ mFwd = val;
+ }
+ break;
+ case CAMERA_MOVE_BACKWARD:
+ {
+ mBwd = val;
+ }
+ break;
+ case CAMERA_MOVE_LEFT:
+ {
+ mLeft = val;
+ }
+ break;
+ case CAMERA_MOVE_RIGHT:
+ {
+ mRight = val;
+ }
+ break;
+ case CAMERA_SHIFT_SPEED:
+ {
+ mKeyShiftDown = val;
+ }
+ break;
+ case CAMERA_JUMP:
+ {
+ if(val)
+ mSample.mJump.startJump(13.0f);
+ }
+ break;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+static PX_FORCE_INLINE PxReal remapAxisValue(PxReal absolutePosition)
+{
+ return absolutePosition * absolutePosition * absolutePosition * 5.0f;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterClothCameraController::onAnalogInputEvent(const SampleFramework::InputEvent& ie, float val)
+{
+ if(ie.m_Id == CAMERA_GAMEPAD_ROTATE_LEFT_RIGHT)
+ {
+ mGamepadYawInc = - remapAxisValue(val);
+ }
+ else if(ie.m_Id == CAMERA_GAMEPAD_ROTATE_UP_DOWN)
+ {
+ mGamepadPitchInc = - remapAxisValue(val);
+ }
+ else if(ie.m_Id == CAMERA_GAMEPAD_MOVE_LEFT_RIGHT)
+ {
+ mGamepadLateralInc = -val;
+ }
+ else if(ie.m_Id == CAMERA_GAMEPAD_MOVE_FORWARD_BACK)
+ {
+ mGamepadForwardInc = val;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterClothCameraController::onPointerInputEvent(const SampleFramework::InputEvent &ie, physx::PxU32, physx::PxU32, physx::PxReal dx, physx::PxReal dy, bool val)
+{
+ if (ie.m_Id == CAMERA_MOUSE_LOOK)
+ {
+ mTargetYaw -= dx * mSensibility;
+ mTargetPitch += dy * mSensibility;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterClothCameraController::setView(PxReal pitch, PxReal yaw)
+{
+ mTargetPitch = pitch;
+ mTargetYaw = yaw;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This function gets called whenever camera needs to be updated
+void SampleCharacterClothCameraController::update(Camera& camera, PxReal dtime)
+{
+ mCamera = &camera;
+ updateFromCCT(dtime);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterClothCameraController::updateFromCCT(PxReal dtime)
+{
+ if(!mSample.isPaused())
+ {
+ PxVec3 disp(0);
+
+ if (mFwd || mBwd || mRight || mLeft || (fabsf(mGamepadForwardInc) > 0.1f) || (fabsf(mGamepadLateralInc) > 0.1f))
+ {
+ PxVec3 targetKeyDisplacement(0);
+ PxVec3 targetPadDisplacement(0);
+
+ // compute basis
+ PxVec3 forward = mCamera->getViewDir();
+ forward.y = 0;
+ forward.normalize();
+ PxVec3 up = PxVec3(0,1,0);
+ PxVec3 right = forward.cross(up);
+ Ps::computeBasis(forward, right, up);
+
+ // increase target displacement due to key press
+ if (mFwd) targetKeyDisplacement += forward;
+ if (mBwd) targetKeyDisplacement -= forward;
+ if (mLeft) targetKeyDisplacement += right;
+ if (mRight) targetKeyDisplacement -= right;
+
+ targetKeyDisplacement *= mKeyShiftDown ? mRunningSpeed : mWalkingSpeed;
+ targetKeyDisplacement *= dtime;
+
+ // displacement due to game pad control
+ targetPadDisplacement += forward * mGamepadForwardInc * mRunningSpeed;
+ targetPadDisplacement += right * mGamepadLateralInc * mRunningSpeed;
+ targetPadDisplacement *= dtime;
+
+ // compute total displacement due to user input
+ disp = targetKeyDisplacement + targetPadDisplacement;
+
+ mSample.mCCTActive = true;
+ }
+ else
+ mSample.mCCTActive = false;
+
+ mSample.bufferCCTMotion(disp, dtime);
+ }
+ else
+ mSample.bufferCCTMotion(PxVec3(0.0f), dtime);
+
+ // Update camera
+ mTargetYaw += mGamepadYawInc * dtime;
+ mTargetPitch += mGamepadPitchInc * dtime;
+
+ // Clamp pitch
+ if (mTargetPitch < mPitchMin) mTargetPitch = mPitchMin;
+ if (mTargetPitch > mPitchMax) mTargetPitch = mPitchMax;
+
+ mCamera->setRot(PxVec3(-mTargetPitch,-mTargetYaw,0));
+
+ const PxExtendedVec3 camTarget = mController.getPosition();
+ const PxVec3 target = PxVec3((PxReal)camTarget.x,(PxReal)camTarget.y,(PxReal)camTarget.z)
+ - mCamera->getViewDir()*7.0f;
+ mCamera->setPos(target);
+}
+
+#endif // PX_USE_CLOTH_API
+
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothCameraController.h b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothCameraController.h
new file mode 100644
index 00000000..87be0cea
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothCameraController.h
@@ -0,0 +1,78 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SAMPLE_CHARACTER_CAMERA_CONTROLLER_H
+#define SAMPLE_CHARACTER_CAMERA_CONTROLLER_H
+
+#include "SampleCameraController.h"
+
+#include "characterkinematic/PxController.h"
+
+class SampleCharacterCloth;
+
+class SampleCharacterClothCameraController : public CameraController
+{
+public:
+ SampleCharacterClothCameraController(PxController& controlled, SampleCharacterCloth& sample);
+
+ // Implements CameraController
+ virtual void onDigitalInputEvent(const SampleFramework::InputEvent& , bool val);
+ virtual void onAnalogInputEvent(const SampleFramework::InputEvent& , float val);
+ virtual void onPointerInputEvent(const SampleFramework::InputEvent&, physx::PxU32, physx::PxU32, physx::PxReal, physx::PxReal, bool);
+ virtual void collectInputEvents(std::vector<const SampleFramework::InputEvent*>& inputEvents);
+
+ virtual void update(Camera& camera, PxReal dtime);
+
+ void updateFromCCT(PxReal dtime);
+ void setView(PxReal pitch, PxReal yaw);
+
+protected:
+
+ Camera* mCamera;
+ PxController& mController;
+ SampleCharacterCloth& mSample;
+
+ PxReal mTargetYaw, mTargetPitch;
+ PxReal mPitchMin, mPitchMax;
+
+ PxReal mGamepadPitchInc, mGamepadYawInc;
+ PxReal mGamepadForwardInc, mGamepadLateralInc;
+ PxReal mSensibility;
+
+ bool mFwd,mBwd,mLeft,mRight,mKeyShiftDown;
+
+ PxReal mRunningSpeed;
+ PxReal mWalkingSpeed;
+
+private:
+ SampleCharacterClothCameraController& operator=(const SampleCharacterClothCameraController&);
+
+};
+
+#endif
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothFlag.cpp b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothFlag.cpp
new file mode 100644
index 00000000..2499201f
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothFlag.cpp
@@ -0,0 +1,201 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "PxPhysXConfig.h"
+#if PX_USE_CLOTH_API
+
+#include "SampleCharacterClothFlag.h"
+#include "SampleCharacterCloth.h"
+
+#include "TestClothHelpers.h"
+#include "cloth/PxClothParticleData.h"
+
+using namespace PxToolkit;
+
+////////////////////////////////////////////////////////////////////////////////
+SampleCharacterClothFlag::SampleCharacterClothFlag(SampleCharacterCloth& sample, const PxTransform &pose, PxU32 resX, PxU32 resY, PxReal sizeX, PxReal sizeY, PxReal height)
+ :
+ mRenderActor(NULL),
+ mSample(sample),
+ mWindDir(1.0f, 0.0f, 0.0f),
+ mWindRange(1.0f),
+ mWindStrength(1.0f),
+ mTime(0.0f),
+ mCapsuleActor(NULL)
+{
+ PxScene& scene = mSample.getActiveScene();
+ PxPhysics& physics = mSample.getPhysics();
+
+ // adjust placement position for the flag with ray casting so that we can put each flag properly on the terrain
+ PxVec3 pos = pose.p;
+ PxRaycastBuffer hit;
+ scene.raycast(PxVec3(pos.x,100,pos.z), PxVec3(0,-1,0), 500.0f, hit, PxHitFlags(0xffff));
+ bool didHit = hit.hasBlock;
+ PX_ASSERT(didHit); PX_UNUSED(didHit);
+ pos = hit.block.position + PxVec3(0,0.2f,0.0);
+
+ // settings to adjust flag and pole position on the ground
+ PxTransform clothPose(pos, pose.q);
+
+ PxReal halfSizeX = sizeX * 0.5f;
+ PxReal halfSizeY = sizeY * 0.5f;
+ PxReal offset = sizeX * 0.1f;
+ PxReal halfHeight = height * 0.5f;
+
+ PxReal clothHeight = height - halfSizeY;
+ clothPose.p.y += clothHeight;
+
+ // create the cloth flag mesh
+ SampleArray<PxVec4> vertices;
+ SampleArray<PxU32> primitives;
+ PxClothMeshDesc meshDesc = Test::ClothHelpers::createMeshGrid(
+ PxVec3(sizeX,0,0), PxVec3(0,-sizeY,0), resX, resY, vertices, primitives, mUVs);
+
+ // attach two corners on the left
+ for (PxU32 i = 0; i < meshDesc.points.count; i++)
+ {
+ PxReal u = mUVs[i].x, v = mUVs[i].y;
+ bool constrain = ( (u < 0.01) && (v < 0.01) ) || (( u < 0.01) && (v > 0.99));
+ vertices[i].w = constrain ? 0.0f : 1.0f;
+ }
+
+ // create cloth fabric
+ PxClothFabric* clothFabric = PxClothFabricCreate(physics, meshDesc, PxVec3(0,-1,0));
+ PX_ASSERT(meshDesc.points.stride == sizeof(PxVec4));
+
+ // create the cloth actor
+ const PxClothParticle* particles = (const PxClothParticle*)meshDesc.points.data;
+ PxCloth* cloth = physics.createCloth( clothPose, *clothFabric, particles, PxClothFlags());
+ PX_ASSERT(cloth);
+
+ // add this cloth into the scene
+ scene.addActor(*cloth);
+
+ // create collision capsule for the pole
+ SampleArray<PxClothCollisionSphere> spheres(2);
+ spheres[0].pos = PxVec3(-halfSizeX - offset, -clothHeight, 0);
+ spheres[1].pos = PxVec3(-halfSizeX - offset, halfSizeY, 0);
+ spheres[0].radius = 0.1f;
+ spheres[1].radius = 0.1f;
+
+ SampleArray<PxU32> indexPairs;
+ indexPairs.pushBack(0);
+ indexPairs.pushBack(1);
+ cloth->setCollisionSpheres(spheres.begin(), 2);
+ cloth->addCollisionCapsule(indexPairs[0], indexPairs[1]);
+
+ // create render material
+ RenderMaterial* clothMaterial = mSample.mFlagMaterial;
+ mRenderActor = SAMPLE_NEW (RenderClothActor)(*mSample.getRenderer(), *cloth, meshDesc,
+ mUVs.begin(), 0.5f);
+ mRenderActor->setRenderMaterial(clothMaterial);
+ mSample.mRenderClothActors.push_back(mRenderActor);
+ mSample.mRenderActors.push_back(mRenderActor);
+
+ // set solver settings
+ cloth->setSolverFrequency(120);
+ cloth->setDampingCoefficient(PxVec3(0.0f));
+
+ cloth->setStretchConfig(PxClothFabricPhaseType::eBENDING, PxClothStretchConfig(0.1f));
+ cloth->setTetherConfig(PxClothTetherConfig(1.0f, 1.0f));
+
+ mCloth = cloth;
+
+ // we create an invisible kinematic capsule so that the CCT avoids colliding character against the pole of this flag
+ // note that cloth collision capsule above has no effect on rigid body scenes.
+ PxTransform capsulePose(pos, PxQuat(PxHalfPi, PxVec3(0,0,1)));
+ capsulePose.p.x -= halfSizeX + offset;
+ capsulePose.p.y += halfHeight;
+ PxCapsuleGeometry geom(0.2f,halfHeight);
+
+ mCapsuleActor = sample.getPhysics().createRigidDynamic(capsulePose);
+ mCapsuleActor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
+ PxRigidActorExt::createExclusiveShape(*mCapsuleActor, geom, sample.getDefaultMaterial());
+ scene.addActor(*mCapsuleActor);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterClothFlag::release()
+{
+ mSample.removeRenderClothActor(*mRenderActor);
+ delete mRenderActor;
+
+ mCloth->release();
+ mCapsuleActor->release();
+
+ delete this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterClothFlag::setWind(const PxVec3 &dir, PxReal strength, const PxVec3& range)
+{
+ mWindStrength = strength;
+ mWindDir = dir;
+ mWindRange = range;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterClothFlag::update(PxReal dtime)
+{
+ PX_ASSERT(mCloth);
+
+ // implementation of a simple wind force that varies its direction, strength over time
+ mTime += dtime * PxToolkit::Rand(0.0f, 1.0f);
+
+ float st = 1.0f + (float)sin(mTime);
+ float windStrength = PxToolkit::Rand(1.0f, st) * mWindStrength;
+ float windRangeStrength = PxToolkit::Rand(0.0f, 2.0f);
+
+ PxVec3 offset( PxReal(PxToolkit::Rand(-1,1)), PxReal(PxToolkit::Rand(-1,1)), PxReal(PxToolkit::Rand(-1,1)));
+ float ct = 1.0f + (float)cos(mTime + 0.1);
+ offset *= ct;
+ PxVec3 windAcceleration = windStrength * mWindDir + windRangeStrength * mWindRange.multiply(offset);
+
+ mCloth->setExternalAcceleration(windAcceleration);
+
+#if 0
+ PxU32 nbParticles = mCloth->getNbParticles();
+ SampleArray<PxVec4> accel(nbParticles);
+
+ for (PxU32 i = 0; i < nbParticles; i++)
+ {
+ accel[i].x = PxToolkit::Rand(-1,1) * mWindRange.x;
+ accel[i].y = PxToolkit::Rand(-1,1) * mWindRange.y;
+ accel[i].z = PxToolkit::Rand(-1,1) * mWindRange.z;
+ }
+ mCloth->setParticleAccelerations(accel.begin());
+#endif
+}
+
+#endif // PX_USE_CLOTH_API
+
+
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothFlag.h b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothFlag.h
new file mode 100644
index 00000000..5e91c325
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothFlag.h
@@ -0,0 +1,63 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SAMPLE_CHARACTER_CLOTH_FLAG_H
+#define SAMPLE_CHARACTER_CLOTH_FLAG_H
+
+#include "cloth/PxCloth.h"
+#include "PhysXSample.h"
+
+class SampleCharacterCloth;
+class RenderClothActor;
+
+class SampleCharacterClothFlag
+{
+public:
+ SampleCharacterClothFlag(SampleCharacterCloth& sample, const PxTransform &pose, PxU32 resX, PxU32 resY, PxReal sizeX, PxReal sizeY, PxReal height);
+
+ void setWind(const PxVec3 &dir, PxReal strength, const PxVec3& range);
+ void update(PxReal dtime);
+ void release();
+ PxCloth* getCloth() { return mCloth; }
+
+protected:
+ RenderClothActor* mRenderActor;
+ SampleCharacterCloth& mSample;
+ PxCloth* mCloth;
+ SampleArray<PxVec2> mUVs;
+ PxVec3 mWindDir;
+ PxVec3 mWindRange;
+ PxReal mWindStrength;
+ PxReal mTime;
+ PxRigidDynamic* mCapsuleActor;
+private:
+ SampleCharacterClothFlag& operator=(const SampleCharacterClothFlag&);
+};
+
+#endif
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothInputEventIds.h b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothInputEventIds.h
new file mode 100644
index 00000000..90f31f10
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothInputEventIds.h
@@ -0,0 +1,45 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+#ifndef _SAMPLE_CCT_INPUT_EVENT_IDS_H
+#define _SAMPLE_CCT_INPUT_EVENT_IDS_H
+
+#include <SampleBaseInputEventIds.h>
+
+// InputEvents used by SampleCharacterController
+enum SampleCharacterControllerInputEventIds
+{
+ SAMPLE_CCT_FIRST = NUM_SAMPLE_BASE_INPUT_EVENT_IDS,
+
+ CROUCH ,
+ RESET_SCENE,
+ JUMP,
+ CHANGE_CLOTH_CONTENT,
+
+ NUM_SAMPLE_CCT_INPUT_EVENT_IDS,
+};
+
+#endif
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothJump.cpp b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothJump.cpp
new file mode 100644
index 00000000..8e96f1e9
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothJump.cpp
@@ -0,0 +1,83 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "SampleCharacterClothJump.h"
+
+using namespace physx;
+
+static PxF32 gJumpGravity = -25.0f;
+
+SampleCharacterClothJump::SampleCharacterClothJump() :
+ mV (0.0f),
+ mTime (0.0f),
+ mJump (false),
+ mFreefall (false)
+{
+}
+
+void SampleCharacterClothJump::startJump(PxF32 v0)
+{
+ if (mJump) return;
+ if (mFreefall) return;
+ mV = v0;
+ mJump = true;
+}
+
+void SampleCharacterClothJump::reset()
+{
+ // reset jump state at most every half a second
+ // otherwise we might miss jump events
+ if (mTime < 0.5f)
+ return;
+
+ mFreefall = false;
+ mJump = false;
+ mV = 0.0f;
+ mTime = 0.0f;
+}
+
+void SampleCharacterClothJump::tick(PxF32 dtime)
+{
+ mTime += dtime;
+ mV += gJumpGravity * dtime;
+ const PxReal vlimit = -25.0f;
+ if (mV < vlimit)
+ {
+ // limit velocity in freefall so that character does not fall at rocket speed.
+ mV = vlimit;
+ mFreefall = true;
+ mJump = false;
+ }
+}
+
+PxF32 SampleCharacterClothJump::getDisplacement(PxF32 dtime)
+{
+ return mV * dtime;
+}
+
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothJump.h b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothJump.h
new file mode 100644
index 00000000..83e7d87e
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothJump.h
@@ -0,0 +1,58 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SAMPLE_CCT_JUMP_H
+#define SAMPLE_CCT_JUMP_H
+
+#include "common/PxPhysXCommonConfig.h"
+#include "SampleAllocator.h"
+
+using namespace physx;
+
+class SampleCharacterClothJump : public SampleAllocateable
+{
+ public:
+ SampleCharacterClothJump();
+
+ bool isJumping() const { return mJump; }
+ bool isInFreefall() const { return mFreefall; }
+ PxF32 getDisplacement(PxF32 dtime);
+ void reset();
+ void startJump(PxF32 v0);
+ void tick(PxF32 elapsedTime);
+
+protected:
+ PxF32 mV;
+ PxF32 mTime;
+ bool mJump;
+ bool mFreefall;
+
+};
+
+#endif
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothPlatform.h b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothPlatform.h
new file mode 100644
index 00000000..a9af7280
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothPlatform.h
@@ -0,0 +1,80 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SAMPLE_CHARACTER_CLOTH_PLATFORM_H
+#define SAMPLE_CHARACTER_CLOTH_PLATFORM_H
+
+#include "PhysXSample.h"
+#include "characterkinematic/PxController.h"
+#include "SampleAllocator.h"
+#include "SampleAllocatorSDKClasses.h"
+
+///////////////////////////////////////////////////////////////////////////////
+class SampleCharacterClothPlatform : public SampleAllocateable
+{
+public:
+
+ ///////////////////////////////////////////////////////////////////////////////
+ enum {
+ ePLATFORM_TYPE_STATIC,
+ ePLATFORM_TYPE_MOVING,
+ ePLATFORM_TYPE_TRIGGERED,
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////
+ SampleCharacterClothPlatform();
+ ~SampleCharacterClothPlatform() {}
+
+ ///////////////////////////////////////////////////////////////////////////////
+ PX_FORCE_INLINE PxRigidDynamic* getPhysicsActor() { return mActor;}
+ PX_FORCE_INLINE PxReal getTravelTime() const { return mTravelTime; }
+ PX_FORCE_INLINE PxU32 getType() const { return mType; }
+
+ PX_FORCE_INLINE void setActive(bool b) { mActive = b; }
+ PX_FORCE_INLINE void setTravelTime(PxReal t) { mTravelTime = t; }
+ PX_FORCE_INLINE void setType(PxU32 t) { mType = t; }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ void init(PxRigidDynamic* actor, PxReal travelTime, const PxVec3& offsetTarget = PxVec3(0,0,0) );
+ void release();
+ void reset();
+ void update(PxReal dtime);
+
+protected:
+ PxRigidDynamic* mActor;
+ PxReal mCurrentTime;
+ PxReal mTravelTime;
+ PxVec3 mStart;
+ PxVec3 mTarget;
+ bool mFlip;
+ PxU32 mType;
+ bool mActive;
+};
+
+#endif
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothSettings.h b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothSettings.h
new file mode 100644
index 00000000..b38cd963
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterClothSettings.h
@@ -0,0 +1,39 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SAMPLE_CHARACTER_CLOTH_SETTINGS_H
+#define SAMPLE_CHARACTER_CLOTH_SETTINGS_H
+
+ #define CONTACT_OFFSET 0.01f
+ #define STEP_OFFSET 0.1f
+ #define SLOPE_LIMIT 0.8f
+ #define INVISIBLE_WALLS_HEIGHT 6.0f
+ #define MAX_JUMP_HEIGHT 4.0f
+
+#endif
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_CCT.cpp b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_CCT.cpp
new file mode 100644
index 00000000..fef32565
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_CCT.cpp
@@ -0,0 +1,201 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "PxPhysXConfig.h"
+
+#if PX_USE_CLOTH_API
+
+#include "SampleCharacterCloth.h"
+
+#include "SampleCharacterClothCameraController.h"
+#include "SampleAllocatorSDKClasses.h"
+
+#include "PxPhysicsAPI.h"
+#include "extensions/PxExtensionsAPI.h"
+
+#include "characterkinematic/PxControllerManager.h"
+#include "characterkinematic/PxBoxController.h"
+#include "characterkinematic/PxCapsuleController.h"
+
+
+#include "geometry/PxMeshQuery.h"
+#include "geometry/PxTriangle.h"
+
+#include "RenderBaseActor.h"
+#include "RenderBoxActor.h"
+#include "RenderCapsuleActor.h"
+#include <SampleUserInputIds.h>
+#include <SamplePlatform.h>
+#include <SampleUserInput.h>
+#include <SampleUserInputDefines.h>
+
+using namespace SampleRenderer;
+using namespace SampleFramework;
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::bufferCCTMotion(const PxVec3& targetDisp, PxReal dtime)
+{
+ PxVec3 disp = targetDisp;
+
+ if(!isPaused())
+ {
+ // advance jump controller
+ mJump.tick(dtime);
+
+ // modify y component of displacement due to jump status
+ disp.y = mJump.getDisplacement(dtime);
+
+ if (mJump.isInFreefall())
+ {
+ disp.x = 0;
+ disp.z = 0;
+ mCCTActive = false;
+ }
+ }
+
+ // buffer the displacement and timestep to feed in onSubstep function
+ mCCTDisplacement = disp;
+ mCCTTimeStep = dtime;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::createCCTController()
+{
+ mControllerManager = PxCreateControllerManager(getActiveScene());
+
+ // use ray casting to position the CCT on the terrain
+ PxScene& scene = getActiveScene();
+ PxRaycastBuffer hit;
+ bool didHit = scene.raycast(PxVec3(0,100,0), PxVec3(0,-1,0), 500.0f, hit, PxHitFlags(0xffff));
+ PX_UNUSED(didHit);
+ PX_ASSERT(didHit);
+ mControllerInitialPosition = hit.block.position + PxVec3(0.0f, 1.6f, 0.0f);
+
+ // create and fill in the descriptor for the capsule controller
+ PxCapsuleControllerDesc cDesc;
+
+ cDesc.height = 2.0f;
+ cDesc.radius = 0.5f;
+ cDesc.material = &getDefaultMaterial();
+ cDesc.position = PxExtendedVec3(mControllerInitialPosition.x, mControllerInitialPosition.y, mControllerInitialPosition.z);
+ cDesc.slopeLimit = 0.1f;
+ cDesc.contactOffset = 0.01f;
+ cDesc.stepOffset = 0.1f;
+ cDesc.scaleCoeff = 0.9f;
+ cDesc.climbingMode = PxCapsuleClimbingMode::eEASY;
+ cDesc.invisibleWallHeight = 0.0f;
+ cDesc.maxJumpHeight = 2.0f;
+ cDesc.reportCallback = this;
+
+ mController = static_cast<PxCapsuleController*>(mControllerManager->createController(cDesc));
+
+ // create camera
+ mCCTCamera = SAMPLE_NEW(SampleCharacterClothCameraController)(*mController, *this);
+
+ setCameraController(mCCTCamera);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::onShapeHit(const PxControllerShapeHit& hit)
+{
+ PxRigidDynamic* hitActor = hit.shape->getActor()->is<PxRigidDynamic>();
+
+ const size_t nbPlatforms = mPlatforms.size();
+ for(PxU32 i = 0;i < nbPlatforms;i++)
+ {
+ if (mPlatforms[i]->getType() == SampleCharacterClothPlatform::ePLATFORM_TYPE_TRIGGERED)
+ {
+ PxRigidDynamic* actor = mPlatforms[i]->getPhysicsActor();
+ if (hitActor == actor)
+ mPlatforms[i]->setActive(true);
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::onControllerHit(const PxControllersHit& hit)
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::onObstacleHit(const PxControllerObstacleHit& hit)
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+PxControllerBehaviorFlags SampleCharacterCloth::getBehaviorFlags(const PxShape&, const PxActor&)
+{
+ return PxControllerBehaviorFlags(0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+PxControllerBehaviorFlags SampleCharacterCloth::getBehaviorFlags(const PxController&)
+{
+ return PxControllerBehaviorFlags(0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+PxControllerBehaviorFlags SampleCharacterCloth::getBehaviorFlags(const PxObstacle& obstacle)
+{
+ return PxControllerBehaviorFlag::eCCT_CAN_RIDE_ON_OBJECT;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::updateCCT(float dtime)
+{
+ // compute target cct displacment for this time step
+ PxVec3 dispCurStep = (mCCTTimeStep > 0.0f) ? mCCTDisplacement * (dtime / mCCTTimeStep) : PxVec3(0.0f);
+
+ // limit horizontal acceleration so that character motion does not produce abrupt impulse
+ PxVec3 accel = dispCurStep - mCCTDisplacementPrevStep;
+ const PxReal accelLimit = 0.3f * dtime;
+ PxVec3 accelHorizontal(accel.x, 0, accel.z);
+ PxReal accelHorizontalMagnitude = accelHorizontal.magnitude();
+ if (accelHorizontalMagnitude > accelLimit)
+ {
+ const PxReal accelScale = accelLimit / accelHorizontalMagnitude;
+ accel.x *= accelScale;
+ accel.z *= accelScale;
+ }
+
+ dispCurStep = mCCTDisplacementPrevStep + accel;
+ mCCTDisplacementPrevStep = dispCurStep;
+
+ // move the CCT and change jump status due to contact
+ const PxU32 flags = mController->move(dispCurStep, 0.01f, dtime, PxControllerFilters());
+ if(flags & PxControllerCollisionFlag::eCOLLISION_DOWN)
+ mJump.reset();
+
+ // update camera controller
+ mCCTCamera->updateFromCCT(dtime);
+
+}
+
+#endif // PX_USE_CLOTH_API
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_ClothController.cpp b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_ClothController.cpp
new file mode 100644
index 00000000..df86d5f9
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_ClothController.cpp
@@ -0,0 +1,452 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "PxPhysXConfig.h"
+
+#if PX_USE_CLOTH_API
+
+#include "SampleCharacterCloth.h"
+
+#include "SampleCharacterClothCameraController.h"
+#include "SampleCharacterClothFlag.h"
+
+#include "TestClothHelpers.h"
+#include "SampleCharacterHelpers.h"
+#include "characterkinematic/PxCapsuleController.h"
+#include "cloth/PxClothParticleData.h"
+#include "extensions/PxClothMeshQuadifier.h"
+
+using namespace PxToolkit;
+
+#if PX_SUPPORT_GPU_PHYSX
+PxClothFlag::Enum gGpuFlag = PxClothFlag::eCUDA;
+#elif PX_XBOXONE
+PxClothFlag::Enum gGpuFlag = PxClothFlag::eDEFAULT;
+#endif
+
+// size of spheres for stickman (total 30 bones + 1 root)
+static const PxReal gSphereRadius[] = {
+ 2.0f, // root
+
+ // left lower limb
+ 1.5f, // lhipjoint
+ 1.5f, // lfemur (upper leg)
+ 1.0f, // ltibia (lower leg)
+ 1.0f, // lfoot
+ 1.0f, // ltoes
+
+ // right lower limb
+ 1.5f, // rhipjoint
+ 1.5f, // rfemur
+ 1.0f, // rtibia
+ 1.0f, // rfoot
+ 1.0f, // rtoes
+
+ // spine
+ 2.5f, // lowerback
+ 2.5f, // upperback
+ 2.0f, // thorax
+ 1.0f, // lowerneck
+ 1.0f, // upperneck
+
+ 2.0f, // head
+
+ // left arm/hand
+ 1.5f, // lclavicle (shoulder)
+ 1.5f, // lhumerus (upper arm)
+ 1.3f, // lradius (lower arm)
+ 1.5f, // lwrist
+ 1.8f, // lhand
+ 0.5f, // lfingers
+ 0.5f, // lthumb
+
+ // right arm/hand
+ 1.5f, // rclavicle
+ 1.5f, // rhumerus
+ 1.3f, // rradius
+ 1.5f, // rwrist
+ 1.8f, // rhand
+ 0.5f, // rfingers
+ 0.5f, // rthumb
+};
+
+static const PxReal gCharacterScale = 0.1;
+
+///////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterCloth::createCharacter()
+{
+ const char* asfpath = getSampleMediaFilename("motion/stickman.asf");
+ if (!mCharacter.create(asfpath, gCharacterScale))
+ {
+ fatalError("ERROR - Cannot load motion/stickman.asf\n");
+ }
+
+ // add motion clips to the character
+ const char* amcpath = 0;
+
+ amcpath = getSampleMediaFilename("motion/stickman_walking_01.amc");
+ mMotionHandleWalk = mCharacter.addMotion(amcpath);
+ if (mMotionHandleWalk < 0)
+ fatalError("ERROR - Cannot load motion/stickman_walking_01.amc\n");
+
+ amcpath = getSampleMediaFilename("motion/stickman_jump_01.amc");
+ mMotionHandleJump = mCharacter.addMotion(amcpath, 100,200);
+ if (mMotionHandleJump < 0)
+ fatalError("ERROR - Cannot load motion/stickman_jump_01.amc\n");
+
+ // initialize character position, scale, and orientation
+ resetCharacter();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterCloth::createCape()
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ // compute root transform and positions of all the bones
+ PxTransform rootPose;
+ SampleArray<PxVec3> positions;
+ SampleArray<PxU32> indexPairs;
+ mCharacter.getFramePose(rootPose, positions, indexPairs);
+
+ // convert bones to collision capsules
+ SampleArray<PxClothCollisionSphere> spheres;
+ spheres.resize(positions.size());
+ for (PxU32 i = 0; i < positions.size(); i++)
+ {
+ spheres[i].pos = positions[i];
+ spheres[i].radius = gCharacterScale * gSphereRadius[i];
+ }
+
+ // create the cloth cape mesh from file
+ SampleArray<PxVec4> vertices;
+ SampleArray<PxU32> primitives;
+ SampleArray<PxVec2> uvs;
+ const char* capeFileName = getSampleMediaFilename("ctdm_cape_m.obj");
+ PxClothMeshDesc meshDesc = Test::ClothHelpers::createMeshFromObj(capeFileName,
+ gCharacterScale * 0.3f, PxQuat(PxIdentity), PxVec3(0,-1.5,0), vertices, primitives, uvs);
+
+ for (PxU32 i = 0; i < meshDesc.invMasses.count; i++)
+ {
+ ((float*)meshDesc.invMasses.data)[i*4] = 0.5f;
+ }
+
+ if (!meshDesc.isValid()) fatalError("Could not load ctdm_cape_m.obj\n");
+
+ for (PxU32 i = 0; i < meshDesc.points.count; i++)
+ {
+ if(uvs[i].y > 0.85f)
+ vertices[i].w = 0.0f;
+ }
+
+ // create the cloth
+ PxClothMeshQuadifier quadifier(meshDesc);
+ mCape = createClothFromMeshDesc(quadifier.getDescriptor(), rootPose, PxVec3(0,-1,0),
+ uvs.begin(), "dummy_cape_d.bmp", 0.8f);
+ PxCloth& cloth = *mCape;
+
+ cloth.setCollisionSpheres(spheres.begin(), static_cast<PxU32>(positions.size()));
+ for(PxU32 i=0; i<indexPairs.size(); i+=2)
+ cloth.addCollisionCapsule(indexPairs[i], indexPairs[i+1]);
+
+ // compute initial skin binding to the character
+ mSkin.bindToCharacter(mCharacter, vertices);
+
+ // set solver settings
+ cloth.setSolverFrequency(240);
+
+ cloth.setStiffnessFrequency(10.0f);
+
+ // damp global particle velocity to 90% every 0.1 seconds
+ cloth.setDampingCoefficient(PxVec3(0.2f)); // damp local particle velocity
+ cloth.setLinearDragCoefficient(PxVec3(0.2f)); // transfer frame velocity
+ cloth.setAngularDragCoefficient(PxVec3(0.2f)); // transfer frame rotation
+
+ // reduce impact of frame acceleration
+ // x, z: cloth swings out less when walking in a circle
+ // y: cloth responds less to jump acceleration
+ cloth.setLinearInertiaScale(PxVec3(0.8f, 0.6f, 0.8f));
+
+ // leave impact of frame torque at default
+ cloth.setAngularInertiaScale(PxVec3(1.0f));
+
+ // reduce centrifugal force of rotating frame
+ cloth.setCentrifugalInertiaScale(PxVec3(0.3f));
+
+ const bool useVirtualParticles = true;
+ const bool useSweptContact = true;
+ const bool useCustomConfig = true;
+
+ // virtual particles
+ if (useVirtualParticles)
+ Test::ClothHelpers::createVirtualParticles(cloth, meshDesc, 4);
+
+ // ccd
+ cloth.setClothFlag(PxClothFlag::eSWEPT_CONTACT, useSweptContact);
+
+ // use GPU or not
+#if PX_SUPPORT_GPU_PHYSX || PX_XBOXONE
+ cloth.setClothFlag(gGpuFlag, mUseGPU);
+#endif
+
+ // custom fiber configuration
+ if (useCustomConfig)
+ {
+ PxClothStretchConfig stretchConfig;
+ stretchConfig.stiffness = 1.0f;
+
+ cloth.setStretchConfig(PxClothFabricPhaseType::eVERTICAL, PxClothStretchConfig(1.0f));
+ cloth.setStretchConfig(PxClothFabricPhaseType::eVERTICAL, PxClothStretchConfig(1.0f));
+ cloth.setStretchConfig(PxClothFabricPhaseType::eSHEARING, PxClothStretchConfig(0.75f));
+ cloth.setStretchConfig(PxClothFabricPhaseType::eBENDING, PxClothStretchConfig(0.5f));
+ cloth.setTetherConfig(PxClothTetherConfig(1.0f));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterCloth::createFlags()
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ PxQuat q = PxQuat(PxIdentity);
+
+ PxU32 numFlagRow = 2;
+ PxU32 resX = 20, resY = 10;
+ if (mClothFlagCountIndex == 0)
+ {
+ numFlagRow = 2;
+ resX = 20;
+ resY = 10;
+ }
+ else if (mClothFlagCountIndex == 1)
+ {
+ numFlagRow = 4;
+ resX = 30;
+ resY = 15;
+ }
+ else if (mClothFlagCountIndex == 2)
+ {
+ numFlagRow = 8;
+ resX = 50;
+ resY = 25;
+ }
+ else if (mClothFlagCountIndex == 3)
+ {
+ numFlagRow = 15;
+ resX = 50;
+ resY = 25;
+ }
+
+ for (PxU32 i = 0; i < numFlagRow; i++)
+ {
+ mFlags.pushBack(new SampleCharacterClothFlag(*this, PxTransform(PxVec3(-4,0,-10.0f -5.0f * i), q), resX, resY, 2.0f, 1.0f, 5.0f));
+ mFlags.pushBack(new SampleCharacterClothFlag(*this, PxTransform(PxVec3(4,0,-10.0f -5.0f * i), q), resX, resY, 2.0f, 1.0f, 5.0f));
+ }
+
+#if PX_SUPPORT_GPU_PHYSX || PX_XBOXONE
+ for (PxU32 i = 0; i < mFlags.size(); ++i)
+ mFlags[i]->getCloth()->setClothFlag(gGpuFlag, mUseGPU);
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterCloth::releaseFlags()
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ const size_t nbFlags = mFlags.size();
+ for(PxU32 i = 0;i < nbFlags;i++)
+ mFlags[i]->release();
+ mFlags.clear();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterCloth::resetCape()
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ PxCloth& cloth = *mCape;
+
+ // compute cloth pose and collider positions
+ PxTransform rootPose;
+ SampleArray<PxVec3> positions;
+ SampleArray<PxU32> indexPairs;
+ mCharacter.getFramePose(rootPose, positions, indexPairs);
+
+ // set cloth pose and zero velocity/acceleration
+ cloth.setGlobalPose(rootPose);
+
+ // set collision sphere positions
+ SampleArray<PxClothCollisionSphere> spheres(positions.size());
+ cloth.getCollisionData(spheres.begin(), 0, 0, 0, 0);
+ for (PxU32 i = 0; i < positions.size(); i++)
+ spheres[i].pos = positions[i];
+ cloth.setCollisionSpheres(spheres.begin(), spheres.size());
+
+ // set positions for constrained particles
+ SampleArray<PxVec3> particlePositions;
+ mSkin.computeNewPositions(mCharacter, particlePositions);
+ Test::ClothHelpers::setParticlePositions(cloth, particlePositions, false, false);
+
+ cloth.setExternalAcceleration(PxVec3(0.0f));
+
+ // clear previous state of collision shapes etc.
+ cloth.clearInterpolation();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterCloth::resetCharacter()
+{
+ // compute global pose and local positions
+ PxExtendedVec3 posExt = mController->getPosition();
+ PxVec3 pos = PxVec3(PxReal(posExt.x), PxReal(posExt.y), PxReal(posExt.z)) - PxVec3(0.0f, 1.5, 0.0f);
+
+ PxTransform pose;
+ pose.p = pos;
+ pose.q = PxQuat(PxIdentity);
+
+ mCharacter.resetMotion(37.0f);
+ mCharacter.setGlobalPose(pose);
+ mCharacter.setTargetPosition(PxVec3(pos.x, pos.y, pos.z));
+ mCharacter.setMotion(mMotionHandleWalk, true);
+ mCharacter.move(1.0f, false, mCCTActive);
+ mCharacter.faceToward(PxVec3(0,0,-1));
+
+ mJump.reset();
+
+ mCCTDisplacementPrevStep = PxVec3(0.0f);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterCloth::updateCape(float dtime)
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ PxCloth& cloth = *mCape;
+
+ // compute cloth pose and collider positions
+ PxTransform rootPose;
+ SampleArray<PxVec3> spherePositions;
+ SampleArray<PxU32> indexPairs;
+ mCharacter.getFramePose(rootPose, spherePositions, indexPairs);
+
+ // set cloth pose
+ cloth.setTargetPose(rootPose);
+
+ // set collision sphere positions
+ SampleArray<PxClothCollisionSphere> spheres(spherePositions.size());
+ cloth.getCollisionData(spheres.begin(), 0, 0, 0, 0);
+ for (PxU32 i = 0; i < spherePositions.size(); i++)
+ spheres[i].pos = spherePositions[i];
+ cloth.setCollisionSpheres(spheres.begin(), spheres.size());
+
+ // set positions for constrained particles
+ SampleArray<PxVec3> particlePositions;
+ mSkin.computeNewPositions(mCharacter, particlePositions);
+
+ Test::ClothHelpers::setParticlePositions(cloth, particlePositions, true, true);
+
+ // add wind while in freefall
+ if (mJump.isInFreefall())
+ {
+ PxReal strength = 20.0f;
+ PxVec3 offset( PxReal(PxToolkit::Rand(-1,1)), 1.0f + PxReal(PxToolkit::Rand(-1,1)), PxReal(PxToolkit::Rand(-1,1)));
+ PxVec3 windAcceleration = strength * offset;
+ cloth.setExternalAcceleration(windAcceleration);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterCloth::updateCharacter(float dtime)
+{
+ // compute global pose of the character from CCT
+ PxExtendedVec3 posExt = mController->getPosition();
+ PxVec3 offset(0.0f, gCharacterScale * 15.0f, 0.0f); // offset from controller center to the foot
+ PxVec3 pos = PxVec3(PxReal(posExt.x), PxReal(posExt.y), PxReal(posExt.z)) - offset;
+
+ // update character pose and motion
+ if (mJump.isJumping() == true)
+ {
+ mCharacter.setTargetPosition(pos);
+ mCharacter.setMotion(mMotionHandleJump);
+ mCharacter.move(0.25f, true);
+ }
+ else
+ {
+ bool cctActive = mCCTActive && (mJump.isInFreefall() == false);
+
+ mCharacter.setTargetPosition(pos);
+ mCharacter.setMotion(mMotionHandleWalk);
+ mCharacter.move(1.0f, false, cctActive);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterCloth::updateFlags(float dtime)
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ // apply wind force to flags
+ for (PxU32 i = 0 ; i < mFlags.size(); i++)
+ {
+ mFlags[i]->setWind(PxVec3(1,0.1,0), 40.0f, PxVec3(0.0f, 10.0f, 10.0f));
+ mFlags[i]->update(dtime);
+ }
+}
+
+#if PX_SUPPORT_GPU_PHYSX || PX_XBOXONE
+///////////////////////////////////////////////////////////////////////////////
+void
+SampleCharacterCloth::toggleGPU()
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ mUseGPU = !mUseGPU;
+
+ if (mCape)
+ mCape->setClothFlag(gGpuFlag, mUseGPU);
+
+ for (PxU32 i = 0 ; i < mFlags.size(); i++)
+ {
+ mFlags[i]->getCloth()->setClothFlag(gGpuFlag, mUseGPU);
+ }
+}
+#endif
+
+#endif // PX_USE_CLOTH_API
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_FilterShader.cpp b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_FilterShader.cpp
new file mode 100644
index 00000000..ec6d68bb
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_FilterShader.cpp
@@ -0,0 +1,52 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+
+#include "PxPhysicsAPI.h"
+#include "SampleCharacterCloth.h"
+
+static PxFilterFlags filter(PxFilterObjectAttributes attributes0,
+ PxFilterData filterData0,
+ PxFilterObjectAttributes attributes1,
+ PxFilterData filterData1,
+ PxPairFlags& pairFlags,
+ const void* constantBlock,
+ PxU32 constantBlockSize)
+{
+ pairFlags |= PxPairFlag::eCONTACT_DEFAULT;
+ return PxFilterFlags();
+}
+
+void SampleCharacterCloth::customizeSceneDesc(PxSceneDesc& sceneDesc)
+{
+ sceneDesc.gravity = PxVec3(0,-9.81,0);
+ sceneDesc.filterShader = filter;
+ sceneDesc.flags |= PxSceneFlag::eREQUIRE_RW_LOCK;
+}
+
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_Main.cpp b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_Main.cpp
new file mode 100644
index 00000000..cfe641e9
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_Main.cpp
@@ -0,0 +1,441 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "PxPhysXConfig.h"
+
+#if PX_USE_CLOTH_API
+
+#include "SampleCharacterCloth.h"
+
+#include "SampleAllocatorSDKClasses.h"
+#include "SampleCharacterClothCameraController.h"
+#include "SampleCharacterClothInputEventIds.h"
+#include "SampleCharacterClothSettings.h"
+#include "SampleCharacterClothFlag.h"
+#include "SamplePlatform.h"
+
+#include "RenderMaterial.h"
+#include "RenderBaseActor.h"
+
+#include "characterkinematic/PxCapsuleController.h"
+#include "characterkinematic/PxControllerManager.h"
+#include "PxPhysicsAPI.h"
+
+#include "SampleCharacterClothInputEventIds.h"
+#include <SampleUserInputIds.h>
+#include <SampleUserInput.h>
+#include <SampleUserInputDefines.h>
+
+REGISTER_SAMPLE(SampleCharacterCloth, "SampleCharacterCloth")
+
+using namespace SampleFramework;
+using namespace SampleRenderer;
+using namespace PxToolkit;
+
+///////////////////////////////////////////////////////////////////////////////
+
+SampleCharacterCloth::SampleCharacterCloth(PhysXSampleApplication& app)
+ : PhysXSample (app, 2)
+ , mCCTCamera (NULL)
+ , mController (NULL)
+ , mControllerManager (NULL)
+ , mCCTDisplacement (0.0f)
+ , mCCTDisplacementPrevStep (0.0f)
+ , mCCTTimeStep (0.0f)
+ , mCape (NULL)
+#if PX_SUPPORT_GPU_PHYSX || PX_XBOXONE
+ , mUseGPU (true)
+#endif
+{
+ mCreateGroundPlane = false;
+ //mStepperType = FIXED_STEPPER;
+ mControllerInitialPosition = PxVec3(0.0, 3.0f, 0.0);
+
+ mCCTActive = false;
+
+ mNbVerts = 0;
+ mNbTris = 0;
+ mVerts = NULL;
+ mTris = NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+SampleCharacterCloth::~SampleCharacterCloth()
+{
+ DELETESINGLE(mCCTCamera);
+
+ SAMPLE_FREE(mTris);
+ SAMPLE_FREE(mVerts);
+
+ const size_t nbPlatforms = mPlatforms.size();
+ for(PxU32 i = 0;i < nbPlatforms;i++)
+ mPlatforms[i]->release();
+
+// releaseFlags();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// create render materials used for render objects.
+// The newly created materials are appended to PhysXSample::mRenderMaterials array
+void SampleCharacterCloth::createRenderMaterials()
+{
+ getRenderer()->setAmbientColor(RendererColor(100, 100, 100));
+
+ // create render materials used in this sample
+ mSnowMaterial = SAMPLE_NEW(RenderMaterial)(*getRenderer(), PxVec3(0.70f, 0.70f, 0.8f), 1.0f, false, 0, NULL);
+ mRenderMaterials.push_back(mSnowMaterial);
+
+ mFlagMaterial = createRenderMaterialFromTextureFile("nvidia_flag_d.bmp");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SampleCharacterCloth::customizeSample(SampleSetup& setup)
+{
+ setup.mName = "SampleCharacterCloth";
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::collectInputEvents(std::vector<const InputEvent*>& inputEvents)
+{
+ PhysXSample::collectInputEvents(inputEvents);
+ getApplication().getPlatform()->getSampleUserInput()->unregisterInputEvent(SPAWN_DEBUG_OBJECT);
+
+ //digital keyboard events
+ DIGITAL_INPUT_EVENT_DEF(RESET_SCENE, WKEY_R, XKEY_R, X1KEY_R, PS3KEY_R, PS4KEY_R, AKEY_UNKNOWN, OSXKEY_R, IKEY_UNKNOWN, LINUXKEY_R, WIIUKEY_UNKNOWN);
+ DIGITAL_INPUT_EVENT_DEF(CHANGE_CLOTH_CONTENT, WKEY_M, XKEY_M, X1KEY_M, PS3KEY_M, PS4KEY_M, AKEY_UNKNOWN, OSXKEY_M, IKEY_UNKNOWN, LINUXKEY_M, WIIUKEY_UNKNOWN);
+
+ //digital mouse events
+
+ //touch events
+ TOUCH_INPUT_EVENT_DEF(RESET_SCENE, "Reset", ABUTTON_5, IBUTTON_5);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::onDigitalInputEvent(const InputEvent& ie, bool val)
+{
+ if(val)
+ {
+ switch (ie.m_Id)
+ {
+ case RESET_SCENE:
+ {
+ resetScene();
+ }
+ break;
+ case CHANGE_CLOTH_CONTENT:
+ mClothFlagCountIndex = (mClothFlagCountIndex+1)% (mClothFlagCountIndexMax+1);
+ releaseFlags();
+ createFlags();
+ break;
+
+#if PX_SUPPORT_GPU_PHYSX || PX_XBOXONE
+ case TOGGLE_CPU_GPU:
+ toggleGPU();
+ return;
+ break;
+#endif
+ }
+ }
+
+ PhysXSample::onDigitalInputEvent(ie,val);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SampleCharacterCloth::helpRender(PxU32 x, PxU32 y, PxU8 textAlpha)
+{
+ Renderer* renderer = getRenderer();
+ const PxU32 yInc = 18;
+ const PxReal scale = 0.5f;
+ const PxReal shadowOffset = 6.0f;
+ const RendererColor textColor(255, 255, 255, textAlpha);
+ const bool isMouseSupported = getApplication().getPlatform()->getSampleUserInput()->mouseSupported();
+ const bool isPadSupported = getApplication().getPlatform()->getSampleUserInput()->gamepadSupported();
+ const char* msg;
+
+ if (isMouseSupported && isPadSupported)
+ renderer->print(x, y += yInc, "Use mouse or right stick to rotate the camera", scale, shadowOffset, textColor);
+ else if (isMouseSupported)
+ renderer->print(x, y += yInc, "Use mouse to rotate the camera", scale, shadowOffset, textColor);
+ else if (isPadSupported)
+ renderer->print(x, y += yInc, "Use right stick to rotate the camera", scale, shadowOffset, textColor);
+ if (isPadSupported)
+ renderer->print(x, y += yInc, "Use left stick to move",scale, shadowOffset, textColor);
+ msg = mApplication.inputMoveInfoMsg("Press "," to move", CAMERA_MOVE_FORWARD,CAMERA_MOVE_BACKWARD, CAMERA_MOVE_LEFT, CAMERA_MOVE_RIGHT);
+ if(msg)
+ renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor);
+ msg = mApplication.inputInfoMsg("Press "," to move fast", CAMERA_SHIFT_SPEED, -1);
+ if(msg)
+ renderer->print(x, y += yInc, msg, scale, shadowOffset, textColor);
+ msg = mApplication.inputInfoMsg("Press "," to jump", CAMERA_JUMP, -1);
+ if(msg)
+ renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor);
+
+ msg = mApplication.inputInfoMsg("Press "," to toggle visualization", TOGGLE_VISUALIZATION, -1);
+ if(msg)
+ renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor);
+
+ msg = mApplication.inputInfoMsg("Press "," to reset scene", RESET_SCENE, -1);
+ if(msg)
+ renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor);
+
+ msg = mApplication.inputInfoMsg("Press "," to change flag count", CHANGE_CLOTH_CONTENT,-1);
+ if(msg)
+ renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor);
+
+#if PX_SUPPORT_GPU_PHYSX || PX_XBOXONE
+ msg = mApplication.inputInfoMsg("Press "," to toggle CPU/GPU", TOGGLE_CPU_GPU, -1);
+ if(msg)
+ renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor);
+#endif
+}
+
+void SampleCharacterCloth::descriptionRender(PxU32 x, PxU32 y, PxU8 textAlpha)
+{
+ bool print=(textAlpha!=0.0f);
+
+ if(print)
+ {
+ Renderer* renderer = getRenderer();
+ const PxU32 yInc = 24;
+ const PxReal scale = 0.5f;
+ const PxReal shadowOffset = 6.0f;
+ const RendererColor textColor(255, 255, 255, textAlpha);
+
+ char line0[256]="This sample demonstrates the PhysX cloth feature. In particular, the ";
+ char line1[256]="setup and simulation of a cape attached to an animated character is";
+ char line2[256]="presented. This involves generating an approximate description of the";
+ char line3[256]="character's geometry, cloth instantiation, the binding of the cloth to a";
+ char line4[256]="skinned character, and the setup of simulation parameters and values";
+ char line5[256]="controlling the different phases of the cloth solver. To clarify the";
+ char line6[256]="process, and to offer some variety, a flag is also created and simulated.";
+#if PX_WINDOWS
+ char line7[256]="Finally, the sample illustrates the steps required to enable GPU";
+ char line8[256]="acceleration of PhysX cloth.";
+#endif
+
+ renderer->print(x, y+=yInc, line0, scale, shadowOffset, textColor);
+ renderer->print(x, y+=yInc, line1, scale, shadowOffset, textColor);
+ renderer->print(x, y+=yInc, line2, scale, shadowOffset, textColor);
+ renderer->print(x, y+=yInc, line3, scale, shadowOffset, textColor);
+ renderer->print(x, y+=yInc, line4, scale, shadowOffset, textColor);
+ renderer->print(x, y+=yInc, line5, scale, shadowOffset, textColor);
+ renderer->print(x, y+=yInc, line6, scale, shadowOffset, textColor);
+#if PX_WINDOWS
+ renderer->print(x, y+=yInc, line7, scale, shadowOffset, textColor);
+ renderer->print(x, y+=yInc, line8, scale, shadowOffset, textColor);
+#endif
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::customizeRender()
+{
+#if PX_SUPPORT_GPU_PHYSX || PX_XBOXONE
+ SampleRenderer::Renderer* renderer = getRenderer();
+
+ const PxU32 yInc = 20;
+ const PxReal scale = 0.5f;
+ const PxReal shadowOffset = 6.0f;
+ PxU32 width, height;
+ renderer->getWindowSize(width, height);
+
+ PxU32 y = height-2*yInc;
+ PxU32 x = width - 360;
+
+ {
+ const RendererColor textColor(255, 0, 0, 255);
+ const char* message[4] = { "Flag count: Moderate", "Flag count: Medium", "Flag count: High", "Flag count: Very High" };
+ renderer->print(x, y, message[mClothFlagCountIndex], scale, shadowOffset, textColor);
+ }
+
+ {
+ y -= yInc;
+ const RendererColor textColor(255, 0, 0, 255);
+
+ char buf[2048];
+ sprintf(buf, mUseGPU ? "Running on GPU" : "Running on CPU");
+
+ if(PX_SUPPORT_GPU_PHYSX && mUseGPU)
+ sprintf(buf + strlen(buf), " (%s)", getActiveScene().getTaskManager()->getGpuDispatcher()->getCudaContextManager()->getDeviceName());
+
+ renderer->print(x, y, buf, scale, shadowOffset, textColor);
+ }
+
+ {
+ y -= yInc;
+
+ char fpsText[512];
+ sprintf(fpsText, "Average PhysX time: %3.3f ms", 1000.0f * mAverageSimulationTime);
+
+ const RendererColor textColor(255, 255, 255, 255);
+ renderer->print(x, y, fpsText, scale, shadowOffset, textColor);
+ }
+
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::onInit()
+{
+ mNbThreads = PxMax(PxI32(shdfnd::Thread::getNbPhysicalCores())-1, 0);
+
+ // try to get gpu support
+ mCreateCudaCtxManager = true;
+
+ PhysXSample::onInit();
+
+ PxSceneWriteLock scopedLock(*mScene);
+
+ mApplication.setMouseCursorHiding(true);
+ mApplication.setMouseCursorRecentering(true);
+
+ mClothFlagCountIndex = 0;
+ mClothFlagCountIndexMax = 3;
+
+ // create materials and render setup
+ createRenderMaterials();
+
+ // build static heightfield landscape
+ buildHeightField();
+
+ // create CCT controller
+ createCCTController();
+
+ // create the stickman character
+ createCharacter();
+
+ // create a cape for the stickman
+ createCape();
+
+ // create flags
+ createFlags();
+
+ // reset scene
+ resetScene();
+
+ // apply global physx settings
+ getActiveScene().setGravity(PxVec3(0,-10.0f,0));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::resetScene()
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ // reset cct
+ PxVec3 pos = mControllerInitialPosition;
+ mController->setPosition(PxExtendedVec3(pos.x, pos.y, pos.z));
+
+ // compute global pose and local positions
+ PxExtendedVec3 posExt = mController->getPosition();
+ PxTransform pose = mController->getActor()->getGlobalPose();
+ pose.p = PxVec3(PxReal(posExt.x), PxReal(posExt.y), PxReal(posExt.z)) - PxVec3(0.0f, 1.5, 0.0f);
+
+ mCharacter.setGlobalPose(pose);
+
+ resetCharacter();
+ resetCape();
+
+ // reset platforms
+ const size_t nbPlatforms = mPlatforms.size();
+ for(PxU32 i = 0;i < nbPlatforms;i++)
+ mPlatforms[i]->reset();
+
+ // reset camera
+ mCCTCamera->setView(0.0f, 0.0f);
+
+ // reset stats
+ mFrameCount = 0;
+ mAccumulatedSimulationTime = 0.0f;
+ mAverageSimulationTime = 0.0f;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::onShutdown()
+{
+ {
+ PxSceneWriteLock scopedLock(*mScene);
+ DELETESINGLE(mCCTCamera);
+ SAFE_RELEASE(mControllerManager);
+ }
+ PhysXSample::onShutdown();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::onTickPreRender(float dtime)
+{
+ PhysXSample::onTickPreRender(dtime);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// called after each substep is done (can be called more than once per frame)
+void SampleCharacterCloth::onSubstep(float dtime)
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ updatePlatforms(dtime);
+ updateCCT(dtime);
+ updateCharacter(dtime);
+ updateCape(dtime);
+ updateFlags(dtime);
+
+#if PX_SUPPORT_GPU_PHYSX || PX_XBOXONE
+ // update the GPU flag (may have been disabled if CUDA error, not enough shared memory, etc)
+ mUseGPU = mCape->getClothFlags() & (PxClothFlag::eCUDA);
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::onTickPostRender(float dtime)
+{
+ PhysXSample::onTickPostRender(dtime);
+
+ mFrameCount++;
+ mAccumulatedSimulationTime += getSimulationTime();
+ PxReal delta = PxReal(mTimer.peekElapsedSeconds());
+ if (delta > 1.0f)
+ {
+ mAverageSimulationTime = mAccumulatedSimulationTime / PxReal(mFrameCount);
+ mFrameCount = 0;
+ mAccumulatedSimulationTime = 0.0f;
+ mTimer.getElapsedSeconds();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::onPointerInputEvent(const SampleFramework::InputEvent& ie, physx::PxU32 x, physx::PxU32 y, physx::PxReal dx, physx::PxReal dy, bool val)
+{
+ PhysXSample::onPointerInputEvent(ie,x,y,dx,dy,val);
+}
+
+#endif // PX_USE_CLOTH_API
+
+
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_Platform.cpp b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_Platform.cpp
new file mode 100644
index 00000000..641e477a
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_Platform.cpp
@@ -0,0 +1,120 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "SampleCharacterCloth.h"
+
+#include "SampleCharacterClothPlatform.h"
+
+
+///////////////////////////////////////////////////////////////////////////////
+SampleCharacterClothPlatform::SampleCharacterClothPlatform() :
+ mActor(NULL),
+ mCurrentTime(0.0f),
+ mTravelTime(0.0f),
+ mStart(0.0f),
+ mTarget(0.0f),
+ mFlip(false),
+ mType(ePLATFORM_TYPE_MOVING),
+ mActive(true)
+ {
+ }
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterClothPlatform::init(PxRigidDynamic* actor, PxReal travelTime, const PxVec3& offsetTarget)
+{
+ mActor = actor;
+ mCurrentTime = 0.0f;
+ mTravelTime = travelTime;
+
+ mStart = mActor->getGlobalPose().p;
+ mTarget = mStart + offsetTarget;
+
+ reset();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterClothPlatform::release()
+{
+ delete this;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterClothPlatform::reset()
+{
+ mCurrentTime = 0.0f;
+ mFlip = false;
+
+ switch (mType)
+ {
+ case ePLATFORM_TYPE_MOVING:
+ mActive = true;
+ break;
+ default:
+ mActive = false;
+ }
+
+ update(0.0f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterClothPlatform::update(PxReal dtime)
+{
+ PxReal t = mCurrentTime / mTravelTime;
+
+ PxTransform pose = mActor->getGlobalPose();
+ if (!mFlip)
+ {
+ pose.p = (1 - t) * mStart + t * mTarget;
+ }
+ else
+ pose.p = t * mStart + (1-t) * mTarget;
+
+ mActor->setKinematicTarget(pose);
+
+ if (mActive == false)
+ return;
+
+ mCurrentTime += dtime;
+
+ if (mCurrentTime > mTravelTime)
+ {
+ mCurrentTime -= mTravelTime;
+ mFlip = !mFlip;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void SampleCharacterCloth::updatePlatforms(float dtime)
+{
+ const size_t nbPlatforms = mPlatforms.size();
+ for(PxU32 i = 0;i < nbPlatforms;i++)
+ {
+ mPlatforms[i]->update(dtime);
+ }
+} \ No newline at end of file
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_PlatformBuilder.cpp b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_PlatformBuilder.cpp
new file mode 100644
index 00000000..a1919d60
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_PlatformBuilder.cpp
@@ -0,0 +1,201 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "SampleCharacterCloth.h"
+
+#include "SampleCharacterClothPlatform.h"
+
+//////////////////////////////////////////////////////////////////////////////
+// create a kinematic capsule
+SampleCharacterClothPlatform*
+SampleCharacterCloth::createPlatform(const PxTransform &pose, const PxGeometry &geom, PxReal travelTime, const PxVec3 &offset, RenderMaterial *renderMaterial)
+{
+ PxRigidDynamic* actor = getPhysics().createRigidDynamic(pose);
+ actor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
+
+ PxShape* shape = PxRigidActorExt::createExclusiveShape(*actor, geom, getDefaultMaterial());
+
+ PxScene& scene = getActiveScene();
+ scene.addActor(*actor);
+
+ createRenderObjectFromShape(actor, shape, renderMaterial);
+
+ SampleCharacterClothPlatform* platform = SAMPLE_NEW(SampleCharacterClothPlatform);
+ platform->init(actor, travelTime, offset);
+
+ mPlatforms.pushBack(platform);
+
+ return platform;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// create moving platforms
+void SampleCharacterCloth::createPlatforms()
+{
+ SampleCharacterClothPlatform* platform = 0;
+
+ // initial deck
+ PxVec3 p0(0,0,-4);
+ platform = createPlatform(PxTransform(p0, PxQuat(PxIdentity)),
+ PxBoxGeometry(PxVec3(2,1,8)), 2.0f, PxVec3(0,0,0), mPlatformMaterial);
+
+ // moving platform (moving in x)
+ PxVec3 p1 = p0 + PxVec3(-4, 0, -6);
+ PxVec3 p1offset(-10,0,0);
+ platform = createPlatform(PxTransform(p1, PxQuat(PxIdentity)),
+ PxBoxGeometry(PxVec3(2,1,2)), 4.0f, p1offset, mPlatformMaterial);
+
+ // moving platform triggered by contact
+ PxVec3 p2 = p1 + p1offset + PxVec3(-4,2,0);
+ PxVec3 p2offset(0,0,-10);
+ platform = createPlatform(PxTransform(p2, PxQuat(PxIdentity)),
+ PxBoxGeometry(PxVec3(2,1,2)), 5.0f, p2offset, mPlatformMaterial);
+ platform->setType(SampleCharacterClothPlatform::ePLATFORM_TYPE_TRIGGERED);
+
+ // trampoline-like platform
+ PxVec3 p3 = p2 + p2offset + PxVec3(-4,-3,0);
+ PxVec3 p3offset(0,10, 0);
+ platform = createPlatform(PxTransform(p3, PxQuat(PxIdentity)),
+ PxBoxGeometry(PxVec3(1,1,1)), 5.0f, p3offset, mRockMaterial);
+ platform->setType(SampleCharacterClothPlatform::ePLATFORM_TYPE_TRIGGERED);
+
+ // a wide deck with a hole
+ PxVec3 p4 = p3 + PxVec3(-10, 5, -4);
+ PxVec3 p4offset(0.0f);
+
+ platform = createPlatform(PxTransform(p4+PxVec3(0,0,-4), PxQuat(PxIdentity)),
+ PxBoxGeometry(PxVec3(6,0.5,2)), 5.0f, p4offset, mWoodMaterial);
+ platform = createPlatform(PxTransform(p4+PxVec3(0,0,4), PxQuat(PxIdentity)),
+ PxBoxGeometry(PxVec3(6,0.5,2)), 5.0f, p4offset, mWoodMaterial);
+
+ platform = createPlatform(PxTransform(p4+PxVec3(-4,0,0), PxQuat(PxIdentity)),
+ PxBoxGeometry(PxVec3(2,0.5,2)), 5.0f, p4offset, mWoodMaterial);
+ platform = createPlatform(PxTransform(p4+PxVec3(4,0,0), PxQuat(PxIdentity)),
+ PxBoxGeometry(PxVec3(2,0.5,2)), 5.0f, p4offset, mWoodMaterial);
+
+ // walls
+ platform = createPlatform(PxTransform(p4+PxVec3(0,5.5,-6), PxQuat(PxIdentity)),
+ PxBoxGeometry(PxVec3(6,6,0.5)), 1.0f, p4offset, mRockMaterial);
+ platform = createPlatform(PxTransform(p4+PxVec3(-6,5.5,0), PxQuat(PxIdentity)),
+ PxBoxGeometry(PxVec3(0.5,6,6)), 1.0f, p4offset, mRockMaterial);
+
+ // moving platform under the deck
+ PxVec3 p5 = p4 + PxVec3(0,-6,0);
+ PxVec3 p5offset(15,0,-15);
+ platform = createPlatform(PxTransform(p5, PxQuat(PxIdentity)),
+ PxBoxGeometry(PxVec3(3,1,3)), 5.0f, p5offset, mPlatformMaterial);
+
+ // steps made of spheres
+ PxVec3 sphere0 = p5 + p5offset + PxVec3(4,1,-4);
+ platform = createPlatform(PxTransform(sphere0, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 3.0f, PxVec3(0), mRockMaterial);
+
+ PxVec3 sphere1 = sphere0 + PxVec3(4,1,-3);
+ platform = createPlatform(PxTransform(sphere1, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 3.0f, PxVec3(0), mRockMaterial);
+
+ PxVec3 sphere2 = sphere1 + PxVec3(-2,1,-4);
+ platform = createPlatform(PxTransform(sphere2, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 3.0f, PxVec3(0), mRockMaterial);
+
+ PxVec3 sphere3 = sphere2 + PxVec3(-5,1,1);
+ platform = createPlatform(PxTransform(sphere3, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 3.0f, PxVec3(0), mRockMaterial);
+
+ PxVec3 sphere4 = sphere3 + PxVec3(-2,1,4);
+ platform = createPlatform(PxTransform(sphere4, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 3.0f, PxVec3(0), mRockMaterial);
+
+ PxVec3 sphere5 = sphere4 + PxVec3(3,1,1);
+ platform = createPlatform(PxTransform(sphere5, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 3.0f, PxVec3(0), mRockMaterial);
+
+ PxVec3 sphere6 = sphere5 + PxVec3(3,1,-3);
+ platform = createPlatform(PxTransform(sphere6, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 3.0f, PxVec3(0), mRockMaterial);
+
+
+ // capsule platform
+ PxVec3 capsule0 = sphere6 + PxVec3(12, 1, -12);
+ platform = createPlatform(PxTransform(capsule0, PxQuat(PxPi / 4.0f, PxVec3(0,1.0f, 0.0f))),
+ PxCapsuleGeometry(1.5f,12.0f), 2.0f, PxVec3(0.0f), mSnowMaterial);
+
+ // second capsule base
+ PxVec3 capsule1 = capsule0 + PxVec3(12, 0, -22);
+ platform = createPlatform(PxTransform(capsule1, PxQuat(PxPi / 2.0f, PxVec3(0,1.0f, 0.0f))),
+ PxCapsuleGeometry(1.5f,10.0f), 2.0f, PxVec3(0.0f), mPlatformMaterial);
+
+ PxVec3 csphere0 = capsule1 + PxVec3(3,0.5,10);
+ platform = createPlatform(PxTransform(csphere0, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 1.0f, PxVec3(-6,0,0), mPlatformMaterial);
+
+ PxVec3 csphere1 = capsule1 + PxVec3(-3,0.5,6);
+ platform = createPlatform(PxTransform(csphere1, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 1.0f, PxVec3(6,0,0), mPlatformMaterial);
+
+ PxVec3 csphere2 = capsule1 + PxVec3(-3,0.5,2);
+ platform = createPlatform(PxTransform(csphere2, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 1.0f, PxVec3(6,0,0), mPlatformMaterial);
+
+ PxVec3 csphere3 = capsule1 + PxVec3(3,0.5,-2);
+ platform = createPlatform(PxTransform(csphere3, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 1.0f, PxVec3(-6,0,0), mPlatformMaterial);
+
+ PxVec3 csphere4 = capsule1 + PxVec3(3,0.5,-6);
+ platform = createPlatform(PxTransform(csphere4, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 1.0f, PxVec3(-6,0,0), mPlatformMaterial);
+
+ PxVec3 csphere5 = capsule1 + PxVec3(-3,0.5,-10);
+ platform = createPlatform(PxTransform(csphere5, PxQuat(PxIdentity)),
+ PxSphereGeometry(1.5f), 1.0f, PxVec3(6,0,0), mPlatformMaterial);
+
+ // jump deck
+ PxVec3 jumpDeck = capsule1 + PxVec3(0,1, 0) + PxVec3(-10,0,-10);
+ platform = createPlatform(PxTransform(jumpDeck, PxQuat(-PxPi / 4.0f, PxVec3(0,1.0f, 0.0f))),
+ PxBoxGeometry(PxVec3(6,1,2)), 5.0f, PxVec3(0.0f), mWoodMaterial);
+
+ // wind tunnel
+ PxVec3 windTunnel = jumpDeck + PxVec3(0,0,0) + PxVec3(-6,0,-6);
+ platform = createPlatform(PxTransform(windTunnel, PxQuat(-PxPi / 4.0f, PxVec3(0,1.0f, 0.0f))),
+ PxBoxGeometry(PxVec3(2,0.5,2)), 5.0f, PxVec3(0.0f), mPlatformMaterial);
+
+ // landing deck
+ PxVec3 landingDeck = jumpDeck + PxVec3(0,2, 0) + PxVec3(-15,0,-15);
+ platform = createPlatform(PxTransform(landingDeck, PxQuat(-PxPi / 4.0f, PxVec3(0,1.0f, 0.0f))),
+ PxBoxGeometry(PxVec3(4,1,2)), 5.0f, PxVec3(0.0f), mRockMaterial);
+
+ // reset platforms
+ const size_t nbPlatforms = mPlatforms.size();
+ for(PxU32 i = 0;i < nbPlatforms;i++)
+ mPlatforms[i]->reset();
+
+ // debugging cheat to start from later levels
+// mControllerInitialPosition = jumpDeck + PxVec3(0,5,0);
+
+}
diff --git a/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_TerrainBuilder.cpp b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_TerrainBuilder.cpp
new file mode 100644
index 00000000..c3443a10
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleCharacterCloth/SampleCharacterCloth_TerrainBuilder.cpp
@@ -0,0 +1,268 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+
+#include "PxPhysicsAPI.h"
+#include "PxTkStream.h"
+#include "SampleCharacterCloth.h"
+
+using namespace PxToolkit;
+
+//#define USE_MESH
+
+static PxToolkit::BasicRandom gClothRandom;
+
+static PxReal randomScaled(PxReal value)
+{
+ PxReal val = value*(gClothRandom.randomFloat());
+ return val;
+}
+
+static void computeTerrain(bool* done, PxReal* pVB, PxU32 x0, PxU32 y0, PxU32 currentSize, PxReal value, PxU32 initSize)
+{
+ // Compute new size
+ currentSize>>=1;
+ if (currentSize > 0) {
+ PxU32 x1 = (x0+currentSize) % initSize;
+ PxU32 x2 = (x0+currentSize+currentSize) % initSize;
+ PxU32 y1 = (y0+currentSize) % initSize;
+ PxU32 y2 = (y0+currentSize+currentSize) % initSize;
+
+ if(!done[x1 + y0*initSize]) pVB[(x1 + y0*initSize)] = randomScaled(value) + 0.5f * (pVB[(x0 + y0*initSize)] + pVB[(x2 + y0*initSize)]);
+ if(!done[x0 + y1*initSize]) pVB[(x0 + y1*initSize)] = randomScaled(value) + 0.5f * (pVB[(x0 + y0*initSize)] + pVB[(x0 + y2*initSize)]);
+ if(!done[x2 + y1*initSize]) pVB[(x2 + y1*initSize)] = randomScaled(value) + 0.5f * (pVB[(x2 + y0*initSize)] + pVB[(x2 + y2*initSize)]);
+ if(!done[x1 + y2*initSize]) pVB[(x1 + y2*initSize)] = randomScaled(value) + 0.5f * (pVB[(x0 + y2*initSize)] + pVB[(x2 + y2*initSize)]);
+ if(!done[x1 + y1*initSize]) pVB[(x1 + y1*initSize)] = randomScaled(value) + 0.5f * (pVB[(x0 + y1*initSize)] + pVB[(x2 + y1*initSize)]);
+
+ done[x1 + y0*initSize] = true;
+ done[x0 + y1*initSize] = true;
+ done[x2 + y1*initSize] = true;
+ done[x1 + y2*initSize] = true;
+ done[x1 + y1*initSize] = true;
+
+ // Recurse through 4 corners
+ value *= 0.5f;
+ computeTerrain(done, pVB, x0, y0, currentSize, value, initSize);
+ computeTerrain(done, pVB, x0, y1, currentSize, value, initSize);
+ computeTerrain(done, pVB, x1, y0, currentSize, value, initSize);
+ computeTerrain(done, pVB, x1, y1, currentSize, value, initSize);
+ }
+}
+
+static void fractalize(PxReal* heights, const PxU32 size, const PxReal roughness)
+{
+ PxU32 num = size*size;
+ bool* done = (bool*)SAMPLE_ALLOC(sizeof(bool)*num);
+ for(PxU32 i=0; i<num; i++)
+ done[i]=false;
+ computeTerrain(done,heights,0,0,size,roughness,size);
+ SAMPLE_FREE(done);
+}
+
+PxRigidStatic* SampleCharacterCloth::buildHeightField()
+{
+ // create a height map
+ gClothRandom.setSeed(42);
+
+ const PxU32 hfSize = 32; // some power of 2
+ const PxU32 hfNumVerts = hfSize*hfSize;
+
+ const PxReal hfScale = 8.0f; // this is how wide one heightfield square is
+
+ PxReal* heightmap = (PxReal*)SAMPLE_ALLOC(sizeof(PxReal)*hfNumVerts);
+// memset(heightmap,0,hfNumVerts*sizeof(PxReal));
+ for(PxU32 i = 0; i < hfNumVerts; i++)
+ heightmap[i] = -9.0f;
+
+ fractalize(heightmap,hfSize,16);
+
+ for(PxU32 i = 0; i < hfNumVerts; i++)
+ heightmap[i] -= 5.0f;
+
+ { // make render terrain
+ PxReal* hfVerts = (PxReal*)SAMPLE_ALLOC(sizeof(PxReal)*hfNumVerts*3);
+ PxReal* hfNorms = (PxReal*)SAMPLE_ALLOC(sizeof(PxReal)*hfNumVerts*3);
+ const PxU32 hfNumTris = (hfSize-1)*(hfSize-1)*2;
+ PxU32* hfTris = (PxU32*)SAMPLE_ALLOC(sizeof(PxU32)*hfNumTris*3);
+
+ createLandscape(heightmap,hfSize,hfScale,hfVerts,hfNorms,hfTris);
+
+ RAWMesh data;
+ data.mName = "terrain";
+ data.mTransform = PxTransform(PxIdentity);
+ data.mTransform.p = PxVec3(-(hfSize/2*hfScale),0,-(hfSize/2*hfScale));
+ data.mNbVerts = hfNumVerts;
+ data.mVerts = (PxVec3*)hfVerts;
+ data.mVertexNormals = (PxVec3*)hfNorms;
+ data.mUVs = 0;
+ data.mMaterialID = 0;
+ data.mNbFaces = hfNumTris;
+ data.mIndices = hfTris;
+
+ createRenderMeshFromRawMesh(data);
+
+ mNbVerts = hfNumVerts;
+ mNbTris = hfNumTris;
+ mVerts = hfVerts;
+ mTris = hfTris;
+
+ SAMPLE_FREE(hfNorms);
+ }
+
+ // eventually create the physics heightfield
+ PxRigidStatic* hfActor = createHeightField(heightmap,hfScale,hfSize);
+
+ SAMPLE_FREE(heightmap);
+
+ return hfActor;
+}
+
+void SampleCharacterCloth::createLandscape(PxReal* heightmap, PxU32 width, PxReal hfScale, PxReal* outVerts, PxReal* outNorms, PxU32* outTris)
+{
+ for(PxU32 y=0; y<width; y++)
+ {
+ for(PxU32 x=0; x<width; x++)
+ {
+ PxU32 index=(x+y*width)*3;
+
+ outVerts[index+0]=(PxReal(x))* hfScale;
+ outVerts[index+1]=heightmap[x+y*width];
+ outVerts[index+2]=(PxReal(y))*hfScale;
+
+ outNorms[index+0]=0;
+ outNorms[index+1]=1;
+ outNorms[index+2]=0;
+ }
+ }
+
+ // Sobel filter
+ for (PxU32 y=1;y<width-1;y++) {
+ for (PxU32 x=1;x<width-1;x++) {
+
+ // 1 0 -1
+ // 2 0 -2
+ // 1 0 -1
+ PxReal dx;
+ dx = outVerts[((x-1)+(y-1)*width)*3+1];
+ dx -= outVerts[((x+1)+(y-1)*width)*3+1];
+ dx += 2.0f*outVerts[((x-1)+(y+0)*width)*3+1];
+ dx -= 2.0f*outVerts[((x+1)+(y+0)*width)*3+1];
+ dx += outVerts[((x-1)+(y+1)*width)*3+1];
+ dx -= outVerts[((x+1)+(y+1)*width)*3+1];
+
+ // 1 2 1
+ // 0 0 0
+ // -1 -2 -1
+ PxReal dy;
+ dy = outVerts[((x-1)+(y-1)*width)*3+1];
+ dy += 2.0f*outVerts[((x+0)+(y-1)*width)*3+1];
+ dy += outVerts[((x+1)+(y-1)*width)*3+1];
+ dy -= outVerts[((x-1)+(y+1)*width)*3+1];
+ dy -= 2.0f*outVerts[((x+0)+(y+1)*width)*3+1];
+ dy -= outVerts[((x+1)+(y+1)*width)*3+1];
+
+ PxReal nx = dx/hfScale*0.15f;
+ PxReal ny = 1.0f;
+ PxReal nz = dy/hfScale*0.15f;
+
+ PxReal len = sqrtf(nx*nx+ny*ny+nz*nz);
+
+ outNorms[(x+y*width)*3+0] = nx/len;
+ outNorms[(x+y*width)*3+1] = ny/len;
+ outNorms[(x+y*width)*3+2] = nz/len;
+ }
+ }
+
+ PxU32 numTris = 0;
+ for(PxU32 j=0; j<width-1; j++)
+ {
+ for(PxU32 i=0; i<width-1; i++)
+ {
+ outTris[3*numTris+0]= i + j *(width);
+ outTris[3*numTris+1]= i + (j+1)*(width);
+ outTris[3*numTris+2]= i+1 + j *(width);
+ outTris[3*numTris+3]= i + (j+1)*(width);
+ outTris[3*numTris+4]= i+1 + (j+1)*(width);
+ outTris[3*numTris+5]= i+1 + j *(width);
+ numTris+=2;
+ }
+ }
+}
+
+PxRigidStatic* SampleCharacterCloth::createHeightField(PxReal* heightmap, PxReal hfScale, PxU32 hfSize)
+{
+ const PxReal heightScale = 0.01f;
+
+ PxU32 hfNumVerts = hfSize*hfSize;
+
+ PxHeightFieldSample* samples = (PxHeightFieldSample*)SAMPLE_ALLOC(sizeof(PxHeightFieldSample)*hfNumVerts);
+ memset(samples,0,hfNumVerts*sizeof(PxHeightFieldSample));
+
+ for(PxU32 x = 0; x < hfSize; x++)
+ for(PxU32 y = 0; y < hfSize; y++)
+ {
+ PxI32 h = PxI32(heightmap[y+x*hfSize]/heightScale);
+ PX_ASSERT(h<=0xffff);
+ samples[x+y*hfSize].height = (PxI16)(h);
+ samples[x+y*hfSize].setTessFlag();
+ samples[x+y*hfSize].materialIndex0=1;
+ samples[x+y*hfSize].materialIndex1=1;
+ }
+
+ PxHeightFieldDesc hfDesc;
+ hfDesc.format = PxHeightFieldFormat::eS16_TM;
+ hfDesc.nbColumns = hfSize;
+ hfDesc.nbRows = hfSize;
+ hfDesc.samples.data = samples;
+ hfDesc.samples.stride = sizeof(PxHeightFieldSample);
+
+ PxHeightField* heightField = getCooking().createHeightField(hfDesc, getPhysics().getPhysicsInsertionCallback());
+ if(!heightField)
+ fatalError("creating the heightfield failed");
+
+ PxTransform pose = PxTransform(PxIdentity);
+ pose.p = PxVec3(-(hfSize/2*hfScale),0,-(hfSize/2*hfScale));
+ mHFPose = pose;
+
+ PxRigidStatic* hfActor = getPhysics().createRigidStatic(pose);
+ if(!hfActor)
+ fatalError("creating heightfield actor failed");
+
+ PxHeightFieldGeometry hfGeom(heightField, PxMeshGeometryFlags(), heightScale, hfScale, hfScale);
+ PxShape* hfShape = PxRigidActorExt::createExclusiveShape(*hfActor, hfGeom, getDefaultMaterial());
+ if(!hfShape)
+ fatalError("creating heightfield shape failed");
+
+ getActiveScene().addActor(*hfActor);
+
+ SAMPLE_FREE(samples);
+
+ return hfActor;
+}
+