HavokDemo에서 캐릭터 제어2

< 캐릭터의 충돌 메쉬 위치와 렌더링 캐릭터의 위치 일치 시키기 >

캐릭터의 충돌 메쉬는 아래와 같은 코드로 만든다. 실행하면 캐릭터는 위 그림처럼 캡슐의 중심 높이 위치에 캐릭터가 둥둥 떠 있을 것이다.
충돌 메쉬는 캡슐의 중간 높이가 중심이지만 렌더링 되는 캐릭터의 중심 위치는 0이다.

    hkVector4 va( 0.0f, 0.0f, CHARACTER_SCALE_RATIO * 0.2f );

    hkVector4 vb( 0.0f, 0.0f, CHARACTER_SCALE_RATIO * -0.2f );

    m_pStandShape = new  hkpCapsuleShape( va, vb, CHARACTER_SCALE_RATIO * 0.497f );       

 

    va.setZero4();

    m_pCrouchShape = new  hkpCapsuleShape( va, vb, CHARACTER_SCALE_RATIO * 0.497f );

캡슐의 중심 높이를 0으로 맞추기 위해서는 다음과 같이 한다.

lerp 값을 잘 조정하면 캐릭터의 충돌 메쉬 중심점과 렌더링 되는 캐릭터의 중심점이 일치 될 것이다.

    const hkReal totalHeight = CHARACTER_SCALE_RATIO;

    const hkReal radius = CHARACTER_SCALE_RATIO * 0.45f;

 

    float lerp = 4.5f;

    hkVector4 va(0, 0, totalHeight + lerp );

    hkVector4 vb(0, 0, 0 + lerp );

 

    m_pStandShape = new hkpCapsuleShape( va, vb, radius );       

    va.setZero4();

    m_pCrouchShape = new hkpCapsuleShape( va, vb, radius );

충돌 메쉬 중심점과 렌더링 되는 캐릭터의 중심점이 일치 하는지 확인 하기 위해서 다음을 실행한다.

    hkpCharacterInput   xInput;

    m_pHavokRigidBody->checkSupport( stepInfo, xInput.m_surfaceInfo );

 

    hkVector4 charPos = m_pHavokRigidBody->getPosition();

    hkVector4 pos = xInput.m_position;

    hkVector4 normal = xInput.m_surfaceInfo.m_surfaceNormal;

    OutputDebugPrintf( "캐릭터 높이 %.2f: 위치: %.2f, %.2f, %.2f 표면 노멀 %f, %f, %f\n",

        charPos(2), pos(0), pos(1), pos(2),

        normal(0), normal(1), normal(2) );

출력 되는 캐릭터의 높이(z축) charPos(2)와 지형과 충돌된 충돌 정점의 값을 일치 시킨다.

캐릭터 높이 0.05: 위치: 0.00, 0.00, 0.05 표면 노멀 0.000000, 0.000000, 1.000000

 

< 벽과 충돌 면 구하기 >

1. hkpCharacterRigidBody::hkpRigidBody::getLinkedCollidable()를 이용해서 hkpLinkedCollidable로
hkContactPoint 구하는 방식

HavokCharacter::CheckContactPoint( ) 메소드를 참조한다.

m_pHavokRigidBody->getSupportInfo로 구한 지형 높이보다 큰 경우를 벽의 충돌이라 가정한다.

HavokCharacter::IsCheckWall(  const hkVector4& velocity )로 CheckContactPoint( )에서 구한
ContactPoint 중에서 현재 진행 방향의 역방향과의 각도 차이로 벽과 충돌 했는지 체크한다.

2. hkContactPoint를 구하는 또 한가지의 방법은 hkpCharacterRigidBodyListener를 상속해서 가상함수
processActualPoints( )를 사용해서 hkContactPoint( )를 구하는 방식이다.

여기서는 hkpCharacterRigidBodyListener를 상속한 HavokCharacterListener 클래스를 리스너로 셋팅한다.

    HavokCharacterListener* pListener = new  HavokCharacterListener();

    m_pHavokRigidBody->setListener( pListener );

프로젝트 :
HavokTest_wall.zip

HavokCharacterListener.h
HavokCharacterListener.cpp

HavokCharacter.h
HavokCharacter.cpp