aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Samples/SampleNorthPole
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Samples/SampleNorthPole
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'PhysX_3.4/Samples/SampleNorthPole')
-rw-r--r--PhysX_3.4/Samples/SampleNorthPole/SampleNorthPole.cpp238
-rw-r--r--PhysX_3.4/Samples/SampleNorthPole/SampleNorthPole.h196
-rw-r--r--PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleBuilder.cpp450
-rw-r--r--PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCCT.cpp225
-rw-r--r--PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCameraController.cpp221
-rw-r--r--PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCameraController.h69
-rw-r--r--PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleDynamics.cpp401
-rw-r--r--PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleFilterShader.cpp127
-rw-r--r--PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleInputEventIds.h46
9 files changed, 1973 insertions, 0 deletions
diff --git a/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPole.cpp b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPole.cpp
new file mode 100644
index 00000000..21e4244d
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPole.cpp
@@ -0,0 +1,238 @@
+// 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 "characterkinematic/PxControllerManager.h"
+
+#include "PxPhysicsAPI.h"
+
+#include "SampleNorthPole.h"
+#include "SampleNorthPoleCameraController.h"
+
+#include "SampleUtils.h"
+#include "SampleCommandLine.h"
+#include "SampleAllocatorSDKClasses.h"
+#include "RendererMemoryMacros.h"
+#include "RenderMaterial.h"
+#include "SampleNorthPoleInputEventIds.h"
+
+#include <SamplePlatform.h>
+#include <SampleUserInput.h>
+
+REGISTER_SAMPLE(SampleNorthPole, "SampleNorthPole")
+
+using namespace SampleFramework;
+using namespace SampleRenderer;
+
+///////////////////////////////////////////////////////////////////////////////
+
+SampleNorthPole::SampleNorthPole(PhysXSampleApplication& app) :
+ PhysXSample (app),
+ mNorthPoleCamera (NULL),
+ mController (NULL),
+ mControllerManager (NULL),
+ mDoStandup (false)
+{
+ mCreateGroundPlane = false;
+ //mStepperType = FIXED_STEPPER;
+ mStandingSize = 1.0f;
+ mCrouchingSize = 0.20f;
+ mControllerRadius = 0.3f;
+ mControllerInitialPosition = PxExtendedVec3(5,mStandingSize,5);
+
+ memset(mSnowBalls,0,sizeof(mSnowBalls));
+ memset(mSnowBallsRenderActors,0,sizeof(mSnowBallsRenderActors));
+}
+
+SampleNorthPole::~SampleNorthPole()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SampleNorthPole::customizeSample(SampleSetup& setup)
+{
+ setup.mName = "SampleNorthPole";
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SampleNorthPole::onInit()
+{
+ PhysXSample::onInit();
+
+ PxSceneWriteLock scopedLock(*mScene);
+
+ mApplication.setMouseCursorHiding(true);
+ mApplication.setMouseCursorRecentering(true);
+
+ getRenderer()->setAmbientColor(RendererColor(100, 100, 100));
+
+ // some colors for the rendering
+ mSnowMaterial = SAMPLE_NEW(RenderMaterial)(*getRenderer(), PxVec3(0.85f, 0.85f, 0.95f), 1.0f, false, 0, NULL);
+ mCarrotMaterial = SAMPLE_NEW(RenderMaterial)(*getRenderer(), PxVec3(1.00f, 0.50f, 0.00f), 1.0f, false, 1, NULL);
+ mButtonMaterial = SAMPLE_NEW(RenderMaterial)(*getRenderer(), PxVec3(0.00f, 0.00f, 0.00f), 1.0f, false, 2, NULL);
+
+ mRenderMaterials.push_back(mSnowMaterial);
+ mRenderMaterials.push_back(mCarrotMaterial);
+ mRenderMaterials.push_back(mButtonMaterial);
+
+
+ // PhysX
+ buildHeightField();
+ buildIglooTriMesh();
+
+ // add some stand-up characters
+ cookCarrotConvexMesh();
+
+ createSnowMen();
+
+ mControllerManager = PxCreateControllerManager(getActiveScene());
+
+ mController = createCharacter(mControllerInitialPosition);
+
+ mNorthPoleCamera = SAMPLE_NEW(SampleNorthPoleCameraController)(*mController,*this);
+ setCameraController(mNorthPoleCamera);
+
+ mNorthPoleCamera->setView(0,0);
+}
+
+void SampleNorthPole::onShutdown()
+{
+ {
+ PxSceneWriteLock scopedLock(*mScene);
+ DELETESINGLE(mNorthPoleCamera);
+ mControllerManager->release();
+ }
+
+ PhysXSample::onShutdown();
+}
+
+void SampleNorthPole::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 crouch", CROUCH, -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 throw a ball", THROW_BALL, -1);
+ if(msg)
+ renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor);
+}
+
+void SampleNorthPole::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 creation of dynamic objects (snowmen) with";
+ char line1[256]="multiple shapes. The snowmen, though visibly identical, are configured";
+ char line2[256]="with different masses, inertias and centres of mass in order to show how";
+ char line3[256]="to set up these properties using the sdk, and the effect they have on";
+ char line4[256]="behavior. A technical description of the snowmen's rigid body properties";
+ char line5[256]="can be found in the PhysX Guide documentation in Rigid Body Dynamics:";
+ char line6[256]="Mass Properties. The sample also introduces contact notification reports as";
+ char line7[256]="a mechanism to detach snowman body parts, and applies ccd flags in order";
+ char line8[256]="to prevent small objects such as snowballs and detached snowman body parts ";
+ char line9[256]="from tunneling through collision geometry.";
+
+ 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);
+ renderer->print(x, y+=yInc, line7, scale, shadowOffset, textColor);
+ renderer->print(x, y+=yInc, line8, scale, shadowOffset, textColor);
+ renderer->print(x, y+=yInc, line9, scale, shadowOffset, textColor);
+ }
+}
+
+void SampleNorthPole::onTickPreRender(PxReal dtime)
+{
+ if(mDoStandup)
+ tryStandup();
+
+ PhysXSample::onTickPreRender(dtime);
+}
+
+void SampleNorthPole::onSubstep(float dtime)
+{
+ detach();
+}
+
+void SampleNorthPole::onPointerInputEvent(const SampleFramework::InputEvent& ie, physx::PxU32 x, physx::PxU32 y, physx::PxReal dx, physx::PxReal dy, bool val)
+{
+ if((ie.m_Id == THROW_BALL) && val)
+ {
+ throwBall();
+ }
+
+ if((ie.m_Id == RAYCAST_HIT) && val)
+ {
+ PxRaycastBuffer hit;
+ getActiveScene().raycast(getCamera().getPos()+getCamera().getViewDir(), getCamera().getViewDir(), 1.0f, hit);
+ shdfnd::printFormatted("hits: %p\n",hit.block.shape);
+ }
+
+ PhysXSample::onPointerInputEvent(ie,x,y,dx,dy,val);
+}
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPole.h b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPole.h
new file mode 100644
index 00000000..e271442e
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPole.h
@@ -0,0 +1,196 @@
+// 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_NORTHPOLE_H
+#define SAMPLE_NORTHPOLE_H
+
+#include "PhysXSample.h"
+#include "PxSimulationEventCallback.h"
+#include "characterkinematic/PxController.h" // for PxUserControllerHitReport
+#include "characterkinematic/PxControllerBehavior.h"
+#include "PxShape.h"
+
+namespace physx
+{
+ class PxCapsuleController;
+ class PxControllerManager;
+}
+
+class SampleNorthPoleCameraController;
+
+#define NUM_SNOWMEN 10
+#define NUM_BALLS 50
+
+struct SnowMan
+{
+ PxShape* eyeL;
+ PxShape* eyeR;
+
+ void changeMood()
+ {
+ PxTransform tl = eyeL->getLocalPose();
+ PxTransform tr = eyeR->getLocalPose();
+
+ eyeL->setLocalPose(PxTransform(tl.p,tr.q));
+ eyeR->setLocalPose(PxTransform(tr.p,tl.q));
+ }
+};
+
+class SampleNorthPole : public PhysXSample,
+ public PxSimulationEventCallback,
+ public PxUserControllerHitReport,
+ public PxControllerBehaviorCallback
+ {
+ public:
+ SampleNorthPole(PhysXSampleApplication& app);
+ virtual ~SampleNorthPole();
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Implements SampleApplication
+ virtual void onInit();
+ virtual void onInit(bool restart) { onInit(); }
+ virtual void onShutdown();
+ virtual void onTickPreRender(PxReal 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);
+ virtual void collectInputEvents(std::vector<const SampleFramework::InputEvent*>& inputEvents);
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Implements PhysXSampleApplication
+ virtual void helpRender(PxU32 x, PxU32 y, PxU8 textAlpha);
+ virtual void descriptionRender(PxU32 x, PxU32 y, PxU8 textAlpha);
+ virtual void customizeSample(SampleSetup&);
+ virtual void customizeSceneDesc(PxSceneDesc&);
+ virtual void onSubstep(float dtime);
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Implements PxSimulationEventCallback
+ virtual void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs);
+ virtual void onTrigger(PxTriggerPair*, PxU32) {}
+ virtual void onConstraintBreak(PxConstraintInfo*, PxU32) {}
+ virtual void onWake(PxActor** , PxU32 ) {}
+ virtual void onSleep(PxActor** , PxU32 ){}
+ virtual void onAdvance(const PxRigidBody*const*, const PxTransform*, const PxU32) {}
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // 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&) { return PxControllerBehaviorFlags(0); }
+ virtual PxControllerBehaviorFlags getBehaviorFlags(const PxController&) { return PxControllerBehaviorFlags(0); }
+ virtual PxControllerBehaviorFlags getBehaviorFlags(const PxObstacle&) { return PxControllerBehaviorFlags(0); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Implements PxSimulationFilterShader
+ static PxFilterFlags filter( PxFilterObjectAttributes attributes0,
+ PxFilterData filterData0,
+ PxFilterObjectAttributes attributes1,
+ PxFilterData filterData1,
+ PxPairFlags& pairFlags,
+ const void* constantBlock,
+ PxU32 constantBlockSize);
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // dynamics
+ enum
+ {
+ CCD_FLAG = 1<<29,
+ SNOWBALL_FLAG = 1<<30,
+ DETACHABLE_FLAG = 1<<31
+ };
+
+ void cookCarrotConvexMesh();
+ PxConvexMesh* mCarrotConvex;
+
+ PxRigidDynamic* throwBall();
+ PxRigidDynamic* mSnowBalls[NUM_BALLS];
+ RenderBaseActor* mSnowBallsRenderActors[NUM_BALLS];
+
+ void createSnowMen();
+ PxRigidDynamic* createSnowMan(const PxTransform& pos, const PxU32 mode, const PxU32 index);
+ SnowMan mSnowman[NUM_SNOWMEN+1]; // 1 extra so that NUM_SNOWMEN can be set to 0 for debugging
+
+ void resetScene();
+
+ static void setSnowball(PxShape& shape);
+ static void setDetachable(PxShape& shape);
+ static bool isDetachable(PxFilterData& filterData);
+ static bool needsContactReport(const PxFilterData& filterData0, const PxFilterData& filterData1);
+ static void setCCDActive(PxShape& shape, PxRigidBody* rigidBody);
+ static bool isCCDActive(PxFilterData& filterData);
+ void detach();
+ std::vector<PxShape*> mDetaching;
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // static landscape
+ std::vector<PxVec3> mVerts;
+ std::vector<PxVec3> mNorms;
+ std::vector<PxU32> mTris;
+
+ PxRigidStatic* buildIglooTriMesh();
+ void addBlock(PxVec3 blockVerts[8]);
+
+ PxRigidStatic* buildHeightField();
+ void createLandscape(PxReal* heightmap, PxU32 size, PxReal scale, PxReal* outVerts, PxReal* outNorms, PxU32* outTris);
+ PxRigidStatic* createHeightField(PxReal* heightmap, PxReal scale, PxU32 size);
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Camera and Controller
+ SampleNorthPoleCameraController* mNorthPoleCamera;
+ PxCapsuleController* mController;
+ PxControllerManager* mControllerManager;
+ PxExtendedVec3 mControllerInitialPosition;
+ bool mDoStandup;
+ PxReal mControllerRadius;
+ PxReal mStandingSize;
+ PxReal mCrouchingSize;
+ PxCapsuleController* createCharacter(const PxExtendedVec3& position);
+ void tryStandup();
+ void resizeController(PxReal height);
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // rendering
+ RenderMaterial* mSnowMaterial;
+ RenderMaterial* mCarrotMaterial;
+ RenderMaterial* mButtonMaterial;
+ };
+
+#endif
diff --git a/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleBuilder.cpp b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleBuilder.cpp
new file mode 100644
index 00000000..a50d65e5
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleBuilder.cpp
@@ -0,0 +1,450 @@
+// 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 "SampleNorthPole.h"
+
+using namespace PxToolkit;
+
+#define USE_MESH_LANDSCAPE // PT: define this to use a triangle mesh for the landscape, instead of a heightfield
+
+static PxReal randomScaled(PxReal value)
+{
+ PxReal val = value*(getSampleRandom().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* SampleNorthPole::buildHeightField()
+{
+ // create a height map
+
+ PxU32 hfSize = 32; // some power of 2
+ PxU32 hfNumVerts = hfSize*hfSize;
+
+ PxReal hfScale = 8.0f; // this is how wide one heightfield square is
+
+ PxReal* heightmap = (PxReal*)SAMPLE_ALLOC(sizeof(PxReal)*hfNumVerts);
+ for(PxU32 i = 0; i < hfNumVerts; i++)
+ heightmap[i]=-9.0f;
+
+ getSampleRandom().setSeed(42);
+ fractalize(heightmap,hfSize,16);
+
+ { // make a plateau to place the igloo
+ const PxU32 i = hfSize*hfSize/2+hfSize/2;
+ PxReal h = 0;
+ heightmap[i-hfSize-1]=h; heightmap[i-hfSize]=h; heightmap[i-hfSize+1]=h;
+ heightmap[i-1]=h; heightmap[i]=h; heightmap[i+1]=h;
+ heightmap[i+hfSize-1]=h; heightmap[i+hfSize]=h; heightmap[i+hfSize+1]=h;
+ }
+
+ { // make render terrain
+ PxReal* hfVerts = (PxReal*)SAMPLE_ALLOC(sizeof(PxReal)*hfNumVerts*3);
+ PxReal* hfNorms = (PxReal*)SAMPLE_ALLOC(sizeof(PxReal)*hfNumVerts*3);
+ 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;
+#ifdef USE_MESH_LANDSCAPE
+ setFilename(getSampleMediaFilename("SampleNorthPole_Mesh"));
+ newMesh(data);
+#else
+ createRenderMeshFromRawMesh(data);
+#endif
+ SAMPLE_FREE(hfTris);
+ SAMPLE_FREE(hfNorms);
+ SAMPLE_FREE(hfVerts);
+ }
+
+#ifndef USE_MESH_LANDSCAPE
+ // eventually create the physics heightfield
+ PxRigidStatic* hfActor = createHeightField(heightmap,hfScale,hfSize);
+#endif
+
+ SAMPLE_FREE(heightmap);
+#ifdef USE_MESH_LANDSCAPE
+ return 0;
+#else
+ return hfActor;
+#endif
+}
+
+void SampleNorthPole::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* SampleNorthPole::createHeightField(PxReal* heightmap, PxReal hfScale, PxU32 hfSize)
+{
+ const PxReal heightScale = 0.001f;
+
+ 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++)
+ {
+ samples[x+y*hfSize].height = (PxI16)(heightmap[y+x*hfSize]/heightScale);
+ 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));
+
+ 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());
+ //setCCDActive(*hfShape);
+ if(!hfShape)
+ fatalError("creating heightfield shape failed");
+
+ getActiveScene().addActor(*hfActor);
+
+ SAMPLE_FREE(samples);
+
+ return hfActor;
+}
+
+
+PxRigidStatic* SampleNorthPole::buildIglooTriMesh()
+{
+ { // construct the mesh data
+ const PxReal innerR = 2.7;
+ const PxReal outerR = 3;
+ const PxU32 numBlocks = 16;
+ const PxU32 numRows = 8;
+ const PxU32 doorHeight = 2;
+ const PxReal accesslength = outerR*1.2f;
+ const PxReal step = PxPi*2/numBlocks;
+ const PxReal step2 = PxPi/2/numRows;
+ const PxReal thickness = (outerR - innerR);
+
+ const PxVec3 initpos(1,0,0);
+
+ const PxU32 n = 2*numBlocks;
+ PxVec3 bufferVerts[2][n+2];
+ PxU32 buf = 0;
+
+ PxVec3* currentVerts = bufferVerts[buf];
+
+ for(int i = 0; i < (int)numBlocks; i++)
+ {
+ PxQuat rotY(i*step-step/2,PxVec3(0,1,0));
+ PxVec3 pos = rotY.rotate(initpos);
+ currentVerts[2*i] = pos*innerR;
+ currentVerts[2*i+1] = pos*outerR;
+ }
+ currentVerts[n] = currentVerts[0];
+ currentVerts[n+1] = currentVerts[1];
+
+ for(int j = 0; j < (int)numRows; j++)
+ {
+ PxVec3* previousVerts = currentVerts;
+ currentVerts = bufferVerts[buf=1-buf];
+
+ PxQuat rotZ((j+1)*step2,PxVec3(0,0,1));
+ PxVec3 posX = rotZ.rotate(initpos);
+
+ for(int i = 0; i < (int)numBlocks; i++)
+ {
+ PxQuat rotY(i*step-step/2,PxVec3(0,1,0));
+ PxVec3 pos = rotY.rotate(posX);
+ currentVerts[2*i] = pos*innerR;
+ currentVerts[2*i+1] = pos*outerR;
+ }
+ currentVerts[n] = currentVerts[0];
+ currentVerts[n+1] = currentVerts[1];
+
+ for(int i = 0; i < (int)numBlocks; i++)
+ {
+ if( (i==0 && (j<(int)doorHeight)) || (i==numBlocks/3 && j==numRows/2) )
+ {
+ // omit the door and window
+ continue;
+ }
+
+ PxVec3 block[8] =
+ {
+ previousVerts[2*i],previousVerts[2*i+1],previousVerts[2*i+2],previousVerts[2*i+3],
+ currentVerts[2*i], currentVerts[2*i+1], currentVerts[2*i+2], currentVerts[2*i+3]
+ };
+
+ addBlock(block);
+ }
+ }
+
+ PxQuat rotZ((doorHeight)*step2,PxVec3(0,0,1));
+ PxQuat rotY(step/2,PxVec3(0,1,0));
+
+ PxVec3 topIL = rotY.rotate(rotZ.rotate(initpos))*innerR;
+ PxVec3 topIR = rotY.rotateInv(rotZ.rotate(initpos))*innerR;
+
+ PxVec3 topOL = topIL; topOL.x = accesslength;
+ PxVec3 topOR = topIR; topOR.x = accesslength;
+
+ PxVec3 bottomIL = rotY.rotate(initpos)*innerR;
+ PxVec3 bottomIR = rotY.rotateInv(initpos)*innerR;
+
+ PxVec3 bottomOL = topOL; bottomOL.y = 0;
+ PxVec3 bottomOR = topOR; bottomOR.y = 0;
+
+ PxVec3 dZ = PxVec3(0,0,thickness);
+ PxVec3 dY = PxVec3(0,thickness,0);
+
+ PxVec3 blockL[8] =
+ {
+ bottomIL, bottomOL, bottomIL-dZ, bottomOL-dZ,
+ topIL, topOL, topIL-dZ, topOL-dZ
+ };
+ addBlock(blockL);
+
+ PxVec3 blockR[8] =
+ {
+ bottomIR+dZ, bottomOR+dZ, bottomIR, bottomOR,
+ topIR+dZ, topOR+dZ, topIR, topOR
+ };
+ addBlock(blockR);
+
+ PxVec3 blockT[8] =
+ {
+ topIR+dZ, topOR+dZ, topIL-dZ, topOL-dZ,
+ topIR+dY, topOR+dY, topIL+dY, topOL+dY
+ };
+ addBlock(blockT);
+ }
+
+ const PxU32 numTris = (PxU32)(mTris.size()/3);
+ const PxU32 numVerts = (PxU32)(mVerts.size());
+
+ // make render mesh
+ RAWMesh data;
+ data.mIndices = &mTris[0];
+ data.mNbFaces = numTris;
+ data.mVerts = &mVerts[0];
+ data.mNbVerts = numVerts;
+ data.mVertexNormals = &mVerts[0];
+ data.mMaterialID = 0;
+ data.mTransform = PxTransform(PxVec3(0,0,0));
+ createRenderMeshFromRawMesh(data);
+
+ PxTriangleMesh* triMesh = PxToolkit::createTriangleMesh32(getPhysics(), getCooking(), &mVerts[0], numVerts, &mTris[0], numTris);
+ if(!triMesh)
+ fatalError("creating the triangle mesh failed");
+
+ mVerts.clear();
+ mTris.clear();
+ mNorms.clear();
+
+ // create actor
+ PxRigidStatic* iglooActor = getPhysics().createRigidStatic(PxTransform(PxVec3(0,0,0)));
+ if(!iglooActor)
+ fatalError("creating igloo actor failed");
+
+ PxTriangleMeshGeometry geom(triMesh);
+ PxShape* iglooShape = PxRigidActorExt::createExclusiveShape(*iglooActor, geom,getDefaultMaterial());
+ if(!iglooShape)
+ fatalError("creating igloo shape failed");
+
+ //setCCDActive(*iglooShape);
+
+ getActiveScene().addActor(*iglooActor);
+
+ return iglooActor;
+}
+
+void SampleNorthPole::addBlock(PxVec3 blockVerts[8])
+{
+ PxU32 n = 8;
+ PxVec3* v = blockVerts;
+ const PxU32 offset = (PxU32)mVerts.size();
+
+ while(n--)
+ mVerts.push_back(*v++);
+
+ // bottom
+ mTris.push_back(0 + offset); mTris.push_back(3 + offset); mTris.push_back(1 + offset);
+ mTris.push_back(0 + offset); mTris.push_back(2 + offset); mTris.push_back(3 + offset);
+ // top
+ mTris.push_back(4 + offset); mTris.push_back(5 + offset); mTris.push_back(7 + offset);
+ mTris.push_back(4 + offset); mTris.push_back(7 + offset); mTris.push_back(6 + offset);
+ // right
+ mTris.push_back(0 + offset); mTris.push_back(1 + offset); mTris.push_back(4 + offset);
+ mTris.push_back(5 + offset); mTris.push_back(4 + offset); mTris.push_back(1 + offset);
+ // left
+ mTris.push_back(6 + offset); mTris.push_back(7 + offset); mTris.push_back(2 + offset);
+ mTris.push_back(3 + offset); mTris.push_back(2 + offset); mTris.push_back(7 + offset);
+ // front
+ mTris.push_back(5 + offset); mTris.push_back(1 + offset); mTris.push_back(7 + offset);
+ mTris.push_back(3 + offset); mTris.push_back(7 + offset); mTris.push_back(1 + offset);
+ // back
+ mTris.push_back(4 + offset); mTris.push_back(6 + offset); mTris.push_back(0 + offset);
+ mTris.push_back(2 + offset); mTris.push_back(0 + offset); mTris.push_back(6 + offset);
+}
+
+
+
+
+
diff --git a/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCCT.cpp b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCCT.cpp
new file mode 100644
index 00000000..34e87923
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCCT.cpp
@@ -0,0 +1,225 @@
+// 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.
+
+#include "PxPhysicsAPI.h"
+#include "extensions/PxExtensionsAPI.h"
+
+#include "characterkinematic/PxControllerManager.h"
+#include "characterkinematic/PxCapsuleController.h"
+
+#include "SampleNorthPole.h"
+#include "SampleNorthPoleCameraController.h"
+#include "SampleNorthPoleInputEventIds.h"
+#include <SamplePlatform.h>
+#include <SampleUserInput.h>
+#include <SampleUserInputIds.h>
+#include <SampleUserInputDefines.h>
+
+using namespace SampleRenderer;
+using namespace SampleFramework;
+
+void SampleNorthPole::tryStandup()
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ // overlap with upper part
+ PxReal r = mController->getRadius();
+ PxReal dh = mStandingSize-mCrouchingSize-2*r;
+ PxCapsuleGeometry geom(r, dh*.5f);
+
+ PxExtendedVec3 position = mController->getPosition();
+ PxVec3 pos((float)position.x,(float)position.y+mStandingSize*.5f+r,(float)position.z);
+ PxQuat orientation(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f));
+
+ PxOverlapBuffer hit;
+ if(getActiveScene().overlap(geom, PxTransform(pos,orientation),hit,
+ PxQueryFilterData(PxQueryFlag::eANY_HIT|PxQueryFlag::eSTATIC|PxQueryFlag::eDYNAMIC)))
+ return;
+
+ // if no hit, we can stand up
+ resizeController(mStandingSize);
+ mDoStandup = false;
+}
+
+void SampleNorthPole::resizeController(PxReal height)
+{
+ PxSceneWriteLock scopedLock(*mScene);
+ mController->resize(height);
+}
+
+PxCapsuleController* SampleNorthPole::createCharacter(const PxExtendedVec3& position)
+{
+ PxCapsuleControllerDesc cDesc;
+ cDesc.material = &getDefaultMaterial();
+ cDesc.position = position;
+ cDesc.height = mStandingSize;
+ cDesc.radius = mControllerRadius;
+ cDesc.slopeLimit = 0.0f;
+ cDesc.contactOffset = 0.1f;
+ cDesc.stepOffset = 0.02f;
+ cDesc.reportCallback = this;
+ cDesc.behaviorCallback = this;
+
+ mControllerInitialPosition = cDesc.position;
+
+ PxCapsuleController* ctrl = static_cast<PxCapsuleController*>(mControllerManager->createController(cDesc));
+
+ // remove controller shape from scene query for standup overlap test
+ PxRigidDynamic* actor = ctrl->getActor();
+ if(actor)
+ {
+ if(actor->getNbShapes())
+ {
+ PxShape* ctrlShape;
+ actor->getShapes(&ctrlShape,1);
+ ctrlShape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE,false);
+ }
+ else
+ fatalError("character actor has no shape");
+ }
+ else
+ fatalError("character could not create actor");
+
+ // uncomment the next line to render the character
+ //createRenderObjectsFromActor(ctrl->getActor());
+
+ return ctrl;
+}
+
+
+void SampleNorthPole::onShapeHit(const PxControllerShapeHit& hit)
+{
+ PxRigidDynamic* actor = hit.shape->getActor()->is<PxRigidDynamic>();
+ if(actor)
+ {
+ // We only allow horizontal pushes. Vertical pushes when we stand on dynamic objects creates
+ // useless stress on the solver. It would be possible to enable/disable vertical pushes on
+ // particular objects, if the gameplay requires it.
+ if(hit.dir.y==0.0f)
+ {
+ PxReal coeff = actor->getMass() * hit.length;
+ PxRigidBodyExt::addForceAtLocalPos(*actor,hit.dir*coeff, PxVec3(0,0,0), PxForceMode::eIMPULSE);
+ }
+ }
+}
+
+void SampleNorthPole::resetScene()
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ mController->setPosition(mControllerInitialPosition);
+ mNorthPoleCamera->setView(0,0);
+
+ while(mPhysicsActors.size())
+ {
+ PxRigidActor* actor = mPhysicsActors.back();
+ removeActor(actor);
+ }
+
+ createSnowMen();
+ buildHeightField();
+
+ for(unsigned int b = 0; b < NUM_BALLS; b++)
+ {
+ PxRigidDynamic* ball = mSnowBalls[b];
+ if(ball)
+ {
+ removeActor(ball);
+ ball->release();
+ mSnowBalls[b] = 0;
+
+ // render actor is released inside of removeActor()
+ mSnowBallsRenderActors[b] = 0;
+ }
+ }
+}
+
+void SampleNorthPole::collectInputEvents(std::vector<const SampleFramework::InputEvent*>& inputEvents)
+{
+ PhysXSample::collectInputEvents(inputEvents);
+
+ getApplication().getPlatform()->getSampleUserInput()->unregisterInputEvent(SPAWN_DEBUG_OBJECT);
+ getApplication().getPlatform()->getSampleUserInput()->unregisterInputEvent(CAMERA_MOVE_BUTTON);
+
+ //digital keyboard events
+ DIGITAL_INPUT_EVENT_DEF(CROUCH, SCAN_CODE_DOWN, XKEY_C, X1KEY_C, PS3KEY_C, PS4KEY_C, AKEY_UNKNOWN, SCAN_CODE_DOWN, IKEY_UNKNOWN, SCAN_CODE_DOWN, WIIUKEY_UNKNOWN);
+ 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 gamepad events
+ DIGITAL_INPUT_EVENT_DEF(CROUCH, GAMEPAD_WEST, GAMEPAD_WEST, GAMEPAD_WEST, GAMEPAD_WEST, GAMEPAD_WEST, AKEY_UNKNOWN, GAMEPAD_WEST, IKEY_UNKNOWN, LINUXKEY_UNKNOWN, GAMEPAD_WEST);
+ DIGITAL_INPUT_EVENT_DEF(RESET_SCENE, GAMEPAD_NORTH, GAMEPAD_NORTH, GAMEPAD_NORTH, GAMEPAD_NORTH, GAMEPAD_NORTH, KEY_UNKNOWN, GAMEPAD_NORTH, IKEY_UNKNOWN, LINUXKEY_UNKNOWN, GAMEPAD_NORTH);
+ DIGITAL_INPUT_EVENT_DEF(THROW_BALL, GAMEPAD_RIGHT_SHOULDER_BOT, GAMEPAD_RIGHT_SHOULDER_BOT, GAMEPAD_RIGHT_SHOULDER_BOT, GAMEPAD_RIGHT_SHOULDER_BOT, GAMEPAD_RIGHT_SHOULDER_BOT, AKEY_UNKNOWN, GAMEPAD_RIGHT_SHOULDER_BOT, IKEY_UNKNOWN, LINUXKEY_UNKNOWN, GAMEPAD_RIGHT_SHOULDER_BOT);
+
+ //digital mouse events
+ if (!isPaused())
+ {
+ DIGITAL_INPUT_EVENT_DEF(THROW_BALL, MOUSE_BUTTON_LEFT, XKEY_UNKNOWN, X1KEY_UNKNOWN, PS3KEY_UNKNOWN, PS4KEY_UNKNOWN, AKEY_UNKNOWN, MOUSE_BUTTON_LEFT, IKEY_UNKNOWN, MOUSE_BUTTON_LEFT, WIIUKEY_UNKNOWN);
+ }
+
+ //touch events
+ TOUCH_INPUT_EVENT_DEF(RESET_SCENE, "Reset", ABUTTON_5, IBUTTON_5);
+ TOUCH_INPUT_EVENT_DEF(CROUCH, "Crouch", ABUTTON_6, IBUTTON_6);
+ TOUCH_INPUT_EVENT_DEF(THROW_BALL, "Throw Ball", AQUICK_BUTTON_1, IQUICK_BUTTON_1);
+}
+
+void SampleNorthPole::onDigitalInputEvent(const SampleFramework::InputEvent& ie, bool val)
+{
+ switch (ie.m_Id)
+ {
+ case CROUCH:
+ {
+ if(val)
+ {
+ resizeController(mCrouchingSize);
+ }
+ else
+ {
+ mDoStandup = true;
+ }
+ }
+ break;
+ case RESET_SCENE:
+ {
+ if(val)
+ {
+ resetScene();
+ }
+ }
+ break;
+ case THROW_BALL:
+ {
+ if(val)
+ {
+ throwBall();
+ }
+ }
+ break;
+ }
+
+ PhysXSample::onDigitalInputEvent(ie,val);
+}
+
diff --git a/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCameraController.cpp b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCameraController.cpp
new file mode 100644
index 00000000..0fe2e83a
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCameraController.cpp
@@ -0,0 +1,221 @@
+// 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 "SampleNorthPole.h"
+#include "SampleNorthPoleCameraController.h"
+#include "PxRigidDynamic.h"
+#include "geometry/PxCapsuleGeometry.h"
+#include "PxShape.h"
+#include "characterkinematic/PxCapsuleController.h"
+#include <SampleBaseInputEventIds.h>
+#include <SamplePlatform.h>
+#include <SampleUserInput.h>
+#include <SampleUserInputIds.h>
+#include <SampleUserInputDefines.h>
+
+using namespace SampleRenderer;
+using namespace SampleFramework;
+
+SampleNorthPoleCameraController::SampleNorthPoleCameraController(PxCapsuleController& controlled, SampleNorthPole& base) :
+ mCCT (controlled),
+ mBase (base),
+ mTargetYaw (0.0f-PxPi/2),
+ mTargetPitch (0.0f),
+ mPitchMin (-PxHalfPi*.99f),
+ mPitchMax (PxHalfPi*.99f),
+ mGamepadPitchInc (0.0f),
+ mGamepadYawInc (0.0f),
+ mGamepadForwardInc (0.0f),
+ mGamepadLateralInc (0.0f),
+ mSensibility (0.001f),
+ mFwd (false),
+ mBwd (false),
+ mLeft (false),
+ mRight (false),
+ mKeyShiftDown (false),
+ mRunningSpeed (10.0f),
+ mWalkingSpeed (2.5f),
+ mFilterMemory (0.0f)
+{
+ mFilterMemory = float(computeCameraTarget().y);
+}
+
+void SampleNorthPoleCameraController::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);
+
+ //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);
+}
+
+void SampleNorthPoleCameraController::onDigitalInputEvent(const SampleFramework::InputEvent& ie, bool val)
+{
+ if(val)
+ {
+ if(ie.m_Id == CAMERA_MOVE_FORWARD) mFwd = true;
+ else if(ie.m_Id == CAMERA_MOVE_BACKWARD) mBwd = true;
+ else if(ie.m_Id == CAMERA_MOVE_LEFT) mLeft = true;
+ else if(ie.m_Id == CAMERA_MOVE_RIGHT) mRight = true;
+ else if(ie.m_Id == CAMERA_SHIFT_SPEED) mKeyShiftDown = true;
+ }
+ else
+ {
+ if(ie.m_Id == CAMERA_MOVE_FORWARD) mFwd = false;
+ else if(ie.m_Id == CAMERA_MOVE_BACKWARD) mBwd = false;
+ else if(ie.m_Id == CAMERA_MOVE_LEFT) mLeft = false;
+ else if(ie.m_Id == CAMERA_MOVE_RIGHT) mRight = false;
+ else if(ie.m_Id == CAMERA_SHIFT_SPEED) mKeyShiftDown = false;
+ }
+}
+
+static PX_FORCE_INLINE PxReal remapAxisValue(PxReal absolutePosition)
+{
+ return absolutePosition * absolutePosition * absolutePosition * 5.0f;
+}
+
+void SampleNorthPoleCameraController::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)
+ {
+ // PT: ideally we'd need an option to "invert Y axis" here
+// mGamepadPitchInc = - remapAxisValue(val);
+ 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 SampleNorthPoleCameraController::onPointerInputEvent(const SampleFramework::InputEvent &ie, physx::PxU32 x, physx::PxU32 y, physx::PxReal dx, physx::PxReal dy, bool val)
+{
+ if (ie.m_Id == CAMERA_MOUSE_LOOK)
+ {
+ mTargetYaw -= dx * mSensibility;
+ mTargetPitch += dy * mSensibility;
+ }
+}
+
+void SampleNorthPoleCameraController::setView(PxReal pitch, PxReal yaw)
+{
+ mTargetPitch = pitch;
+ mTargetYaw = yaw;
+}
+
+PxExtendedVec3 SampleNorthPoleCameraController::computeCameraTarget()
+{
+ PxRigidActor* characterActor = mCCT.getActor();
+ PxShape* shape;
+ characterActor->getShapes(&shape,1);
+ PxCapsuleGeometry geom;
+ shape->getCapsuleGeometry(geom);
+
+ const PxExtendedVec3 headPos = PxExtendedVec3(0,geom.halfHeight+geom.radius,0);
+ return mCCT.getPosition() + headPos;
+}
+
+static PX_INLINE float feedbackFilter(float val, float& memory, float sharpness)
+{
+ if(sharpness<0.0f) sharpness = 0.0f;
+ else if(sharpness>1.0f) sharpness = 1.0f;
+ return memory = val * sharpness + memory * (1.0f - sharpness);
+}
+
+void SampleNorthPoleCameraController::update(Camera& camera, PxReal dtime)
+{
+ PxSceneReadLock scopedLock(mBase.getActiveScene());
+
+ // Update CCT
+ if(!mBase.isPaused())
+ {
+ PxVec3 targetKeyDisplacement(0);
+ PxVec3 targetPadDisplacement(0);
+
+ PxVec3 forward = camera.getViewDir();
+ forward.y = 0;
+ forward.normalize();
+ PxVec3 up = PxVec3(0,1,0);
+ PxVec3 right = forward.cross(up);
+
+ if(mFwd) targetKeyDisplacement += forward;
+ if(mBwd) targetKeyDisplacement -= forward;
+
+ if(mRight) targetKeyDisplacement += right;
+ if(mLeft) targetKeyDisplacement -= right;
+
+ targetKeyDisplacement *= mKeyShiftDown ? mRunningSpeed : mWalkingSpeed;
+ targetKeyDisplacement += PxVec3(0,-9.81,0);
+ targetKeyDisplacement *= dtime;
+
+ targetPadDisplacement += forward * mGamepadForwardInc * mRunningSpeed;
+ targetPadDisplacement += right * mGamepadLateralInc * mRunningSpeed;
+ targetPadDisplacement += PxVec3(0,-9.81,0);
+ targetPadDisplacement *= dtime;
+
+// PxU32 flags = mCCT.move(targetKeyDisplacement + targetPadDisplacement, 0.001f, dtime, PxControllerFilters(0));
+ PxU32 flags = mCCT.move(targetKeyDisplacement + targetPadDisplacement, 0.0f, dtime, PxControllerFilters(0));
+ PX_UNUSED(flags);
+ }
+ // Update camera
+ {
+ mTargetYaw += mGamepadYawInc * dtime;
+ mTargetPitch += mGamepadPitchInc * dtime;
+
+ // Clamp pitch
+ if(mTargetPitch<mPitchMin) mTargetPitch = mPitchMin;
+ if(mTargetPitch>mPitchMax) mTargetPitch = mPitchMax;
+
+ camera.setRot(PxVec3(-mTargetPitch,-mTargetYaw,0));
+
+ PxExtendedVec3 camTarget = computeCameraTarget();
+ const float filteredHeight = feedbackFilter((float)camTarget.y, mFilterMemory, dtime*6.0f);
+ camTarget.y = filteredHeight;
+
+ const PxF32 distanceToTarget = 0.0f;
+ const PxVec3 target = toVec3(camTarget) - camera.getViewDir()*distanceToTarget;
+ camera.setPos(target);
+ }
+}
+
diff --git a/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCameraController.h b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCameraController.h
new file mode 100644
index 00000000..cfae8725
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleCameraController.h
@@ -0,0 +1,69 @@
+// 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 "PhysXSample.h"
+#include "SampleCameraController.h"
+#include "characterkinematic/PxController.h"
+
+class SampleNorthPoleCameraController : public CameraController
+{
+ public:
+ SampleNorthPoleCameraController(PxCapsuleController& controlled, SampleNorthPole& base);
+
+ virtual void onDigitalInputEvent(const SampleFramework::InputEvent& , bool val);
+ virtual void onAnalogInputEvent(const SampleFramework::InputEvent& , float val);
+ virtual void onPointerInputEvent(const SampleFramework::InputEvent&, PxU32 x, PxU32 y, PxReal dx, PxReal dy, bool val);
+
+ virtual void collectInputEvents(std::vector<const SampleFramework::InputEvent*>& inputEvents);
+
+ virtual void update(Camera& camera, PxReal dtime);
+
+ void setView(PxReal pitch, PxReal yaw);
+
+ private:
+ SampleNorthPoleCameraController& operator=(const SampleNorthPoleCameraController&);
+ PxExtendedVec3 computeCameraTarget();
+
+ PxCapsuleController& mCCT;
+ SampleNorthPole& mBase; // PT: TODO: find a way to decouple us from PhysXSampleApplication. Only needed for "recenterCursor". Maybe the app could inherit from the cam...
+
+ PxReal mTargetYaw, mTargetPitch;
+ PxReal mPitchMin, mPitchMax;
+
+ PxReal mGamepadPitchInc, mGamepadYawInc;
+ PxReal mGamepadForwardInc, mGamepadLateralInc;
+ PxReal mSensibility;
+
+ bool mFwd,mBwd,mLeft,mRight,mKeyShiftDown;
+
+ PxReal mRunningSpeed;
+ PxReal mWalkingSpeed;
+
+ PxF32 mFilterMemory;
+};
diff --git a/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleDynamics.cpp b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleDynamics.cpp
new file mode 100644
index 00000000..8cb7e798
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleDynamics.cpp
@@ -0,0 +1,401 @@
+// 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 "extensions/PxExtensionsAPI.h"
+#include "PxTkStream.h"
+#include "SampleNorthPole.h"
+#include "RenderBaseActor.h"
+
+using namespace PxToolkit;
+
+//#define USE_RAYCAST_CCD_FOR_SNOWBALLS
+
+void SampleNorthPole::detach()
+{
+ std::vector<PxShape*>::const_iterator ite;
+ for(ite=mDetaching.begin(); ite<mDetaching.end(); ++ite)
+ {
+ PxSceneWriteLock scopedLock(*mScene);
+
+ PxShape* shape = *ite;
+ PxRigidActor* actor = shape->getActor();
+
+ PxMaterial* mat;
+ shape->getMaterials(&mat,1);
+ PxGeometryHolder geometry = shape->getGeometry();
+ PxTransform newActorPose = PxShapeExt::getGlobalPose(*shape, *actor);
+
+ PxRigidDynamic* newActor = PxCreateDynamic(*mPhysics, newActorPose, geometry.any(), *mat, 1);
+ if(!newActor)
+ fatalError("creating detached actor failed");
+ getActiveScene().addActor(*newActor);
+ mPhysicsActors.push_back(newActor);
+
+ // the only convex shape is the nose, so we can just test the type
+ if(geometry.getType() == PxGeometryType::eCONVEXMESH)
+ {
+ newActor->addForce(PxVec3(0,.1,0),PxForceMode::eFORCE);
+ size_t index = reinterpret_cast<size_t>(actor->userData);
+ mSnowman[index].changeMood();
+ }
+
+ // reuse the old shape's rendering actor
+ RenderBaseActor* render = getRenderActor(actor, shape);
+ PxShape* newShape;
+ newActor->getShapes(&newShape,1);
+ unlink(render, shape, actor);
+ link(render, newShape, newActor);
+ setCCDActive(*newShape, newActor);
+
+ actor->detachShape(*shape);
+ }
+ mDetaching.clear();
+}
+
+void SampleNorthPole::cookCarrotConvexMesh()
+{
+ static const PxVec3 carrotVerts[] = {PxVec3(0,0,.3),PxVec3(.05,0,0),PxVec3(-.05,0,0),PxVec3(0,.05,0),PxVec3(0,-.05,0)};
+
+ mCarrotConvex = PxToolkit::createConvexMesh(getPhysics(), getCooking(), carrotVerts, 5, PxConvexFlag::eCOMPUTE_CONVEX);
+ if(!mCarrotConvex)
+ fatalError("creating the convex mesh failed");
+}
+
+PxRigidDynamic* SampleNorthPole::throwBall()
+{
+ PxSceneWriteLock scopedLock(*mScene);
+
+ static unsigned int numBall = 0;
+
+ PxVec3 vel = getCamera().getViewDir() * 20.0f;
+
+ PxRigidDynamic* ballActor = getPhysics().createRigidDynamic(PxTransform(getCamera().getPos()+getCamera().getViewDir()));
+ if(!ballActor)
+ fatalError("creating ball actor failed");
+
+ ballActor->setLinearVelocity(vel);
+
+ PxShape* ballShape = PxRigidActorExt::createExclusiveShape(*ballActor, PxSphereGeometry(0.1f),getDefaultMaterial());
+ if(!ballShape)
+ fatalError("creating ball shape failed");
+
+ setSnowball(*ballShape);
+
+ PxRigidBodyExt::updateMassAndInertia(*ballActor,1);
+
+#ifndef USE_RAYCAST_CCD_FOR_SNOWBALLS
+ setCCDActive(*ballShape, ballActor);
+#endif
+
+ getActiveScene().addActor(*ballActor);
+
+ RenderBaseActor* actor = mSnowBallsRenderActors[numBall];;
+ if(actor)
+ {
+ link(actor, ballShape, ballActor);
+ }
+ else
+ {
+ actor = createRenderObjectFromShape(ballActor, ballShape, mSnowMaterial);
+ mSnowBallsRenderActors[numBall] = actor;
+ }
+
+#ifdef USE_RAYCAST_CCD_FOR_SNOWBALLS
+ if(ballShape)
+ {
+ RenderBaseActor* renderActor = getRenderActor(ballActor, ballShape);
+ renderActor->setRaycastCCD(true);
+ }
+#endif
+
+ PxRigidDynamic* oldBall = mSnowBalls[numBall];
+
+ if(oldBall)
+ {
+ removeActor(oldBall);
+ oldBall->release();
+ }
+
+ mSnowBalls[numBall] = ballActor;
+ if(! (++numBall < NUM_BALLS))
+ numBall=0;
+
+ return ballActor;
+}
+
+void SampleNorthPole::createSnowMen()
+{
+ PxU32 numSnowmen = NUM_SNOWMEN; // can't have NUM_SNOWMEN in the loop since setting to 0 causes compiler warnings
+ for(PxU32 i=0; i<numSnowmen; i++)
+ {
+ PxVec3 pos(0,1,-8);
+ PxQuat rot(2*PxPi*i/numSnowmen,PxVec3(0,1,0));
+ createSnowMan(PxTransform(rot.rotate(pos),rot),i,i);
+ }
+
+}
+
+PxRigidDynamic* SampleNorthPole::createSnowMan(const PxTransform& pos, const PxU32 mode, const PxU32 index)
+{
+ PxRigidDynamic* snowmanActor = getPhysics().createRigidDynamic(PxTransform(pos));
+ if(!snowmanActor)
+ fatalError("create snowman actor failed");
+
+ PxMaterial& material = getDefaultMaterial();
+ PxShape* armL = NULL; PxShape* armR = NULL;
+
+ switch(mode%5)
+ {
+ case 0: // with a weight at the bottom
+ {
+ PxShape* shape = NULL;
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.2),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+ shape->setLocalPose(PxTransform(PxVec3(0,-.29,0)));
+
+ PxRigidBodyExt::updateMassAndInertia(*snowmanActor,10);
+
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.5),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.4),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+ shape->setLocalPose(PxTransform(PxVec3(0,.6,0)));
+
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.3),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+ shape->setLocalPose(PxTransform(PxVec3(0,1.1,0)));
+
+ armL = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.1,.1),material);
+ if(!armL)
+ fatalError("creating snowman shape failed");
+ armL->setLocalPose(PxTransform(PxVec3(-.4,.7,0)));
+
+ armR = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.1,.1),material);
+ if(!armR)
+ fatalError("creating snowman shape failed");
+ armR->setLocalPose(PxTransform(PxVec3( .4,.7,0)));
+ }
+ break;
+ case 1: // only considering lowest shape mass
+ {
+ PxShape* shape = NULL;
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.5),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+
+ PxRigidBodyExt::updateMassAndInertia(*snowmanActor,1);
+
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.4),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+ shape->setLocalPose(PxTransform(PxVec3(0,.6,0)));
+
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.3),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+ shape->setLocalPose(PxTransform(PxVec3(0,1.1,0)));
+
+ armL = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.1,.1),material);
+ if(!armL)
+ fatalError("creating snowman shape failed");
+ armL->setLocalPose(PxTransform(PxVec3(-.4,.7,0)));
+
+ armR = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.1,.1),material);
+ if(!armR)
+ fatalError("creating snowman shape failed");
+ armR->setLocalPose(PxTransform(PxVec3( .4,.7,0)));
+
+ snowmanActor->setCMassLocalPose(PxTransform(PxVec3(0,-.5,0)));
+ }
+ break;
+ case 2: // considering whole mass
+ {
+ PxShape* shape = NULL;
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.5),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.4),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+ shape->setLocalPose(PxTransform(PxVec3(0,.6,0)));
+
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.3),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+ shape->setLocalPose(PxTransform(PxVec3(0,1.1,0)));
+
+ armL = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.1,.1),material);
+ if(!armL)
+ fatalError("creating snowman shape failed");
+ armL->setLocalPose(PxTransform(PxVec3(-.4,.7,0)));
+
+ armR = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.1,.1),material);
+ if(!armR)
+ fatalError("creating snowman shape failed");
+ armR->setLocalPose(PxTransform(PxVec3( .4,.7,0)));
+
+ PxRigidBodyExt::updateMassAndInertia(*snowmanActor,1);
+ snowmanActor->setCMassLocalPose(PxTransform(PxVec3(0,-.5,0)));
+ }
+ break;
+ case 3: // considering whole mass with low COM
+ {
+ PxShape* shape = NULL;
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.5),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.4),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+ shape->setLocalPose(PxTransform(PxVec3(0,.6,0)));
+
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.3),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+ shape->setLocalPose(PxTransform(PxVec3(0,1.1,0)));
+
+ armL = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.1,.1),material);
+ if(!armL)
+ fatalError("creating snowman shape failed");
+ armL->setLocalPose(PxTransform(PxVec3(-.4,.7,0)));
+
+ armR = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.1,.1),material);
+ if(!armR)
+ fatalError("creating snowman shape failed");
+ armR->setLocalPose(PxTransform(PxVec3( .4,.7,0)));
+
+ const PxVec3 localPos = PxVec3(0,-.5,0);
+ PxRigidBodyExt::updateMassAndInertia(*snowmanActor,1,&localPos);
+ }
+ break;
+ case 4: // setting up mass properties manually
+ {
+ PxShape* shape = NULL;
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.5),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.4),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+ shape->setLocalPose(PxTransform(PxVec3(0,.6,0)));
+
+ shape = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.3),material);
+ if(!shape)
+ fatalError("creating snowman shape failed");
+ shape->setLocalPose(PxTransform(PxVec3(0,1.1,0)));
+
+ armL = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.1,.1),material);
+ if(!armL)
+ fatalError("creating snowman shape failed");
+ armL->setLocalPose(PxTransform(PxVec3(-.4,.7,0)));
+
+ armR = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.1,.1),material);
+ if(!armR)
+ fatalError("creating snowman shape failed");
+ armR->setLocalPose(PxTransform(PxVec3( .4,.7,0)));
+
+ snowmanActor->setMass(1);
+ snowmanActor->setCMassLocalPose(PxTransform(PxVec3(0,-.5,0)));
+ snowmanActor->setMassSpaceInertiaTensor(PxVec3(.05,100,100));
+ }
+ break;
+ default:
+ break;
+ }
+
+ setDetachable(*armL);
+ setDetachable(*armR);
+
+ createRenderObjectsFromActor(snowmanActor,mSnowMaterial);
+
+ PxShape* carrot = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxConvexMeshGeometry(mCarrotConvex),material);
+ if(!carrot)
+ fatalError("create snowman shape failed");
+ carrot->setLocalPose(PxTransform(PxVec3(0,1.1,.3)));
+ setDetachable(*carrot);
+
+ createRenderObjectFromShape(snowmanActor, carrot, mCarrotMaterial);
+
+ PxShape* button = NULL;
+
+ button = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.02,.05),material);
+ if(!button)
+ fatalError("create snowman shape failed");
+ button->setLocalPose(PxTransform(PxVec3(.1,1.2,.3),PxQuat(PxHalfPi/3,PxVec3(0,0,1))));
+ button->setFlag(PxShapeFlag::eSIMULATION_SHAPE,false);
+ mSnowman[index].eyeL = button;
+ createRenderObjectFromShape(snowmanActor, button, mButtonMaterial);
+
+ button = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxCapsuleGeometry(.02,.05),material);
+ if(!button)
+ fatalError("create snowman shape failed");
+ button->setLocalPose(PxTransform(PxVec3(-.1,1.2,.3),PxQuat(-PxHalfPi/3,PxVec3(0,0,1))));
+ button->setFlag(PxShapeFlag::eSIMULATION_SHAPE,false);
+ mSnowman[index].eyeR = button;
+ createRenderObjectFromShape(snowmanActor, button, mButtonMaterial);
+
+ button = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.05),material);
+ if(!button)
+ fatalError("create snowman shape failed");
+ button->setLocalPose(PxTransform(PxVec3(0,.8,.35)));
+ setDetachable(*button);
+ createRenderObjectFromShape(snowmanActor, button, mButtonMaterial);
+
+ button = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.05),material);
+ if(!button)
+ fatalError("create snowman shape failed");
+ button->setLocalPose(PxTransform(PxVec3(0,.6,.4)));
+ setDetachable(*button);
+ createRenderObjectFromShape(snowmanActor, button, mButtonMaterial);
+
+ button = PxRigidActorExt::createExclusiveShape(*snowmanActor, PxSphereGeometry(.05),material);
+ if(!button)
+ fatalError("create snowman shape failed");
+ button->setLocalPose(PxTransform(PxVec3(0,.4,.35)));
+ setDetachable(*button);
+ createRenderObjectFromShape(snowmanActor, button, mButtonMaterial);
+
+ getActiveScene().addActor(*snowmanActor);
+
+ snowmanActor->userData = (void*)size_t(index);
+
+ mPhysicsActors.push_back(snowmanActor);
+
+ return snowmanActor;
+}
diff --git a/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleFilterShader.cpp b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleFilterShader.cpp
new file mode 100644
index 00000000..fd640709
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleFilterShader.cpp
@@ -0,0 +1,127 @@
+// 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 "SampleNorthPole.h"
+
+void SampleNorthPole::customizeSceneDesc(PxSceneDesc& sceneDesc)
+{
+ sceneDesc.gravity = PxVec3(0,-9.81,0);
+ sceneDesc.filterShader = filter;
+ sceneDesc.simulationEventCallback = this;
+ sceneDesc.flags |= PxSceneFlag::eENABLE_CCD;
+ sceneDesc.flags |= PxSceneFlag::eREQUIRE_RW_LOCK;
+}
+
+void SampleNorthPole::setSnowball(PxShape& shape)
+{
+ PxFilterData fd = shape.getSimulationFilterData();
+ fd.word3 |= SNOWBALL_FLAG;
+ shape.setSimulationFilterData(fd);
+}
+
+bool SampleNorthPole::needsContactReport(const PxFilterData& filterData0, const PxFilterData& filterData1)
+{
+ const PxU32 needsReport = PxU32(DETACHABLE_FLAG | SNOWBALL_FLAG);
+ PxU32 flags = (filterData0.word3 | filterData1.word3);
+ return (flags & needsReport) == needsReport;
+}
+
+void SampleNorthPole::setDetachable(PxShape& shape)
+{
+ PxFilterData fd = shape.getSimulationFilterData();
+ fd.word3 |= PxU32(DETACHABLE_FLAG);
+ shape.setSimulationFilterData(fd);
+}
+
+bool SampleNorthPole::isDetachable(PxFilterData& filterData)
+{
+ return filterData.word3 & PxU32(DETACHABLE_FLAG) ? true : false;
+}
+
+void SampleNorthPole::setCCDActive(PxShape& shape, PxRigidBody* rigidBody)
+{
+ rigidBody->setRigidBodyFlag(PxRigidBodyFlag::eENABLE_CCD, true);
+ PxFilterData fd = shape.getSimulationFilterData();
+ fd.word3 |= CCD_FLAG;
+ shape.setSimulationFilterData(fd);
+
+}
+
+bool SampleNorthPole::isCCDActive(PxFilterData& filterData)
+{
+ return filterData.word3 & CCD_FLAG ? true : false;
+}
+
+PxFilterFlags SampleNorthPole::filter( PxFilterObjectAttributes attributes0,
+ PxFilterData filterData0,
+ PxFilterObjectAttributes attributes1,
+ PxFilterData filterData1,
+ PxPairFlags& pairFlags,
+ const void* constantBlock,
+ PxU32 constantBlockSize)
+{
+
+ if (isCCDActive(filterData0) || isCCDActive(filterData1))
+ {
+ pairFlags |= PxPairFlag::eSOLVE_CONTACT;
+ pairFlags |= PxPairFlag::eDETECT_CCD_CONTACT;
+ }
+
+ if (needsContactReport(filterData0, filterData1))
+ {
+ pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND;
+ }
+
+ pairFlags |= PxPairFlag::eCONTACT_DEFAULT;
+ return PxFilterFlags();
+}
+
+void SampleNorthPole::onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs)
+{
+ for(PxU32 i=0; i < nbPairs; i++)
+ {
+ PxU32 n = 2;
+ const PxContactPairFlag::Enum delShapeFlags[] = { PxContactPairFlag::eREMOVED_SHAPE_0, PxContactPairFlag::eREMOVED_SHAPE_1 };
+ const PxContactPair& cp = pairs[i];
+ while(n--)
+ {
+ if(!(cp.flags & delShapeFlags[n]))
+ {
+ PxShape* shape = cp.shapes[n];
+ PxFilterData fd = shape->getSimulationFilterData();
+ if(isDetachable(fd))
+ {
+ mDetaching.push_back(shape);
+ }
+ }
+ }
+ }
+}
diff --git a/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleInputEventIds.h b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleInputEventIds.h
new file mode 100644
index 00000000..2dd91e4f
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleNorthPole/SampleNorthPoleInputEventIds.h
@@ -0,0 +1,46 @@
+// 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_NORTH_POLE_INPUT_EVENT_IDS_H
+#define _SAMPLE_NORTH_POLE_INPUT_EVENT_IDS_H
+
+#include <SampleBaseInputEventIds.h>
+
+// InputEvents used by SampleNorthPole
+enum SampleNorthPoleInputEventIds
+{
+ SAMPLE_NORTH_POLE_FIRST = NUM_SAMPLE_BASE_INPUT_EVENT_IDS,
+
+ THROW_BALL ,
+ RAYCAST_HIT,
+ CROUCH ,
+ CROUCH_TOGGLE ,
+ RESET_SCENE ,
+
+ NUM_SAMPLE_NORTH_POLE_INPUT_EVENT_IDS,
+};
+
+#endif