PhysX
jjuiddong
PhysX 는 항상 최신버젼을 사용하자. 비주얼스튜디오와 버젼이 맞지 않으면, 빌드가 되지 않는다.
- NVidia 그래픽카드가 아닐경우 Sample프로젝트에 RENDERER_PVD 을 선언해줘야 한다.
PhysX 정리
- PxQuat
- 오른손좌표계에서 (PhysX sample 은 오른손좌표계를 사용한다.) PxQuat::rotate 함수는 시계방향으로 회전한다.
- OpenGL 은 오른손 좌표계를 사용한다. (여러 운영체제에서 지원하다보니 일반적인 오른손 좌표계를 사용하는듯)
- PxTransform
- PxTransform(PxVec3(10,0,0), PxQuat())
- Position 적용 후, Rotation 이 적용된다.
- Rotation 적용 후, Position을 적용하고 싶다면,
- PxTransform(PxQuat()) * PxTransform(PxVec3() 형태로 코딩하면 된다.
- PxTransform(PxVec3(10,0,0), PxQuat())
- Joint생성 함수
PxRevoluteJointCreate(PxPhysics& physics, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1);
- localFrame0, localFrame1 은 역행렬로 적용된다. 다시말해 actor0의 localFrame0 는 actro0에 localFrame0의 역행렬로 적용된다.
- actor0, actor1에 각각 역행렬로 적용해서 joint를 붙인다고 생각하면 된다. (왜 이렇게 되었는지는 잘 모름)
- Joint localFrame0,1 정리
- 두 액터 actor0, actor1, 은 joint의 상대 변환 행렬 localFrame0,1을 설정해서 joint를 생성한다.
- localFrame0,1은 actor0,1을 원점으로 한 상대 변환이다. actor0,1을 원점으로 두고, joint를 향해, 회전, 이동 값을 계산해 설정한다. 그래서, localFrame0 는 ctor0가 joint를 향한 변환행렬이기 때문에, 역행렬 형태로 나타난다
- Joint localFrame 행렬 계산
actor0TM * tm = jointTM tm0 = reverse(actor0TM) * jointTM actor1TM * tm = jointTM tm1 = reverse(actor1TM) * jointTM
- joint를 부실수도 있다.
- joint->setBreakForce(100.0f, 100.0f);
- 부셔졌는지 판단 가능하다. 깨질때 콜백함수가 호출된다.
- 여러가지 관절을 만들어놔서 쉽게 갖다 쓸수있다.
- kinematic 속성의 rigidActor를 joint로 연결하면 localFrame 매트릭스가 적용되지 않는다.
- fixed joint 에서 죽을 때 (fixed joint crash bug)
- ePROJECTION 옵션을 설정해서 허용오차를 설정하자.
PxReal tolerance = 0.1f; j->setProjectionLinearTolerance(tolerance); j->setConstraintFlag(PxConstraintFlag::ePROJECTION, true);
- PxSphericalJoint
j->setLimitCone(PxJointLimitCone(PxPi/4, PxPi/4)); j->setSphericalJointFlag(PxSphericalJointFlag::eLIMIT_ENABLED, true);
- PxJointLimitCon y,z 모두 설정 되었을 때 작동한다.
- Joint는 기본적으로 회전 가능하며, 좌우 움직임 제한을 할 수 있다.
- y,z 는 좌우 움직일 수 있는 각도를 설정한다.
- PxTransform, PxQuat, PxVec3 연산
PxTransform tm = PxTransform(PxVec3(1,0,0)) * PxTransform(PxQuat(1.3f,PxVec3(0,0,1))); - (1,0,0) 으로 이동한 후에 PxQuat 회전이 적용된다.
PxTransform tm = PxTransform(PxQuat(1.3f,PxVec3(0,0,1))) * PxTransform(PxVec3(1,0,0)); - 로컬좌표에서 회전한 후 (1,0,0) 으로 이동한다.
- 더블 버퍼링
- simulate() 가 실행되는 도중에 object를 추가해서 상태 값을 얻을 때 제대로 값을 못가져오는 경우가 있고, 이 때 다음 simulate() 가 호출되면 제대로된 값을 얻어온다.
- 더블버퍼링이 지원되지 않는 객체, cloth, particle
- Continuous Collision Detection
- CCD 를 켜려면 여러 플래그를 등록해야 한다.
- collision filtering
- PxAggregate
- bool NxPhysicsSDK::setParameter(NX_SKIN_WIDTH, fSkin);
- NX_SKIN_WIDTH로 설정된 값이 너무 작을 때, 오브젝트가 sleep상태가 되지 못하고 덜덜 거리는 현상이 발생합니다. 적절한 수준이 나올때까지 테스트 해보면 된다.
- 떨림 문제 drift problem