티스토리 뷰

나의 이해를 돕기 위해 이 내용 저 내용을 다룬다....

bone based animation , skeketal animation

계층적 애니메이션 방식을 좀 더 범용적으로 발전시킨 것이다. 인간의 몸 속에 뼈가 있듯, 3 차원적으로 구성된 뼈대를 만들고 이 뼈대에 메시를 자식으로 붙이는 방식이다.

뼈대는 메시가 아니므로 화면에 렌더는 되지 않는다.

동일한 뼈대 구조를 가진 오브젝트들의 메시만 뼈대에 적용하면 되기 때문에

메모리절약, 다양한 응용 가능하다.

 

본은 D3DXFRAME 구조체를 통해 기술되며 이 구조체를 통하여 완전한 본 게층 구조 구성이 가능하다.

해당되는 멤버들에 대하여 조금 살펴보자면 

 

//변환 프레임 계층 내의 변환 프레임을 캡슐화한다.
struct D3DXFRAME{
    LPSTR Name;                                                   //본(프레임)의 이름
    D3DXMATRIX TransformationMatrix;                    //로컬변환행렬
    LPD3DXMESHCONTAINER pMeshContainer;       //본에 연결된 메시 컨테이너 포인터
    D3DXFRAME* pFrameSibling;                            //형제 본 포인터
    D3DXFRAME* pFrameFirstChild;                        //첫번째 차일드 본 포인터
};

 D3DXFRAME 구조체는 자신에게 연결된 메시 컨테이너의 포인터를 가지고있다.

메시 컨테이너 구조체는 다음과같은 멤버를 가지고있다.

//변환 프레임 계층 내의 메쉬 개체를 캡슐화 한다.
struct D3DXMESHCONTAINER{
    LPSTR Name;                                                   //메쉬의 이름
    D3DXMESHDATA  MeshData                              //메시내의 데이터형태
    LPD3DXMATERIAL  pMaterials                            //메시 머티리얼의 매열
    LPD3DXEFFECTINSTANCE  pEffects                    //이펙트 인스턴스의 포인터
    DWORD  pFrameFirstChild;                                 //메시에 포함되는 머티리얼 수
    DWORD *pAdjacency;                                       //메쉬삼각형마다의 adjacency 저장된 배열포인터
    LPD3DXSKININFO pSkinInfo;                              //스킨 정보인터페이스의 포인터
    D3DXMESHCONTAINER *pNextMeshContainer;     //다음메시컨테이너포인터

};

이 구조체가 가진 멤버중에 D3DXMESHDATA를 타고 들어가면 메시도 만날 수 있다.

//메쉬 데이터의 구조
struct D3DXMESHDATA{
    D3DXMESHDATATYPE Type;                     //메쉬 데이터의 종류
    union
    { 
        LPD3DXMESH pMesh;                          //메쉬의 포인터
        LPD3DXMESH pPMesh;                        //프로그래시브 메시의 포인터
        LPD3DXPARCHMESH pPatchMesh;       //패치메시포인터
    }
};

 

머티리얼 배열을 가리키는 pMatrials,  구조체 D3DXMATERIAL은 다음과 같이 구성된다.

//.x 파일에 보존되고 있는 머티리얼 정보 

struct D3DXMATERIAL{
    D3DMATERIAL9 MatD3D;      //머티리얼
    LPSTR pTextureFilename;    //텍스쳐파일명지정하는 캐릭터라인 포인터
};

 

그리고 D3DXSkinInfo 는 스키닝에 이용됨

"애플리케이션은,ID3DXSkinInfo 인터페이스의 메서드를 사용해, 애니메이션의 정점 데이터의 스키닝에 사용하는 뼈 행렬을 조작한다. 이 인터페이스는,ID3DXMesh 인 만큼 제한되는 일 없이, 임의의 정점 데이터 세트의 스키닝에 사용할 수 있게 되었다. "

라고 한다.

GetMaxVertexInfluences

뼈의 영향의 수를 얻어온다

SetBoneOffsetMatrix

뼈의 오프셋(offset) 행렬을 설정한다.

UpdateSkinnedMesh

현재의 행렬에 근거해, 타겟의 정점에 소프트웨어 스키닝을 적용한다.

뭐 이런 멤버들이 있다.

=> 더많은 멤버보기

=> 스키닝?

 

여튼 다시 본론으로 돌아와서

D3DXFRAME 구조체가 가진 이름으로 우리는 계층구조에서 특정 프레임을 찾을 수 가 있고, 해당 프레임에 원하는 메시오브젝트를 붙일 수도 있다.

각각의 본은 부모 본에 대해 상대적이니 자신의 위치 방향 스케일을 표시하느 변환행렬 가지고있는데 이것이 계층적  애니메이션이 가진 자신의 변환 행렬이다. 상대적인 위치이기 때문에 월드변환행렬이 아닌 로컬스페이스 상의 자신변환 행렬이다.

