Skin Info 세팅
pMeshContainer->pSkinInfo에 값을 채워주자.
객체가 사라지지않게 하기위해 Safe_AddRef로 참조수 1증가시켜주자.
컨테이너_Derived에 있는 3개의 행렬포인터들은 뼈의 갯수만큼 동적할당해줘야한다.
pMeshContainer->pSkinInfo->GetNumBones()로 현재 메시에 영향을 미치는 뼈의 갯수를 구해올수있다. -> 이를 iNumBones에 넣어주자.
pMeshContainer의 3개의 _matrix를 위해서 구한 뼈의 갯수만큼 동적할당해주자.
(컴바인드는 더블포인터이므로 행렬의 포인터)
왜 컴바인드는 더블포인터인가?
{
뼈의 컴바인행렬을 계산해주는 Update_Combined..함수는 애니메이션이 재생된다면 매프레임마다 호출되는함수. 현재 애니메이션 재생값에 따라
Combined값을 계속 메시컨테이너에 채워주는것은 너무 느리다.
그래서 최초 한번 현재 메시에 영향을 주고있는 뼈들의 컴바인드트랜스포메이션매트릭스 행렬의 주소를 보관할것이다.
}
오프셋매트릭스에대한 정보는 pSkinInfo가 가지고있어서 바로 넣어줄수있다.
{
바뀌지않는 행렬인 오프셋매트릭스 로드시에 미리 다 가져온다.
뼈의 갯수(iNumones)만큼 반복문을 통해
스킨인포에서 GetBoneOffsetMatrix로 얻어온 오프셋 매트릭스값을 메시컨터이너의 오프셋 매트릭스에 넣어주자
}
렌더링매트릭스 매 렌더링마다 수행한다- 오프셋 * 컴바인드
메시_다이내믹 - 셋업 컨바인드트랜스포메이션매트릭스포인터
메시컨테이너들이 가지고있는 컴바인드트랜스폼매트릭스포인터 이차원 배열에 값을 채워둔다.
->메시 컨테이너의 주소를 알고있어야한다.
(로드시에 호출한다)
D3DXMESHCONTAINER_DERIVED의 주소를 가져와서
pFrame의 컴바인드행렬의 주소를 전달하고싶다.
d3dxFrame의 pMeshContainer를 가지고있다
(첫번째 뼈만 이주소를 가지고있다)
메시에 영향을 미치는 뼈들중에 하나만 메시컨테이너의 주소를 가지고있다.
모든뼈들을 순회하면서 메시컨테이너의 주소를 찾으면된다.
{
if( nullptr != pFrame->pMeshContainer) 로 유효한 메시컨테이너를 찾는다.
해당 컨테이너를 DERIVED로 형변환해주자.
for문을 통해 뼈의갯수만 loop를 돌면서
GetBoneName으로 현재 메시에 영향을 미치는 뼈들 중, i번째 뼈의 이름을 리턴해준다.
D3DXFrameFind로 뺘를 찾는다.(루트프레임부터 검사해야한다
메시컨테이너의 컴바인드행렬에 주소값을 넣어주자.
값을 자식으로 캐스팅해서 넣어주고
해당주소를 메시컨테이너에 채워주자.
}
재귀로 순회를 해야한다.(함수의 인자로 pFrame을 받자.)
만약 자식이나 형제뼈가있다면 이를 인자로 재귀함수를 호출해주자.
메시_다이내믹 렌더링
HRESULT Render()로 메시를 그려주자.
{
DrawSubset()로 그려주기위해선 메시컨테이너를 알아야한다.
아까처럼 뼈를 순회하면서 찾아두기엔 너무 연산이오래걸린다
아까 컨테이너를 찾을때 멤버변수 m_MeshContainer에 넣어두자.
메시 컨테이너에서 메시데이타를 찾아 DrawSubset을 호출해주자.
루프를 클라이언트에서 돌기위해 컨테이너인덱스와 머테리얼인덱스를 인자로 받자.
이를위해 두 인자를 리턴해주는 Get함수 두개를 만들어주자
Get_NumMeshContainer()
Get_NumMaterials(_uint iMeshContainerIndex)
몇번째 메시컨테이너 머테리얼 개숫를 가져올것인지를 알기위해 인자가 필요하다.
}
플레이어를 다이내믹 메시로 로드해보자.
플레이어 렌더 (다이내믹 메시 렌더링)
비긴셰이더와 엔드셰이더 사이를 날려주자.
m_pMeshCom->GetNumMeshContainer()함수로 컨테이너 갯수를 받아오자.
다음 이 컨테이너를 하나하나 순회하며 서브셋을 받아오자
Get_NumMaterials로 해당 컨테이너의 서브셋 갯수를 받아와서
이 둘을 인자로 MeshCom의 Render함수를 호출해주자.
텍스쳐를 던져주자.
메시_스태틱과 같이 SetUp_TextureShader함수를 만들어주자.
메시컨테이너스에서 꺼내서 주자
{
지금 메시컨테이너_Derived에 메시컨테이너 보관이 포인터로되어있다 더블포인터로 변경해주자.
}
m_pMeshCom의 SetUp_TextureOnShader을 호출해주자.
아직 메시_다이나믹의 복사생성자의 값전달과 뼈의 값을 전달해주는것을 하지않았다.
뼈의값을 전달
메시_다이나믹의 렌더에서 값을 전달해주자.
HRESULT Update_SkinnedMesh(_uint iMeshContainerIndex)
몇번쨰 컨테이너의 값을 채울것인지를 인자로 받음
{
뼈에 스킨을 붙인다.
m_MeshContainers[iMeshContainerIndex]->iNumBones만큼 루프롤들며
오프셋매트릭스와 컨바인드 트랜스폼매이션매트릭스를 곱해서
렌더링 매트릭에서 넣어주자.
정점들의 위치에다가 렌더링 매트릭스를 곱한다.
m_MeshContainers[iMeshContainerIndex]->의 스킨인포의 UpdateSkinnedMesh가 변환을위한 배열을 인자로 받는다(렌더링 매트릭스), 역행렬도넣어줘야한다.
렌더링매트릭스는 변환되지않은 정점을 기준으로 변환시켜주기위한 행렬이다.값이 누적되서는안된다.
다음인자로 어떤 정점들에 곱하고 이를 어디에 저장할지를 인자로 받는다. 이를 절대 바뀌지않는 오리지널메쉬를 이용하자
메시컨테이너_Derived에 멤버로 pOriginalMesh를 추가한다.
하이어라키로도에서 오리지널메쉬에도 CloneMesh로 복사해주자.
이제 메시를 두개가지고있다 (메모리는 쓰지만 연산량 줄어듬)
다시 업데이트_스킨드메시로 돌아와서
오리지널메시와 메시데이타.pMesh를 모두 락해준다.
업데이트스킨드메시로 소스를 곱해서 얻는 결과물(오리지널)을 데스트(메시데이타) 에 저장한다.
이렇게해서 오리지널을 변하지않고 데스트만 변한다 원래대로 되돌려주는 작업을 안해도된다.
Mesh_Dynamic에서 값을 복사해주자.
루트프레임,피봇매트릭스,메시컨테이너를 복사해주자.
메시컨테이너의 참조수를 증가시키자.
iNumMeshContainer을 구해서
컨테이너 안의 MeshData.pMesh를 증가시키고
오리지널메시도 증가
ppMaterialTextures를 메시컨테이너의 머테리얼의 갯수만큼 순횧면서 디퓨즈 스펙큘러 노말 맵의 레퍼런스를 증가시켜주자.
ppMaterials를 각각 동적할당해주자. 메시컨테이너구조체 널포인트로 초기화해주자
플레이어에서 그릴때 뼈의 정보를 적용해주자.
CloneMesh에서 element말고 fvf로 변경해주자.
한 정점이 영향을 받을수있는 뼈의 갯수는 4개이다.
정점의 구조체가
BoneIndex를 가지고있고 각각의 본의 얼마큼 영향을 받아야하는지를
BlendWeight로 저장한다.
이작업을 UpdateSKinedMesh가 해준다 근데 Element로하면서 이값을 넣어주지않아서 애니메이팅이 불가능한상황이된다.
그리고 스킨인포는 내가 엘리메트로 인자를 뺀거를 모른다.웨이트값을 위치라고 생각하고 읽어온다.
Element를 MAX_FVF_DECL_SIZE만큼 선언하고
GetDeclartion의 인자로 정의를 받아오고
여기에 D3DCEL_END()를 찾아서 추가해줄수있다.
pSkinInfo->SetDeclaration으로 바뀐 정보도 넘겨줘야한다.
}