aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/PhysXCharacterKinematic/src/CctCharacterController.h
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/PhysXCharacterKinematic/src/CctCharacterController.h
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'PhysX_3.4/Source/PhysXCharacterKinematic/src/CctCharacterController.h')
-rw-r--r--PhysX_3.4/Source/PhysXCharacterKinematic/src/CctCharacterController.h459
1 files changed, 459 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/PhysXCharacterKinematic/src/CctCharacterController.h b/PhysX_3.4/Source/PhysXCharacterKinematic/src/CctCharacterController.h
new file mode 100644
index 00000000..f87f7512
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXCharacterKinematic/src/CctCharacterController.h
@@ -0,0 +1,459 @@
+// 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 CCT_CHARACTER_CONTROLLER
+#define CCT_CHARACTER_CONTROLLER
+
+//#define USE_CONTACT_NORMAL_FOR_SLOPE_TEST
+
+#include "PxController.h"
+#include "PxControllerObstacles.h"
+#include "CctCharacterControllerManager.h"
+#include "CctUtils.h"
+#include "PxTriangle.h"
+#include "PsArray.h"
+#include "PsHashSet.h"
+#include "CmPhysXCommon.h"
+
+namespace physx
+{
+
+struct PxFilterData;
+class PxQueryFilterCallback;
+class PxObstacle;
+
+namespace Cm
+{
+ class RenderBuffer;
+}
+
+namespace Cct
+{
+ struct CCTParams
+ {
+ CCTParams();
+
+ PxControllerNonWalkableMode::Enum mNonWalkableMode;
+ PxQuat mQuatFromUp;
+ PxVec3 mUpDirection;
+ PxF32 mSlopeLimit;
+ PxF32 mContactOffset;
+ PxF32 mStepOffset;
+ PxF32 mInvisibleWallHeight;
+ PxF32 mMaxJumpHeight;
+ PxF32 mMaxEdgeLength2;
+ bool mTessellation;
+ bool mHandleSlope; // True to handle walkable parts according to slope
+ bool mOverlapRecovery;
+ bool mPreciseSweeps;
+ bool mPreventVerticalSlidingAgainstCeiling;
+ };
+
+ template<class T, class A>
+ PX_INLINE T* reserve(Ps::Array<T, A>& array, PxU32 nb)
+ {
+ const PxU32 currentSize = array.size();
+ array.resizeUninitialized(array.size() + nb);
+ return array.begin() + currentSize;
+ }
+
+// typedef Ps::Array<PxTriangle> TriArray;
+ typedef Ps::Array<PxU32> IntArray;
+
+ // PT: using private inheritance to control access, and make sure allocations are SIMD friendly
+ class TriArray : private Ps::Array<PxTriangle>
+ {
+ public:
+
+ PX_FORCE_INLINE PxTriangle* reserve(PxU32 nbTris)
+ {
+ const PxU32 currentSize = Ps::Array<PxTriangle>::size();
+ // PT: allocate one more tri to make sure we can safely V4Load the last one...
+ Ps::Array<PxTriangle>::resizeUninitialized(currentSize + nbTris + 1);
+ // ...but we still want the size to reflect the correct number
+ Ps::Array<PxTriangle>::forceSize_Unsafe(currentSize + nbTris);
+ return Ps::Array<PxTriangle>::begin() + currentSize;
+ }
+
+ PX_FORCE_INLINE void pushBack(const PxTriangle& tri)
+ {
+// Ps::Array<PxTriangle>::pushBack(tri);
+ PxTriangle* memory = reserve(1);
+ memory->verts[0] = tri.verts[0];
+ memory->verts[1] = tri.verts[1];
+ memory->verts[2] = tri.verts[2];
+ }
+
+ PX_FORCE_INLINE PxU32 size() const
+ {
+ return Ps::Array<PxTriangle>::size();
+ }
+
+ PX_FORCE_INLINE void clear()
+ {
+ Ps::Array<PxTriangle>::clear();
+ }
+
+ PX_FORCE_INLINE void forceSize_Unsafe(PxU32 size)
+ {
+ Ps::Array<PxTriangle>::forceSize_Unsafe(size);
+ }
+
+ PX_FORCE_INLINE const PxTriangle& getTriangle(PxU32 index) const
+ {
+ return (*this)[index];
+ }
+
+ };
+
+ /* Exclude from documentation */
+ /** \cond */
+
+ struct TouchedGeomType
+ {
+ enum Enum
+ {
+ eUSER_BOX,
+ eUSER_CAPSULE,
+ eMESH,
+ eBOX,
+ eSPHERE,
+ eCAPSULE,
+
+ eLAST,
+
+ eFORCE_DWORD = 0x7fffffff
+ };
+ };
+
+ class SweptVolume;
+
+ // PT: apparently .Net aligns some of them on 8-bytes boundaries for no good reason. This is bad.
+ // Whenever a variable points to a field of a specially aligned struct, it has to be declared with __packed (see GHS docu, Structure Packing, page 111).
+ // Every reference to such a field needs the __packed declaration: all function parameters and assignment operators etc.
+#pragma pack(push,4)
+
+ struct TouchedGeom
+ {
+ TouchedGeomType::Enum mType;
+ const void* mTGUserData; // PxController or PxShape pointer
+ const PxRigidActor* mActor; // PxActor for PxShape pointers (mandatory with shared shapes)
+ PxExtendedVec3 mOffset; // Local origin, typically the center of the world bounds around the character. We translate both
+ // touched shapes & the character so that they are nearby this PxVec3, then add the offset back to
+ // computed "world" impacts.
+ protected:
+ ~TouchedGeom(){}
+ };
+
+ struct TouchedUserBox : public TouchedGeom
+ {
+ PxExtendedBox mBox;
+ };
+ PX_COMPILE_TIME_ASSERT(sizeof(TouchedUserBox)==sizeof(TouchedGeom)+sizeof(PxExtendedBox));
+
+ struct TouchedUserCapsule : public TouchedGeom
+ {
+ PxExtendedCapsule mCapsule;
+ };
+ PX_COMPILE_TIME_ASSERT(sizeof(TouchedUserCapsule)==sizeof(TouchedGeom)+sizeof(PxExtendedCapsule));
+
+ struct TouchedMesh : public TouchedGeom
+ {
+ PxU32 mNbTris;
+ PxU32 mIndexWorldTriangles;
+ };
+
+ struct TouchedBox : public TouchedGeom
+ {
+ PxVec3 mCenter;
+ PxVec3 mExtents;
+ PxQuat mRot;
+ };
+
+ struct TouchedSphere : public TouchedGeom
+ {
+ PxVec3 mCenter; //!< Sphere's center
+ PxF32 mRadius; //!< Sphere's radius
+ };
+
+ struct TouchedCapsule : public TouchedGeom
+ {
+ PxVec3 mP0; //!< Start of segment
+ PxVec3 mP1; //!< End of segment
+ PxF32 mRadius; //!< Capsule's radius
+ };
+
+#pragma pack(pop)
+
+ struct SweptContact
+ {
+ PxExtendedVec3 mWorldPos; // Contact position in world space
+ PxVec3 mWorldNormal; // Contact normal in world space
+ PxF32 mDistance; // Contact distance
+ PxU32 mInternalIndex; // Reserved for internal usage
+ PxU32 mTriangleIndex; // Triangle index for meshes/heightfields
+ TouchedGeom* mGeom;
+
+ PX_FORCE_INLINE void setWorldPos(const PxVec3& localImpact, const PxExtendedVec3& offset)
+ {
+ mWorldPos.x = PxExtended(localImpact.x) + offset.x;
+ mWorldPos.y = PxExtended(localImpact.y) + offset.y;
+ mWorldPos.z = PxExtended(localImpact.z) + offset.z;
+ }
+ };
+
+ // PT: user-defined obstacles. Note that "user" is from the SweepTest class' point of view,
+ // i.e. the PhysX CCT module is the user in this case. This is to limit coupling between the
+ // core CCT module and the PhysX classes.
+ struct UserObstacles// : PxObstacleContext
+ {
+ PxU32 mNbBoxes;
+ const PxExtendedBox* mBoxes;
+ const void** mBoxUserData;
+
+ PxU32 mNbCapsules;
+ const PxExtendedCapsule* mCapsules;
+ const void** mCapsuleUserData;
+ };
+
+ struct InternalCBData_OnHit{};
+ struct InternalCBData_FindTouchedGeom{};
+
+ enum SweepTestFlag
+ {
+ STF_HIT_NON_WALKABLE = (1<<0),
+ STF_WALK_EXPERIMENT = (1<<1),
+ STF_VALIDATE_TRIANGLE_DOWN = (1<<2), // Validate touched triangle data (down pass)
+ STF_VALIDATE_TRIANGLE_SIDE = (1<<3), // Validate touched triangle data (side pass)
+ STF_TOUCH_OTHER_CCT = (1<<4), // Are we standing on another CCT or not? (only updated for down pass)
+ STF_TOUCH_OBSTACLE = (1<<5), // Are we standing on an obstacle or not? (only updated for down pass)
+ STF_NORMALIZE_RESPONSE = (1<<6),
+ STF_FIRST_UPDATE = (1<<7),
+ STF_IS_MOVING_UP = (1<<8)
+ };
+
+ enum SweepPass
+ {
+ SWEEP_PASS_UP,
+ SWEEP_PASS_SIDE,
+ SWEEP_PASS_DOWN,
+ SWEEP_PASS_SENSOR
+ };
+
+ class Controller;
+
+ template<class T>
+ struct TouchedObject
+ {
+ TouchedObject(bool regDl)
+ : mTouchedObject(NULL), mRegisterDeletionListener(regDl), mCctManager(NULL)
+ {
+ }
+
+ PX_FORCE_INLINE const T* operator->() const { return mTouchedObject; }
+ PX_FORCE_INLINE bool operator==(const TouchedObject& otherObject) { return mTouchedObject == otherObject.mTouchedObject; }
+ PX_FORCE_INLINE bool operator==(const T* otherObject) { return mTouchedObject == otherObject; }
+ PX_FORCE_INLINE bool operator==(const PxBase* otherObject) { return mTouchedObject == otherObject; }
+ PX_FORCE_INLINE operator bool() const { return mTouchedObject != NULL; }
+ PX_FORCE_INLINE TouchedObject& operator=(const T* assignedObject)
+ {
+ if(mRegisterDeletionListener && (mTouchedObject != assignedObject))
+ {
+ if(mTouchedObject)
+ mCctManager->unregisterObservedObject(mTouchedObject);
+
+ if(assignedObject)
+ mCctManager->registerObservedObject(assignedObject);
+ }
+ mTouchedObject = assignedObject;
+ return *this;
+ }
+
+ const T* get() const { return mTouchedObject; }
+
+ void setCctManager(CharacterControllerManager* cm) { mCctManager = cm; }
+
+ private:
+ TouchedObject& operator=(const TouchedObject&);
+
+ const T* mTouchedObject;
+ bool mRegisterDeletionListener;
+ CharacterControllerManager* mCctManager;
+ };
+
+ class SweepTest
+ {
+ public:
+ SweepTest(bool registerDeletionListener);
+ ~SweepTest();
+
+ PxControllerCollisionFlags moveCharacter( const InternalCBData_FindTouchedGeom* userData,
+ InternalCBData_OnHit* user_data2,
+ SweptVolume& volume,
+ const PxVec3& direction,
+ const UserObstacles& userObstacles,
+ PxF32 min_dist,
+ const PxControllerFilters& filters,
+ bool constrainedClimbingMode,
+ bool standingOnMoving,
+ const PxRigidActor*& touchedActor,
+ const PxShape*& touchedShape
+ );
+
+ bool doSweepTest(const InternalCBData_FindTouchedGeom* userDataTouchedGeom,
+ InternalCBData_OnHit* userDataOnHit,
+ const UserObstacles& userObstacles,
+ SweptVolume& swept_volume,
+ const PxVec3& direction, const PxVec3& sideVector, PxU32 max_iter,
+ PxU32* nb_collisions, PxF32 min_dist, const PxControllerFilters& filters, SweepPass sweepPass,
+ const PxRigidActor*& touchedActor, const PxShape*& touchedShape);
+
+ void findTouchedObstacles(const UserObstacles& userObstacles, const PxExtendedBounds3& world_box);
+
+ void voidTestCache();
+ void onRelease(const PxBase& observed);
+ void updateCachedShapesRegistration(PxU32 startIndex, bool unregister);
+
+ // observer notifications
+ void onObstacleRemoved(ObstacleHandle index);
+ void onObstacleUpdated(ObstacleHandle index, const PxObstacleContext* context, const PxVec3& origin, const PxVec3& unitDir, const PxReal distance);
+ void onObstacleAdded(ObstacleHandle index, const PxObstacleContext* context, const PxVec3& origin, const PxVec3& unitDir, const PxReal distance);
+
+ void onOriginShift(const PxVec3& shift);
+
+ Cm::RenderBuffer* mRenderBuffer;
+ PxU32 mRenderFlags;
+ TriArray mWorldTriangles;
+ IntArray mTriangleIndices;
+ IntArray mGeomStream;
+ PxExtendedBounds3 mCacheBounds;
+ PxU32 mCachedTriIndexIndex;
+ mutable PxU32 mCachedTriIndex[3];
+ PxU32 mNbCachedStatic;
+ PxU32 mNbCachedT;
+ public:
+#ifdef USE_CONTACT_NORMAL_FOR_SLOPE_TEST
+ PxVec3 mContactNormalDownPass;
+#else
+ PxVec3 mContactNormalDownPass;
+ PxVec3 mContactNormalSidePass;
+ float mTouchedTriMin;
+ float mTouchedTriMax;
+ //PxTriangle mTouchedTriangle;
+#endif
+ //
+ TouchedObject<PxShape> mTouchedShape; // Shape on which the CCT is standing
+ TouchedObject<PxRigidActor> mTouchedActor; // Actor from touched shape
+ ObstacleHandle mTouchedObstacleHandle; // Obstacle on which the CCT is standing
+ PxVec3 mTouchedPos; // Last known position of mTouchedShape/mTouchedObstacle
+ // PT: TODO: union those
+ PxVec3 mTouchedPosShape_Local;
+ PxVec3 mTouchedPosShape_World;
+ PxVec3 mTouchedPosObstacle_Local;
+ PxVec3 mTouchedPosObstacle_World;
+ //
+ CCTParams mUserParams;
+ PxF32 mVolumeGrowth; // Must be >1.0f and not too big
+ PxF32 mContactPointHeight; // UBI
+ PxU32 mSQTimeStamp;
+ PxU16 mNbFullUpdates;
+ PxU16 mNbPartialUpdates;
+ PxU16 mNbTessellation;
+ PxU16 mNbIterations;
+ PxU32 mFlags;
+ bool mRegisterDeletionListener;
+
+ PX_FORCE_INLINE void resetStats()
+ {
+ mNbFullUpdates = 0;
+ mNbPartialUpdates = 0;
+ mNbTessellation = 0;
+ mNbIterations = 0;
+ }
+
+ void setCctManager(CharacterControllerManager* cm)
+ {
+ mCctManager = cm;
+ mTouchedActor.setCctManager(cm);
+ mTouchedShape.setCctManager(cm);
+ }
+
+ private:
+ void updateTouchedGeoms( const InternalCBData_FindTouchedGeom* userData, const UserObstacles& userObstacles,
+ const PxExtendedBounds3& worldBox, const PxControllerFilters& filters, const PxVec3& sideVector);
+
+ CharacterControllerManager* mCctManager;
+ SweepTest(const SweepTest&);
+ SweepTest& operator=(const SweepTest& );
+ };
+
+ class CCTFilter // PT: internal filter data, could be replaced with PxControllerFilters eventually
+ {
+ public:
+ PX_FORCE_INLINE CCTFilter() :
+ mFilterData (NULL),
+ mFilterCallback (NULL),
+ mStaticShapes (false),
+ mDynamicShapes (false),
+ mPreFilter (false),
+ mPostFilter (false),
+ mCCTShapes (NULL)
+ {
+ }
+ const PxFilterData* mFilterData;
+ PxQueryFilterCallback* mFilterCallback;
+ bool mStaticShapes;
+ bool mDynamicShapes;
+ bool mPreFilter;
+ bool mPostFilter;
+ Ps::HashSet<PxShape>* mCCTShapes;
+ };
+
+ PxU32 getSceneTimestamp(const InternalCBData_FindTouchedGeom* userData);
+
+ void findTouchedGeometry(const InternalCBData_FindTouchedGeom* userData,
+ const PxExtendedBounds3& world_aabb,
+
+ TriArray& world_triangles,
+ IntArray& triIndicesArray,
+ IntArray& geomStream,
+
+ const CCTFilter& filter,
+ const CCTParams& params,
+ PxU16& nbTessellation);
+
+ PxU32 shapeHitCallback(const InternalCBData_OnHit* userData, const SweptContact& contact, const PxVec3& dir, PxF32 length);
+ PxU32 userHitCallback(const InternalCBData_OnHit* userData, const SweptContact& contact, const PxVec3& dir, PxF32 length);
+
+} // namespace Cct
+
+}
+
+/** \endcond */
+#endif