PhysX

PhysX API 구조 (2)

RuNaPi 2022. 10. 14. 15:41

PhysX에서 물리를 연산할 오브젝트인 PxActor를 물리 연산 하기 위해서는 인스턴스된 PxActor의 공간 범위와 충돌 속성을 설명하는 PxShape를 인스턴스하고 PxActor에 모양을 설정해주어야 한다.

PX_FORCE_INLINE	PxShape* createShape(const PxGeometry& geometry, 
	const PxMaterial& material, 
	bool isExclusive = false, 
    PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE)

Shape를 생성하기 위해선 Shape의 Geometry 정보를 담고 있는 PxGeometry, 물리 작동시 표면의 특성(마찰계수, 반발계수 등)를 정해주는 PxMaterial, 액터 공유 여부 그리고 Flag가 필요하다.

 

PxShapeFlag는 이 Shape의 물리 충돌 충돌을 할 것인지 Trigger 작동을 할 것인지 여부를 결정 할 수 있다.

eSIMULATION_SHAPE와 eTRIGGER_SHAPE는 서로 상반된 Flag이기 때문에 어느 한쪽이 true면 반대쪽은 false여야 한다. 다른 Flag는 아래 링크에서 확인 가능하다.

https://gameworksdocs.nvidia.com/PhysX/4.0/documentation/PhysXAPI/files/structPxShapeFlag.html

 

PxShapeFlag Struct Reference

Flags which affect the behavior of PxShapes. More... #include Flags which affect the behavior of PxShapes. See alsoPxShape PxShape.setFlag() EnumeratoreSIMULATION_SHAPE The shape will partake in collision in the physical simulation. NoteIt is illegal to r

gameworksdocs.nvidia.com

아래는 상자, 구체, 캡슐 모양의 Shape 생성 예시이다.

// Box 모양
_pxShape = PhysicsSDK->GetPhysics()->createShape(physx::PxBoxGeometry(boxColliderInfo._size._x, boxColliderInfo._size._y, boxColliderInfo._size._z),
		*pxMaterial, true, flags);

// Sphere 모양
_pxShape = PhysicsSDK->GetPhysics()->createShape(physx::PxSphereGeometry(sphereColliderInfo._radius),
		*pxMaterial, true, flags);
 
 // Capsule 모양
_pxShape = PhysicsSDK->GetPhysics()->createShape(physx::PxCapsuleGeometry(capsuleColliderInfo._radius, capsuleColliderInfo._height),
		*pxMaterial, true, flags);

이 생성된 shape를 actor를 생성후 각 actor에 붙여주면 씬을 simulate 할때 actor에 붙어있는 shape를 통해 물리를 시뮬레이션 한다.

// actor 를 생성후
_pxRigidActor = PhysicsSDK->GetPhysics()->createRigidDynamic(transform);

// actor에 shape를 붙일 수 있다.
_pxRigidActor->attachShape(*shape);

PxShape에 PxFilterData라는 것을 활용해 Layer 구조를 만들 수도 있다. 자세한 방법은 아래 링크의 Collision Filtering 탭에서 확인 가능하다.

https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/RigidBodyCollision.html

 

Rigid Body Collision — NVIDIA PhysX SDK 4.1 Documentation

Rigid Body Collision Introduction This section will introduce the fundamentals of rigid body collision. Shapes Shapes describe the spatial extent and collision properties of actors. They are used for three purposes within PhysX: intersection tests that det

gameworksdocs.nvidia.com

이제 Actor를 생성하기 위해 필요한 Shape를 생성하였으니 static 혹은 dynamic RigidActor를 생성후 attachShape 매서드를 호출해 shape를 붙여 주면된다.

/// Staitc RigidActor를 인스턴스후 shape를 붙여준다.

_pxRigidActor = PhysicsSDK->GetPhysics()->createRigidStatic(transform);

_pxRigidActor->attachShape(*shape);

_rigidType = eRigidType::Static;

/// Dynamic RigidActor를 인스턴스후 shape를 붙여준다

_pxRigidActor = PhysicsSDK->GetPhysics()->createRigidDynamic(transform);

