게임엔진 제 13 강 ofusion 씬구성 이대현교수 한국산업기술대학교게임공학과
학습목차 Ofusion 을이용한 export Export 된씬의재현 씬노드애니메이션을이용한수동카메라트래킹
ofusion OGRE3D 엔진용 3D MAX 익스포터 http://www.ofusiontechnologies.com
ofusion 의특징 Realtime Viewport 3D MAX 안에서 OGRE3D 용씬을구성하고, 실시간으로확인및변환이가능 Material System 다양한재질스크립트구현가능 Shader System GPU 파라미터의설정및실시간확인가능 Export 가능 (Professional Edition) Content exporter system 씬, 광원, 카메라, 애니메이션등등 Scene Loader Library OGRE3D 엔진용로더소스제공
ofusion 의설치 3D Max 를설치한후, ofusion 인스톨러를이용하여설치하여, 3D Max 의메뉴에 ofusion 항목이생성됨.
Exporter 메뉴
출력된파일의종류.osm - 카메라, 라이트, 그림자, 애니메이션등 Export 한 Scene 에대한전반적인정보를가지고있음..mesh 3D 메쉬기하정보.material 메쉬재질정보.skeleton 골격애니메이션정보 그외각종 image 파일들 Exporter option 의 Copy Texture 체크
실습 OSMCharacter ofusion 으로출력된캐릭터의재현
실습에필요한파일들 ofusion 로더소스코드 OgreOSMScene.cpp IOSMSceneCallBacks.h OgreOSMScene.h OSMAnimSerializer.h TinyXML 소스코드 Tinystr.cpp Tinyxml.cpp Tinyxmlerror.cpp Tinyxmlparser.cpp Tinystr.h Tinyxmlh ofusion 출력물 GeosungPack.zip BackgroundPack.zip
PlayState.cpp void GameManager::enter(void) { 중략 실습 mosmscene = new OSMScene(mSceneMgr, mroot->getautocreatedwindow()); OSMSceneCallbacks *eventcallbacksfn = new OSMSceneCallbacks(); mosmscene->initialise("geosung.osm", eventcallbacksfn); mosmscene->createscene(); mscenemgr = mosmscene->getscenemanager(); ninjaentity = mscenemgr->getentity("crash_play_cubeboy2"); ninjanode = mscenemgr->getscenenode("crash_play_cubeboy2"); midlestate = ninjaentity->getanimationstate("idle"); mattack2state = ninjaentity->getanimationstate("crash_o"); msidekickstate = ninjaentity->getanimationstate("crash_x"); mcrouchstate = ninjaentity->getanimationstate("stretching_1"); mjumpstate = ninjaentity->getanimationstate("crash_idle"); } 중략
실행결과
ofusion 씬로딩과정 (1) mosmscene = new OSMScene(mSceneMgr, mroot->getautocreatedwindow()); OSMSceneCallbacks *eventcallbacksfn = new OSMSceneCallbacks(); mosmscene->initialise("geosung.osm", eventcallbacksfn); class OSMSceneCallbacks { public: virtual ~OSMSceneCallbacks() {}; virtual void OnNodeCreate(Ogre::SceneNode *pnode, TiXmlElement* pnodedesc) {}; virtual void OnEntityCreate(Ogre::Entity *pentity, TiXmlElement* pentitydesc) {}; virtual void OnCameraCreate(Ogre::Camera *pcamera, TiXmlElement* pcameradesc) {}; virtual void OnLightCreate(Ogre::Light *plight, TiXmlElement* plightdesc) {}; virtual void OnHelperCreated(Ogre::SceneNode* phelper, TiXmlElement* phelperdesc) {}; virtual void OnShapeLoaded(const Ogre::SimpleSpline& spline) {}; virtual bool OnStaticGeometryCreated(Ogre::StaticGeometry* pstatic, const NodeList& nodelist) { return false; } };
ofusion 씬로딩과정 (2) mosmscene->createscene(); mscenemgr = mosmscene->getscenemanager(); ninjaentity = mscenemgr->getentity("crash_play_cubeboy2"); ninjanode = mscenemgr->getscenenode("crash_play_cubeboy2");
실습 OSMScene ofusion 으로출력된씬의재현
PlayState.cpp (1) void GameManager::enter(void) { 중략 실습 mosmscene = new OSMScene(mSceneMgr, mroot->getautocreatedwindow()); mosmscene->initialise("background.osm"); mosmscene->createscene(); mosmscene->initialise("geosung.osm"); mosmscene->createscene(); mscenemgr = mosmscene->getscenemanager(); mcamera = mscenemgr->getcamera("camera01"); mcamnode = mscenemgr->getscenenode("camera01"); mcamtargetnode = mscenemgr->getscenenode("camera01.target"); mbgentity = mscenemgr->getentity("top"); mbgnode = mscenemgr->getscenenode("top"); mcamanim = mscenemgr->getanimation("r_camera_intro"); } 중략
PlayState.cpp (2) 실습 bool PlayState::frameStarted(GameManager* game, const FrameEvent& evt) { 중략 mcamnode->resettoinitialstate(); mcamtargetnode->resettoinitialstate(); static Ogre::Real curtime = 0.0f; curtime += evt.timesincelastframe; mcamanim->apply(curtime); } return mcontinue;
실행결과
씬의구성 mosmscene = new OSMScene(mSceneMgr, mroot->getautocreatedwindow()); mosmscene->initialise("background.osm"); mosmscene->createscene(); mosmscene->initialise("geosung.osm"); mosmscene->createscene(); mscenemgr = mosmscene->getscenemanager(); mcamera = mscenemgr->getcamera("camera01"); mcamnode = mscenemgr->getscenenode("camera01"); mcamtargetnode = mscenemgr->getscenenode("camera01.target"); mbgentity = mscenemgr->getentity("top"); mbgnode = mscenemgr->getscenenode("top"); mcamanim = mscenemgr->getanimation("r_camera_intro");
카메라트래킹설정 mcamnode->resettoinitialstate(); mcamtargetnode->resettoinitialstate(); static Ogre::Real curtime = 0.0f; curtime += evt.timesincelastframe; mcamanim->apply(curtime); <animations> <animation name="r_camera_intro" loop="false" length="3"> <keyframe time="0"> <position x="74.5971" y="102.435" z="-91.6862" /> <rotation w="-0.765747" x="-0.577032" y="-0.226825" z="0.170925" /> <scale x="1" y="1" z="1" /> </keyframe> <keyframe time="0.0333333"> <position x="74.5367" y="102.386" z="-91.7632" /> <rotation w="-0.765747" x="-0.577032" y="-0.226825" z="0.170925" /> <scale x="1" y="1" z="1" /> </keyframe>
실습 CameraTrack 씬노드애니메이션을이용한카메라트래킹
PlayState.cpp (1) void PlayState::enter(void) { 중략 mcamera->setautotracking(true, mninjanode); 실습 mcamnode = mscenemgr->getrootscenenode()->createchildscenenode("camnode"); mcamnode->attachobject(mcamera); Animation* anim = mscenemgr->createanimation("cameratrack", 10); anim->setinterpolationmode(animation::im_spline); NodeAnimationTrack* track = anim->createnodetrack(0, mcamnode); TransformKeyFrame* key = track->createnodekeyframe(0); key = track->createnodekeyframe(2.5); key->settranslate(vector3(500,500,-1000)); key = track->createnodekeyframe(5); key->settranslate(vector3(-1500,1000,-600)); key = track->createnodekeyframe(7.5); key->settranslate(vector3(0,100,0)); key = track->createnodekeyframe(10); key->settranslate(vector3(0,0,0)); } manimstate = mscenemgr->createanimationstate("cameratrack"); manimstate->setenabled(true); 중략
PlayState.cpp (2) 실습 bool PlayState::frameStarted(GameManager* game, const FrameEvent& evt) { 중략 manimstate->addtime(evt.timesincelastframe); } return mcontinue;
PlayState.cpp (1) mcamera->setautotracking(true, mninjanode); mcamnode = mscenemgr->getrootscenenode()->createchildscenenode(); mcamnode->attachobject(mcamera); Animation* anim = mscenemgr->createanimation("cameratrack", 10); anim->setinterpolationmode(animation::im_spline);
PlayState.cpp (1) NodeAnimationTrack* track = anim->createnodetrack(0, mcamnode); TransformKeyFrame* key = track->createnodekeyframe(0); key = track->createnodekeyframe(2.5); key->settranslate(vector3(500,500,-1000)); key = track->createnodekeyframe(5); key->settranslate(vector3(-1500,1000,-600)); key = track->createnodekeyframe(7.5); key->settranslate(vector3(0,100,0)); key = track->createnodekeyframe(10); key->settranslate(vector3(0,0,0));
PlayState.cpp (1) manimstate = mscenemgr->createanimationstate("cameratrack"); manimstate->setenabled(true);
실습과제 #8 카메라트래킹설계 원거리에서카메라로지형위의닌자를포착하면서시작. 닌자로가까이카메라를움직이면서멋진 (?) 카메라트래킹으로접근함. 닌자에가까이오면카메라트래킹을멈추고대전모드로들어감.