Biding a Feibe Camea Cass Feibe Camea Camea Design Imementation Detais Camea 예제 3589 28년봄학기 6/4/27 박경신 Camea Design 구현동기 고정된카메라위치설정을위해서 D3DXMatiookAtH( ) 함수사용 장점 : 고정된위치에카메라를놓고목표지점을겨냥 단점 : 사용자입력에반응하여카메라를이동 목표 비행시뮬레이션이나 인칭시점의게임 (e.g. Fist-eson Shooting game) 에적합한유연한 Camea 클래스구현 Camea Design 4 개의카메라벡터 wod coodinate sstem에서의카메라의위치와방향을정의하기위해사용 우향 (ight), 상향 (), 전방 (ook), 위치벡터 (osition vecto) osition vecto ight vecto vecto ook vecto (,, ) 방위벡터 (oientation vectos) 정직교 (othonoma) 직교행렬 (othogona mati) 역행렬 전치행렬 Camea Sace Wod Sace
Camea Design 구현하고자하는카메라동작 6 가지의자유도 (6DOF) itch - 우행벡터를기준으로회전 Yaw - 상향벡터를기준으로회전 o - 전방벡터를기준으로회전 Stafe - 우향벡터방향으로이동 ( 옆걸음질 ) F - 상향벡터방향으로이동 ( 날기 ) Wak - 전방벡터방향으로이동 ( 전, 후진 ) 구현하고자하는카메라타입 AICAFT 6 가지자유도를허용 ANDOBJECT 특정축으로의이동을제한 인칭슈팅게임등과같이주인공이하늘을날수없도록제한함 Camea Design #incde <d3d9.h> cass Camea bic: enm CameaTe ANDOBJECT, AICAFT ; Camea(); Camea(CameaTe cameate); ~Camea(); void stafe(foat nits); // eft/ight void f(foat nits); // /down void wak(foat nits); // fowad/backwad void itch(foat ange); // otate on ight vecto void aw(foat ange); // otate on vecto void o(foat ange); // otate on ook vecto void getviewmati(d3dxmatix* V); void setcameate(cameate cameate); void getosition(d3dxvecto3* os); void setosition(d3dxvecto3* os); void getight(d3dxvecto3* ight); void get(d3dxvecto3* ); void getook(d3dxvecto3* ook); ivate: CameaTe _cameate; D3DXVECTO3 _ight; D3DXVECTO3 _; D3DXVECTO3 _ook; D3DXVECTO3 _os; ; Camea Design #incde camea.h Camea::Camea() _cameate AICAFT; _os D3DXVECTO3(.f,.f,.f); _ight D3DXVECTO3(.f,.f,.f); _ D3DXVECTO3(.f,.f,.f); _ook D3DXVECTO3(.f,.f,.f); Camea::Camea(CameaTe cameate) _cameate cameate; _os D3DXVECTO3(.f,.f,.f); _ight D3DXVECTO3(.f,.f,.f); _ D3DXVECTO3(.f,.f,.f); _ook D3DXVECTO3(.f,.f,.f); Camea::~Camea() void Camea::getosition(D3DXVECTO3* os) *os _os; void Camea::setosition(D3DXVECTO3* os) _os *os; void Camea::getight(D3DXVECTO3* ight) *ight _ight; void Camea::get(D3DXVECTO3* ) * _; void Camea::getook(D3DXVECTO3* ook) *ook _ook; void Camea::setCameaTe(CameaTe cameate) _cameate cameate; View Mati 주어진카메라 vecto 로부터 View Mati ( 뷰행렬 ) 를변환을위하여 Wod sace 의점 q 를 View sace 의점 q 으로변환하는행렬 V 를구해야한다. q qv Wod sace 에서 View sace 로의변환 (viewing tansfomation) 카메라위치가 Wod Sace 의원점에오도록이동시킴 ( 카메라와모든물체 ) ook vecto 가 + 축과일치되도록회전시킴 ( 카메라와모든물체 ) 4 개의카메라벡터 (,, ) (,, ) (,, ) (,, )
View Mati View sace tansfomation 변환행렬 V (,, ) : osition vecto (,, ) : ight vecto (,, ) : vecto (,, ) : ook vecto + + O A B C D + + O A B C D + + O A D B C V (,, ) : oigin V (,, ) : -ais V (,, ) : -ais V (,, ) : -ais View Mati Tansfomation: Tansation 를원점으로이동 ( ) ( ) ( ) T T View Mati Tansfomation: otation 3 개카메라벡터 (,, ) 를월드의축에일치하도록회전 2 2 2 2 2 2 2 2 2 2 2 2 View Mati Tansfomation: otation 3 개카메라벡터 (,, ) 를월드의축에일치하도록회전 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 T - - M M M I M I M
View Mati Tansfomation: V Camea :: getviewmati ( ) 뷰변환행렬 V: V T void Camea::getViewMati(D3DXMATIX* V) // Kee camea's aes othogona to each othe D3DXVec3Nomaie(&_ook, &_ook); D3DXVec3Coss(&_, &_ook, &_ight); D3DXVec3Nomaie(&_, &_); D3DXVec3Coss(&_ight, &_, &_ook); D3DXVec3Nomaie(&_ight, &_ight); // Bid the view mati: foat -D3DXVec3Dot(&_ight, &_os); foat -D3DXVec3Dot(&_, &_os); foat -D3DXVec3Dot(&_ook, &_os); (*V)(, ) _ight.; (*V)(, ) _.; (*V)(, 2) _ook.; (*V)(, 3).f; (*V)(, ) _ight.; (*V)(, ) _.; (*V)(, 2) _ook.; (*V)(, 3).f; (*V)(2, ) _ight.; (*V)(2, ) _.; (*V)(2, 2) _ook.; (*V)(2, 3).f; (*V)(3, ) ; (*V)(3, ) ; (*V)(3, 2) ; (*V)(3, 3).f; otation Ais/Ange 임의의회전축 (ais) 에대한하나의회전각도 (ange) 4 개의숫자로표현한다. 임의의회전축을나타내는단위벡터 a (,, ) 와단위벡터주위로회전각도를나타내는 θ (~36) 값으로구성된다. + a θ (θ, a) + Yaw, itch, o 임의의축을기준으로회전하는변환행렬 D3DXMATIX &D3DXMatiotationAis ( D3DXMATIX *Ot, // ott otation mati CONST D3DXVECTO *V, // abita ais FOAT Ange); // ange of otation (in adians) 예제 : vecto (.77,.77, ) 로정의된축을기준으로 i/2만큼회전 D3DXMATIX ; Y D3DXVECTO3 ais(.77f,.77f,.f); D3DXMatiotationAis(&, &ais, D3DX_I/2.f); Z A - X
Yaw, itch, o Yaw/itch/o /ight/ook vecto 를기준으로회전 ANDOBJECT 에대해서는물체가기울어진상태에서 aw/o 은부자연스러움 Yaw 는 vecto 가아닌 - 축을기준으로회전 o 은이용할수없도록함 Yaw itch o Camea :: itch ( ) and aw ( ) void Camea::itch(foat ange) D3DXMATIX T; D3DXMatiotationAis(&T, &_ight, ange); // otate _ and _ook aond _ight vecto D3DXVec3TansfomCood(&_,&_, &T); D3DXVec3TansfomCood(&_ook,&_ook, &T); void Camea::aw(foat ange) D3DXMATIX T; // otate aond wod (,, ) awas fo and object if( _cameate ANDOBJECT ) D3DXMatiotationY(&T, ange); // otate aond own vecto fo aicaft if( _cameate AICAFT ) D3DXMatiotationAis(&T, &_, ange); // otate _ight and _ook aond _ o -ais D3DXVec3TansfomCood(&_ight,&_ight, &T); D3DXVec3TansfomCood(&_ook,&_ook, &T); Camea :: o ( ) void Camea::o(foat ange) // on o fo aicaft te if( _cameate AICAFT ) D3DXMATIX T; D3DXMatiotationAis(&T, &_ook, ange); // otate _ and _ight aond _ook vecto D3DXVec3TansfomCood(&_ight,&_ight, &T); D3DXVec3TansfomCood(&_,&_, &T); Wak, Stafe, F Stafe/F/Wak /ight/ook vecto 를기준으로이동 이동하고자하는크기 / 방향의벡터를더하면됨 ANDOBJECT: 평면으로움직임을제한하여야함. 위를보는상황에서전진하거나기울이진상황에서옆걸음을해도공중에뜨지않도록함. 계단 / 언덕을오르는방법으로고도가바뀔수있으므로 Camea::setosition 방법을제공하여카메라의높이나위치지정이가능하도록함 + +s s t +t
Camea :: wak, stafe, f ( ) Eame: Camea void Camea::wak(foat nits) // move on on ane fo and object if( _cameate ANDOBJECT ) _os + D3DXVECTO3(_ook.,.f, _ook.) * nits; if( _cameate AICAFT ) _os + _ook * nits; void Camea::stafe(foat nits) // move on on ane fo and object if( _cameate ANDOBJECT ) _os + D3DXVECTO3(_ight.,.f, _ight.) * nits; if( _cameate AICAFT ) _os + _ight * nits; void Camea::f(foat nits) // move on on -ais fo and object if( _cameate ANDOBJECT ) _os. + nits; if( _cameate AICAFT ) _os + _ * nits; Conto Kes W / S 전진 / 후진 (Wak fowad/backwad) A / D 왼쪽 / 오른쪽옆걸음질 (Stafe eft/ight) / F 위 / 아래날기 (F / down) eft / ight aow kes Yaw / Down aow kes itch N / M o Eame: DawBasicScene d3dtiit.h boo DawBasicScene( IDiect3DDevice9* device, // ass in fo cean foat scae); // nifom scae stct Vete Vete() Vete(foat, foat, foat, foat n, foat n, foat n, foat, foat v) _ ; _ ; _ ; _n n; _n n; _n n; _ ; _v v; foat _, _, _; foat _n, _n, _n; foat _, _v; static const DWOD FVF;
Eame: DawBasicScene boo d3d::dawbasicscene(idiect3ddevice9* device, foat scae) static IDiect3DVeteBffe* foo ; static IDiect3DTete9* te ; static ID3DXMesh* ia ; HEST h ; if (device ) if (foo && te && ia) d3d::eease<idiect3dvetebffe9*>(foo); d3d::eease<idiect3dtete9*>(te); d3d::eease<id3dxmesh*>(ia); ese if (!foo &&!te &&!ia) device->ceatevetebffe(6 * sieof(d3d::vete),, d3d::vete::fvf, D3DOO_MANAGED, &foo, ); Vete* v ; foo->ock(,, (void**) &v, ); v[] Vete(-2.f, -2.5f, -2.f,.f,.f,.f,.f,.f); v[] Vete(-2.f, -2.5f, 2.f,.f,.f,.f,.f,.f); v[2] Vete( 2.f, -2.5f, 2.f,.f,.f,.f,.f,.f);. v[5] Vete(-2.f, -2.5f, -2.f,.f,.f,.f,.f,.f); foo->nock(); Eame: DawBasicScene D3DXCeateCinde(device,.5f,.5f, 5.f, 2, 2, &ia, ) D3DXCeateTeteFomFie(device, deset.bm, &te) ese device->setsamestate(, D3DSAM_MAGFITE, D3DTEXF_INEA); device->setsamestate(, D3DSAM_MINFITE, D3DTEXF_INEA); device->setsamestate(, D3DSAM_MIFITE, D3DTEXF_OINT); D3DXVECTO3 di(.77f, -.77f,.77f); D3DXCOO co(.f,.f,.f,.f); D3DIGHT9 ight d3d::initdiectionaight(&di, &co); device->setight(, &ight); device->ightenabe(, te); device->setendestate(d3ds_nomaizenomas, te); device->setendestate(d3ds_secaenabe, te); // ende D3DXMATIX T,,, S; D3DXMatiScaing(&S, scae, scae, scae); D3DXMatiotationX(&, -D3DX_I *.5f); Eame: DawBasicScene // daw foo D3DXMatiIdentit(&T); T T * S; device->settansfom(d3dts_wod, &T); device->setmateia(&d3d::white_mt); device->settete(, te); device->setsteamsoce(, foo,, sieof(vete)); device->setfvf(vete::fvf); device->dawimitive(d3dt_tiangeist,, 2); // daw ia device->setmateia(&d3d::be_mt); device->settete(, ); fo (int i ; I < 5; i++) D3DXMatiTansation(&T, -5.f,.f, -5.f + (i * 7.5f)); T T * S; device->settansfom(d3dt_wod, &); ia->dawsbset(); D3DXMatiTansation(&T, 5.f,.f, -5.f + (i * 7.5f)); * T * S; device->settansfom(d3dt_wod, &); ia->dawsbset(); etn te; Eame: Camea #incde d3dhee.h #incde d3dtiit.h #incde camea.h IDiect3DDevice9* Device ; const int Width 64; const int Height 48; Camea TheCamea(Camea::ANDOBJECT); boo Set() d3d::dawbasicscene(device,.f); // ojection mati D3DXMATIX oj; D3DXMatiesectiveFovH(&oj, D3DX_I *.25f, (foat) Width/ (foat) Height,.f,.f); Device->SetTansfom(D3DTS_OJECTION, &oj); etn te; void Cean() // ass fo the fist aamete to cean d3d::dawbasicscene(,.f);
Eame: Camea Eame: Camea boo Disa(foat timedeta) if (Device) if (::GetAsncKeState( W ) & 8f) TheCamea.wak( 4.f*timeDeta); if (::GetAsncKeState( S ) & 8f) TheCamea.wak( -4.f*timeDeta); if (::GetAsncKeState( A ) & 8f) TheCamea.stafe( -4.f*timeDeta); if (::GetAsncKeState( D ) & 8f) TheCamea.stafe( 4.f*timeDeta); if (::GetAsncKeState( ) & 8f) TheCamea.f( 4.f*timeDeta); if (::GetAsncKeState( F ) & 8f) TheCamea.f( -4.f*timeDeta); if (::GetAsncKeState(VK_) & 8f) TheCamea.itch(.f*timeDeta); if (::GetAsncKeState(VK_DOWN) & 8f) TheCamea.itch( -.f*timedeta); if (::GetAsncKeState(VK_EFT) & 8f) TheCamea.aw( -.f*timedeta); if (::GetAsncKeState(VK_IGHT) & 8f) TheCamea.aw(.f*timeDeta); if (::GetAsncKeState( N ) & 8f) TheCamea.o(.f*timeDeta); if (::GetAsncKeState( M ) & 8f) TheCamea.o( -.f*timedeta); // date the view mati eesenting the camea D3DXMATIX V; TheCamea.getViewMati(&V); Device->SetTansfom(D3DTS_VIEW, &V); // ende Device->Cea(,, D3DCEA_TAGET D3DCEA_ZBFFE,,.f, ); Device->BeginScene(); d3d::dawbasicscene(device,.f); Device->EndScene(); Device->esent(,,, ); etn te;