<4D F736F F F696E74202D20C1A63137B0AD202D20C1F6C7FCC3E6B5B9C3B3B8AE>

Similar documents
슬라이드 1

슬라이드 1

(Microsoft PowerPoint - \301\24613\260\255 - oFusion \276\300 \261\270\274\272)

슬라이드 1

슬라이드 1

(Microsoft PowerPoint - \301\24615\260\255 - \303\346\265\271\303\263\270\256)

<4D F736F F F696E74202D20C1A63034B0AD202D20C7C1B7B9C0D3B8AEBDBAB3CABFCD20B9ABB9F6C6DBC0D4B7C2>

슬라이드 1

<4D F736F F F696E74202D20C1A63037B0AD202D20B1A4BFF8B0FA20B1D7B8B2C0DA>

<4D F736F F F696E74202D20C1A63134B0AD202D20BBE7BFF8BCF6BFCD20C8B8C0FC>

슬라이드 1

슬라이드 1

chap 5: Trees

(Microsoft PowerPoint - \301\24608\260\255 - \261\244\277\370\260\372 \300\347\301\372)

* Factory class for query and DML clause creation * tiwe * */ public class JPAQueryFactory implements JPQLQueryFactory private f

<4D F736F F F696E74202D20C1A63130B0AD202D20C1F6C7FCB0FA20C7CFB4C3C0C720B7BBB4F5B8B5>

PowerPoint Template

UI TASK & KEY EVENT

(Microsoft PowerPoint - \301\24611\260\255 - \276\326\264\317\270\336\300\314\274\307)

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

게임 기획서 표준양식 연구보고서

슬라이드 1

유니티 변수-함수.key

제 1 장 기본 개념

Microsoft PowerPoint - ch10 - 이진트리, AVL 트리, 트리 응용 pm0600

PowerPoint 프레젠테이션

Microsoft PowerPoint - 07-Data Manipulation.pptx

K&R2 Reference Manual 번역본

제이쿼리 (JQuery) 정의 자바스크립트함수를쉽게사용하기위해만든자바스크립트라이브러리. 웹페이지를즉석에서변경하는기능에특화된자바스크립트라이브러리. 사용법 $( 제이쿼리객체 ) 혹은 $( 엘리먼트 ) 참고 ) $() 이기호를제이쿼리래퍼라고한다. 즉, 제이쿼리를호출하는기호

<4D F736F F F696E74202D B3E22032C7D0B1E220C0A9B5B5BFECB0D4C0D3C7C1B7CEB1D7B7A1B9D620C1A638B0AD202D20C7C1B7B9C0D320BCD3B5B5C0C720C1B6C0FD>

슬라이드 1

Windows 8에서 BioStar 1 설치하기

설계란 무엇인가?

어댑터뷰

OCW_C언어 기초

PowerPoint 프레젠테이션

(8) getpi() 함수는정적함수이므로 main() 에서호출할수있다. (9) class Circle private double radius; static final double PI= ; // PI 이름으로 로초기화된정적상수 public

Microsoft PowerPoint - es-arduino-lecture-03

var answer = confirm(" 확인이나취소를누르세요."); // 확인창은사용자의의사를묻는데사용합니다. if(answer == true){ document.write(" 확인을눌렀습니다."); else { document.write(" 취소를눌렀습니다.");

Microsoft PowerPoint - ch07 - 포인터 pm0415

쉽게 풀어쓴 C 프로그래밍

윈도우시스템프로그래밍

Analytics > Log & Crash Search > Unity ios SDK [Deprecated] Log & Crash Unity ios SDK. TOAST SDK. Log & Crash Unity SDK Log & Crash Search. Log & Cras

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CC0E7B0EDB0FCB8AE5C53746F636B5F4D616E D656E74732E637070>

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

Spring Data JPA Many To Many 양방향 관계 예제

JUNIT 실습및발표

Lab 3. 실습문제 (Single linked list)_해답.hwp

03장.스택.key

