Havok Shape Rendering 01

비쥬얼 디버거를 통해, 하복의 충돌 상황을 알수 있다.

캐릭터의 RigidBody를 만드는데 사용되는 Shape를 다이렉트 X 메쉬로 렌더링 해 보자.

hkpCapsuleShape의 정보를 렌더리해서 캐릭터의 RigidBody가 움직일때 행렬 정보에 따라서 다이렉트 X의 메쉬를 움직이는 것을 목표로 한다.

 

1 . 다이렉트 X 메쉬 생성

hkpShape에서 메쉬 정보를 추출 할려면 hkpShapeDisplayBuilder 클래스의 buildDisplayGeometries 메소드를 이용 한다.

hkpShapeDisplayBuilder::buildDisplayGeometries(
                const hkpShape* shape,
                hkArray<hkDisplayGeometry*>& displayGeometries );

정점 정보를 구해서 DxVertex를 설정한다..
삼각형의 인덱스 정보를 구해서 DxIndex를 설정한다..
이때, 인덱스 정보를 설정시 DxVertex의 노멀값을 계산한다.

DxVertex와 DxIndex를 이용해 DxMesh를 생성한다.

void  HavokDebug::MakeMesh( hkpShape* pShape, hkpRigidBody* pRigidBody )

{

    hkArray<hkDisplayGeometry*> displayGeometry;

    hkpShapeDisplayBuilder::hkpShapeDisplayBuilderEnvironment env;

    hkpShapeDisplayBuilder builder(env);

 

    builder.buildDisplayGeometries( pShape, displayGeometry );

 

    int  nSize = displayGeometry.getSize();

    for( int  n = 0; n < nSize; ++n )

    {

        displayGeometry[n]->buildGeometry();

 

        const  hkGeometry* geom = displayGeometry[n]->getGeometry();

 

        int  numTriangles = geom->m_triangles.getSize();

        DWORD numIndices = numTriangles * 3;

 

        DxIndex* indexPtr = new  DxIndex[numIndices];

        DxIndex* curIndex = indexPtr;

 

        int  numVerts = geom->m_vertices.getSize();

        DxVertex* vertexData = new  DxVertex[numVerts];

 

        for(int  currentVertex = 0; currentVertex < numVerts; ++currentVertex)

        {

            // Get the vertex data for each point

            const  hkVector4& pos = geom->m_vertices[ currentVertex ];

            vertexData[currentVertex].position = D3DXVECTOR3(pos(0), pos(1), pos(2));

            vertexData[currentVertex].normal = D3DXVECTOR3(0, 1, 2 );

        }

 

        for( int  currentTriangle = 0; currentTriangle < numTriangles; ++currentTriangle)

        {

            const  hkGeometry::Triangle& triIndices = geom->m_triangles[ currentTriangle ];

 

            curIndex[0].index = triIndices.m_a;

            curIndex[1].index = triIndices.m_b;

            curIndex[2].index = triIndices.m_c;

            curIndex += 3;

 

            //노멀값을 정확하진 않지만 대충 계산한다.

            D3DXVECTOR3 out;

            ComputeNormal( &out,

                &(vertexData[ triIndices.m_a ].position),

                &(vertexData[ triIndices.m_b ].position),   

                &(vertexData[ triIndices.m_c ].position ) );

 

            vertexData[triIndices.m_a ].normal = out;

            vertexData[triIndices.m_b ].normal = out;

            vertexData[triIndices.m_c ].normal = out;

 

            displayGeometry[n]->releaseGeometry();

        }

 

        //Create DxMesh

        DxMesh* dxMesh = new  DxMesh;

        dxMesh->SetIndexBuffer( numIndices, indexPtr );

        dxMesh->SetVertexBuffer( numVerts, vertexData );

        //dxMesh->SetWireFrame( true );

 

        MeshInfo info;

        info.dxMesh = dxMesh;

        info.refRigidBody = pRigidBody;

        m_meshArr.push_back( info );

    }

}

2 . 다이렉트 X 메쉬 이동

캐릭터의 RigidBody가 움직일때 DxMesh를 이동( SetTransform 메소드 이용 ) 시켜주면 된다.

hkpRigidBody::getTransform( )으로 hkTransform 값을 구한다.

하복은 열우선 행렬이지만 다이렉트 X는 행우선이므로 transMat 설정시 주의 하여야 한다.
하복의 t(0, 3), t(1, 3), t(2, 3)이 위치 정보이다.

void  HavokDebug::Render()

{

    int  nSize = (int)m_meshArr.size();

    for( int  n = 0; n < nSize; ++n )

    {

        const  MeshInfo& info = m_meshArr[n];

        DxMesh* pMesh = info.dxMesh;

        hkpRigidBody* pRigidBody = info.refRigidBody;

 

        if( pRigidBody )

        {

            const  hkTransform &t = pRigidBody->getTransform();

            D3DXMATRIX transMat(

                t(0,0), t(1,0), t(2,0), 0.0f,

                t(0,1), t(1,1), t(2,1), 0.0f,

                t(0,2), t(1,2), t(2,2), 0.0f,

                t(0,3), t(1,3), t(2,3), 1.0f);

            pMesh->SetTransform( transMat );

        }

 

        pMesh->Render();

    }   

}

 

프로젝트 : havok_shapeDebug.zip