diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Samples/SampleNorthPole | |
| download | physx-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')
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 |