Init
This commit is contained in:
980
physx/samples/samplebridges/SampleBridges.cpp
Normal file
980
physx/samples/samplebridges/SampleBridges.cpp
Normal file
@ -0,0 +1,980 @@
|
||||
//
|
||||
// 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 "SamplePreprocessor.h"
|
||||
#include "SampleBridges.h"
|
||||
#include "SampleUtils.h"
|
||||
#include "RendererMemoryMacros.h"
|
||||
#include "KinematicPlatform.h"
|
||||
#include "RenderMaterial.h"
|
||||
#include "RenderBaseActor.h"
|
||||
#include "RenderPhysX3Debug.h"
|
||||
#include <SamplePlatform.h>
|
||||
#include <SampleUserInput.h>
|
||||
#include <SampleBaseInputEventIds.h>
|
||||
#include "SampleBridgesInputEventIds.h"
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "extensions/PxExtensionsAPI.h"
|
||||
#include "PsMathUtils.h"
|
||||
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
#include "characterkinematic/PxControllerManager.h"
|
||||
#include "SampleCCTActor.h"
|
||||
#include "SampleCCTCameraController.h"
|
||||
|
||||
#define CONTACT_OFFSET 0.01f
|
||||
// #define CONTACT_OFFSET 0.1f
|
||||
// #define STEP_OFFSET 0.01f
|
||||
#define STEP_OFFSET 0.05f
|
||||
// #define STEP_OFFSET 0.1f
|
||||
// #define STEP_OFFSET 0.2f
|
||||
|
||||
// #define SLOPE_LIMIT 0.8f
|
||||
#define SLOPE_LIMIT 0.0f
|
||||
// #define INVISIBLE_WALLS_HEIGHT 6.0f
|
||||
#define INVISIBLE_WALLS_HEIGHT 0.0f
|
||||
// #define MAX_JUMP_HEIGHT 4.0f
|
||||
#define MAX_JUMP_HEIGHT 0.0f
|
||||
|
||||
static const float gScaleFactor = 1.5f;
|
||||
static const float gStandingSize = 1.0f * gScaleFactor;
|
||||
static const float gCrouchingSize = 0.25f * gScaleFactor;
|
||||
static const float gControllerRadius = 0.3f * gScaleFactor;
|
||||
|
||||
const char* gPlankName = "Plank";
|
||||
const char* gPlatformName = "Platform";
|
||||
|
||||
#endif
|
||||
|
||||
using namespace SampleRenderer;
|
||||
using namespace SampleFramework;
|
||||
|
||||
REGISTER_SAMPLE(SampleBridges, "SampleBridges")
|
||||
|
||||
//using namespace physx;
|
||||
|
||||
static const bool gBreakableBridges = false;
|
||||
static const PxReal gBreakForce = 1.0f;
|
||||
//static const PxReal gPlatformSpeed = 100.0f;
|
||||
static const PxReal gPlatformSpeed = 10.0f;
|
||||
//static const PxReal gPlatformSpeed = 5.0f;
|
||||
static const PxReal gGlobalScale = 2.0f;
|
||||
|
||||
static const PxReal gBoxUVs[] =
|
||||
{
|
||||
0.0f, 180.0f/256.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 180.0f/256.0f,
|
||||
|
||||
0.0f, 180.0f/256.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 180.0f/256.0f,
|
||||
|
||||
0.0f, 180.0f/256.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 180.0f/256.0f,
|
||||
|
||||
0.0f, 180.0f/256.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 180.0f/256.0f,
|
||||
|
||||
0.0f, 180.0f/256.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 180.0f/256.0f,
|
||||
|
||||
0.0f, 180.0f/256.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 180.0f/256.0f,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// PT: TODO: use PhysXSampleApplication helper for this
|
||||
|
||||
static PxRigidActor* createRigidActor( PxScene& scene, PxPhysics& physics,
|
||||
const PxTransform& pose, const PxGeometry& geometry, PxMaterial& material,
|
||||
const PxFilterData* fd, const PxReal* density, const PxReal* mass, PxU32 flags)
|
||||
{
|
||||
const bool isDynamic = (density && *density) || (mass && *mass);
|
||||
|
||||
PxRigidActor* actor = isDynamic ? static_cast<PxRigidActor*>(physics.createRigidDynamic(pose))
|
||||
: static_cast<PxRigidActor*>(physics.createRigidStatic(pose));
|
||||
if(!actor)
|
||||
return NULL;
|
||||
|
||||
PxShape* shape = PxRigidActorExt::createExclusiveShape(*actor, geometry, material);
|
||||
if(!shape)
|
||||
{
|
||||
actor->release();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(fd)
|
||||
shape->setSimulationFilterData(*fd);
|
||||
|
||||
if(isDynamic)
|
||||
{
|
||||
PxRigidDynamic* body = static_cast<PxRigidDynamic*>(actor);
|
||||
{
|
||||
if(density)
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, *density);
|
||||
else
|
||||
PxRigidBodyExt::setMassAndUpdateInertia(*body, *mass);
|
||||
}
|
||||
}
|
||||
|
||||
scene.addActor(*actor);
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
static PxRigidActor* createBox( PxScene& scene, PxPhysics& physics,
|
||||
const PxTransform& pose, const PxVec3& dimensions, const PxReal density, PxMaterial& m, const PxFilterData* fd, PxU32 flags)
|
||||
{
|
||||
return createRigidActor(scene, physics, pose, PxBoxGeometry(dimensions), m, fd, &density, NULL, flags);
|
||||
}
|
||||
|
||||
enum BridgeJoint
|
||||
{
|
||||
BRIDGE_REVOLUTE,
|
||||
BRIDGE_SPHERICAL,
|
||||
BRIDGE_FIXED,
|
||||
|
||||
BRIDGE_COUNT
|
||||
};
|
||||
|
||||
// PT: TODO: share this function with original code in Visual Tests?
|
||||
static void buildBridge(PxScene& scene, PxPhysics& physics, PxMaterial& material, std::vector<PxRigidActor*>& actors, std::vector<PxJoint*>& joints, const PxTransform& tr, PxReal scale, BridgeJoint type)
|
||||
{
|
||||
const PxVec3 offset(0,0,0);
|
||||
|
||||
const PxReal groundLength = 5.0f;
|
||||
const PxReal groundHeight = 5.0f;
|
||||
|
||||
// create ground under character
|
||||
if(1)
|
||||
{
|
||||
PxTransform boxPose = tr * PxTransform(PxVec3(0.0f, -groundHeight, -10.0f-groundLength)*scale, PxQuat(PxIdentity));
|
||||
boxPose.p += offset;
|
||||
|
||||
const PxVec3 boxSize = PxVec3(1.0f, groundHeight, groundLength) * scale;
|
||||
PxRigidActor* box = createBox(scene, physics, boxPose, boxSize, 0.0f, material, NULL, 0);
|
||||
actors.push_back(box);
|
||||
}
|
||||
|
||||
// create bridge...
|
||||
if(1)
|
||||
{
|
||||
const PxReal plankWidth = 1.0f;
|
||||
const PxReal plankHeight = 0.02f;
|
||||
const PxReal plankDepth = 0.5f;
|
||||
const PxReal plankDensity = 0.03f;
|
||||
// const PxReal plankDensity = 0.3f;
|
||||
PxRigidDynamic* lastPlank = 0;
|
||||
|
||||
for(PxReal z = -10.0f+plankDepth; z<10.0f; z+= plankDepth*2)
|
||||
{
|
||||
const PxVec3 boxSize = PxVec3(plankWidth, plankHeight, plankDepth) * scale;
|
||||
|
||||
PxTransform boxPose = tr * PxTransform(PxVec3(0,-plankHeight,z)*scale);
|
||||
|
||||
PxRigidDynamic* plank = createBox(scene, physics, boxPose, boxSize, plankDensity, material, NULL, 0)->is<PxRigidDynamic>();
|
||||
if(plank)
|
||||
{
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
plank->setName(gPlankName);
|
||||
#endif
|
||||
actors.push_back(plank);
|
||||
|
||||
//plank->setSolverIterationCounts(1, 1);
|
||||
// plank->setSolverIterationCounts(255, 255);
|
||||
// plank->setSolverIterationCounts(10, 10);
|
||||
plank->setSolverIterationCounts(8, 8);
|
||||
plank->setLinearDamping(1.0f);
|
||||
plank->setAngularDamping(1.0f);
|
||||
// plank->putToSleep();
|
||||
|
||||
if(!lastPlank)
|
||||
{
|
||||
// plank = first plank...
|
||||
plank->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// joint together plank and lastPlank...
|
||||
if(type==BRIDGE_REVOLUTE)
|
||||
{
|
||||
PxRevoluteJoint* j = PxRevoluteJointCreate(physics,
|
||||
lastPlank, PxTransform(PxVec3(0,0, plankDepth)*scale),
|
||||
plank, PxTransform(PxVec3(0,0,-plankDepth)*scale));
|
||||
if(j)
|
||||
{
|
||||
j->setProjectionLinearTolerance(0.5f);
|
||||
joints.push_back(j);
|
||||
}
|
||||
}
|
||||
else if(type==BRIDGE_FIXED)
|
||||
{
|
||||
PxFixedJoint* j = PxFixedJointCreate(physics,
|
||||
lastPlank, PxTransform(PxVec3(0,0, plankDepth)*scale),
|
||||
plank, PxTransform(PxVec3(0,0,-plankDepth)*scale));
|
||||
if(j)
|
||||
{
|
||||
j->setProjectionLinearTolerance(0.5f);
|
||||
joints.push_back(j);
|
||||
}
|
||||
}
|
||||
else if(type==BRIDGE_SPHERICAL)
|
||||
{
|
||||
const PxReal plankX = 0.1f;
|
||||
PxSphericalJoint* j1 = PxSphericalJointCreate(physics,
|
||||
lastPlank, PxTransform(PxVec3(plankX, 0.0f, plankDepth)*scale),
|
||||
plank, PxTransform(PxVec3(plankX, 0.0f, -plankDepth)*scale));
|
||||
if(j1)
|
||||
{
|
||||
j1->setProjectionLinearTolerance(0.5f);
|
||||
joints.push_back(j1);
|
||||
}
|
||||
|
||||
PxSphericalJoint* j2 = PxSphericalJointCreate(physics,
|
||||
lastPlank, PxTransform(PxVec3(-plankX, 0.0f, plankDepth)*scale),
|
||||
plank, PxTransform(PxVec3(-plankX, 0.0f, -plankDepth)*scale));
|
||||
if(j2)
|
||||
{
|
||||
j2->setProjectionLinearTolerance(0.5f);
|
||||
joints.push_back(j2);
|
||||
}
|
||||
}
|
||||
else PX_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
if(gBreakableBridges)
|
||||
{
|
||||
for(PxU32 i=0;i<joints.size();i++)
|
||||
joints[i]->setBreakForce(gBreakForce * scale, gBreakForce * scale);
|
||||
}
|
||||
|
||||
lastPlank = plank;
|
||||
}
|
||||
if(lastPlank)
|
||||
{
|
||||
lastPlank->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
|
||||
}
|
||||
}
|
||||
|
||||
// create ground after bridge
|
||||
if(1)
|
||||
{
|
||||
PxTransform boxPose = tr * PxTransform(PxVec3(0.0f, -groundHeight, 10.0f+groundLength)*scale);
|
||||
boxPose.p += offset;
|
||||
|
||||
const PxVec3 boxSize = PxVec3(1.0f, groundHeight, groundLength) * scale;
|
||||
PxRigidActor* box = createBox(scene, physics, boxPose, boxSize, 0.0f, material, NULL, 0);
|
||||
actors.push_back(box);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SampleBridges::SampleBridges(PhysXSampleApplication& app) :
|
||||
PhysXSample (app),
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
mCCTCamera (NULL),
|
||||
mActor (NULL),
|
||||
mControllerManager (NULL),
|
||||
#endif
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
mObstacleContext (NULL),
|
||||
mBoxObstacles (NULL),
|
||||
#endif
|
||||
mGlobalScale (gGlobalScale),
|
||||
mCurrentPlatform (0xffffffff),
|
||||
mElapsedRenderTime (0.0f),
|
||||
mRockMaterial (NULL),
|
||||
mWoodMaterial (NULL),
|
||||
mPlatformMaterial (NULL),
|
||||
mBomb (NULL),
|
||||
mBombTimer (0.0f),
|
||||
mWaterY (0.0f),
|
||||
mMustResync (false),
|
||||
mEnableCCTDebugRender (false)
|
||||
{
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
mControllerInitialPosition = PxExtendedVec3(18.0f, 2.0f, -64.0f);
|
||||
#endif
|
||||
mCreateGroundPlane = false;
|
||||
//mStepperType = FIXED_STEPPER;
|
||||
mDefaultDensity = 0.1f;
|
||||
// mDefaultDensity = 1.0f;
|
||||
|
||||
}
|
||||
|
||||
SampleBridges::~SampleBridges()
|
||||
{
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
DELETESINGLE(mActor);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SampleBridges::customizeSample(SampleSetup& setup)
|
||||
{
|
||||
setup.mName = "SampleBridges";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// PT: this is called from the RAW-loader when loading a scene. The default behavior
|
||||
// in PhysXSampleApplication creates a physics and a graphics mesh for each exported object. We
|
||||
// intercept the call here to disable the physics mesh for the "water plane".
|
||||
void SampleBridges::newMesh(const RAWMesh& data)
|
||||
{
|
||||
if(data.mName && (Ps::strcmp(data.mName, "WaterPlane")==0 || Ps::strcmp(data.mName, "skyshape")==0))
|
||||
{
|
||||
// PT: create render mesh only (not physics) for the waterplane & skyboxes
|
||||
createRenderMeshFromRawMesh(data);
|
||||
if(Ps::strcmp(data.mName, "WaterPlane")==0)
|
||||
mWaterY = data.mTransform.p.y;
|
||||
return;
|
||||
}
|
||||
PhysXSample::newMesh(data);
|
||||
}
|
||||
|
||||
// PT: this is a callback from the RAW-loader, used to import a new shape. We use
|
||||
// simple segment shapes in the MAX scene to define where our bridges should be.
|
||||
void SampleBridges::newShape(const RAWShape& data)
|
||||
{
|
||||
if(data.mName)
|
||||
{
|
||||
if(::strcmp(data.mName, "Bridge")==0)
|
||||
{
|
||||
PX_ASSERT(data.mNbVerts==2);
|
||||
const PxVec3 p0 = data.mTransform.transform(data.mVerts[0]);
|
||||
const PxVec3 p1 = data.mTransform.transform(data.mVerts[1]);
|
||||
const PxVec3 center = (p0 + p1)*0.5f;
|
||||
|
||||
PxVec3 dir, right, up;
|
||||
Ps::computeBasis(p0, p1, dir, right, up);
|
||||
|
||||
PxMat33 m(right, up, dir);
|
||||
PxTransform tr;
|
||||
tr.p = center;
|
||||
tr.q = PxQuat(m);
|
||||
|
||||
const float l = (p1 - p0).magnitude();
|
||||
const float coeff = l / 80.0f;
|
||||
|
||||
float scale = 2.0f * coeff;
|
||||
// float scale = 4.0f * coeff;
|
||||
// float scale = 1.0f;
|
||||
|
||||
BridgeJoint type = BRIDGE_REVOLUTE;
|
||||
{
|
||||
static int count=0;
|
||||
if(count==0)
|
||||
type = BRIDGE_REVOLUTE;
|
||||
else if(count==1)
|
||||
type = BRIDGE_SPHERICAL;
|
||||
else if(count==2)
|
||||
type = BRIDGE_FIXED;
|
||||
else PX_ASSERT(0);
|
||||
|
||||
count++;
|
||||
if(count==BRIDGE_COUNT)
|
||||
count = 0;
|
||||
}
|
||||
|
||||
std::vector<PxRigidActor*> bridgeActors;
|
||||
buildBridge(getActiveScene(), getPhysics(), getDefaultMaterial(), bridgeActors, mJoints, tr, scale, type);
|
||||
|
||||
for(PxU32 i=0;i<bridgeActors.size();i++)
|
||||
{
|
||||
RenderMaterial* m = (i==0 || i==bridgeActors.size()-1) ? mRockMaterial : mWoodMaterial;
|
||||
|
||||
PX_ASSERT(bridgeActors[i]->getNbShapes()==1);
|
||||
PxShape* boxShape;
|
||||
PxU32 nb = bridgeActors[i]->getShapes(&boxShape, 1);
|
||||
PX_ASSERT(nb==1);
|
||||
PX_UNUSED(nb);
|
||||
createRenderBoxFromShape(bridgeActors[i], boxShape, m, gBoxUVs);
|
||||
}
|
||||
}
|
||||
else if(::strcmp(data.mName, "Platform")==0)
|
||||
{
|
||||
const PxTransform idt = PxTransform(PxIdentity);
|
||||
|
||||
PxRigidDynamic* platformActor = (PxRigidDynamic*)::createBox(getActiveScene(), getPhysics(), idt, gGlobalScale * PxVec3(1.0f, 5.0f, 5.0f), 1.0f, getDefaultMaterial(), NULL, 0);
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
platformActor->setName(gPlatformName);
|
||||
#endif
|
||||
platformActor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
|
||||
|
||||
// createRenderObjectsFromActor(platformActor, mPlatformMaterial);
|
||||
PxShape* platformShape = NULL;
|
||||
platformActor->getShapes(&platformShape, 1);
|
||||
PX_ASSERT(platformShape);
|
||||
RenderBaseActor* renderActor = createRenderObjectFromShape(platformActor, platformShape, mPlatformMaterial);
|
||||
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
// platformShape->userData = NULL;
|
||||
renderActor->setPhysicsShape(NULL, NULL);
|
||||
PxBounds3 maxBounds;
|
||||
maxBounds.setMaximal();
|
||||
renderActor->setWorldBounds(maxBounds);
|
||||
#else
|
||||
PX_UNUSED(renderActor);
|
||||
#endif
|
||||
|
||||
#ifdef ROTATING_PLATFORMS
|
||||
const PxF32 rotationSpeed = 0.5f;
|
||||
#else
|
||||
const PxF32 rotationSpeed = 0.0f;
|
||||
#endif
|
||||
const PxVec3 up(0.0f, 1.0f, 0.0f);
|
||||
const PxQuat q = PxShortestRotation(PxVec3(1.0f, 0.0f, 0.0f), up);
|
||||
|
||||
mPlatformManager.createPlatform(data.mNbVerts, data.mVerts, data.mTransform, q, platformActor, gPlatformSpeed, rotationSpeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SampleBridges::onInit()
|
||||
{
|
||||
PhysXSample::onInit();
|
||||
PxSceneWriteLock scopedLock(*mScene);
|
||||
|
||||
mApplication.setMouseCursorHiding(true);
|
||||
mApplication.setMouseCursorRecentering(true);
|
||||
|
||||
getRenderer()->setAmbientColor(RendererColor(170, 170, 170));
|
||||
// mScene->setGravity(PxVec3(0.0f, -98.1f, 0.0f));
|
||||
getActiveScene().setGravity(PxVec3(0.0f, -9.81f, 0.0f));
|
||||
|
||||
{
|
||||
{
|
||||
RAWTexture data;
|
||||
data.mName = "rock_distance_diffuse.tga";
|
||||
RenderTexture* rockTexture = createRenderTextureFromRawTexture(data);
|
||||
|
||||
mRockMaterial = SAMPLE_NEW(RenderMaterial)(*getRenderer(), PxVec3(1.0f, 1.0f, 1.0f), 1.0f, false, 0xffffffff, rockTexture);
|
||||
mRenderMaterials.push_back(mRockMaterial);
|
||||
}
|
||||
|
||||
{
|
||||
RAWTexture data;
|
||||
data.mName = "pier_diffuse.dds";
|
||||
RenderTexture* woodTexture = createRenderTextureFromRawTexture(data);
|
||||
|
||||
mWoodMaterial = SAMPLE_NEW(RenderMaterial)(*getRenderer(), PxVec3(1.0f, 1.0f, 1.0f), 1.0f, false, 0xffffffff, woodTexture);
|
||||
mRenderMaterials.push_back(mWoodMaterial);
|
||||
}
|
||||
|
||||
{
|
||||
RAWTexture data;
|
||||
data.mName = "divingBoardFloor_diffuse.dds";
|
||||
RenderTexture* platformTexture = createRenderTextureFromRawTexture(data);
|
||||
|
||||
mPlatformMaterial = SAMPLE_NEW(RenderMaterial)(*getRenderer(), PxVec3(1.0f, 1.0f, 1.0f), 1.0f, false, 0xffffffff, platformTexture);
|
||||
mRenderMaterials.push_back(mPlatformMaterial);
|
||||
}
|
||||
|
||||
importRAWFile("SampleBridges.raw", gGlobalScale);
|
||||
importRAWFile("sky_mission_race1.raw", 1.0f);
|
||||
}
|
||||
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
mControllerManager = PxCreateControllerManager(getActiveScene());
|
||||
|
||||
ControlledActorDesc desc;
|
||||
desc.mType = PxControllerShapeType::eCAPSULE;
|
||||
desc.mPosition = mControllerInitialPosition;
|
||||
desc.mSlopeLimit = SLOPE_LIMIT;
|
||||
desc.mContactOffset = CONTACT_OFFSET;
|
||||
desc.mStepOffset = STEP_OFFSET;
|
||||
desc.mInvisibleWallHeight = INVISIBLE_WALLS_HEIGHT;
|
||||
desc.mMaxJumpHeight = MAX_JUMP_HEIGHT;
|
||||
desc.mRadius = gControllerRadius;
|
||||
desc.mHeight = gStandingSize;
|
||||
desc.mCrouchHeight = gCrouchingSize;
|
||||
desc.mReportCallback = this;
|
||||
desc.mBehaviorCallback = this;
|
||||
|
||||
{
|
||||
mActor = SAMPLE_NEW(ControlledActor)(*this);
|
||||
mActor->init(desc, mControllerManager);
|
||||
|
||||
RenderBaseActor* actor0 = mActor->getRenderActorStanding();
|
||||
RenderBaseActor* actor1 = mActor->getRenderActorCrouching();
|
||||
if(actor0)
|
||||
mRenderActors.push_back(actor0);
|
||||
if(actor1)
|
||||
mRenderActors.push_back(actor1);
|
||||
}
|
||||
|
||||
mCCTCamera = SAMPLE_NEW(SampleCCTCameraController)(*this);
|
||||
mCCTCamera->setControlled(&mActor, 0, 1);
|
||||
// mCCTCamera->setFilterData();
|
||||
mCCTCamera->setFilterCallback(this);
|
||||
mCCTCamera->setGravity(-20.0f);
|
||||
|
||||
setCameraController(mCCTCamera);
|
||||
|
||||
mCCTCamera->setView(0,0);
|
||||
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
mObstacleContext = mControllerManager->createObstacleContext();
|
||||
mCCTCamera->setObstacleContext(mObstacleContext);
|
||||
|
||||
const PxVec3 up(0.0f, 1.0f, 0.0f);
|
||||
const PxQuat q = PxShortestRotation(PxVec3(1.0f, 0.0f, 0.0f), up);
|
||||
|
||||
const PxU32 nbPlatforms = mPlatformManager.getNbPlatforms();
|
||||
KinematicPlatform** platforms = mPlatformManager.getPlatforms();
|
||||
mBoxObstacles = new PxBoxObstacle[nbPlatforms];
|
||||
for(PxU32 i=0;i<nbPlatforms;i++)
|
||||
{
|
||||
mBoxObstacles[i].mPos.x = 0.0;
|
||||
mBoxObstacles[i].mPos.y = 0.0;
|
||||
mBoxObstacles[i].mPos.z = 0.0;
|
||||
mBoxObstacles[i].mRot = q;
|
||||
mBoxObstacles[i].mHalfExtents = gGlobalScale * PxVec3(1.0f, 5.0f, 5.0f);
|
||||
// mBoxObstacles[i].mHalfExtents = gGlobalScale * PxVec3(5.0f, 1.0f, 5.0f);
|
||||
const ObstacleHandle handle = mObstacleContext->addObstacle(mBoxObstacles[i]);
|
||||
platforms[i]->setBoxObstacle(handle, mBoxObstacles + i);
|
||||
}
|
||||
#endif
|
||||
|
||||
// mCCTCamera->setCameraLinkToPhysics(true);
|
||||
#endif
|
||||
|
||||
// mScene->setVisualizationParameter(PxVisualizationParameter::eCONTACT_NORMAL, 1.0f);
|
||||
// mScene->setVisualizationParameter(PxVisualizationParameter::eJOINT_LOCAL_FRAMES, 1.0f);
|
||||
|
||||
// advanceSimulation(4.0f);
|
||||
}
|
||||
|
||||
void SampleBridges::onShutdown()
|
||||
{
|
||||
{
|
||||
PxSceneWriteLock scopedLock(*mScene);
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
DELETESINGLE(mCCTCamera);
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
SAFE_RELEASE(mObstacleContext);
|
||||
DELETEARRAY(mBoxObstacles);
|
||||
#endif
|
||||
mControllerManager->release();
|
||||
#endif
|
||||
const size_t nbJoints = mJoints.size();
|
||||
for(PxU32 i=0;i<nbJoints;i++)
|
||||
if(mJoints[i])
|
||||
mJoints[i]->release();
|
||||
mJoints.clear();
|
||||
}
|
||||
|
||||
|
||||
mPlatformManager.release();
|
||||
|
||||
PhysXSample::onShutdown();
|
||||
}
|
||||
|
||||
// PT: very crude attempt here, just to have something running
|
||||
static void applyBombForce(PxRigidActor* actor, const PxVec3& actorPos, const PxVec3& bombPos, PxReal bombRange)
|
||||
{
|
||||
PxRigidDynamic* dyna = actor->is<PxRigidDynamic>();
|
||||
if(dyna)
|
||||
{
|
||||
PxVec3 dir = (actorPos - bombPos);
|
||||
const PxReal m = dir.magnitude();
|
||||
if(m<bombRange)
|
||||
{
|
||||
const PxReal coeff = (1.0f - m/bombRange) * 50.0f;
|
||||
dir /= m;
|
||||
// dyna->addForce(dir*coeff);
|
||||
|
||||
PxBounds3 worldBounds = dyna->getWorldBounds();
|
||||
|
||||
const PxVec3 center = worldBounds.getCenter();
|
||||
const PxVec3 extents = worldBounds.getExtents();
|
||||
const PxVec3 axis0(extents.x, 0.0f, 0.0f);
|
||||
const PxVec3 axis1(0.0f, extents.y, 0.0f);
|
||||
const PxVec3 axis2(0.0f, 0.0f, extents.z);
|
||||
|
||||
PxVec3 pts[8];
|
||||
pts[0] = pts[3] = pts[4] = pts[7] = center - axis0;
|
||||
pts[1] = pts[2] = pts[5] = pts[6] = center + axis0;
|
||||
|
||||
PxVec3 tmp = axis1 + axis2;
|
||||
pts[0] -= tmp;
|
||||
pts[1] -= tmp;
|
||||
pts[6] += tmp;
|
||||
pts[7] += tmp;
|
||||
|
||||
tmp = axis1 - axis2;
|
||||
pts[2] += tmp;
|
||||
pts[3] += tmp;
|
||||
pts[4] -= tmp;
|
||||
pts[5] -= tmp;
|
||||
|
||||
PxReal minDist = 1e+30f;
|
||||
PxU32 index = 0;
|
||||
for(PxU32 i=0;i<8;i++)
|
||||
{
|
||||
PxReal d2 = (pts[i] - bombPos).magnitudeSquared();
|
||||
if(d2<minDist)
|
||||
{
|
||||
minDist = d2;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
PxRigidBodyExt::addForceAtPos(*dyna, dir*coeff, pts[index]);
|
||||
// PxRigidBodyExt::addForceAtPos(*dyna, dir*coeff, actorPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool findAndReplaceWithLast(std::vector<T*>& array, T* ptr)
|
||||
{
|
||||
const size_t s = array.size();
|
||||
for(PxU32 j=0; j<s; j++)
|
||||
{
|
||||
if(array[j]==ptr)
|
||||
{
|
||||
T* last = array[s-1];
|
||||
array.pop_back();
|
||||
if(j!=s-1)
|
||||
array[j] = last;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SampleBridges::onTickPreRender(float dtime)
|
||||
{
|
||||
// shdfnd::printFormatted("SampleBridges::onTickPreRender\n");
|
||||
|
||||
const bool paused = isPaused();
|
||||
|
||||
// PT: keep track of elapsed render time
|
||||
if(!paused)
|
||||
mElapsedRenderTime += dtime;
|
||||
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
// const bool postUpdate = mCCTCamera->getCameraLinkToPhysics();
|
||||
const bool postUpdate = true;
|
||||
// const bool postUpdate = false;
|
||||
|
||||
if(!postUpdate && !mPause)
|
||||
{
|
||||
// shdfnd::printFormatted("CCT sync\n");
|
||||
mActor->sync();
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!paused)
|
||||
{
|
||||
// mPlatformManager.updatePhysicsPlatforms(dtime);
|
||||
|
||||
if(mBomb)
|
||||
{
|
||||
mBombTimer -= dtime;
|
||||
if(mBombTimer<0.0f)
|
||||
{
|
||||
PxSceneWriteLock scopedLock(*mScene);
|
||||
mBombTimer = 0.0f;
|
||||
|
||||
{
|
||||
const PxVec3 bombPos = mBomb->getGlobalPose().p;
|
||||
const PxReal bombActorRange = 30.0f;
|
||||
const PxReal bombJointRange = 10.0f;
|
||||
size_t nbJoints = mJoints.size();
|
||||
for(PxU32 i=0;i<nbJoints;i++)
|
||||
{
|
||||
PxJoint* j = mJoints[i];
|
||||
if(!j)
|
||||
continue;
|
||||
|
||||
PxRigidActor* actor0;
|
||||
PxRigidActor* actor1;
|
||||
j->getActors(actor0, actor1);
|
||||
const PxVec3 actorPos0 = actor0->getGlobalPose().p;
|
||||
const PxVec3 actorPos1 = actor1->getGlobalPose().p;
|
||||
|
||||
applyBombForce(actor0, actorPos0, bombPos, bombActorRange);
|
||||
applyBombForce(actor1, actorPos1, bombPos, bombActorRange);
|
||||
|
||||
const PxVec3 jointPos = (actorPos0 + actorPos1)*0.5f;
|
||||
const PxReal d2 = (bombPos - jointPos).magnitudeSquared();
|
||||
if(d2<bombJointRange*bombJointRange)
|
||||
{
|
||||
j->release();
|
||||
mJoints[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
PxU32 nbShapes = mBomb->getNbShapes();
|
||||
PxShape** shapes = (PxShape**)SAMPLE_ALLOC(sizeof(PxShape*)*nbShapes);
|
||||
PxU32 nb = mBomb->getShapes(shapes, nbShapes);
|
||||
PX_ASSERT(nb==nbShapes);
|
||||
PX_UNUSED(nb);
|
||||
for(PxU32 i=0;i<nbShapes;i++)
|
||||
{
|
||||
PxShape* currentShape = shapes[i];
|
||||
|
||||
RenderBaseActor* renderActor = getRenderActor(mBomb, currentShape);
|
||||
unlink(renderActor, currentShape, mBomb);
|
||||
|
||||
findAndReplaceWithLast(mRenderActors, renderActor);
|
||||
|
||||
renderActor->release();
|
||||
}
|
||||
SAMPLE_FREE(shapes);
|
||||
}
|
||||
|
||||
findAndReplaceWithLast(mPhysicsActors, mBomb);
|
||||
|
||||
SAFE_RELEASE(mBomb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PhysXSample::onTickPreRender(dtime);
|
||||
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
if(!paused)
|
||||
updateRenderPlatforms(dtime);
|
||||
#endif
|
||||
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
if(postUpdate && !mPause)
|
||||
{
|
||||
// shdfnd::printFormatted("CCT sync\n");
|
||||
mActor->sync();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SampleBridges::onTickPostRender(float dtime)
|
||||
{
|
||||
PhysXSample::onTickPostRender(dtime);
|
||||
|
||||
// PT: add CCT's internal debug rendering
|
||||
if(mEnableCCTDebugRender)
|
||||
{
|
||||
mControllerManager->setDebugRenderingFlags(PxControllerDebugRenderFlag::eALL);
|
||||
PxRenderBuffer& renderBuffer = mControllerManager->getRenderBuffer();
|
||||
RenderPhysX3Debug* renderer = getDebugRenderer();
|
||||
renderer->update(renderBuffer);
|
||||
renderBuffer.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
mControllerManager->setDebugRenderingFlags(PxControllerDebugRenderFlag::eNONE);
|
||||
}
|
||||
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
// mControllerManager->setDebugRenderingFlags(PxControllerDebugRenderFlag::eCACHED_BV|PxControllerDebugRenderFlag::eTEMPORAL_BV);
|
||||
PxRenderBuffer& renderBuffer = mControllerManager->getRenderBuffer();
|
||||
getDebugRenderer()->update(renderBuffer);
|
||||
renderBuffer.clear();
|
||||
#endif
|
||||
|
||||
const float lag = fabsf(mPlatformManager.getElapsedTime() - mElapsedRenderTime);
|
||||
mMustResync = lag > 1.0f/60.0f;
|
||||
|
||||
if(0)
|
||||
{
|
||||
shdfnd::printFormatted("Render time: %f\n", mElapsedRenderTime);
|
||||
shdfnd::printFormatted("Platform time: %f\n", mPlatformManager.getElapsedTime());
|
||||
shdfnd::printFormatted("Delta: %f\n", lag);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
void SampleBridges::updateRenderPlatforms(float dtime)
|
||||
{
|
||||
// PT: compute new positions for (render) platforms, then move their corresponding obstacles to these positions.
|
||||
const PxU32 nbPlatforms = mPlatformManager.getNbPlatforms();
|
||||
KinematicPlatform** platforms = mPlatformManager.getPlatforms();
|
||||
|
||||
{
|
||||
PxSceneReadLock scopedLock(*mScene);
|
||||
|
||||
for(PxU32 i=0;i<nbPlatforms;i++)
|
||||
{
|
||||
if(1)
|
||||
{
|
||||
PxRigidDynamic* actor = platforms[i]->getPhysicsActor();
|
||||
PxShape* shape = NULL;
|
||||
actor->getShapes(&shape, 1);
|
||||
RenderBaseActor* renderActor = getRenderActor(actor, shape);
|
||||
renderActor->setTransform(platforms[i]->getRenderPose());
|
||||
}
|
||||
|
||||
platforms[i]->updateRender(dtime, mObstacleContext);
|
||||
}
|
||||
}
|
||||
|
||||
// PT: if render time & physics time varies too much, we must resync the physics to avoid large visual mismatchs
|
||||
if(mMustResync)
|
||||
{
|
||||
PxSceneWriteLock scopedLock(*mScene);
|
||||
|
||||
// mElapsedPlatformTime = mElapsedRenderTime;
|
||||
mPlatformManager.syncElapsedTime(mElapsedRenderTime);
|
||||
// static int count=0; shdfnd::printFormatted("Resync %d\n", count++);
|
||||
for(PxU32 i=0;i<nbPlatforms;i++)
|
||||
{
|
||||
PxRigidDynamic* actor = platforms[i]->getPhysicsActor();
|
||||
actor->setKinematicTarget(platforms[i]->getRenderPose());
|
||||
platforms[i]->resync();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SampleBridges::onSubstep(float dtime)
|
||||
{
|
||||
// shdfnd::printFormatted("onSubstep\n");
|
||||
mPlatformManager.updatePhysicsPlatforms(dtime);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SampleBridges::helpRender(PxU32 x, PxU32 y, PxU8 textAlpha)
|
||||
{
|
||||
Renderer* renderer = getRenderer();
|
||||
const PxU32 yInc = 18;
|
||||
const PxReal scale = 0.5f;
|
||||
const PxReal shadowOffset = 6.0f;
|
||||
const RendererColor textColor(255, 255, 255, textAlpha);
|
||||
const bool isMouseSupported = getApplication().getPlatform()->getSampleUserInput()->mouseSupported();
|
||||
const bool isPadSupported = getApplication().getPlatform()->getSampleUserInput()->gamepadSupported();
|
||||
const char* msg;
|
||||
|
||||
if (isMouseSupported && isPadSupported)
|
||||
renderer->print(x, y += yInc, "Use mouse or right stick to rotate the camera", scale, shadowOffset, textColor);
|
||||
else if (isMouseSupported)
|
||||
renderer->print(x, y += yInc, "Use mouse to rotate the camera", scale, shadowOffset, textColor);
|
||||
else if (isPadSupported)
|
||||
renderer->print(x, y += yInc, "Use right stick to rotate the camera", scale, shadowOffset, textColor);
|
||||
if (isPadSupported)
|
||||
renderer->print(x, y += yInc, "Use left stick to move",scale, shadowOffset, textColor);
|
||||
msg = mApplication.inputMoveInfoMsg("Press "," to move", CAMERA_MOVE_FORWARD,CAMERA_MOVE_BACKWARD, CAMERA_MOVE_LEFT, CAMERA_MOVE_RIGHT);
|
||||
if(msg)
|
||||
renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor);
|
||||
msg = mApplication.inputInfoMsg("Press "," to move fast", CAMERA_SHIFT_SPEED, -1);
|
||||
if(msg)
|
||||
renderer->print(x, y += yInc, msg, scale, shadowOffset, textColor);
|
||||
msg = mApplication.inputInfoMsg("Press "," to jump", CAMERA_JUMP,-1);
|
||||
if(msg)
|
||||
renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor);
|
||||
msg = mApplication.inputInfoMsg("Press "," to crouch", CAMERA_CROUCH,-1);
|
||||
if(msg)
|
||||
renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor); ;
|
||||
msg = mApplication.inputInfoMsg("Press "," to throw an object", SPAWN_DEBUG_OBJECT, -1);
|
||||
if(msg)
|
||||
renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor); ;
|
||||
msg = mApplication.inputInfoMsg("Press "," to reset CCT position", RETRY,-1);
|
||||
if(msg)
|
||||
renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor);
|
||||
msg = mApplication.inputInfoMsg("Press "," to teleport from one platform to another", TELEPORT,-1);
|
||||
if(msg)
|
||||
renderer->print(x, y += yInc, msg,scale, shadowOffset, textColor);
|
||||
}
|
||||
|
||||
void SampleBridges::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 configuration and run-time control of the";
|
||||
char line1[256]="PhysX kinematic character controller (cct). In particular, the";
|
||||
char line2[256]="interaction between the cct and both kinematic and dynamic scene objects";
|
||||
char line3[256]="is presented. Jointed bridges with a variety of configurations are also";
|
||||
char line4[256]="added to the scene to illustrate the setup code and behavior of some of";
|
||||
char line5[256]="the different joint types supported by the PhysX SDK.";
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SampleBridges::customizeRender()
|
||||
{
|
||||
// PT: add a simple screenquad when underwater
|
||||
if(getCamera().getPos().y<mWaterY)
|
||||
{
|
||||
const RendererColor color(0, 90, 90);
|
||||
ScreenQuad sq;
|
||||
sq.mLeftUpColor = color;
|
||||
sq.mRightUpColor = color;
|
||||
sq.mLeftDownColor = color;
|
||||
sq.mRightDownColor = color;
|
||||
sq.mAlpha = 0.75;
|
||||
|
||||
getRenderer()->drawScreenQuad(sq);
|
||||
}
|
||||
}
|
||||
|
||||
149
physx/samples/samplebridges/SampleBridges.h
Normal file
149
physx/samples/samplebridges/SampleBridges.h
Normal file
@ -0,0 +1,149 @@
|
||||
//
|
||||
// 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_BRIDGES_H
|
||||
#define SAMPLE_BRIDGES_H
|
||||
|
||||
#include "PhysXSample.h"
|
||||
#include "PxSimulationEventCallback.h"
|
||||
#include "SampleBridgesSettings.h"
|
||||
#include "KinematicPlatform.h"
|
||||
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
#include "characterkinematic/PxController.h"
|
||||
#include "characterkinematic/PxControllerBehavior.h"
|
||||
#endif
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
#include "characterkinematic/PxControllerObstacles.h"
|
||||
#endif
|
||||
|
||||
namespace physx
|
||||
{
|
||||
class PxJoint;
|
||||
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
class PxControllerManager;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
class SampleCCTCameraController;
|
||||
class ControlledActor;
|
||||
#endif
|
||||
|
||||
class SampleBridges : public PhysXSample
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
, public PxUserControllerHitReport, public PxControllerBehaviorCallback, public PxQueryFilterCallback
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
SampleBridges(PhysXSampleApplication& app);
|
||||
virtual ~SampleBridges();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Implements RAWImportCallback
|
||||
virtual void newMesh(const RAWMesh&);
|
||||
virtual void newShape(const RAWShape&);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Implements SampleApplication
|
||||
virtual void onInit();
|
||||
virtual void onInit(bool restart) { onInit(); }
|
||||
virtual void onShutdown();
|
||||
virtual void onTickPreRender(float dtime);
|
||||
virtual void onTickPostRender(float dtime);
|
||||
virtual void onDigitalInputEvent(const SampleFramework::InputEvent& , bool val);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Implements PhysXSampleApplication
|
||||
virtual void helpRender(PxU32 x, PxU32 y, PxU8 textAlpha);
|
||||
virtual void descriptionRender(PxU32 x, PxU32 y, PxU8 textAlpha);
|
||||
virtual void customizeSample(SampleSetup&);
|
||||
virtual void customizeSceneDesc(PxSceneDesc&);
|
||||
virtual void customizeRender();
|
||||
virtual void onSubstep(float dtime);
|
||||
virtual void collectInputEvents(std::vector<const SampleFramework::InputEvent*>& inputEvents);
|
||||
virtual PxU32 getDebugObjectTypes() const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
// 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& shape, const PxActor& actor);
|
||||
virtual PxControllerBehaviorFlags getBehaviorFlags(const PxController& controller);
|
||||
virtual PxControllerBehaviorFlags getBehaviorFlags(const PxObstacle& obstacle);
|
||||
|
||||
// Implements PxQueryFilterCallback
|
||||
virtual PxQueryHitType::Enum preFilter(const PxFilterData& filterData, const PxShape* shape, const PxRigidActor* actor, PxHitFlags& queryFlags);
|
||||
virtual PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit);
|
||||
#endif
|
||||
|
||||
private:
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
SampleCCTCameraController* mCCTCamera;
|
||||
ControlledActor* mActor;
|
||||
PxControllerManager* mControllerManager;
|
||||
PxExtendedVec3 mControllerInitialPosition;
|
||||
#endif
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
PxObstacleContext* mObstacleContext;
|
||||
PxBoxObstacle* mBoxObstacles;
|
||||
#endif
|
||||
PxReal mGlobalScale;
|
||||
std::vector<PxJoint*> mJoints;
|
||||
KinematicPlatformManager mPlatformManager;
|
||||
PxU32 mCurrentPlatform;
|
||||
PxF32 mElapsedRenderTime;
|
||||
|
||||
RenderMaterial* mRockMaterial;
|
||||
RenderMaterial* mWoodMaterial;
|
||||
RenderMaterial* mPlatformMaterial;
|
||||
|
||||
PxRigidActor* mBomb;
|
||||
PxReal mBombTimer;
|
||||
|
||||
PxReal mWaterY;
|
||||
bool mMustResync;
|
||||
bool mEnableCCTDebugRender;
|
||||
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
void updateRenderPlatforms(float dtime);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
204
physx/samples/samplebridges/SampleBridgesCCT.cpp
Normal file
204
physx/samples/samplebridges/SampleBridgesCCT.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
//
|
||||
// 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 "SampleBridges.h"
|
||||
#include "SampleUtils.h"
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "SampleAllocatorSDKClasses.h"
|
||||
#include "SampleBridgesInputEventIds.h"
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
#include "KinematicPlatform.h"
|
||||
#include "SampleCCTActor.h"
|
||||
#include "SampleCCTCameraController.h"
|
||||
extern const char* gPlankName;
|
||||
extern const char* gPlatformName;
|
||||
#endif
|
||||
#include <SamplePlatform.h>
|
||||
#include <SampleUserInput.h>
|
||||
#include <SampleUserInputIds.h>
|
||||
#include <SampleUserInputDefines.h>
|
||||
|
||||
using namespace SampleRenderer;
|
||||
using namespace SampleFramework;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SampleBridges::collectInputEvents(std::vector<const InputEvent*>& inputEvents)
|
||||
{
|
||||
PhysXSample::collectInputEvents(inputEvents);
|
||||
getApplication().getPlatform()->getSampleUserInput()->unregisterInputEvent(VARIABLE_TIMESTEP);
|
||||
|
||||
//digital keyboard events
|
||||
DIGITAL_INPUT_EVENT_DEF(RETRY, WKEY_R, OSXKEY_R, LINUXKEY_R );
|
||||
DIGITAL_INPUT_EVENT_DEF(TELEPORT, WKEY_T, OSXKEY_T, LINUXKEY_T );
|
||||
DIGITAL_INPUT_EVENT_DEF(CAMERA_LINK, WKEY_X, OSXKEY_X, LINUXKEY_X );
|
||||
DIGITAL_INPUT_EVENT_DEF(DEBUG_RENDER, WKEY_J, OSXKEY_J, LINUXKEY_J );
|
||||
|
||||
// gamepad events
|
||||
DIGITAL_INPUT_EVENT_DEF(RETRY, GAMEPAD_DIGI_LEFT, OSXKEY_UNKNOWN, LINUXKEY_UNKNOWN );
|
||||
DIGITAL_INPUT_EVENT_DEF(TELEPORT, GAMEPAD_DIGI_RIGHT, OSXKEY_UNKNOWN, LINUXKEY_UNKNOWN );
|
||||
DIGITAL_INPUT_EVENT_DEF(CAMERA_LINK, GAMEPAD_DIGI_DOWN, OSXKEY_UNKNOWN, LINUXKEY_UNKNOWN );
|
||||
}
|
||||
|
||||
PxU32 SampleBridges::getDebugObjectTypes() const
|
||||
{
|
||||
return DEBUG_OBJECT_BOX | DEBUG_OBJECT_SPHERE | DEBUG_OBJECT_CAPSULE | DEBUG_OBJECT_CONVEX;
|
||||
}
|
||||
|
||||
void SampleBridges::onDigitalInputEvent(const InputEvent& ie, bool val)
|
||||
{
|
||||
switch (ie.m_Id)
|
||||
{
|
||||
case RETRY:
|
||||
{
|
||||
if(val)
|
||||
{
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
mActor->reset();
|
||||
mCCTCamera->setView(0,0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TELEPORT:
|
||||
{
|
||||
if(val)
|
||||
{
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
if(mCurrentPlatform==0xffffffff)
|
||||
mCurrentPlatform = 0;
|
||||
else
|
||||
{
|
||||
mCurrentPlatform++;
|
||||
if(mCurrentPlatform==mPlatformManager.getNbPlatforms())
|
||||
mCurrentPlatform = 0;
|
||||
}
|
||||
const KinematicPlatform* platform = mPlatformManager.getPlatforms()[mCurrentPlatform];
|
||||
const float y = 3.0f;
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
mActor->teleport(platform->getRenderPose().p+PxVec3(0.0f, y, 0.0f));
|
||||
#else
|
||||
mActor->teleport(platform->getPhysicsPose().p+PxVec3(0.0f, y, 0.0f));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CAMERA_LINK:
|
||||
{
|
||||
if(val)
|
||||
{
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
mCCTCamera->setCameraLinkToPhysics(!mCCTCamera->getCameraLinkToPhysics());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DEBUG_RENDER:
|
||||
{
|
||||
if(val)
|
||||
mEnableCCTDebugRender = !mEnableCCTDebugRender;
|
||||
}
|
||||
}
|
||||
|
||||
PhysXSample::onDigitalInputEvent(ie,val);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static PxFilterFlags SampleBridgesFilterShader( PxFilterObjectAttributes attributes0, PxFilterData filterData0,
|
||||
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
|
||||
PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
|
||||
{
|
||||
pairFlags = PxPairFlag::eCONTACT_DEFAULT;
|
||||
|
||||
return PxFilterFlags();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SampleBridges::customizeSceneDesc(PxSceneDesc& sceneDesc)
|
||||
{
|
||||
sceneDesc.filterShader = SampleBridgesFilterShader;
|
||||
sceneDesc.flags |= PxSceneFlag::eREQUIRE_RW_LOCK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef CCT_ON_BRIDGES
|
||||
void SampleBridges::onShapeHit(const PxControllerShapeHit& hit)
|
||||
{
|
||||
defaultCCTInteraction(hit);
|
||||
}
|
||||
|
||||
PxControllerBehaviorFlags SampleBridges::getBehaviorFlags(const PxShape& shape, const PxActor& actor)
|
||||
{
|
||||
const char* actorName = actor.getName();
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
PX_ASSERT(actorName!=gPlatformName); // PT: in this mode we should have filtered out those guys already
|
||||
#endif
|
||||
|
||||
// PT: ride on planks
|
||||
if(actorName==gPlankName)
|
||||
return PxControllerBehaviorFlag::eCCT_CAN_RIDE_ON_OBJECT;
|
||||
|
||||
// PT: ride & slide on platforms
|
||||
if(actorName==gPlatformName)
|
||||
return PxControllerBehaviorFlag::eCCT_CAN_RIDE_ON_OBJECT|PxControllerBehaviorFlag::eCCT_SLIDE;
|
||||
|
||||
return PxControllerBehaviorFlags(0);
|
||||
}
|
||||
|
||||
PxControllerBehaviorFlags SampleBridges::getBehaviorFlags(const PxController&)
|
||||
{
|
||||
return PxControllerBehaviorFlags(0);
|
||||
}
|
||||
|
||||
PxControllerBehaviorFlags SampleBridges::getBehaviorFlags(const PxObstacle&)
|
||||
{
|
||||
return PxControllerBehaviorFlag::eCCT_CAN_RIDE_ON_OBJECT|PxControllerBehaviorFlag::eCCT_SLIDE;
|
||||
}
|
||||
|
||||
PxQueryHitType::Enum SampleBridges::preFilter(const PxFilterData& filterData, const PxShape* shape, const PxRigidActor* actor, PxHitFlags& queryFlags)
|
||||
{
|
||||
#ifdef PLATFORMS_AS_OBSTACLES
|
||||
const char* actorName = shape->getActor()->getName();
|
||||
if(actorName==gPlatformName)
|
||||
return PxQueryHitType::eNONE;
|
||||
#endif
|
||||
|
||||
return PxQueryHitType::eBLOCK;
|
||||
}
|
||||
|
||||
PxQueryHitType::Enum SampleBridges::postFilter(const PxFilterData& filterData, const PxQueryHit& hit)
|
||||
{
|
||||
return PxQueryHitType::eBLOCK;
|
||||
}
|
||||
|
||||
#endif
|
||||
46
physx/samples/samplebridges/SampleBridgesInputEventIds.h
Normal file
46
physx/samples/samplebridges/SampleBridgesInputEventIds.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_BRIDGES_INPUT_EVENT_IDS_H
|
||||
#define _SAMPLE_BRIDGES_INPUT_EVENT_IDS_H
|
||||
|
||||
#include <SampleBaseInputEventIds.h>
|
||||
|
||||
// InputEvents used by SampleBridges
|
||||
enum SampleBridgesInputEventIds
|
||||
{
|
||||
SAMPLE_BRIDGES_FIRST_ID = NUM_SAMPLE_BASE_INPUT_EVENT_IDS,
|
||||
|
||||
RETRY,
|
||||
CAMERA_LINK,
|
||||
TELEPORT,
|
||||
DEBUG_RENDER,
|
||||
|
||||
NUM_SAMPLE_BRIDGS_INPUT_EVENT_IDS
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
37
physx/samples/samplebridges/SampleBridgesSettings.h
Normal file
37
physx/samples/samplebridges/SampleBridgesSettings.h
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// 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_BRIDGES_SETTINGS_H
|
||||
#define SAMPLE_BRIDGES_SETTINGS_H
|
||||
|
||||
#define CCT_ON_BRIDGES // Enable CCT in this sample, or just create dynamic bridges
|
||||
// #define PLATFORMS_AS_OBSTACLES // Enable variable-stepped "obstacle" platforms, else regular kinematic objects
|
||||
#define ROTATING_PLATFORMS // Enable rotating platforms
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user