계층적, 객체지향적 그래픽스 최 수 미 smchoi@sejong.ac.kr http://www.sejong.ac.kr/~smchoi
모델링 실세계 모델 예: 뉴턴의 법칙 기하학적 모델 형상
네 가지 접근방법 1. 기본요소를 이용해서 구성 2. 절차적 모델링 예) 유한상태 오토마타, 프랙탈 3. 물리기반 예) 입자 시스템(particle system) 4. 해석적 기술방법 예) 곡선, 곡면, 입체
기호와 사례 기호 그래픽 라이브러리의 기본요소들 (다각형, 직선, 입방체, 원기둥, …) 폰트 각 응용에 따른 그래픽 객체들 기본적인 구성요소
사례 변환 M = T R S 모델 좌표계 세계 좌표계
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef( ... ); glRotatef( ... ); glScalef( ... ); glutSolidCylinder( ... ); /* 또는 다른 기호 */
객체를 그리기 위한 정보를 포함 그러나 객체들 사이의 관계는 포함하지 않음 각 기호는 자신의 식별자를 가질 수 있음 객체를 그리기 위한 정보를 포함 그러나 객체들 사이의 관계는 포함하지 않음 기호-사례 변환표
계층적 모델 예 표현해야 할 것: 1. 기하학적 관계 2. 물리적 제약 3. 동일 객체의 다중 사례
계층적 표현을 사용하면 애니메이션이 용이
좋지 않은 방법 구성요소 사이의 관계가 표현되지 않음 main() { float s = ...; /* 속도 */ float d[3] = ... ; /* 방향 */ draw_right_front_wheel(s, d); draw_left_front_wheel(s, d); draw_right_rear_wheel(s, d); draw_left_rear_wheel(s, d); draw_chassis(s, d); }
트리에 의해서 표현된 관계 단말 노드는 기호의 사례들 노드는 객체를 그리는 방법에 대한 정보를 포함
방향성 비순환 그래프 (Directed Acyclic Graph, DAG)에 의해서 표현된 관계 바퀴의 각 사례에 대한 위치 정보를 각 노드나 간선에 저장할 수 있다
로봇 팔 기저 아래 팔 위 팔
기저부의 높이 아래쪽 팔 높이
display ( ) { glRotate (, 0, 1, 0); base( ); glTranslate (0, h1, 0); glRotate (, 0, 0, 1); lower-arm ( ); glTranslate (0, h2, 0); glRotate (, 0, 0, 1); upper-arm ( ); }
자료구조 세계 기저 아래 팔 위 팔 노드가 표현하는 객체를 그릴 함수 포인터 부모노드에 대한 상대적인 위치, 크기 방향을 지정하는 동차좌표 행렬 노드의 자식을 가리키는 포인터 세계 기저 아래 팔 위 팔
트리와 순회 인물 표현
트리 표현
변환행렬이 기술된 트리 렌더링 = 트리 순회 (깊이 우선 탐색)
구현 모델관측행렬에 대한 연산들만으로는 충분치 않다 트리 순회를 지원하기 위한 방법이 필요하다 행렬 스택 푸시/팝 glPushMatrix, glPopMatrix 속성 속성 스택 glPushAttrib, glPopAttrib
figure() { glPushMatrix(); torso(); glTranslate glRotate3 head(); glPopMatrix(); left_upper_arm(); glTranslate glRotate3 left_lower_arm(); glPopMatrix(); glPushMatrix(); right_upper_arm(); . ..
트리 자료 구조의 사용 8.4 절 트리 순회 방법의 문제점 계층구조를 표현하고 모델에 독립적인 순회 알고리즘을 사용 특정 응용에 의존적, 확장하거나 동적 사용이 어려움, 모델 구축과 렌더링 사이에 분명한 구분이 없음 계층구조를 표현하고 모델에 독립적인 순회 알고리즘을 사용 표준적인 트리 자료 구조 사용 Left-child right-sibling 구조 사용 자식들 루트 형제들
노드 구조 typedef struct treenode { Glfloat m[16]; /* 4*4의 동차좌표행렬, 열우선순위 */ Void (*f) (); /* 그래픽스 기본 요소를 포함하는 함수 */ struct treenode *sibling; /* 형제 노드에 대한 포인터 */ struct treenode *child; /* 가장 왼쪽의 자식 포인터 */ }; treenode torso_node, head_node, lua_node, rua_node, lll_node, rll_node, lla_node, rla_node, rul_node, lul_node;
루트인 몸통에 대한 트리 노드 구축 glLoadIdentity(); glRotatef(theta[0], 0.0, 1.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,torso_node.m); torso_node.f = torso; torso_node.sibling = NULL; torso_node.child = &head_node;
왼쪽 위 팔에 대한 트리 노드 구축 glLoadIdentity(); glTranslatef(-(TORSO_RADIUS+UPPER_ARM_RADIUS), 0.9*TORSO_HEIGHT, 0.0); glRotatef(theta[3], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,lua_node.m); lua_node.f = left_upper_arm; lua_node.sibling = &rua_node; lua_node.child = &lla_node;
트리의 전위 순회 (pre-order traversal) void traverse(treenode* root) { if(root==NULL) return; glPushMatrix(); /* 상태 저장 */ glMultMatrixf(root->m); root->f(); /* 변경된 행렬이 자식들에게 전달 */ if(root->child!=NULL) traverse(root->child); glPopMatrix(); /* 형제들에게는 변경된 행렬이 전달되지 않도록 함 */ if(root->sibling!=NULL) traverse(root->sibling); }
- 순회 방식이 특정 트리에 독립적이므로 다음과 같은 포괄적인 디스플레이 콜백 사용 가능 void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); traverse(&torso_node); glutSwapBuffers(); }
마우스 콜백 void mouse(int btn, int state, int x, int y) { if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) theta[angle] += 5.0; if( theta[angle] > 360.0 ) theta[angle] -= 360.0; } if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) theta[angle] -= 5.0; if( theta[angle] < 360.0 ) theta[angle] += 360.0; glPushMatrix(); switch(angle) case 0 : glLoadIdentity(); glRotatef(theta[0], 0.0, 1.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,torso_node.m); break; … glPopMatrix(); glutPostRedisplay();
대화식으로 변하는 구조들을 생성하기 위해서는 동적인 접근 사용 인물들을 편집하거나 부분들을 더하기 위해서 동적 노드 생성 대화식으로 변하는 구조들을 생성하기 위해서는 동적인 접근 사용 인물들을 편집하거나 부분들을 더하기 위해서 typedef treenode* tree_ptr; tree_prt torso_ptr; torso_ptr = malloc(sizeof(treenode));
애니메이션 예제 - 로봇 팔 로봇 팔의 위치와 관절 각들의 관계: 운동학(kinematics)모델 역운동학(inverse kinematics)모델 c.f. 장애물 회피
주 프레임 애니메이션(key-frame animation) 중간 삽입(in-betweening) 포핑(morphing) = 형상의 중간삽입 각도 t t1 t2
장면 그래프 장면 = 객체들 + 조명 + 카메라 장면의 표현 장면 그래프 (scene graph) 예
Open Inventor(OpenGL의 상위에 구축된 객체지향적 API)에서 장면그래프가 사용된다. 프로그램의 실행 : 트리의 순회 장면 그래프는 객체지향 패러다임과 조화를 이룸 기본요소, 속성, 변환들을 객체로 간주할 수 있고 이들을 다루는 클래스를 정의할 수 있다. 복잡한 장면을 미리 정의한 객체들을 사용하여 간단히 구축할 수 있다.