diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Samples/SampleCCTSharedCode | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'PhysX_3.4/Samples/SampleCCTSharedCode')
8 files changed, 1600 insertions, 0 deletions
diff --git a/PhysX_3.4/Samples/SampleCCTSharedCode/KinematicPlatform.cpp b/PhysX_3.4/Samples/SampleCCTSharedCode/KinematicPlatform.cpp new file mode 100644 index 00000000..62a23bc4 --- /dev/null +++ b/PhysX_3.4/Samples/SampleCCTSharedCode/KinematicPlatform.cpp @@ -0,0 +1,270 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "SamplePreprocessor.h" +#include "KinematicPlatform.h" +#include "RendererMemoryMacros.h" +#include "PxScene.h" +#include "PxSceneLock.h" +#include "PxRigidDynamic.h" +#include "PxTkMatrixUtils.h" + +PlatformState::PlatformState() : + mCurrentTime (0.0f), + mCurrentRotationTime(0.0f), + mFlip (false) +{ + mPrevPose = PxTransform(PxIdentity); +} + +KinematicPlatform::KinematicPlatform() : + mNbPts (0), + mPts (NULL), + mActor (NULL), + mBoxObstacle (NULL), + mObstacle (INVALID_OBSTACLE_HANDLE), + mTravelTime (0.0f), + mRotationSpeed (0.0f), + mMode (LOOP_FLIP) +{ +} + +KinematicPlatform::~KinematicPlatform() +{ + DELETEARRAY(mPts); +} + +void KinematicPlatform::release() +{ + delete this; +} + +void KinematicPlatform::init(PxU32 nbPts, const PxVec3* pts, const PxTransform& globalPose, const PxQuat& localRot, PxRigidDynamic* actor, PxReal travelTime, PxReal rotationSpeed, LoopMode mode) +{ + DELETEARRAY(mPts); + mNbPts = nbPts; + mPts = SAMPLE_NEW(PxVec3Alloc)[nbPts]; + PxVec3* dst = mPts; + for(PxU32 i=0;i<nbPts;i++) + dst[i] = globalPose.transform(pts[i]); + + mLocalRot = localRot; + mActor = actor; + mTravelTime = travelTime; + mRotationSpeed = rotationSpeed; + mMode = mode; + PX_ASSERT(travelTime>0.0f); +} + +void KinematicPlatform::setBoxObstacle(ObstacleHandle handle, const PxBoxObstacle* boxObstacle) +{ + mObstacle = handle; + mBoxObstacle = boxObstacle; +} + +PxU32 KinematicPlatform::getNbSegments() const +{ + return mNbPts - 1; +} + +PxReal KinematicPlatform::computeLength() const +{ + const PxU32 nbSegments = getNbSegments(); + + float totalLength = 0.0f; + for(PxU32 i=0;i<nbSegments;i++) + { + const PxU32 a = i % mNbPts; + const PxU32 b = (i+1) % mNbPts; + totalLength += (mPts[b] - mPts[a]).magnitude(); + } + return totalLength; +} + +bool KinematicPlatform::getPoint(PxVec3& p, PxU32 seg, PxReal t) const +{ + const PxU32 a = seg % mNbPts; + const PxU32 b = (seg+1) % mNbPts; + const PxVec3& p0 = mPts[a]; + const PxVec3& p1 = mPts[b]; + p = (1.0f - t) * p0 + t * p1; + return true; +} + +bool KinematicPlatform::getPoint(PxVec3& p, PxReal t) const +{ + // ### Not really optimized + + const PxReal totalLength = computeLength(); + const PxReal coeff = 1.0f / totalLength; + + const PxU32 nbSegments = getNbSegments(); + + PxReal currentLength = 0.0f; + for(PxU32 i=0;i<nbSegments;i++) + { + const PxU32 a = i % mNbPts; + const PxU32 b = (i+1) % mNbPts; + const PxReal length = coeff * (mPts[b] - mPts[a]).magnitude(); + + if(t>=currentLength && t<=currentLength + length) + { + // Desired point is on current segment + // currentLength maps to 0.0 + // currentLength+length maps to 1.0 + const PxReal nt = (t-currentLength)/(length); + return getPoint(p, i, nt); + } + currentLength += length; + } + return false; +} + +void KinematicPlatform::setT(PxF32 t) +{ + if(t<0.0f || t>1.0f) + { + PX_ASSERT(0); + return; + } + + const PxF32 curTime = mTravelTime*t; + + mPhysicsState.mCurrentTime = curTime; + mRenderState.mCurrentTime = curTime; +} + +void KinematicPlatform::updateState(PlatformState& state, PxObstacleContext* obstacleContext, PxReal dtime, bool updateActor) const +{ + state.mCurrentTime += dtime; + state.mCurrentRotationTime += dtime; + + // Compute current position on the path + PxReal t = state.mCurrentTime/mTravelTime; + if(t>1.0f) + { + if(mMode==LOOP_FLIP) + { + state.mFlip = !state.mFlip; + // Make it loop + state.mCurrentTime = fmodf(state.mCurrentTime, mTravelTime); + t = state.mCurrentTime/mTravelTime; + } + else + { + PX_ASSERT(mMode==LOOP_WRAP); +// state.mCurrentTime = fmodf(state.mCurrentTime, mTravelTime); + t = 1.0f - t; + state.mCurrentTime = t * mTravelTime; + } + } + + PxVec3 currentPos; + if(getPoint(currentPos, state.mFlip ? 1.0f - t : t)) + { + const PxVec3 wp = currentPos; + + PxMat33 rotY; + PxToolkit::setRotX(rotY, state.mCurrentRotationTime*mRotationSpeed); + const PxQuat rotation(rotY); + + const PxTransform tr(wp, mLocalRot * rotation); + +//PxVec3 delta = wp - state.mPrevPos; +//shdfnd::printFormatted("Kine: %f | %f | %f\n", delta.x, delta.y, delta.z); +state.mPrevPose = tr; + if(updateActor) + { + PxSceneWriteLock scopedLock(*mActor->getScene()); + mActor->setKinematicTarget(tr); // * +/*PxVec3 test = mActor->getGlobalPose().p; +test -= tr.p; +shdfnd::printFormatted("%f | %f | %f\n", test.x, test.y, test.z);*/ + } + else if(obstacleContext && mBoxObstacle) + { + PxBoxObstacle localBox = *mBoxObstacle; + localBox.mPos.x = wp.x; + localBox.mPos.y = wp.y; + localBox.mPos.z = wp.z; + localBox.mRot = tr.q; + bool status = obstacleContext->updateObstacle(mObstacle, localBox); + PX_ASSERT(status); + PX_UNUSED(status); + } + } +} + +void KinematicPlatform::resync() +{ + mPhysicsState = mRenderState; +} + +/////////////////////////////////////////////////////////////////////////////// + +KinematicPlatformManager::KinematicPlatformManager() : + mElapsedPlatformTime(0.0f) +{ +} + +KinematicPlatformManager::~KinematicPlatformManager() +{ +} + +void KinematicPlatformManager::release() +{ + const size_t nbPlatforms = mPlatforms.size(); + for(PxU32 i=0;i<nbPlatforms;i++) + mPlatforms[i]->release(); + mPlatforms.clear(); +} + +KinematicPlatform* KinematicPlatformManager::createPlatform(PxU32 nbPts, const PxVec3* pts, const PxTransform& pose, const PxQuat& localRot, PxRigidDynamic* actor, PxReal platformSpeed, PxReal rotationSpeed, LoopMode mode) +{ + KinematicPlatform* kine = SAMPLE_NEW(KinematicPlatform); + kine->init(nbPts, pts, pose, localRot, actor, 1.0f, rotationSpeed, mode); + mPlatforms.push_back(kine); + + const PxReal pathLength = kine->computeLength(); + kine->setTravelTime(pathLength / platformSpeed); + return kine; +} + +void KinematicPlatformManager::updatePhysicsPlatforms(float dtime) +{ + // PT: keep track of time from the point of view of physics platforms. + // - if we call this each substep using fixed timesteps, it is never exactly in sync with the render time. + // - if we drop substeps because of the "well of despair", it can seriously lag behind the render time. + mElapsedPlatformTime += dtime; + + // PT: compute new positions for (physics) platforms, then 'setKinematicTarget' their physics actors to these positions. + const size_t nbPlatforms = mPlatforms.size(); + for(PxU32 i=0;i<nbPlatforms;i++) + mPlatforms[i]->updatePhysics(dtime); +} diff --git a/PhysX_3.4/Samples/SampleCCTSharedCode/KinematicPlatform.h b/PhysX_3.4/Samples/SampleCCTSharedCode/KinematicPlatform.h new file mode 100644 index 00000000..9ec67914 --- /dev/null +++ b/PhysX_3.4/Samples/SampleCCTSharedCode/KinematicPlatform.h @@ -0,0 +1,132 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + + +#ifndef KINEMATIC_PLATFORM_H +#define KINEMATIC_PLATFORM_H + +#include "common/PxPhysXCommonConfig.h" +#include "foundation/PxTransform.h" +#include "SampleAllocator.h" +#include "SampleAllocatorSDKClasses.h" +#include "characterkinematic/PxControllerObstacles.h" +#include <vector> + +namespace physx +{ + class PxRigidDynamic; +} + + // PT: Captures the state of the platform. We decouple this data from the platform itself so that the + // same platform path (const data) can be used by several platform instances. + struct PlatformState + { + PlatformState(); + + PxTransform mPrevPose; + PxReal mCurrentTime; + PxReal mCurrentRotationTime; + bool mFlip; + }; + + enum LoopMode + { + LOOP_FLIP, + LOOP_WRAP, + }; + + class KinematicPlatform : public SampleAllocateable + { + public: + KinematicPlatform(); + ~KinematicPlatform(); + + void release(); + void init(PxU32 nbPts, const PxVec3* pts, const PxTransform& globalPose, const PxQuat& localRot, PxRigidDynamic* actor, PxReal travelTime, PxReal rotationSpeed, LoopMode mode=LOOP_FLIP); + void setBoxObstacle(ObstacleHandle handle, const PxBoxObstacle* boxObstacle); + PxU32 getNbSegments() const; + PxReal computeLength() const; + bool getPoint(PxVec3& p, PxU32 seg, PxReal t) const; + bool getPoint(PxVec3& p, PxReal t) const; + void resync(); + + PX_FORCE_INLINE void updatePhysics(PxReal dtime) { updateState(mPhysicsState, NULL, dtime, true); } + PX_FORCE_INLINE void updateRender(PxReal dtime, PxObstacleContext* obstacleContext) { updateState(mRenderState, obstacleContext, dtime, false); } + + PX_FORCE_INLINE PxReal getTravelTime() const { return mTravelTime; } + PX_FORCE_INLINE void setTravelTime(PxReal t) { mTravelTime = t; } + void setT(PxF32 t); + + PX_FORCE_INLINE const PxTransform& getPhysicsPose() const { return mPhysicsState.mPrevPose; } + PX_FORCE_INLINE const PxTransform& getRenderPose() const { return mRenderState.mPrevPose; } + + PX_FORCE_INLINE PxRigidDynamic* getPhysicsActor() { return mActor; } + + PX_FORCE_INLINE PxReal getRotationSpeed() const { return mRotationSpeed; } + PX_FORCE_INLINE void setRotationSpeed(PxReal s) { mRotationSpeed = s; } + + protected: + PxQuat mLocalRot; // Local rotation (const data) + PxU32 mNbPts; + PxVec3Alloc* mPts; + PxRigidDynamic* mActor; // Physics + const PxBoxObstacle* mBoxObstacle; + ObstacleHandle mObstacle; // Render + PxReal mTravelTime; + PxReal mRotationSpeed; + LoopMode mMode; + + PlatformState mPhysicsState; + PlatformState mRenderState; + void updateState(PlatformState& state, PxObstacleContext* obstacleContext, PxReal dtime, bool updateActor) const; + }; + + class KinematicPlatformManager : public SampleAllocateable + { + public: + KinematicPlatformManager(); + ~KinematicPlatformManager(); + + void release(); + KinematicPlatform* createPlatform(PxU32 nbPts, const PxVec3* pts, const PxTransform& pose, const PxQuat& localRot, PxRigidDynamic* actor, PxReal platformSpeed, PxReal rotationSpeed, LoopMode mode=LOOP_FLIP); + + PX_FORCE_INLINE PxU32 getNbPlatforms() { return (PxU32)mPlatforms.size(); } + PX_FORCE_INLINE KinematicPlatform** getPlatforms() { return &mPlatforms[0]; } + PX_FORCE_INLINE PxF32 getElapsedTime() { return mElapsedPlatformTime; } + PX_FORCE_INLINE void syncElapsedTime(float time) { mElapsedPlatformTime = time; } + + void updatePhysicsPlatforms(float dtime); + + protected: + std::vector<KinematicPlatform*> mPlatforms; + PxF32 mElapsedPlatformTime; + }; + + +#endif diff --git a/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTActor.cpp b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTActor.cpp new file mode 100644 index 00000000..bf763905 --- /dev/null +++ b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTActor.cpp @@ -0,0 +1,329 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "SampleCCTActor.h" +#include "characterkinematic/PxBoxController.h" +#include "characterkinematic/PxCapsuleController.h" +#include "characterkinematic/PxControllerManager.h" +#include "RenderBoxActor.h" +#include "RenderCapsuleActor.h" +#include "PhysXSample.h" + +using namespace physx; +using namespace SampleRenderer; + +/////////////////////////////////////////////////////////////////////////////// + +ControlledActorDesc::ControlledActorDesc() : + mType (PxControllerShapeType::eFORCE_DWORD), + mPosition (PxExtendedVec3(0,0,0)), + mSlopeLimit (0.0f), + mContactOffset (0.0f), + mStepOffset (0.0f), + mInvisibleWallHeight(0.0f), + mMaxJumpHeight (0.0f), + mRadius (0.0f), + mHeight (0.0f), + mCrouchHeight (0.0f), + mProxyDensity (10.0f), +// mProxyScale (0.8f) + mProxyScale (0.9f), + mVolumeGrowth (1.5f), + mReportCallback (NULL), + mBehaviorCallback (NULL) +{ +} + +/////////////////////////////////////////////////////////////////////////////// + +ControlledActor::ControlledActor(PhysXSample& owner) : + mOwner (owner), + mType (PxControllerShapeType::eFORCE_DWORD), + mController (NULL), + mRenderActorStanding (NULL), + mRenderActorCrouching (NULL), + mStandingSize (0.0f), + mCrouchingSize (0.0f), + mControllerRadius (0.0f), + mDoStandup (false), + mIsCrouching (false) +{ + mInitialPosition = PxExtendedVec3(0,0,0); + mDelta = PxVec3(0); + mTransferMomentum = false; +} + +ControlledActor::~ControlledActor() +{ +} + +void ControlledActor::reset() +{ + PxSceneWriteLock scopedLock(mOwner.getActiveScene()); + mController->setPosition(mInitialPosition); +} + +void ControlledActor::teleport(const PxVec3& pos) +{ + PxSceneWriteLock scopedLock(mOwner.getActiveScene()); + mController->setPosition(PxExtendedVec3(pos.x, pos.y, pos.z)); + mTransferMomentum = false; + mDelta = PxVec3(0); +} + +PxExtendedVec3 ControlledActor::getFootPosition() const +{ + return mController->getFootPosition(); +} + +void ControlledActor::sync() +{ + if(mDoStandup) + tryStandup(); + + if(mRenderActorStanding) + mRenderActorStanding->setRendering(!mIsCrouching); + if(mRenderActorCrouching) + mRenderActorCrouching->setRendering(mIsCrouching); + + const PxExtendedVec3& newPos = mController->getPosition(); + + const PxTransform tr(toVec3(newPos)); + +// shdfnd::printFormatted("%f %f %f\n", tr.p.x, tr.p.y, tr.p.z); + + if(mRenderActorStanding) + mRenderActorStanding->setTransform(tr); + if(mRenderActorCrouching) + mRenderActorCrouching->setTransform(tr); +} + +PxController* ControlledActor::init(const ControlledActorDesc& desc, PxControllerManager* manager) +{ + const float radius = desc.mRadius; + float height = desc.mHeight; + float crouchHeight = desc.mCrouchHeight; + + PxControllerDesc* cDesc; + PxBoxControllerDesc boxDesc; + PxCapsuleControllerDesc capsuleDesc; + + if(desc.mType==PxControllerShapeType::eBOX) + { + height *= 0.5f; + height += radius; + crouchHeight *= 0.5f; + crouchHeight += radius; + boxDesc.halfHeight = height; + boxDesc.halfSideExtent = radius; + boxDesc.halfForwardExtent = radius; + cDesc = &boxDesc; + } + else + { + PX_ASSERT(desc.mType==PxControllerShapeType::eCAPSULE); + capsuleDesc.height = height; + capsuleDesc.radius = radius; + capsuleDesc.climbingMode = PxCapsuleClimbingMode::eCONSTRAINED; + cDesc = &capsuleDesc; + } + + cDesc->density = desc.mProxyDensity; + cDesc->scaleCoeff = desc.mProxyScale; + cDesc->material = &mOwner.getDefaultMaterial(); + cDesc->position = desc.mPosition; + cDesc->slopeLimit = desc.mSlopeLimit; + cDesc->contactOffset = desc.mContactOffset; + cDesc->stepOffset = desc.mStepOffset; + cDesc->invisibleWallHeight = desc.mInvisibleWallHeight; + cDesc->maxJumpHeight = desc.mMaxJumpHeight; +// cDesc->nonWalkableMode = PxControllerNonWalkableMode::ePREVENT_CLIMBING_AND_FORCE_SLIDING; + cDesc->reportCallback = desc.mReportCallback; + cDesc->behaviorCallback = desc.mBehaviorCallback; + cDesc->volumeGrowth = desc.mVolumeGrowth; + + mType = desc.mType; + mInitialPosition = desc.mPosition; + mStandingSize = height; + mCrouchingSize = crouchHeight; + mControllerRadius = radius; + + PxController* ctrl = static_cast<PxBoxController*>(manager->createController(*cDesc)); + PX_ASSERT(ctrl); + + // 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); + + Renderer* renderer = mOwner.getRenderer(); + + if(desc.mType==PxControllerShapeType::eBOX) + { + const PxVec3 standingExtents(radius, height, radius); + const PxVec3 crouchingExtents(radius, crouchHeight, radius); + + mRenderActorStanding = SAMPLE_NEW(RenderBoxActor)(*renderer, standingExtents); + mRenderActorCrouching = SAMPLE_NEW(RenderBoxActor)(*renderer, crouchingExtents); + } + else if(desc.mType==PxControllerShapeType::eCAPSULE) + { + mRenderActorStanding = SAMPLE_NEW(RenderCapsuleActor)(*renderer, radius, height*0.5f); + mRenderActorCrouching = SAMPLE_NEW(RenderCapsuleActor)(*renderer, radius, crouchHeight*0.5f); + } + } + } + + mController = ctrl; + return ctrl; +} + +void ControlledActor::tryStandup() +{ + // overlap with upper part + if(mType==PxControllerShapeType::eBOX) + { + } + else if(mType==PxControllerShapeType::eCAPSULE) + { + PxScene* scene = mController->getScene(); + PxSceneReadLock scopedLock(*scene); + + PxCapsuleController* capsuleCtrl = static_cast<PxCapsuleController*>(mController); + + PxReal r = capsuleCtrl->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(scene->overlap(geom, PxTransform(pos,orientation), hit, PxQueryFilterData(PxQueryFlag::eANY_HIT|PxQueryFlag::eSTATIC|PxQueryFlag::eDYNAMIC))) + return; + } + + // if no hit, we can stand up + resizeStanding(); + + mDoStandup = false; + mIsCrouching = false; +} + +void ControlledActor::resizeController(PxReal height) +{ + PxSceneWriteLock scopedLock(mOwner.getActiveScene()); + mIsCrouching = true; + mController->resize(height); +} + + + +// PT: I'm forced to duplicate this code here for now, since otherwise "eACCELERATION" is banned + +PX_INLINE void addForceAtPosInternal(PxRigidBody& body, const PxVec3& force, const PxVec3& pos, PxForceMode::Enum mode, bool wakeup) +{ +/* if(mode == PxForceMode::eACCELERATION || mode == PxForceMode::eVELOCITY_CHANGE) + { + Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxRigidBodyExt::addForce methods do not support eACCELERATION or eVELOCITY_CHANGE modes"); + return; + }*/ + + const PxTransform globalPose = body.getGlobalPose(); + const PxVec3 centerOfMass = globalPose.transform(body.getCMassLocalPose().p); + + const PxVec3 torque = (pos - centerOfMass).cross(force); + body.addForce(force, mode, wakeup); + body.addTorque(torque, mode, wakeup); +} + +static void addForceAtLocalPos(PxRigidBody& body, const PxVec3& force, const PxVec3& pos, PxForceMode::Enum mode, bool wakeup=true) +{ + //transform pos to world space + const PxVec3 globalForcePos = body.getGlobalPose().transform(pos); + + addForceAtPosInternal(body, force, globalForcePos, mode, wakeup); +} + +void defaultCCTInteraction(const PxControllerShapeHit& hit) +{ + PxRigidDynamic* actor = hit.shape->getActor()->is<PxRigidDynamic>(); + if(actor) + { + if(actor->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC) + return; + + if(0) + { + const PxVec3 p = actor->getGlobalPose().p + hit.dir * 10.0f; + + PxShape* shape; + actor->getShapes(&shape, 1); + PxRaycastHit newHit; + PxU32 n = PxShapeExt::raycast(*shape, *shape->getActor(), p, -hit.dir, 20.0f, PxHitFlag::ePOSITION, 1, &newHit); + if(n) + { + // 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. + const PxVec3 upVector = hit.controller->getUpDirection(); + const PxF32 dp = hit.dir.dot(upVector); + // shdfnd::printFormatted("%f\n", fabsf(dp)); + if(fabsf(dp)<1e-3f) + // if(hit.dir.y==0.0f) + { + const PxTransform globalPose = actor->getGlobalPose(); + const PxVec3 localPos = globalPose.transformInv(newHit.position); + ::addForceAtLocalPos(*actor, hit.dir*hit.length*1000.0f, localPos, PxForceMode::eACCELERATION); + } + } + } + + // 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. + const PxVec3 upVector = hit.controller->getUpDirection(); + const PxF32 dp = hit.dir.dot(upVector); +// shdfnd::printFormatted("%f\n", fabsf(dp)); + if(fabsf(dp)<1e-3f) +// if(hit.dir.y==0.0f) + { + const PxTransform globalPose = actor->getGlobalPose(); + const PxVec3 localPos = globalPose.transformInv(toVec3(hit.worldPos)); + ::addForceAtLocalPos(*actor, hit.dir*hit.length*1000.0f, localPos, PxForceMode::eACCELERATION); + } + } +} diff --git a/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTActor.h b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTActor.h new file mode 100644 index 00000000..cb8c28ad --- /dev/null +++ b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTActor.h @@ -0,0 +1,127 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef SAMPLE_CCT_ACTOR_H +#define SAMPLE_CCT_ACTOR_H + +#include "characterkinematic/PxExtended.h" +#include "characterkinematic/PxController.h" +#include "SamplePreprocessor.h" +#include "SampleCCTJump.h" + +namespace physx +{ + class PxController; + class PxUserControllerHitReport; + class PxControllerBehaviorCallback; + class PxControllerManager; + class PxPhysics; + class PxScene; +} + +using namespace physx; + +namespace SampleRenderer +{ + class Renderer; +} + +class RenderBaseActor; +class PhysXSample; + + struct ControlledActorDesc + { + ControlledActorDesc(); + + PxControllerShapeType::Enum mType; + PxExtendedVec3 mPosition; + float mSlopeLimit; + float mContactOffset; + float mStepOffset; + float mInvisibleWallHeight; + float mMaxJumpHeight; + float mRadius; + float mHeight; + float mCrouchHeight; + float mProxyDensity; + float mProxyScale; + float mVolumeGrowth; + PxUserControllerHitReport* mReportCallback; + PxControllerBehaviorCallback* mBehaviorCallback; + }; + + class ControlledActor : public SampleAllocateable + { + public: + ControlledActor(PhysXSample& owner); + virtual ~ControlledActor(); + + PxController* init(const ControlledActorDesc& desc, PxControllerManager* manager); + PxExtendedVec3 getFootPosition() const; + void reset(); + void teleport(const PxVec3& pos); + void sync(); + void tryStandup(); + void resizeController(PxReal height); + void resizeStanding() { resizeController(mStandingSize); } + void resizeCrouching() { resizeController(mCrouchingSize); } + void jump(float force) { mJump.startJump(force); } + + PX_FORCE_INLINE RenderBaseActor* getRenderActorStanding() { return mRenderActorStanding; } + PX_FORCE_INLINE RenderBaseActor* getRenderActorCrouching() { return mRenderActorCrouching; } + PX_FORCE_INLINE PxController* getController() { return mController; } + + const Jump& getJump() const { return mJump; } + + protected: + PhysXSample& mOwner; + PxControllerShapeType::Enum mType; + Jump mJump; + + PxExtendedVec3 mInitialPosition; + PxVec3 mDelta; + bool mTransferMomentum; + + PxController* mController; + RenderBaseActor* mRenderActorStanding; + RenderBaseActor* mRenderActorCrouching; + PxReal mStandingSize; + PxReal mCrouchingSize; + PxReal mControllerRadius; + bool mDoStandup; + bool mIsCrouching; + friend class SampleCCTCameraController; + + private: + ControlledActor& operator=(const ControlledActor&); + }; + + void defaultCCTInteraction(const PxControllerShapeHit& hit); + +#endif diff --git a/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTCameraController.cpp b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTCameraController.cpp new file mode 100644 index 00000000..afccab14 --- /dev/null +++ b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTCameraController.cpp @@ -0,0 +1,517 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "PhysXSample.h" +#include "SampleCCTCameraController.h" +#include "SampleCCTActor.h" +#include "SampleCCTJump.h" +#include "SampleConsole.h" +#include <SampleFrameworkInputEventIds.h> +#include <SamplePlatform.h> +#include <SampleUserInput.h> +#include <SampleUserInputIds.h> +#include <SampleUserInputDefines.h> + +using namespace SampleRenderer; +using namespace SampleFramework; + +// PT: TODO: move this inside the CCT? +static const bool gTransferPlatformMomentum = true; + +static bool gDumpCCTState = false; +static bool gDumpCCTStats = false; + +static bool canJump(ControlledActor* actor) +{ + PxControllerState cctState; + actor->getController()->getState(cctState); + return (cctState.collisionFlags & PxControllerCollisionFlag::eCOLLISION_DOWN)!=0; +} + +static void gConsole_DumpCCTState(Console* console, const char* text, void* userData) +{ + gDumpCCTState = !gDumpCCTState; +} + +static void gConsole_DumpCCTStats(Console* console, const char* text, void* userData) +{ + gDumpCCTStats = !gDumpCCTStats; +} + +#if defined(WIN32) && !PX_XBOXONE +static bool copyToClipboard(const char* text) +{ + if(!text) + return false; + + if(OpenClipboard(NULL)) + { + HGLOBAL hMem = GlobalAlloc(GHND|GMEM_DDESHARE, strlen(text)+1); + if(hMem) + { + char* pMem = (char*)GlobalLock(hMem); + strcpy(pMem, text); + GlobalUnlock(hMem); + EmptyClipboard(); + SetClipboardData(CF_TEXT, hMem); + } + CloseClipboard(); + } + return true; +} +#endif + +static void gConsole_DumpCCTPosition(Console* console, const char* text, void* userData) +{ +#if defined(WIN32) && !PX_XBOXONE + SampleCCTCameraController* sample = (SampleCCTCameraController*)userData; + const PxExtendedVec3 pos = sample->getControlledActor()->getController()->getPosition(); + + char buffer[4096]; + sprintf(buffer, "PxExtendedVec3(%f, %f, %f);", float(pos.x), float(pos.y), float(pos.z)); + copyToClipboard(buffer); + + console->out("Position has been copied to clipboard"); +#endif +} + +SampleCCTCameraController::SampleCCTCameraController(PhysXSample& base) : + mBase (base), + mObstacleContext (NULL), + mFilterData (NULL), + mFilterCallback (NULL), + mCCTFilterCallback (NULL), + mControlledIndex (0), + mNbCCTs (0), + mCCTs (NULL), + mTargetYaw (0.0f-PxPi/2), + mTargetPitch (0.0f), + mPitchMin (-PxHalfPi), + mPitchMax (PxHalfPi), + mGamepadPitchInc (0.0f), + mGamepadYawInc (0.0f), + mGamepadForwardInc (0.0f), + mGamepadLateralInc (0.0f), + mSensibility (0.001f), + mFwd (false), + mBwd (false), + mLeft (false), + mRight (false), + mKeyShiftDown (false), + mCCTEnabled (true), + mRunningSpeed (10.0f), + mWalkingSpeed (2.5f), +// mWalkingSpeed (0.5f), + mGamepadWalkingSpeed(10.0f), + mCameraMaxSpeed (FLT_MAX), + mJumpForce (30.0f), + mGravity (-9.81f), + mLinkCameraToPhysics(false) +{ + Console* console = base.getConsole(); + if(console) + { + console->addCmd("DumpCCTState", gConsole_DumpCCTState); + console->addCmd("DumpCCTStats", gConsole_DumpCCTStats); + console->addCmd("DumpCCTPosition", gConsole_DumpCCTPosition); + + console->setUserData(this); + } +} + +void SampleCCTCameraController::setControlled(ControlledActor** controlled, PxU32 controlledIndex, PxU32 nbCCTs) +{ + mControlledIndex = controlledIndex; + mNbCCTs = nbCCTs; + mCCTs = controlled; +} + +void SampleCCTCameraController::startJump() +{ + ControlledActor* actor = getControlledActor(); + if(canJump(actor)) + actor->jump(mJumpForce); +} + +void SampleCCTCameraController::collectInputEvents(std::vector<const SampleFramework::InputEvent*>& inputEvents) +{ + //digital keyboard events + DIGITAL_INPUT_EVENT_DEF(CAMERA_MOVE_FORWARD, SCAN_CODE_FORWARD, XKEY_W, X1KEY_W, PS3KEY_W, PS4KEY_W, AKEY_UNKNOWN, SCAN_CODE_FORWARD, IKEY_UNKNOWN, SCAN_CODE_FORWARD, WIIUKEY_UNKNOWN); + DIGITAL_INPUT_EVENT_DEF(CAMERA_MOVE_BACKWARD, SCAN_CODE_BACKWARD, XKEY_S, X1KEY_S, PS3KEY_S, PS4KEY_S, AKEY_UNKNOWN, SCAN_CODE_BACKWARD, IKEY_UNKNOWN, SCAN_CODE_BACKWARD, WIIUKEY_UNKNOWN); + DIGITAL_INPUT_EVENT_DEF(CAMERA_MOVE_LEFT, SCAN_CODE_LEFT, XKEY_A, X1KEY_A, PS3KEY_A, PS4KEY_A, AKEY_UNKNOWN, SCAN_CODE_LEFT, IKEY_UNKNOWN, SCAN_CODE_LEFT, WIIUKEY_UNKNOWN); + DIGITAL_INPUT_EVENT_DEF(CAMERA_MOVE_RIGHT, SCAN_CODE_RIGHT, XKEY_D, X1KEY_D, PS3KEY_D, PS4KEY_D, AKEY_UNKNOWN, SCAN_CODE_RIGHT, IKEY_UNKNOWN, SCAN_CODE_RIGHT, WIIUKEY_UNKNOWN); + DIGITAL_INPUT_EVENT_DEF(CAMERA_SHIFT_SPEED, SCAN_CODE_LEFT_SHIFT, XKEY_SHIFT, X1KEY_SHIFT, PS3KEY_SHIFT, PS4KEY_SHIFT, AKEY_UNKNOWN, OSXKEY_SHIFT, IKEY_UNKNOWN, LINUXKEY_SHIFT, WIIUKEY_UNKNOWN); + DIGITAL_INPUT_EVENT_DEF(CAMERA_JUMP, SCAN_CODE_SPACE, XKEY_SPACE, X1KEY_SPACE, PS3KEY_SPACE, PS4KEY_SPACE, AKEY_UNKNOWN, OSXKEY_SPACE, IKEY_UNKNOWN, LINUXKEY_SPACE, WIIUKEY_UNKNOWN); + DIGITAL_INPUT_EVENT_DEF(CAMERA_CROUCH, SCAN_CODE_DOWN, XKEY_C, X1KEY_C, PS3KEY_C, PS4KEY_C, AKEY_UNKNOWN, SCAN_CODE_DOWN, IKEY_UNKNOWN, SCAN_CODE_DOWN, WIIUKEY_UNKNOWN); + DIGITAL_INPUT_EVENT_DEF(CAMERA_CONTROLLER_INCREASE, WKEY_ADD, XKEY_ADD, X1KEY_ADD, PS3KEY_ADD, PS4KEY_ADD, AKEY_UNKNOWN, OSXKEY_ADD, IKEY_UNKNOWN, LINUXKEY_ADD, WIIUKEY_UNKNOWN); + DIGITAL_INPUT_EVENT_DEF(CAMERA_CONTROLLER_DECREASE, WKEY_SUBTRACT, XKEY_SUBTRACT, X1KEY_SUBTRACT, PS3KEY_SUBTRACT, PS4KEY_SUBTRACT, AKEY_UNKNOWN, OSXKEY_SUBTRACT, IKEY_UNKNOWN, LINUXKEY_SUBTRACT, WIIUKEY_UNKNOWN); + + //digital gamepad events + DIGITAL_INPUT_EVENT_DEF(CAMERA_JUMP, GAMEPAD_SOUTH, GAMEPAD_SOUTH, GAMEPAD_SOUTH, GAMEPAD_SOUTH, GAMEPAD_SOUTH, AKEY_UNKNOWN, GAMEPAD_SOUTH, IKEY_UNKNOWN, LINUXKEY_UNKNOWN, GAMEPAD_SOUTH); + DIGITAL_INPUT_EVENT_DEF(CAMERA_CROUCH, GAMEPAD_LEFT_STICK, GAMEPAD_LEFT_STICK, GAMEPAD_LEFT_STICK, GAMEPAD_LEFT_STICK, GAMEPAD_LEFT_STICK, AKEY_UNKNOWN, GAMEPAD_LEFT_STICK, IKEY_UNKNOWN, LINUXKEY_UNKNOWN, GAMEPAD_LEFT_STICK); + DIGITAL_INPUT_EVENT_DEF(CAMERA_CONTROLLER_INCREASE, GAMEPAD_RIGHT_SHOULDER_TOP, GAMEPAD_RIGHT_SHOULDER_TOP, GAMEPAD_RIGHT_SHOULDER_TOP, GAMEPAD_RIGHT_SHOULDER_TOP, GAMEPAD_RIGHT_SHOULDER_TOP, AKEY_UNKNOWN, GAMEPAD_RIGHT_SHOULDER_TOP, IKEY_UNKNOWN, LINUXKEY_UNKNOWN, GAMEPAD_RIGHT_SHOULDER_TOP); + DIGITAL_INPUT_EVENT_DEF(CAMERA_CONTROLLER_DECREASE, GAMEPAD_LEFT_SHOULDER_TOP, GAMEPAD_LEFT_SHOULDER_TOP, GAMEPAD_LEFT_SHOULDER_TOP, GAMEPAD_LEFT_SHOULDER_TOP, GAMEPAD_LEFT_SHOULDER_TOP, AKEY_UNKNOWN, GAMEPAD_LEFT_SHOULDER_TOP, IKEY_UNKNOWN, LINUXKEY_UNKNOWN, GAMEPAD_LEFT_SHOULDER_TOP); + + //analog gamepad events + ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_ROTATE_LEFT_RIGHT, GAMEPAD_ROTATE_SENSITIVITY, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, GAMEPAD_RIGHT_STICK_X, LINUXKEY_UNKNOWN, GAMEPAD_RIGHT_STICK_X); + ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_ROTATE_UP_DOWN, GAMEPAD_ROTATE_SENSITIVITY, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, GAMEPAD_RIGHT_STICK_Y, LINUXKEY_UNKNOWN, GAMEPAD_RIGHT_STICK_Y); + ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_MOVE_LEFT_RIGHT, GAMEPAD_DEFAULT_SENSITIVITY, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, GAMEPAD_LEFT_STICK_X, LINUXKEY_UNKNOWN, GAMEPAD_LEFT_STICK_X); + ANALOG_INPUT_EVENT_DEF(CAMERA_GAMEPAD_MOVE_FORWARD_BACK, GAMEPAD_DEFAULT_SENSITIVITY, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, GAMEPAD_LEFT_STICK_Y, LINUXKEY_UNKNOWN, GAMEPAD_LEFT_STICK_Y); + + //touch events (these are defined in the samples, since overwriting is currently not well possible) +} + +void SampleCCTCameraController::onDigitalInputEvent(const SampleFramework::InputEvent& ie, bool val) +{ + Console* console = mBase.getConsole(); + if(console && console->isActive()) + return; + + switch (ie.m_Id) + { + case CAMERA_MOVE_FORWARD: + { + mFwd = val; + } + break; + case CAMERA_MOVE_BACKWARD: + { + mBwd = val; + } + break; + case CAMERA_MOVE_LEFT: + { + mLeft = val; + } + break; + case CAMERA_MOVE_RIGHT: + { + mRight = val; + } + break; + case CAMERA_SHIFT_SPEED: + { + mKeyShiftDown = val; + } + break; + case CAMERA_JUMP: + { + if(val) + startJump(); + } + break; + case CAMERA_CROUCH: + { + if(val) + { + getControlledActor()->resizeCrouching(); + } + else + { + getControlledActor()->mDoStandup = true; + } + } + break; + case CAMERA_CONTROLLER_INCREASE: + { + if(val) + { + if(mControlledIndex<mNbCCTs-1) + mControlledIndex++; + } + } + break; + case CAMERA_CONTROLLER_DECREASE: + { + if(val) + { + if(mControlledIndex) + mControlledIndex--; + } + } + break; + case CAMERA_SPEED_INCREASE: + { + if(val) + { + if(mKeyShiftDown) + { + if(mRunningSpeed * 2.0f <= mCameraMaxSpeed) + mRunningSpeed *= 2.f; + } + else + { + if(mWalkingSpeed * 2.0f <= mCameraMaxSpeed) + mWalkingSpeed *= 2.f; + + if(mGamepadWalkingSpeed * 2.0f <= mCameraMaxSpeed) + mGamepadWalkingSpeed *= 2.f; + } + } + } + break; + case CAMERA_SPEED_DECREASE: + { + if(val) + { + if(mKeyShiftDown) + { + mRunningSpeed *= 0.5f; + } + else + { + mWalkingSpeed *= 0.5f; + mGamepadWalkingSpeed *= 0.5f; + } + } + } + break; + } + +} + +static PX_FORCE_INLINE PxReal remapAxisValue(PxReal absolutePosition) +{ + return absolutePosition * absolutePosition * absolutePosition * 5.0f; +} + +void SampleCCTCameraController::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 SampleCCTCameraController::onPointerInputEvent(const SampleFramework::InputEvent &ie, physx::PxU32, physx::PxU32, physx::PxReal dx, physx::PxReal dy, bool val) +{ + if (ie.m_Id == CAMERA_MOUSE_LOOK) + { + mTargetYaw -= dx * mSensibility; + mTargetPitch += dy * mSensibility; + } +} + +void SampleCCTCameraController::setView(PxReal pitch, PxReal yaw) +{ + mTargetPitch = pitch; + mTargetYaw = yaw; +} + +void SampleCCTCameraController::update(Camera& camera, PxReal dtime) +{ + PxSceneReadLock scopedLock(mBase.getActiveScene()); + +// shdfnd::printFormatted("SampleCCTCameraController::update\n"); + + if(!mCCTs) + return; + + // Update CCT +// bool doUpdate = false; + if(!mBase.isPaused() && mCCTEnabled) + { +/* PxScene& scene = mBase.getActiveScene(); + static PxU32 timestamp = 0; + PxU32 t = scene.getTimestamp(); + const PxU32 dt = t - timestamp; + doUpdate = t!=timestamp; + shdfnd::printFormatted("doUpdate: %d\n", doUpdate); + timestamp = t; + if(doUpdate) + dtime = float(dt) * 1.0f/60.0f; + if(doUpdate)*/ + + { + + const PxControllerFilters filters(mFilterData, mFilterCallback, mCCTFilterCallback); + + for(PxU32 i=0;i<mNbCCTs;i++) + { + PxVec3 disp; + + const PxF32 heightDelta = mCCTs[i]->mJump.getHeight(dtime); + float dy; + if(heightDelta!=0.0f) + dy = heightDelta; + else + dy = mGravity * dtime; +// shdfnd::printFormatted("%f\n", dy); + + if(i==mControlledIndex) + { + 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(canJump(mCCTs[i])) // PT: prevent displacement in mid-air + { + if(mFwd) targetKeyDisplacement += forward; + if(mBwd) targetKeyDisplacement -= forward; + + if(mRight) targetKeyDisplacement += right; + if(mLeft) targetKeyDisplacement -= right; + + targetKeyDisplacement *= mKeyShiftDown ? mRunningSpeed : mWalkingSpeed; + targetKeyDisplacement *= dtime; + + targetPadDisplacement += forward * mGamepadForwardInc * mGamepadWalkingSpeed; + targetPadDisplacement += right * mGamepadLateralInc * mGamepadWalkingSpeed; + targetPadDisplacement *= dtime; + } + + disp = targetKeyDisplacement + targetPadDisplacement; + disp.y = dy; + } + else + { + disp = PxVec3(0, dy, 0); + } + + if(gTransferPlatformMomentum) + { +// shdfnd::printFormatted("%d\n", mCCTs[i]->mTransferMomentum); + if(mCCTs[i]->mTransferMomentum) + { + PxVec3 dd = mCCTs[i]->mDelta * dtime; +// shdfnd::printFormatted("dd: %f %f %f (%f)\n", dd.x, dd.y, dd.z, dtime); + disp.x += dd.x; + disp.z += dd.z; + } + } + +// const PxU32 flags = mCCTs[i]->mController->move(disp, 0.001f, dtime, filters, mObstacleContext); + const PxU32 flags = mCCTs[i]->mController->move(disp, 0.0f, dtime, filters, mObstacleContext); + if(flags & PxControllerCollisionFlag::eCOLLISION_DOWN) + { +// shdfnd::printFormatted("Stop jump\n"); + mCCTs[i]->mJump.stopJump(); + } +// shdfnd::printFormatted("%d\n", flags & PxControllerCollisionFlag::eCOLLISION_DOWN); + + if(gTransferPlatformMomentum) + { + if(!flags) + { + mCCTs[i]->mTransferMomentum = true; + } + else + { + // ### optimize this + mCCTs[i]->mTransferMomentum = false; + PxControllerState cctState; + mCCTs[i]->mController->getState(cctState); + mCCTs[i]->mDelta = cctState.deltaXP; +// shdfnd::printFormatted("delta out: %f %f %f\n", cctState.deltaXP.x, cctState.deltaXP.y, cctState.deltaXP.z); + } + } + + if(gDumpCCTState && i==mControlledIndex) + { + PxControllerState cctState; + mCCTs[i]->mController->getState(cctState); + shdfnd::printFormatted("\nCCT state:\n"); + shdfnd::printFormatted("delta: %.02f | %.02f | %.02f\n", cctState.deltaXP.x, cctState.deltaXP.y, cctState.deltaXP.z); + shdfnd::printFormatted("touchedShape: %p\n", cctState.touchedShape); + shdfnd::printFormatted("touchedObstacleHandle: %d\n", cctState.touchedObstacleHandle); + shdfnd::printFormatted("standOnAnotherCCT: %d\n", cctState.standOnAnotherCCT); + shdfnd::printFormatted("standOnObstacle: %d\n", cctState.standOnObstacle); + shdfnd::printFormatted("isMovingUp: %d\n", cctState.isMovingUp); + shdfnd::printFormatted("collisionFlags: %d\n", cctState.collisionFlags); + } + + if(gDumpCCTStats && i==mControlledIndex) + { + PxControllerStats cctStats; + mCCTs[i]->mController->getStats(cctStats); + shdfnd::printFormatted("nbIterations: %d\n", cctStats.nbIterations); + shdfnd::printFormatted("nbFullUpdates: %d\n", cctStats.nbFullUpdates); + shdfnd::printFormatted("nbPartialUpdates: %d\n", cctStats.nbPartialUpdates); + shdfnd::printFormatted("nbTessellation: %d\n", cctStats.nbTessellation); + } + } + + } + } + + // Update camera + PxController* cct = mCCTs[mControlledIndex]->mController; + if(cct/* && doUpdate*/) + { + mTargetYaw += mGamepadYawInc * dtime; + mTargetPitch += mGamepadPitchInc * dtime; + + // Clamp pitch + if(mTargetPitch<mPitchMin) mTargetPitch = mPitchMin; + if(mTargetPitch>mPitchMax) mTargetPitch = mPitchMax; + + camera.setRot(PxVec3(-mTargetPitch,-mTargetYaw,0)); +//shdfnd::printFormatted("Pitch: %f\n", mTargetPitch); + + PxExtendedVec3 camTarget; + if(!mLinkCameraToPhysics) + { + camTarget = cct->getFootPosition(); + } + else + { + const PxVec3 delta = cct->getPosition() - cct->getFootPosition(); + + const PxVec3 physicsPos = cct->getActor()->getGlobalPose().p - delta; + camTarget = PxExtendedVec3(physicsPos.x, physicsPos.y, physicsPos.z); + } + + const float height = 1.0f; + camTarget += PxVec3(0, height, 0); + const PxVec3 target = toVec3(camTarget) - camera.getViewDir()*5.0f; +//const PxVec3 target2 = target; +//shdfnd::printFormatted("target: %f | %f | %f\n", target.x, target.y, target.z); + camera.setPos(target); + } +} + diff --git a/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTCameraController.h b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTCameraController.h new file mode 100644 index 00000000..53e68623 --- /dev/null +++ b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTCameraController.h @@ -0,0 +1,107 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "PhysXSampleApplication.h" +#include "SampleCameraController.h" +#include "characterkinematic/PxController.h" +#include "characterkinematic/PxControllerObstacles.h" + +class ControlledActor; + +class SampleCCTCameraController : public CameraController +{ + public: + SampleCCTCameraController(PhysXSample& base); + + void setControlled(ControlledActor** controlled, PxU32 controlledIndex, PxU32 nbCCTs); + + virtual void onDigitalInputEvent(const SampleFramework::InputEvent& , bool val); + virtual void onAnalogInputEvent(const SampleFramework::InputEvent& , float val); + virtual void onPointerInputEvent(const SampleFramework::InputEvent&, physx::PxU32, physx::PxU32, physx::PxReal, physx::PxReal, bool val); + virtual void collectInputEvents(std::vector<const SampleFramework::InputEvent*>& inputEvents); + + virtual void update(Camera& camera, PxReal dtime); + virtual PxReal getCameraSpeed() + { + return mKeyShiftDown ? mRunningSpeed : mWalkingSpeed ; + } + void setCameraMaxSpeed(PxReal speed) { mCameraMaxSpeed = speed; } + void setView(PxReal pitch, PxReal yaw); + void startJump(); + + PX_FORCE_INLINE ControlledActor* getControlledActor() { return mCCTs[mControlledIndex]; } + PX_FORCE_INLINE void setJumpForce(PxReal force) { mJumpForce = force; } + PX_FORCE_INLINE void setGravity(PxReal g) { mGravity = g; } + PX_FORCE_INLINE void enableCCT(bool bState) { mCCTEnabled = bState; } + PX_FORCE_INLINE bool getCCTState() { return mCCTEnabled; } + + // The CCT's physics & rendering positions don't always match if the CCT + // is updated with variable timesteps and the physics with fixed-timesteps. + // true to link the camera to the CCT's physics position. + // false to link the camera to the CCT's rendering position. + PX_FORCE_INLINE void setCameraLinkToPhysics(bool b) { mLinkCameraToPhysics = b; } + PX_FORCE_INLINE bool getCameraLinkToPhysics() const { return mLinkCameraToPhysics; } + + PX_FORCE_INLINE void setObstacleContext(PxObstacleContext* context) { mObstacleContext = context; } + PX_FORCE_INLINE void setFilterData(const PxFilterData* filterData) { mFilterData = filterData; } + PX_FORCE_INLINE void setFilterCallback(PxQueryFilterCallback* cb) { mFilterCallback = cb; } + PX_FORCE_INLINE void setCCTFilterCallback(PxControllerFilterCallback* cb){ mCCTFilterCallback = cb; } + + private: + SampleCCTCameraController& operator=(const SampleCCTCameraController&); + PhysXSample& mBase; // PT: TODO: find a way to decouple us from PhysXSampleApplication. Only needed for "recenterCursor". Maybe the app could inherit from the cam... + + PxObstacleContext* mObstacleContext; // User-defined additional obstacles + const PxFilterData* mFilterData; // User-defined filter data for 'move' function + PxQueryFilterCallback* mFilterCallback; // User-defined filter data for 'move' function + PxControllerFilterCallback* mCCTFilterCallback; // User-defined filter data for 'move' function + + PxU32 mControlledIndex; + PxU32 mNbCCTs; + ControlledActor** mCCTs; + + PxReal mTargetYaw, mTargetPitch; + PxReal mPitchMin, mPitchMax; + + PxReal mGamepadPitchInc, mGamepadYawInc; + PxReal mGamepadForwardInc, mGamepadLateralInc; + PxReal mSensibility; + + bool mFwd,mBwd,mLeft,mRight,mKeyShiftDown; + bool mCCTEnabled; + + PxReal mRunningSpeed; + PxReal mWalkingSpeed; + PxReal mGamepadWalkingSpeed; + PxReal mCameraMaxSpeed; + PxReal mJumpForce; + PxReal mGravity; + + bool mLinkCameraToPhysics; +}; diff --git a/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTJump.cpp b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTJump.cpp new file mode 100644 index 00000000..c6e13d28 --- /dev/null +++ b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTJump.cpp @@ -0,0 +1,66 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "SampleCCTJump.h" + +using namespace physx; + +static PxF32 gJumpGravity = -50.0f; + +Jump::Jump() : + mV0 (0.0f), + mJumpTime (0.0f), + mJump (false) +{ +} + +void Jump::startJump(PxF32 v0) +{ + if(mJump) return; + mJumpTime = 0.0f; + mV0 = v0; + mJump = true; +} + +void Jump::stopJump() +{ + if(!mJump) return; + mJump = false; +//mJumpTime = 0.0f; +//mV0 = 0.0f; +} + +PxF32 Jump::getHeight(PxF32 elapsedTime) +{ + if(!mJump) return 0.0f; + mJumpTime += elapsedTime; + const PxF32 h = gJumpGravity*mJumpTime*mJumpTime + mV0*mJumpTime; + return h*elapsedTime; +} + diff --git a/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTJump.h b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTJump.h new file mode 100644 index 00000000..8de5ad34 --- /dev/null +++ b/PhysX_3.4/Samples/SampleCCTSharedCode/SampleCCTJump.h @@ -0,0 +1,52 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef SAMPLE_CCT_JUMP_H +#define SAMPLE_CCT_JUMP_H + +#include "common/PxPhysXCommonConfig.h" +#include "SampleAllocator.h" + +using namespace physx; + + class Jump : public SampleAllocateable + { + public: + Jump(); + + PxF32 mV0; + PxF32 mJumpTime; + bool mJump; + + void startJump(PxF32 v0); + void stopJump(); + PxF32 getHeight(PxF32 elapsedTime); + }; + +#endif |