D3D는 자유를 위해..... 우리가 이를 확장해서 사용하도록 만들어두었으며

우리는 이 구조체를 이용하여 올바른 렌더링을 하기 위해서

멤버로 월드 매트릭스를 추가해 주어야 한다.

다음과 같이 확장할 수 있다.

struct D3DXFRAME{
    LPSTR Name;                                                   //본(프레임)의 이름
    D3DXMATRIX TransformationMatrix;                    //로컬변환행렬
    LPD3DXMESHCONTAINER pMeshContainer;       //본에 연결된 메시 컨테이너 포인터
    D3DXFRAME* pFrameSibling;                            //형제 본 포인터
    D3DXFRAME* pFrameFirstChild;                        //첫번째 차일드 본 포인터
};

//상속받아 모든 멤버를 포함한 채로 다음멤버들을 추가한다.  

struct BONE : public D3DXFRAME{
    D3DXMATRIX CombinedTransformationMatrix;     //월드변환 행렬
};
    

 

이렇게 있으면 재귀적방식으로 계층구조의 최상위에있는 매트릭스부터 훑어내려가면서 CombinedTransformationMatrix에 부모매트릭스를 곱해준 후 자식들 , 형제들의 월드매트릭스도 적용해줄 수 있다

메시는 각각의 뼈대마다 존재하는것이 아니라 bind-space 상에 존재한다.( 포인터로 가져다가 위치잡아서 그림을 그리는거)

또한 소프트웨어 스키닝을통하여 렌더링을 좀더 편리하게 하려면

D3DXMESHCONTAINER 구조체도 확장해줄 필요가 있다.

예를들면 다음과 같다.

struct D3DXMESHCONTAINER{
    LPSTR Name;                                                   //메쉬의 이름
    D3DXMESHDATA  MeshData                              //메시내의 데이터형태
    LPD3DXMATERIAL  pMaterials                            //메시 머티리얼의 매열
    LPD3DXEFFECTINSTANCE  pEffects                    //이펙트 인스턴스의 포인터
    DWORD  pFrameFirstChild;                                 //메시에 포함되는 머티리얼 수
    DWORD *pAdjacency;                                       //메쉬삼각형마다의 adjacency 저장된 배열포인터
    LPD3DXSKININFO pSkinInfo;                              //스킨 정보인터페이스의 포인터
    D3DXMESHCONTAINER *pNextMeshContainer;     //다음메시컨테이너포인터

}; 

//상속받아 모든 멤버를 포함한 채로 다음멤버들을 추가한다. 

struct
 BONE_MESH : public D3DXMESHCONTAINER{
    LPD3DXMESH pOrigMesh;                               //스키닝 계산에 사용될 참조 메시
    vector<D3DMATERIAL9> vecMtl;                //재질목록        
    vector<LPDIRECT3DTEXTURE9> vecTexture;    //텍스쳐목록               
    D3DXMATRIX** ppBoneMatrixPtrs;            //본 변환 행렬들의 포인터(현재 메쉬에 영향을주는애들)
    D3DXMATRIX* pBoneOffsetMatrices;                 //본 오프셋 행렬들
    D3DXMATRIX* pCurrentBoneMatrices;              //본들의 합산된 변환 행렬들
    D3DXATTRIBUTERANGE* attributeTable             //속성테이블
    DWORD NumAttributeGroups                             //속성 그룹의 수
};

 

이러한 계층구조를 직접작성하지않고 3d 프로그램으로 제작된 .x 파일을 로드해올 수 있는데..

=>애니메이션을 위한 .x 파일 읽기 및 객체 확장에 관한 내용

 

//D3DXFRAME msdn :

https://msdn.microsoft.com/ko-kr/library/windows/desktop/bb172845(v=vs.85).aspx

http://telnet.or.kr/directx/graphics/reference/d3dx/structures/d3dxframe.htm

http://telnet.or.kr/directx/graphics/reference/d3dx/structures/d3dxmeshdata.htm

http://telnet.or.kr/directx/graphics/reference/d3dx/structures/d3dxmeshcontainer.htm

http://telnet.or.kr/directx/graphics/reference/d3dx/interfaces/id3dxskininfo/_id3dxskininfo.htm

 

//좋은설명감사합니다

http://m.blog.naver.com/codeknight2/110138293948

//

http://m.blog.naver.com/jidon333/220238379981

http://skmagic.tistory.com/entry/Skeletal-Animation

http://m.blog.naver.com/codeknight2/110138293948

 

'ComComComCom > DX .. D3D' 카테고리의 다른 글

ID3DXAnimationController interface  (0) 2017.07.13
Animation Controller class  (0) 2017.07.13
.x 파일을 D3DXLoadMeshHierarchyFromX() 로 읽을때  (0) 2017.07.12
애니메이션 - 스키닝  (0) 2017.07.12
[function] D3DXLoadMeshFromX()  (0) 2017.07.12
댓글