max sdk 관련 자료

반응형
이 문서는 제가 3D Studio Max 3.x SDK 프로그래밍을 하면서 제가 필요한 것들만 정리
한것입니다. 저만 알아볼 수 있도록 되어 있는 부분이 많습니다. 시간날 때 다시 정리
하겠습니다.

--------------------
SDK 관련 사이트
--------------------
http://www.discreet.com/support/max/download/download.php3 : SDK 다운로드
http://sparks.discreet.com/downloads/downloadshome.cfm : SDK 관련 각종 다운로드
http://sparks.discreet.com/search/
http://support.ktx.com/~200/
http://sparks.discreet.com/webboard/wbpx.dll/~maxsdk/
http://support.discreet.com/webboard/wbpx.dll/%7Emos
http://www.gamasutra.com/features/19980220/baumann_01.htm
http://www.scriptspot.com : max sciprt 관련

--------------------
MAX SDK 관련 서적
--------------------

Maxscript and the Sdk for 3d Studio Max
: http://www.amazon.com/exec/obidos/ASIN/0782127940/

--------------------
TimeValue
--------------------

  Max 에서 시간표현은 TimeValue 라는 타입으로 사용한다. 이것은 ticks 라는 단위의
  정수표현인데, 1초는 4800 ticks 에 해당한다. 이값은 아래의 표준 프레임수에 근거
  하여 모두 나누어 질 수 있는 적당한 값을 선택한 것이다.
 
  24 - 필름, 25 - PAL, 30 - NTSC
 
  TimeValue start = ip->GetAnimRange().Start();
  TimeValue end = ip->GetAnimRange().End();
  int number_of_frames = (end - start) / GetTicksPerFrame() + 1;
  int frame_per_second = GetFrameRate(); // = 4800 / GetTicksPerFrame()
 