; struct point p[10] = {{1, 2, {5, -3, {-3, 5, {-6, -2, {2, 2, {-3, -3, {-9, 2, {7, 8, {-6, 4, {8, -5; for (i = 0; i < 10; i++){ if (p[i].x > 0 && p[i

@OneToOne(cascade = = "addr_id") private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a

슬라이드 1

Microsoft PowerPoint - C++ 5 .pptx

chap x: G입력

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

[ 그림 8-1] XML 을이용한옵션메뉴설정방법 <menu> <item 항목ID" android:title=" 항목제목 "/> </menu> public boolean oncreateoptionsmenu(menu menu) { getme

UI TASK & KEY EVENT

12 강. 문자출력 Direct3D 에서는문자를출력하기위해서 LPD3DXFONT 객체를사용한다 LPD3DXFONT 객체생성과초기화 LPD3DXFONT 객체를생성하고초기화하는함수로 D3DXCreateFont() 가있다. HRESULT D3DXCreateFont

gnu-lee-oop-kor-lec10-1-chap10

Visual Basic 반복문

PowerPoint Template

Microsoft PowerPoint - chap04-연산자.pptx

C# Programming Guide - Types

Microsoft Word - ntasFrameBuilderInstallGuide2.5.doc

Microsoft PowerPoint - java1-lab5-ImageProcessorTestOOP.pptx

Microsoft PowerPoint - IP11.pptx

PowerPoint Presentation

Lab 4. 실습문제 (Circular singly linked list)_해답.hwp

untitled

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

사용설명서를 읽기 전에 ios용 아이디스 모바일은 네트워크 연결을 통해 ios 플랫폼 기반의 모바일 기기(iOS 버전 6.0 이상의 ipod Touch, iphone 또는 ipad)에서 장치(DVR, 네트워크 비디오 서버 및 네트워크 카메라)에 접속하여 원격으로 영상을

- JPA를사용하는경우의스프링설정파일에다음을기술한다. <bean id="entitymanagerfactory" class="org.springframework.orm.jpa.localentitymanagerfactorybean" p:persistenceunitname=

초보자를 위한 C# 21일 완성

Frama-C/JESSIS 사용법 소개

제8장 자바 GUI 프로그래밍 II

슬라이드 1

13주-14주proc.PDF

3D MAX + WEEK 9 Hansung Univ. Interior Design

사용설명서를 읽기 전에 안드로이드(Android)용 아이디스 모바일은 네트워크 연결을 통해 안드로이드 플랫폼 기반의 모바일 기기에서 장치 (DVR, NVR, 네트워크 비디오 서버, 네트워크 카메라) 에 접속하여 원격으로 영상을 감시할 수 있는 프로그램입니다. 장치의 사

PowerPoint Presentation

adfasdfasfdasfasfadf

금오공대 컴퓨터공학전공 강의자료

Endpoint Protector - Active Directory Deployment Guide

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

C프로-3장c03逞풚

C++ Programming

쉽게 풀어쓴 C 프로그래밊

Microsoft PowerPoint - Java7.pptx

PowerPoint Presentation

4장기본프로그래밍2

chap10.PDF

Data Sync Manager(DSM) Example Guide Data Sync Manager (DSM) Example Guide DSM Copyright 2003 Ari System, Inc. All Rights reserved. Data Sync Manager

2015 개정교육과정에따른정보과평가기준개발연구 연구책임자 공동연구자 연구협력관

Contents Activity Define Real s Activity Define Reports UI, and Storyboards Activity Refine System Architecture Activity Defin

소프트웨어공학 Tutorial #2: StarUML Eun Man Choi

Microsoft Word - src.doc

윈도우즈프로그래밍(1)

<4D F736F F F696E74202D20C1A63132B0AD20B5BFC0FB20B8DEB8F0B8AEC7D2B4E7>

Transcription:

게임엔진 제 17 강지형충돌처리 이대현교수 한국산업기술대학교게임공학과

학습목차 광선을이용한지형충돌검사와이를이용한지형위의카메라이동구현. 간단한 world editor 의구현 닌자및로봇을지형위에배치, 이동및선택 쿼리마스크 기능 사용법 다중쿼리마스크의사용방법

실습 CamearTerrainMove 지형위를이동하는카메라

구현기능 카메라를이동할때, 지형을통과하는일이일어나지않음.

구현방법 카메라와지형사이의거리를구하여, 그값이아주작으면카메라의위치를재조정한다. 거리를구하는방법 1. 카메라로부터지형까지광선을발사. 2. 광선과지형간의교점을구한다. 3. 카메라와교점사이의거리를구한다.

PlayState.cpp void PlayState::enter() { 중략 실습 mrayscenequery = mscenemgr->createrayquery( Ray() ); 중략 bool PlayState::frameStarted(GameManager* game, const FrameEvent& evt) { 중략 Vector3 campos = mcamera->getposition( ); Ray cameraray( campos, Vector3::NEGATIVE_UNIT_Y ); mrayscenequery->setray( cameraray ); RaySceneQueryResult result = mrayscenequery->execute(); RaySceneQueryResult::iterator itr = result.begin( ); if ( itr!= result.end() && itr->worldfragment ) { Real terrainheight = itr->worldfragment->singleintersection.y; if ((terrainheight + 10.0f) > campos.y) mcamera->setposition(campos.x, terrainheight+10.0f, campos.z); 중략

bool PlayState::mousePressed(GameManager* game, const OIS::MouseEvent &e, OIS::MouseButtonID id) { if (id == OIS::MB_Right) { CEGUI::MouseCursor::getSingleton().hide(); mrmousedown = true; return true; bool PlayState::mouseMoved(GameManager* game, const OIS::MouseEvent &e) { if (mrmousedown) { mcamera->yaw(degree(-e.state.x.rel)); mcamera->pitch(degree(-e.state.y.rel)); else { CEGUI::System::getSingleton().injectMouseMove(e.state.X.rel, e.state.y.rel); if (e.state.z.rel < 0) { mtransvector = Vector3(0.0f, 0.0f, -1.0f); else if (e.state.z.rel > 0) { mtransvector = Vector3(0.0f, 0.0f, 1.0f); 실습 return true;

실행결과 : 지형위의카메라이동

마우스입력처리 :mousemoved bool PlayState::mouseMoved(GameManager* game, const OIS::MouseEvent &e) { if (mrmousedown) { mcamera->yaw(degree(-e.state.x.rel)); mcamera->pitch(degree(-e.state.y.rel)); else { CEGUI::System::getSingleton().injectMouseMove(e.state.X.rel, e.state.y.rel); if (e.state.z.rel < 0) { mtransvector = Vector3(0.0f, 0.0f, -1.0f); else if (e.state.z.rel > 0) { mtransvector = Vector3(0.0f, 0.0f, 1.0f); return true;

마우스입력처리 :mousepressed, mousereleased bool PlayState::mousePressed(GameManager* game, const OIS::MouseEvent &e, OIS::MouseButtonID id) { if (id == OIS::MB_Right) { CEGUI::MouseCursor::getSingleton().hide(); mrmousedown = true; return true; 오른쪽버튼이눌리면 마우스보기 모드가되므로, 커서를없앤다. bool PlayState::mouseReleased(GameManager* game, const OIS::MouseEvent &e, OIS::MouseButtonID id { if (id == OIS::MB_Right) { CEGUI::MouseCursor::getSingleton().show(); mrmousedown = false; return true; 오른쪽버튼이떼어지면, 마우스보기 모드가해제되므로, 커서를다시표시한다.

광선의설정과발사 Vector3 campos = mcamera->getposition( ); Ray cameraray( campos, Vector3::NEGATIVE_UNIT_Y ); mrayscenequery->setray( cameraray ); RaySceneQueryResult result = mrayscenequery->execute(); 발사할광선을설정. 광선의발사에따른결과들 ( 지형과의교점 ) 을저장하는객체. 광선을발사함.

거리계산과카메라위치조정 RaySceneQueryResult::iterator itr = result.begin( ); 광선발사의결과는반복자객체 itr 에저장됨. 광선발사의결과는 worldfragment( 여기는지형 ) 와 movable 의리스트임. if ( itr!= result.end() && itr->worldfragment ) { Real terrainheight = itr->worldfragment->singleintersection.y; 교점의 y 좌표가결국은지형의높이가된다. if ((terrainheight + 10.0f) > campos.y) mcamera->setposition(campos.x, terrainheight+10.0f, campos.z); 카메라높이가지형의높이가 10 이하이면, 강제로카메라를지형보다 10 만큼높게설정한다.

RaySceneQueryResult 자세히살펴보기 RaySceneQueryResult &result = mrayscenequery->execute(); RaySceneQueryResult::iterator itr = result.begin( ); RaySceneQueryResultEntry 의리스트 Real distance; MovableObject* movable; SceneQuery::WorldFragment* worldfragment; distance: 광선시작점으로부터, 교차되는오브젝트까지의거리 movable: MovableObject 엔터티, 광원등과같이장면노드에소속되는개체들. NULL 이면, MovableObject 가아니라는뜻임. worldfragement: 장면관리자에의해생성된 world geometry 의일부분과, 광선이교차된경우. worldframgement 의 type 는 WFT_SINGLE_INTERSECTION 이며 (RaySceneQuery 의결과는항상 ), worldfragment->singleinetersection 은교점을나타내는 Vector3 타입의값임.

실습 PlaceNinja 지형위에닌자들을배치

구현내용 마우스왼쪽버튼을누르면닌자가지형위에만들어진다.

PlayState.cpp 실습 bool PlayState::mousePressed(GameManager* game, const OIS::MouseEvent &e, OIS::MouseButtonID id) { 중략 CEGUI::MouseCursor::getSingleton().hide(); CEGUI::Point mousepos = CEGUI::MouseCursor::getSingleton().getPosition(); Ray mouseray = mcamera->getcameratoviewportray(mousepos.d_x/mwindow->getwidth(), mouse Pos.d_y/mWindow->getHeight()); mrayscenequery->setray(mouseray); RaySceneQueryResult &result = mrayscenequery->execute(); RaySceneQueryResult::iterator itr = result.begin( ); if (itr!= result.end() && itr->worldfragment) { char name[16]; sprintf( name, "ninja%d", mcount++ ); Entity *ent = mscenemgr->createentity( name, "ninja.mesh" ); mcurrentobject = mscenemgr->getrootscenenode( )->createchildscenenode( String(name) + "Node", itr->worldfragment->singleintersection ); mcurrentobject->attachobject( ent ); mcurrentobject->setscale( 0.1f, 0.1f, 0.1f ); mlmousedown = true; 중략

실습 bool PlayState::mouseMoved(GameManager* game, const OIS::MouseEvent &e) { 중략 CEGUI::System::getSingleton().injectMouseMove(e.state.X.rel, e.state.y.rel); CEGUI::Point mousepos = CEGUI::MouseCursor::getSingleton().getPosition(); Ray mouseray = mcamera->getcameratoviewportray(mousepos.d_x/mwindow->getwidth( ), mousepos.d_y/mwindow->getheight()); mrayscenequery->setray(mouseray); RaySceneQueryResult &result = mrayscenequery->execute(); RaySceneQueryResult::iterator itr = result.begin(); if (itr!= result.end() && itr->worldfragment) mcurrentobject->setposition(itr->worldfragment->singleintersection); 후략

실행결과 왼쪽마우스버튼을누르면, 닌자가만들어지고, 마우스버튼을누른채로이동시키면닌자가이동된다. 마우스버튼을놓는위치에닌자가배치된다.

mousepressed: 마우스클릭위치에닌자를생성하고위치시킴 CEGUI::Point mousepos = CEGUI::MouseCursor::getSingleton().getPosition(); Ray mouseray = mcamera->getcameratoviewportray(mousepos.d_x/mwindow->getwidth(), mousepos.d_y/mwindow->getheight()); mrayscenequery->setray(mouseray); RaySceneQueryResult &result = mrayscenequery->execute(); RaySceneQueryResult::iterator itr = result.begin( ); if (itr!= result.end() && itr->worldfragment) { char name[16]; sprintf( name, "ninja%d", mcount++ ); Entity *ent = mscenemgr->createentity( name, "ninja.mesh" ); mcurrentobject = mscenemgr->getrootscenenode( )->createchildscenenode( String(name) + "Node", itr->worldfragment->singleintersection ); mcurrentobject->attachobject( ent ); mcurrentobject->setscale( 0.1f, 0.1f, 0.1f );

mousemoved: 왼쪽마우스버튼을이용한로봇의드래깅 bool PlayState::mouseMoved(GameManager* game, const OIS::MouseEvent &e) { 중략 CEGUI::System::getSingleton().injectMouseMove(e.state.X.rel, e.state.y.rel); CEGUI::Point mousepos = CEGUI::MouseCursor::getSingleton().getPosition(); Ray mouseray = mcamera->getcameratoviewportray(mousepos.d_x/mwindow->getwidth( ), mousepos.d_y/mwindow->getheight()); mrayscenequery->setray(mouseray); RaySceneQueryResult &result = mrayscenequery->execute(); RaySceneQueryResult::iterator itr = result.begin(); if (itr!= result.end() && itr->worldfragment) mcurrentobject->setposition(itr->worldfragment->singleintersection); 후략

바운딩박스의표시 bool PlayState::mousePressed(GameManager* game, const OIS::MouseEvent &e, OIS::MouseButtonID id) { 중략 CEGUI::MouseCursor::getSingleton().hide(); CEGUI::Point mousepos = CEGUI::MouseCursor::getSingleton().getPosition(); Ray mouseray = mcamera->getcameratoviewportray(mousepos.d_x/mwindow->getwidth(), mouse Pos.d_y/mWindow->getHeight()); mrayscenequery->setray(mouseray); RaySceneQueryResult &result = mrayscenequery->execute(); RaySceneQueryResult::iterator itr = result.begin( ); if (itr!= result.end() && itr->worldfragment) { char name[16]; sprintf( name, "ninja%d", mcount++ ); Entity *ent = mscenemgr->createentity( name, "ninja.mesh" ); mcurrentobject = mscenemgr->getrootscenenode( )->createchildscenenode( String(name) + "Node", itr->worldfragment->singleintersection ); mcurrentobject->attachobject( ent ); mcurrentobject->setscale( 0.1f, 0.1f, 0.1f ); if (mcurrentobject) mcurrentobject->showboundingbox(true); mlmousedown = true; 중략 실습

바운딩박스의해제 bool PlayState::mouseReleased(GameManager* game, const OIS::MouseEvent &e, OIS::MouseButtonID id) { if (id == OIS::MB_Right) { CEGUI::MouseCursor::getSingleton().show(); mrmousedown = false; else if (id == OIS::MB_Left) { CEGUI::MouseCursor::getSingleton().show(); mlmousedown = false; if (mcurrentobject) mcurrentobject->showboundingbox(false); return true; 실습

실습과제 #10 지형위를걷는닌자의구현 화살표키이를이용해닌자를이동시킴 ( 걷기 ) 닌자의발이지형에빠지지않게함.

실습 SelectNinja 지형위의닌자를선택및이동

구현방법 카메라로부터닌자를향해광선을발사해서, 그교차점을구한다.

PlayState.cpp bool PlayState::mousePressed(GameManager* game, const OIS::MouseEvent &e, OIS::MouseButtonID id) { 중략 for ( itr = result.begin(); itr!= result.end(); itr++ ) { if (itr->movable && itr->movable->getname().substr(0, 5)!= "tile[") { mcurrentobject = itr->movable->getparentscenenode(); break; else if (itr->worldfragment) { char name[16]; sprintf( name, "ninja%d", mcount++ ); Entity *ent = mscenemgr->createentity( name, "ninja.mesh" ); 실습 중략 mcurrentobject = mscenemgr->getrootscenenode( )->createchildscenenode( String(name) + "Node", itr->worldfragment->singleintersection ); mcurrentobject->attachobject( ent ); mcurrentobject->setscale( 0.1f, 0.1f, 0.1f ); break;

bool PlayState::mouseMoved(GameManager* game, const OIS::MouseEvent &e) { 중략 mrayscenequery->setsortbydistance( false ); 실습 후략 RaySceneQueryResult &result = mrayscenequery->execute(); RaySceneQueryResult::iterator itr = result.begin(); for ( itr = result.begin( ); itr!= result.end(); itr++ ) { if (itr->worldfragment) { mcurrentobject->setposition(itr->worldfragment->singleintersection); break;

실행결과

mousepressed() 이벤트처리 if (id == OIS::MB_Right) { CEGUI::MouseCursor::getSingleton().hide(); mrmousedown = true; else if (id == OIS::MB_Left) { CEGUI::MouseCursor::getSingleton().hide(); CEGUI::Point mousepos = CEGUI::MouseCursor::getSingleton().getPosition(); mcurrentobject = NULL; Ray mouseray = mcamera->getcameratoviewportray(mousepos.d_x/mwindow->getwidth(), mousepos.d_y/mwindow->getheight()); mrayscenequery->setray(mouseray); mrayscenequery->setsortbydistance( true ); 광선을발사한결과, 만들어진교점들을거리순으로정렬하도록설정. 반복자를통해서얻게되는맨처음교점은, 광선의시작점 ( 즉, 카메라 ) 으로부터가장가까운교점이됨.

for ( itr = result.begin( ); itr!= result.end(); itr++) { for 문안에서 itr 를반복함으로써, 광선과교차된오브젝트들을거리가가까운것부터확인해나감. if (itr->movable && itr->movable->getname().substr(0, 5)!= "tile[" ) { 오브젝트가 MovableObject 이지만, 지형오브젝트가아닐경우 결과적으로엔터티일경우에 참고 : 지형장면관리자는지형을여러개의타일로구성된 MovableObject 들을생성해서만든다. 이때오브젝트의이름은 tile[ 로시작된다. mcurrentobject = itr->movable->getparentscenenode( ); break; 엔터티에해당되는노드가얻어지면, 그노드를선택하면되므로, 더이상다른교차되는오브젝트들은처리할필요가없다. else if (itr->worldfragment) {

mousemoved() 이벤트처리 bool PlayState::mouseMoved(GameManager* game, const OIS::MouseEvent &e) { if (mrmousedown) { mcamera->yaw(degree(-e.state.x.rel)); mcamera->pitch(degree(-e.state.y.rel)); else if ( mlmousedown ) { CEGUI::System::getSingleton().injectMouseMove(e.state.X.rel, e.state.y.rel); CEGUI::Point mousepos = CEGUI::MouseCursor::getSingleton().getPosition(); Ray mouseray = mcamera->getcameratoviewportray(mousepos.d_x/mwindow->getwidth(), mousepos.d_y/mwindow->getheight()); mrayscenequery->setray(mouseray); dragged 상태에서는지형상의교점만을찾으면됨. 거리를기준으로정렬하면, 지형이맨뒤로오게되므로, 다음 for 루프에서쓸데없이다른오브젝트들을처리하게된다. 따라서, 거리기준정렬을 false 로설정. RaySceneQueryResult &result = mrayscenequery->execute(); RaySceneQueryResult::iterator itr; for ( itr = result.begin( ); itr!= result.end(); itr++ ) { if ( itr->worldfragment ) { mcurrentobject->setposition( itr->worldfragment->singleintersection ); break;

엔터티의선택시고려할점 닌자와로보트가카메라의시선에겹쳐있는경우 광선을발사하면, 닌자와로봇중앞에있는것과먼저교차하게된다. 만약, 닌자가앞에있고, 로봇이뒤에있는상황에서, 로봇을선택하려면? 엔터티의이름을차례로살펴보면서, 로봇이름을찾으면된다. 문제점은? 교차되는엔터티가매우많을경우, 특정종류의엔터티를찾으려면, 교차되는모든엔터티를일일이검사해야한다. 결국시간이많이걸린다 성능이떨어진다.

쿼리마스크 (Query Mask) 란? Query Mask 모든 MovableObject 에고유한마스크값을설정 RaySceneQuery 에서, 광선을발사하기전에, 교차점을찾고자하는엔터티들의마스크값을지정. 지정된마스크값을가지는엔터티들에대해서교차점을찾는동작이수행됨.

실습 QueryMask 닌자와로봇을효과적으로선택

PlayState.h class PlayState : public GameState { 중략 실습 enum QueryFlags { NINJA_MASK = 1 << 0, ROBOT_MASK = 1 << 1 ; 중략

PlayState.cpp bool PlayState::mousePressed(GameManager* game, const OIS::MouseEvent &e, OIS::Mouse ButtonID id) { 중략 mrayscenequery->setquerymask(mninjamode? NINJA_MASK : ROBOT_MASK); 중략 ent->setqueryflags(ninja_mask); 중략 ent->setqueryflags(robot_mask); 후략 실습

실행결과 닌자모드에서로봇을클릭하면, 뒤에서있는닌자가선택된다.

마스크값기본값정의 class PlayState : public GameState { 중략 각엔터티마다구별될수있는마스크값을부여. enum QueryFlags { NINJA_MASK = 1 << 0, ROBOT_MASK = 1 << 1 ; 중략

엔티티가생성될때, 마스크값을부여 Entity *ent; char name[16]; if ( mninjamode ){ sprintf( name, "Ninja%d", mcount++ ); ent = mscenemgr->createentity( name, "ninja.mesh" ); ent->setqueryflags( NINJA_MASK ); else { sprintf( name, "Robot%d", mcount++ ); ent = mscenemgr->createentity( name, "robot.mesh" ); ent->setqueryflags( ROBOT_MASK );

광선발사할때, 마스크값을설정 Ray mouseray = mcamera->getcameratoviewportray(mousepos.d_x/mwindow- >getwidth(), mousepos.d_y/mwindow->getheight()); mrayscenequery->setray(mouseray); mrayscenequery->setsortbydistance(true); mrayscenequery-> setquerymask(mninjamode? NINJA_MASK : ROBOT_MASK); 광선을발사하기전에 (execute() 함수실행전에 ), query mask 를현재모드에따라, ROBOT_MASK 또는 NINJA_MASK 로설정한다. RaySceneQueryResult &result = mrayscenequery->execute(); 마스크값으로미리설정된엔터티들에대해서만, 교차점검사가이루어진다. RaySceneQueryResult::iterator itr = result.begin( );

다중쿼리마스크값의정의 각각의쿼리마스크는이진수로표현했을때, 반드시한개의비트 1 만을가져야하며, 그자리수가각각달라야한다. 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000

다중쿼리마스크값의정의 각각의쿼리마스크는이진수로표현했을때, 반드시한개의비트 1 만을가져야하며, 그자리수가각각달라야한다. 최대 32 개의쿼리마스크값을만들수있다. 00000001 = 1<<0 00000010 = 1<<1 00000100 = 1<<2 00001000 = 1<<3 00010000 = 1<<4 00100000 = 1<<5 01000000 = 1<<6 10000000 = 1<<7

다중쿼리마스크의사용예 (1) enum QueryFlags { FRIENDLY_CHARACTERS = 1<<0, ENEMY_CHARACTERS = 1<<1, STATIONARY_OBJECTS = 1<<2 ; FRIENDLY_CHARACTERS 타입의경우에만, RaySceneQuery 의실행. mrayscenequery->setquerymask( FRIENDLY_CHARACTERS ); ENEMY_CHARACTERS 또는 STATIONARY_OBJECTS 의경우에, RaySceneQuery 실행 mrayscenequery->setquerymask(enemy_characters STATIONARY_OBJECTS);

다중쿼리마스크의사용예 (2) FRIENDLY_CHARACTERS 타입이아닌경우에만, RaySceneQuery 의실행. mrayscenequery->setquerymask( ~FRIENDLY_CHARACTERS ) FRIENDLY_CHARACTERS 또는 STATIONARY_OBJECTS 가아닌경우에만 RaySceneQuery 실행 mrayscenequery ->setquerymask(~(friendly_characters STATIONARY_OBJECTS));

다중쿼리마스크의사용예 (3) mrayscenequery->setquerymask( 0 ); 지형과만나는점만을얻고자할때는, MovableObject 와의교점을찾을필요가없다. 0 으로쿼리마스크를설정하면, WorldFragment 오브젝트만을얻어낼수있다. SetQueryMask() Basically MovableObject instances will only be returned from this query if a bitwise AND operation between this mask value and the MovableObject::getQueryFlags value is non-zero.

QueryTypeMask 사용자가정의하는쿼리마스크외에 SceneManager 에서미리정의된또한종류의쿼리마스크로써 QueryTypeMask 가있음. QueryMask 는오브젝트인스턴스하나하나에마스크를부여. QueryTypeMask 는오브젝트그룹에마스크를부여. 모두 6 종류의마스크가있음. 설정된기본값은 ENTITY_TYPE_MASK 사용법 : mrayscenequery->setquerytypemask(scenemanager::fx_type_mask); WORLD_GEOMETRY_TYPE_MASK //Returns world geometry. ENTITY_TYPE_MASK //Returns entities. FX_TYPE_MASK //Returns billboardsets / particle systems. STATICGEOMETRY_TYPE_MASK //Returns static geometry. LIGHT_TYPE_MASK //Returns lights. USER_TYPE_MASK_LIMIT //User type mask limit.