Init
This commit is contained in:
238
physx/samples/samplenorthpole/SampleNorthPole.cpp
Normal file
238
physx/samples/samplenorthpole/SampleNorthPole.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
196
physx/samples/samplenorthpole/SampleNorthPole.h
Normal file
196
physx/samples/samplenorthpole/SampleNorthPole.h
Normal file
@ -0,0 +1,196 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
450
physx/samples/samplenorthpole/SampleNorthPoleBuilder.cpp
Normal file
450
physx/samples/samplenorthpole/SampleNorthPoleBuilder.cpp
Normal file
@ -0,0 +1,450 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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.7f;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
220
physx/samples/samplenorthpole/SampleNorthPoleCCT.cpp
Normal file
220
physx/samples/samplenorthpole/SampleNorthPoleCCT.cpp
Normal file
@ -0,0 +1,220 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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, SCAN_CODE_DOWN, SCAN_CODE_DOWN );
|
||||
DIGITAL_INPUT_EVENT_DEF(RESET_SCENE, WKEY_R, OSXKEY_R, LINUXKEY_R );
|
||||
|
||||
//digital gamepad events
|
||||
DIGITAL_INPUT_EVENT_DEF(CROUCH, GAMEPAD_WEST, GAMEPAD_WEST, LINUXKEY_UNKNOWN );
|
||||
DIGITAL_INPUT_EVENT_DEF(RESET_SCENE, GAMEPAD_NORTH, GAMEPAD_NORTH, LINUXKEY_UNKNOWN );
|
||||
DIGITAL_INPUT_EVENT_DEF(THROW_BALL, GAMEPAD_RIGHT_SHOULDER_BOT, GAMEPAD_RIGHT_SHOULDER_BOT, LINUXKEY_UNKNOWN );
|
||||
|
||||
//digital mouse events
|
||||
if (!isPaused())
|
||||
{
|
||||
DIGITAL_INPUT_EVENT_DEF(THROW_BALL, MOUSE_BUTTON_LEFT, MOUSE_BUTTON_LEFT, MOUSE_BUTTON_LEFT );
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -0,0 +1,221 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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, SCAN_CODE_FORWARD, SCAN_CODE_FORWARD );
|
||||
DIGITAL_INPUT_EVENT_DEF(CAMERA_MOVE_BACKWARD, SCAN_CODE_BACKWARD, SCAN_CODE_BACKWARD, SCAN_CODE_BACKWARD );
|
||||
DIGITAL_INPUT_EVENT_DEF(CAMERA_MOVE_LEFT, SCAN_CODE_LEFT, SCAN_CODE_LEFT, SCAN_CODE_LEFT );
|
||||
DIGITAL_INPUT_EVENT_DEF(CAMERA_MOVE_RIGHT, SCAN_CODE_RIGHT, SCAN_CODE_RIGHT, SCAN_CODE_RIGHT );
|
||||
DIGITAL_INPUT_EVENT_DEF(CAMERA_SHIFT_SPEED, SCAN_CODE_LEFT_SHIFT, OSXKEY_SHIFT, LINUXKEY_SHIFT );
|
||||
|
||||
//analog gamepad events
|
||||
ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_ROTATE_LEFT_RIGHT, GAMEPAD_ROTATE_SENSITIVITY, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, LINUXKEY_UNKNOWN );
|
||||
ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_ROTATE_UP_DOWN, GAMEPAD_ROTATE_SENSITIVITY, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, LINUXKEY_UNKNOWN );
|
||||
ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_MOVE_LEFT_RIGHT, GAMEPAD_DEFAULT_SENSITIVITY, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, LINUXKEY_UNKNOWN );
|
||||
ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_MOVE_FORWARD_BACK, GAMEPAD_DEFAULT_SENSITIVITY, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, LINUXKEY_UNKNOWN );
|
||||
}
|
||||
|
||||
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.81f,0);
|
||||
targetKeyDisplacement *= dtime;
|
||||
|
||||
targetPadDisplacement += forward * mGamepadForwardInc * mRunningSpeed;
|
||||
targetPadDisplacement += right * mGamepadLateralInc * mRunningSpeed;
|
||||
targetPadDisplacement += PxVec3(0,-9.81f,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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;
|
||||
};
|
||||
405
physx/samples/samplenorthpole/SampleNorthPoleDynamics.cpp
Normal file
405
physx/samples/samplenorthpole/SampleNorthPoleDynamics.cpp
Normal file
@ -0,0 +1,405 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4305)
|
||||
#endif
|
||||
|
||||
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,0.1f,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;
|
||||
}
|
||||
127
physx/samples/samplenorthpole/SampleNorthPoleFilterShader.cpp
Normal file
127
physx/samples/samplenorthpole/SampleNorthPoleFilterShader.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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.81f,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
physx/samples/samplenorthpole/SampleNorthPoleInputEventIds.h
Normal file
46
physx/samples/samplenorthpole/SampleNorthPoleInputEventIds.h
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
Reference in New Issue
Block a user