--------------------
Transformation Matrix Order
--------------------

  Max 에서 TM(Transform Matrix)는 Matrix3 클래스로 정의된다. 이는 흔히 말하는
  행렬을 의미한다. 다른 점이 있다면 4x3 행렬이라는 것이다. 내부적으로는
  float m[4][3]; 처럼 정의된 데이타타입을 가지고 있다. Max에서 모든 벡터는
  행벡터로 간주되기 때문에 벡터-행렬곱은 다음과 같은 식으로 이루어진다.
 
  [v0 v1 v2 v3] * | m00 m01 m02 m03 | = [ v0\' v1\' v2\' v3\' ]
                  | m10 m11 m12 m13 |
                  | m20 m21 m22 m23 |
                  | m30 m31 m32 m33 |
 
  (* m00, m01,...mij 등등의 표현은 i번째 행, j번째 열의 행렬요소를 의미한다.
     배열이라고 하면 m[i][j]라고 표현할 수 있다)
  
  오픈지엘에서는 아래와 같은 열벡터를 사용한다. 유의할 점은 맥스에서와는 달리 벡
  터가 곱하려는 행렬의 우측에 위치해야 한다는 것이다.
 
  | m00 m01 m02 m03 | * | v0 | = | v0\' |
  | m10 m11 m12 m13 |   | v1 |   | v1\' |
  | m20 m21 m22 m23 |   | v2 |   | v2\' |
  | m30 m31 m32 m33 |   | v3 |   | v3\' |
 
  하지만, 맥스에서는 vector * TM 뿐만 아니라, TM * vector 도 허용한다는 사실을
  알아두자(결과는 동일하다).
 
  맥스에서 사용하는 행렬은 앞서 말한것처럼 4x3 행렬이기 때문에 일반적인 행렬의
  w(scale)성분이 없다. 행렬이 아래와 같은 식으로 구성된다.
 
  | m00 m01 m02 |
  | m10 m11 m12 |
  | m20 m21 m22 |
  | m30 m31 m32 |
 
  만약, [v0 v1 v2] 인 벡터와의 형렬곱은 내부적으로 아래와 같이 계산될 것 같다.
 
  [v0 v1 v2 1] * | m00 m01 m02 | = [v0\' v1\' v2\']
                 | m10 m11 m12 | 
                 | m20 m21 m22 |
                 | m30 m31 m32 |
 
  행벡터를 사용하는 맥스의 행렬을 열벡터를 사용하는 OpenGL에서 사용하려면 행렬을
  전치(Transpose)시켜야 한다.
 
    (맥스:행벡터사용)     (오픈지엘:열벡터사용)
  | m00 m01 m02 N/A |     | m00 m10 m20 m30 |
  | m10 m11 m12 N/A | =>  | m01 m11 m21 m31 |
  | m20 m21 m22 N/A |     | m02 m12 m22 m32 |
  | m30 m31 m32 N/A |     | N/A N/A N/A N/A |
 
  정의되어 있지 않은 [N/A N/A N/A N/A] 는 [0 0 0 1] 로 대입하여야 하며, 오픈지엘
  은 행렬을 배열로 표현시에 아래와 같은 순서를 취하기 때문에,
 
  | g0 g4 g8  g12 |   | g00 g10 g20 g30 |
  | g1 g5 g9  g13 | = | g01 g11 g21 g31 |
  | g2 g6 g10 g14 |   | g02 g12 g22 g32 |
  | g3 g7 g11 g15 |   | g03 g13 g23 g33 |
 
  맥스의 m배열은 OpenGL의 g배열로 아래와 같이 매핑된다.
 
  | m00 m10 m20 m30 |    | g00 g10 g20 g30 |
  | m01 m11 m21 m31 | =  | g01 g11 g21 g31 |
  | m02 m12 m22 m32 |    | g02 g12 g22 g32 |
  |   0   0   0   1 |    | g03 g13 g23 g33 |
 
  운좋게도, MAX 의 m[i][j] 의 값은 OpenGL 의 g[i][j] 와 같다. g[0][3] - g[3][3]
  의 값이 [0 0 0 1] 인 점만 제외하면 나머지 값은 MAX 배열 순서와 일치한다.
  코딩을 한다면 아래와 같을 것이다.
 
  for (i = 0; i < 4;i++) {
    for (j = 0; j < 3;j++) {
      OpenGL[i][j] = Max[i][j];
    }
    OpenGL[i][3] = 0.0;
  }
  OpenGL[3][3] = 1.0;
 

--------------------
Transformation Matrix
--------------------

o Object Offset TM
  Object Offset이란 맥스의 Pivot 축을 기준으로 하여 지오메트리가 위치하는 TM을
  말한다. 맥스에서 Pivot을 움직이거나 회전시킬 수도 있는 것은 이 때문이다.
  아래와 같이 계산된다.
 
  Object Offset TM = Offset Scale * Offset Rotation * Offset Position

o NodeTM
  NodeTM이란 Pivot 축을 월드좌표로 변환하기 위한 TM이다.
 
o Object TM
  Object TM이란 오브젝트의 한 점을 월드좌표계로 변환하기 위한 TM을 의미한다.
  ObjectTM은 부모TM, NodeTM, ObjectOffsetTM을 모두 포함한다.
 
  ObjectTM = Offset Scale * Offset Rotation * Offset Position *
             Controller Scale * Controller Rotation * Controllers Position *
             Parent Transformation

o Local Transformation

  NodeWorldTM = NodeLocalTM * ParentLocalTM * ParentLocalTM * ParentLocalTM ...
 
  ParentWorldTM = ParentLocalTM * ParentLocalTM * ParentLocalTM ...
 
  NodeWorldTM = NodeLocalTM * ParentWorldTM
 
  NodeLocalTM = NodeWorldTM * Inverse(ParentWorldTM)
 
  예제)
 
  ...
  INode *parent;
  Matrix3 parentTM, nodeTM, localTM;
  nodeTM = node->GetNodeTM(0);
  parent = node->GetParentNode();
  parentTM = parent->GetNodeTM(0);
  localTM = nodeTM*Inverse(parentTM);
  ...

--------------------
MAX 3.0 을 Windows 2000 (한) 에서 실행하기
--------------------

  Max 3.1 에서는 상관없지만 3.0 버젼을 Windows 2000 (한글) 에서 사용하려면
  다음과 같은 옵션을 주어 실행한다.
 
  C:\\3DSMAX3\\3dsmax.exe -q
 
  Max 실행화일의 바로가기 아이콘을 만든다음 등록정보의 "대상"에서 실행옵션을
  위와 같이 적어주면 된다.
 
--------------------
SDKLINK.ZIP
--------------------

  MAXSDK/HELP 디렉토리를 보면 SDKLINK.ZIP 라는 파일이 있다. 압축을 풀고 .DOC
  파일을 보면 알 수 있겠지만, 이 파일은 비주얼 씨를 사용할 때에 TOOL 에 등록하여
  헬프를 쉽게 사용하기 위한 방법을 설명해 주고 있다. 예를 들면, SDK 헬프에서
  찾고자 하는 클래스 이름이나 함수명을 선택하고 Ctrl+Alt+C 를 누르면 해당하는
  MAXSDK 헬프창이 뜨도록 할 수 있다. 물론 울트라에디트나 에디트플러스 등에서도
  할 수 있다.

--------------------
Class Mesh
--------------------

[from MAX SDK Help]

- UVVert *tVerts;

  텍스쳐 버텍스 배열. UVW 좌표를 저장한다. 2D 매핑을 위해서는 2개의 값만 필요하
  다. 예를 들면. UV 또는 VW, WU. 이는 사용자에게 UV, VW 또는 WU 중에서 선택할
  수 있도록 하기 위함이다.

(UVVert 의 정의 : typedef Point3 UVVert;)

- TVFace *tvFace;

  3D 스튜디오(도스용) 시절에는 UV 배열과 버텍스 배열사이에 일대일대응이 되었으
  다(즉, 각각의 버텍스에 대해서 하나의 UV만). 하지만, 맥스에서는 UVVert 배열은
  배열과 완전히 독립적이다. 대신에, 별도의 TVFace 배열이 있다. 모든 면은 하나의
  TVFace 를 가지며, 하나의 TVFace 는 UVVert 를 가리키는 세개의 인덱스가
  필요하다. 이렇게 한 이유는 개발자가 매핑에 따라 완전히 다른 토폴로지를 적용할
  수 있도록 하기 위함이다. 객체 각각의 면은 각자 자신의 매핑을 가질 수 있다.
  (다시 말하면, 인접한 서로 다른 면의 버텍스에 대해서 연속적인 텍스쳐 매핑
  좌표를 갖지 않아도 된다는 것이다.)    
 
--------------------
Object Creation
--------------------
- utiltest.cpp -> MakeObject()

1. (Object * ip)->CreateInstance(CLASSID); // CLASSID from PLUGAPI.H
2. ParameterBlock->SetValue
3. CreateObjectNode()
4. Redraw()

--------------------
Rotate
--------------------
- DegToRad (45.0f)
  angle 은 radian 이므로 degree 로 바꿀것

--------------------
TM
--------------------
- A라는 TM에서 b만큼 떨어진 B라는 TM 구하기 (from camera.cpp)

  bM = aM;
  bM.PreTranslate(Point3(0.0f, 0.0f, b));
 
--------------------
Node 다루기
--------------------
INode * node;
TSTR name(_T("MyNode"));
ip->MakeNameUnique(name);
node->SetName(name); // Node 이름 바꾸기
ip->RedrawViews(ip->GetTime());

INode *parent;
Matrix3 parentTM, nodeTM, localTM;
nodeTM = node->GetNodeTM(0);
parent = node->GetParentNode();
parentTM = parent->GetNodeTM(0);
localTM = nodeTM * Inverse(parentTM);
ptm = node->GetParentTM(ip->GetTime());

INode * GetINodeByName (const TCHAR *name) = 0;

--------------------
INode Method
--------------------

  Matrix3 GetNodeTM (TimeValue t, Interval * valid = NULL);
    ; 노드의 pivot 의 월드 TM 구하기
 
  Matrix3 GetObjectTM (TimeValue time, Inverval * valid = NULL);
    ; ObjectOffsetTM + NodeTM + WSM
 
  Point3 VectorTransform (const Matrix3& M, const Point3& V);

--------------------
대화상자 폰트 작게
--------------------
regedit.exe -> HKEY_CURRENT_CONFIG -> Software -> Fonts -> FONTS.FON 에서

hvgasys.fon 를 vgasys.fon 으로 변경 후 리부팅.

http://www.cgmate.com/zeroboard/zboard.php?id=cgmate_master&no=20

--------------------
플러그인이 로딩 안될 때
--------------------
작성한 플러그인이 어떤 시스템에서는 로딩되지만, 어떤 시스템에서는 로딩되지 않을
때에는, 컴파일시 사용한 .DLL 파일이 없어서일 수 있다.
예를 들어, .net 환경에서 컴파일하면, msvcr70.dll 을 사용하게 되는데, 이 파일이
없는 시스템에서는 dll이 동작하지 않는다.
플러그인 파일이 어떤 DLL을 사용하는 지 확인하려면, 비주얼씨의 bin 디렉토리에 있는,
dumpbin.exe 를 사용하여 확인한다.

> dumpbin.exe /imports utility.dlu

'유용한 것들_etc' 카테고리의 다른 글

메모관리 프로그램  (0) 2009.12.02
유니코드 표  (0) 2009.11.25
win api + dialog  (0) 2009.11.19
언리얼의 한글화라....  (0) 2009.11.07
Uninstall 아이콘만들기  (0) 2009.09.14
TAGS.

Comments