===================================================================================
게임 강좌 - 게임개발 문턱 넘기기
by 조무영
제 4 편 : Max Exporter #1
이번 주제는 그래픽 디자이너가 작업한 3D 오브젝트, 애니메이션 등의 정보를
어떻게 우리의 프로그램이 해독 가능한 형태로 가공할 것인가에 대한 내용입니다.
- 들어가며
- 준비
① 3D Studio Max (이하 맥스)
요것이 설치되어있어야 합니다.
버전은 7.0 을 추천합니다. (딴데선 테스트를 못해봤어요…)
② 파일
델마당 게임제작 게시판에 보시면 “[세미나자료] 3D 캐릭터 애니메이션 강의자료입니다.” 라는 제목으로
강의자료를 올려두었습니다.
이걸 다운로드 받으시기 바랍니다.
당분간의 강좌 내용은 세미나 강의자료만으로 충분하므로 별도의 파일 업로드는 없을 듯 합니다.
- 강좌의 내용
스크립트 문법을 단계적으로 정리하기보다는 예제를 살펴보는 방식으로 진행하겠습니다.
좀 답답하겠지만 보다 깊이있는 내용은 맥스의 Help 메뉴에서 MaxScript Reference 를 참고하셔요.
또한, 맥스 자체의
- 참고문헌
MaxScript Reference… -.-;
- 맥스 스크립트의 등록
- 파일 복사
“Max스크립트” 폴더의 하위폴더들을 맥스가 설치된 폴더에 덮어씁니다.
만일에 대비하여, 동일한 파일명이 존재할 경우에는 백업을 합시다.
- Max 실행
Max 를 실행합니다.
- 스크립트 메뉴 등록
MaxScript -> Open Script 메뉴를 클릭합니다.
DelDX_Anim_Export.ms 파일을 불러옵니다.
편집창이 뜨지요 ?
편집창 메뉴의 File -> Evaluate All 메뉴를 클릭합니다.
DelDX_Bone_Export.ms, DelDX_Dobject_Export.ms 파일에 대해서도 같은 과정을 반복합니다.
이제 편집창을 닫은 후 Max 의 Customize -> Customize User Interface 메뉴를 클릭합니다.
인터페이스 설정창이 뜨면 Menus 탭을 클릭합니다.
Category 에서 DelDX 를 선택합니다.
Action 리스트에 세개의 익스포터가 나오지요 ?
오른쪽의 메뉴 리스트에 이 익스포터들을 옮깁니다. (원하는 위치에 옮기면 됩니다.)
그런 다음 창을 닫습니다.
이제 원하는 위치에 세개의 익스포트 메뉴가 생겼는지 확인합니다.
- 익스포트 테스트
강의자료중에서 Max Data 폴더를 보시면 몇가지 오브젝트가 있습니다.
Max 의 File -> Open 메뉴에서 다음 파일을 로드합니다.
Max Data\FreeModel\zeb\zeb.max
이제 Max 화면에 외계에서 온 zeb 이 나타나면
앞서 등록한 세개의 익스포트 메뉴를 각각 클릭해줍니다.
파일이름을 선택해서 적당한 위치에 익스포트하면 됩니다.
단, DBJExport 에서는 Skin 항목에 체크를 하셔야 합니다.
- 로드/렌더링 테스트
강의자료중 예제 폴더에 보면 ObjectTool.exe 라는 실행파일이 있습니다.
이걸 실행합니다.
F3, F4, F5 키를 눌러서 앞서 익스포트한 파일을 하나씩 불러옵니다.
화면에 zeb 이 방정맞게 움직이는게 보이면 성공입니다.
- 맥스 스크립트 맛보기
- 오브젝트 하나 만들기
맥스를 실행하신 후에 화면에 박스를 하나 만듭니다.
(어떻게 만드는지 모르신다면 Max 사용법에 관한 인터넷 자료나 서적을 참고하셔요)
박스가 만들어졌다면 이름은 아마도 “Box01” 일 것입니다.
박스는 버텍스(꼭지점) 8 개, 폴리곤 12개(여섯개의 면에 삼각형 각 두개씩)를 가집니다.
이제 이 정보를 스크립트로 어떻게 알아내는지 보겠습니다.
- 리스너
우선 맥스 화면에서 F11 을 누릅니다.
맥스스크립트 리스너라는 창이 뜨지요 ?
이게 맥스 스크립트를 입력하고 결과를 바로 받을 수 있는 대화창입니다.
창의 위쪽 영역은 입력, 아래쪽은 출력을 담당하도록 되어있습니다.
이제 간단한 질문을 하도록 하겠습니다.
$Box01 (엔터)
응답이 바로 오지요 ?
–> $Box:Box01 @ [-0.418410,0.418410,0.000000]
뭐 이렇게요.
박스에 대한 정보를 요구하자 그에 대한 정보를 출력해준 것입니다.
해석을 하자면 다음과 같습니다.
Box 라는 클래스, Box01 이라는 이름, [-0.418410,0.418410,0.000000] 라는 좌표를 가졌다…
이제 위 질문을 세가지로 나눠서 해보겠습니다.
classof $Box01
$Box01.name
$Box01.position
이렇게 하면 세가지 질문에 대한 각각의 답은 다음과 같이 넘어옵니다.
–> Box
“Box01”
[-0.41841,0.41841,0]
좌표값은 뭐, 위치를 어디에 잡아줬느냐에 따라 각자 다르게 나오겠지요.
암튼 리스너는 스크립트를 개발하는 도중에 매우 유용하게 사용되니 익숙하게 다룰 수 있도록
충분히 연습하시기 바랍니다.
- 좀 더 자세한 정보 얻기
Box01 에 대한 좀 더 자세한 정보를 얻어보겠습니다.
$Box01.Mesh.NumFaces
–> 12
이것은 박스의 Face 수 (폴리곤 수)를 알아내는 명령입니다.
GetFace $Box01.Mesh 1
–> [1,3,4]
이것은 첫번째 폴리곤을 구성하는 버텍스의 번호를 돌려줍니다.
※ Max Script 에서 모든 배열은 0 이 아니라 1 부터 시작합니다… 헷갈리면 안돼요…!!!
이제 위 세 버텍스의 좌표를 알아내도록 해보겠습니다.
GetVert $Box01.Mesh 1
GetVert $Box01.Mesh 3
GetVert $Box01.Mesh 4
각 버텍스의 좌표가 나오지요 ?
GetVert 는 버텍스의 좌표를 받을 수 있는 명령입니다.
GetNormal 을 쓰면 노멀벡터를 받아옵니다.
이번에는 텍스쳐UV 값을 받아오는 명령입니다.
GetTVFace $Box01.Mesh 1
–> [10,12,11]
GetTVert $Box01.Mesh 10
–> [1,0,0]
GetTVert $Box01.Mesh 11
–> [0,1,0]
GetTVert $Box01.Mesh 12
–> [1,1,0]
앞서 Face 를 이루는 버텍스의 인덱스를 알아오는것과 같이
UV 값의 인덱스를 알아온 후 각각의 값을 다시 얻어야 합니다.
위의 [1, 1, 0] 은 U=1, V=1, W=0 이라는 뜻이구요… 일반적으로는 U,V 만 쓰면 됩니다.
- 맛보기 for 문 써보기
앞서 만들어놓은 박스의 8 개의 정보를 파일로 출력하는 스크립트를 만들어보도록 하겠습니다.
리스너의 입력창을 깨끗하게 비운 후에 다음 코드를 적어넣습니다.
DBJFile = fOpen “c:\Test.txt” “wb”
FaceCount = $Box01.Mesh.NumFaces – 폴리곤의 수
for iFace = 1 to FaceCount do – 각 폴리곤별로
(
FaceVerts = GetFace $Box01.Mesh iFace – 버텍스 인덱스 세개
UVVerts = GetTVFace $Box01.Mesh iFace – UV 인덱스 세개
for iVert = 1 to 3 do – 버텍스 세개에 대해서
(
vXYZ = GetVert $Box01.Mesh FaceVerts[iVert] – 위치값
vNorm = GetNormal $Box01.Mesh FaceVerts[iVert] – 노멀벡터
UV = GetTVert $Box01.Mesh UVVerts[iVert] – UV 값을 구하고
WriteFloat DBJFile vXYZ.x – 파일에다가 씁니다.
WriteFloat DBJFile vXYZ.z
WriteFloat DBJFile vXYZ.y
WriteFloat DBJFile vNorm.x
WriteFloat DBJFile vNorm.z
WriteFloat DBJFile vNorm.y
WriteFloat DBJFile UV.x
WriteFloat DBJFile UV.y
)
)
fClose DBJFile – 파일을 닫습니다.
※ 맥스의 좌표계는 D3D 와 차이가 있기 때문에 y 값과 z 값을 바꿔서 넣어야 합니다.
※ U, V 값 모두 약간의 손질이 필요한데요, 요건 나중에 생각합시다.
이제 리스너창 메뉴의 File -> SaveAs 메뉴를 클릭하여 임의의 이름으로 저장합니다.
저장된 파일을 맥스 메뉴의 MaxScript->RunScript 메뉴를 통해서 실행합니다.
에러가 나지 않고 정상적으로 실행되었다면
C 드라이브 루트에 Test.txt 라는 파일이 만들어져있을꺼예요.
바이너리이니 그냥 봐서는 값이 정상적인지 모르겠습니다만,
파일의 크기가 정확히 1152 바이트인 것을 확인할 수 있습니다.
12 폴리곤 x 3 버텍스 x 실수값 8 개 x 각 실수값 4바이트 = 1152 바이트…가 되는거죠.
- 기타
스크립트 리스너는 라인 단위로 입력을 받도록 되어있으며, 맨 마지막 라인이 아니면 입력이
일어나지 않도록 되어있습니다.
그때그때 뭔가를 확인할때에는 유용하지만 스크립트 프로그래밍을 직접 하기에는 불편하죠.
그래서 실제로 익스포터를 만들때에는 “.ms” 확장자의 스크립트 파일로 만들게 됩니다.
맥스 스크립트는 변수를 그때그때 사용과 동시에 생성하는 방식으로 되어있습니다.
선언부가 따로 필요 없지요.
그래서 자칫하면 비슷하면서도 다른 변수명때문에 고생할 수도 있습니다.
또한, gc() 명령으로 필요없는 메모리를 종종 해제해주지 않으면 메모리 사용량이 증가하다가
결국 맥스가 다운되어버리는 경우도 발생합니다.
델파이나 비주얼씨와는 달리 프로그래머들에게는 좀 답답한 구석이 많은 도구입니다만,
장점도 많기 때문에 사용을 하게 되는 것이지요…
오브젝트에 대한 정보를 얻는 것 외에도,
맥스 스크립트는 맥스의 명령을 직접 코드로 수행하게 하는 등
맥스를 이용하는 작업 자체를 프로그래밍할 수 있도록 되어있습니다.
스크립트 예제는 맥스스크립트 레퍼런스의 목차를 보시면 무쟈게 많이 나옵니다.
직접 스크립트를 개발하시려면 레퍼런스를 어느정도 살펴보셔야 합니다.
오늘은 여기까지입니다.
다음번에는 본(뼈대)을 뽑아내는 익스포터를 분석해보도록 하겠습니다.
궁금하신 내용이 있으시면 질문리플 달아주셔요…