_pxRigidActor->attachShape(*shape);

PxRigidDynamicLockFlags lockFlags;

SetConstraints(_rigidInfo._constraints);

_rigidType = eRigidType::Dynamic;

이전 글에서 PhysX의 actor의 상속 구조에 대해 서술하였다.

크게 생각해 Dynamic과 Static PxRigidActor 두 분류로 나눌 수가 있는데

PxRigidDynamicActor의 경우 PxRigidBodyFlag와 PxRigidDynamicLockFlag 두 개의 Flag를 설정이 가능하다.

PxRigidBodyFlag에서는 Kinematic, CCD, CCD_FRICTION 등을 설정이 가능하다 더 자세한 Flag는 아래 링크에서 확인 가능하다.

https://gameworksdocs.nvidia.com/PhysX/4.0/documentation/PhysXAPI/files/structPxRigidBodyFlag.html

 

PxRigidBodyFlag Struct Reference

Collection of flags describing the behavior of a rigid body. More... #include Collection of flags describing the behavior of a rigid body. See alsoPxRigidBody.setRigidBodyFlag(), PxRigidBody.getRigidBodyFlags() EnumeratoreKINEMATIC Enables kinematic mode

gameworksdocs.nvidia.com

PxRigidDynamicLockFlag는 회전과 이동에서 특정 축의 값을 고정 시키는데 사용이 된다.

eLOCK_LINEAR_?? 은 position축을 Lock 할 수 있고 eLOCK_ANGULAR_?? 은 rotation 축을 Lock 가능하다.

https://gameworksdocs.nvidia.com/PhysX/4.0/documentation/PhysXAPI/files/structPxRigidDynamicLockFlag.html

 

PxRigidDynamicLockFlag Struct Reference

Collection of flags providing a mechanism to lock motion along/around a specific axis. More... Collection of flags providing a mechanism to lock motion along/around a specific axis. See alsoPxRigidDynamic.setRigidDynamicLockFlag(), PxRigidBody.getRigidDyna

gameworksdocs.nvidia.com

 

// rigidInfo 값으로 rigidBodyflag 를 설정

PxRigidBodyFlags rigidBodyFlag;

if (rigidInfo._isKinematic)
	rigidBodyFlag |= PxRigidBodyFlag::Enum::eKINEMATIC;

switch (rigidInfo._collisionDetection)
{
	case eCollisionDetection::Continuous:
	{
		rigidBodyFlag |= PxRigidBodyFlag::eENABLE_CCD;
		break;
	}
	case eCollisionDetection::ContinuousSpeculative:
	{
		rigidBodyFlag |= PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD;
		break;
	}
	case eCollisionDetection::Discrete:
	{
		break;
	}
}

((PxRigidBody*)_pxRigidActor)->setRigidBodyFlags(rigidBodyFlag);

/// constraints의 값으로 LockFlags를 설정

PxRigidDynamicLockFlags flags;

(constraints._position._x == true) ? flags |= PxRigidDynamicLockFlag::eLOCK_LINEAR_X : flags &= ~PxRigidDynamicLockFlag::eLOCK_LINEAR_X;
(constraints._position._y == true) ? flags |= PxRigidDynamicLockFlag::eLOCK_LINEAR_Y : flags &= ~PxRigidDynamicLockFlag::eLOCK_LINEAR_Y;
(constraints._position._z == true) ? flags |= PxRigidDynamicLockFlag::eLOCK_LINEAR_Z : flags &= ~PxRigidDynamicLockFlag::eLOCK_LINEAR_Z;
(constraints._rotation._x == true) ? flags |= PxRigidDynamicLockFlag::eLOCK_ANGULAR_X : flags &= ~PxRigidDynamicLockFlag::eLOCK_ANGULAR_X;
(constraints._rotation._y == true) ? flags |= PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y : flags &= ~PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y;
(constraints._rotation._z == true) ? flags |= PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z : flags &= ~PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z;

((physx::PxRigidDynamic*)_pxRigidActor)->setRigidDynamicLockFlags(flags);

 

'PhysX' 카테고리의 다른 글

PhysX API 구조 (1)  (0) 2022.10.11