#include "stdafx.h" #include "KUIControl3DStatic.h" #include "KDeviceManager.h" #include "KResource.h" #include "KPrimitiveSprite.h" #include "GameDefine.h" #include "KUIWndManager.h" #include "KSeqAvatarEx.h" #include "KSeqAvatar.h" #ifdef _RAC #include "SGameViewPort.h" #else #include "KViewport.h" #endif #include "KRenderObjectBone.h" using namespace KUI_MESSAGE; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KUIControl3DStatic Implement //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// namespace { KUIWnd* ControlMiniMapStatic() { return new KUIControlMiniMapStatic; } bool bMiniMapStaticRegister = KUIFactory::GetInstance()->RegisterCreator( ControlMiniMapStatic, "minimap_static"); KUIWnd* Control3DStaticCreator() { return new KUIControl3DStatic; } bool b3DStaticRegister = KUIFactory::GetInstance()->RegisterCreator( Control3DStaticCreator, "3dstatic"); } KUIControlMiniMapStatic::KUIControlMiniMapStatic() { m_spRes = new KResSprite; } KUIControlMiniMapStatic::~KUIControlMiniMapStatic() { } void KUIControlMiniMapStatic::SetRectRatio( float fValue ) { float val1 = (1.f - fValue) / 2; float val2 = (1.f + fValue) / 2; m_prSprite.SetSourceRectRatio( val1,val1,val2,val2 ); } void KUIControlMiniMapStatic::SetRenderTarget( K3DTexture* pRenderTarget ) { m_spRenderTarget = pRenderTarget; if( m_spRenderTarget != NULL) { m_spRes->SetTexture(m_spRenderTarget, NULL); m_rcRegion.right = m_rcRegion.left + GetRect().GetWidth(); m_rcRegion.bottom = m_rcRegion.top + GetRect().GetHeight(); m_prSprite.SetRes( m_spRes ); m_prSprite.SetVisibility( 1.0f ); K3DMatrix mat; K3DMatrixIdentity( mat ); mat.SetPosVector( K3DVertex( m_rcRegion.left, m_rcRegion.top, m_fZPos ) ); m_prSprite.SetTransform( mat ); m_prSprite.SetTargetSize( GetRect().GetWidth(), GetRect().GetHeight() ); m_prSprite.SetMirror( false, true ); //상하 반전 } } void KUIControlMiniMapStatic::OnPosChangeNofity(int XOffset, int YOffset) { KUIControl::OnPosChangeNofity(XOffset, YOffset); m_prSprite.SetAddPosition(XOffset, YOffset); } void KUIControlMiniMapStatic::OnAlphaChangeNotify(float fAlpha) { KUIControl::OnAlphaChangeNotify( fAlpha ); m_prSprite.SetVisibility( fAlpha ); } DWORD KUIControlMiniMapStatic::OnMouseMessage(DWORD dwMessage, int x, int y) { DWORD dwRet = KUIControl::OnMouseMessage(dwMessage,x,y); if(KMR_NO_GET & dwRet) return dwRet; if( IsDisable() ) return dwRet; if(IsInRect(x,y) ) { switch(dwMessage) { case KLBUTTON_DOWN: PumpUpMessage(GetID(), KMINIMAP_PRESSING, 0,0); break; default: break; } } else { if ( dwMessage == KLBUTTON_UP ) { m_pManager->ReleaseCapture( this ); } } return dwRet; } void KUIControlMiniMapStatic::Create(KUIWND_CREATE_ARG& CREATE_ARG) { KUIControl::Create( CREATE_ARG); } void KUIControlMiniMapStatic::Render(KViewportObject * pViewport, bool isFront/* = false*/ ) { if( IsShow() ) pViewport->Register( &m_prSprite ); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KUIControl3DStatic::KUIControl3DStatic() { m_pSeqForm = NULL; KViewportStruct vp; vp.X = 0; vp.Y = 0; vp.Width = 128; vp.Height = 128; vp.MaxZ = 1.f; vp.MinZ = 0; #ifdef _RAC SGameViewPort * pViewport = new SGameViewPort; pViewport->Initilaize( KDeviceManager::GetDeviceManager()->GetRenderDevice(), vp, 1.f, 1000.f ); pViewport->SetFillColor( KColor( 0,0,0,0 ) ); //pViewport->SetUseHDR( false ); pViewport->SetHdrQuality( 0 ); pViewport->SetFogMode( K3DRenderDevice::FOGM_NONE, KColor(0,0,0), 1,1,1,1 ); pViewport->SetUseSpecular( true ); pViewport->SetRenderBumpMapMode( false ); //#ifndef NDEBUG // pViewport->SetDebugMode( true ); //#endif m_pViewport = pViewport; K3DColor diff = K3DColor(150/255.f,150/255.f,150/255.f); K3DColor spec = K3DColor( 90/255.f, 90/255.f, 90/255.f); K3DColor ambient = K3DColor(150/255.f,150/255.f,150/255.f); m_pLight = new K3DLight( diff, spec, ambient, K3DVector(0.33f, 1.f, 0.f) ); m_pLight->position.x = 500000000*0.33f; m_pLight->position.y = 500000000*1.f; m_pLight->position.z = 500000000*0.f; m_pLight->attenuation1 = 0; m_pLight->range = 500000001.F; #endif SetCamPos( K3DVertex(0, -8, 1) ); m_spRes = new KResSprite; m_nObjType = 0; m_nCamBoneIndex = DETAIL_HEAD; SetAutoTargetMode( true ); SetFullExpression( false ); SetEnableLight( false ); m_fullScene = false; /// 2011.01.11 - prodongi } KUIControl3DStatic::~KUIControl3DStatic() { SAFE_DELETE( m_pSeqForm ); #ifdef _RAC SAFE_DELETE( m_pViewport ); SAFE_DELETE( m_pLight ); #endif } void KUIControl3DStatic::SetLightDirection( float x, float y, float z ) { #ifdef _RAC m_pLight->direction.x = x; m_pLight->direction.y = y; m_pLight->direction.z = z; #endif } void KUIControl3DStatic::SetLightDiffuseColor( K3DColor color ) { #ifdef _RAC m_pLight->diffuse = color; #endif } void KUIControl3DStatic::SetLightSpecularColor( K3DColor color ) { #ifdef _RAC m_pLight->specular = color; #endif } void KUIControl3DStatic::SetLightAmbientColor( K3DColor color ) { #ifdef _RAC m_pLight->ambient = color; #endif } void KUIControl3DStatic::OnPosChangeNofity(int XOffset, int YOffset) { m_prSprite.SetAddPosition(XOffset, YOffset); } void KUIControl3DStatic::Create(KUIWND_CREATE_ARG& CREATE_ARG) { KUIControl::Create( CREATE_ARG); } void KUIControl3DStatic::SetCamPos( K3DVertex & pos ) { m_cam.Reset(); m_cam.SetCamPos( pos.x, pos.y, pos.z ); m_bPosValid = false; } void KUIControl3DStatic::SetCamPosOnly(K3DVector const& pos) { m_cam.SetCamPos( pos.x, pos.y, pos.z ); } void KUIControl3DStatic::SetCamTargetPos( K3DVertex & pos ) { m_cam.SetTargetPos( pos.x, pos.y, pos.z ); m_bPosValid = true; } void KUIControl3DStatic::SetSeqForm( KSeqAvatarEx *pSeq, KSize sizeTarget, int nObjType, K3DVertex & pos ) { if ( pSeq ) { // _oprint( "KUIControl3DStatic::SetSeqForm Start\n" ); //몬스터, 소환수이면 // if( nObjType != 0 ) { // m_cam.SetCamPos( pos.x, pos.y, pos.z ); SetCamPos( pos ); // _oprint( "Camera Target Pos : [%f %f %f]", pos.x, pos.y, pos.z ); } SAFE_DELETE( m_pSeqForm ); std::string strKey = "una_default01"; if( m_strAniName.length() > 1 ) strKey = m_strAniName; m_pSeqForm = (KSeqAvatarEx *)pSeq->Clone(); //m_pSeqForm->PlayAnimation( ANIPART_BIPED, 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); m_pSeqForm->PlayAnimation_temp( ANIPART_BIPED, 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); // sfreer 임시코드임. 인벤토리 창에 나오는 아바타에서 방패 장착시 표시 안되는 버그 수정. 2009.03.09 m_nObjType = nObjType; if( nObjType == 0 || nObjType == 1 ) //Player, NPC { m_pSeqForm->PlayAnimation( ANIPART_HAIR , 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); m_pSeqForm->PlayAnimation( ANIPART_NECKLACE , 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); m_pSeqForm->PlayAnimation( ANIPART_EARRING , 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); m_pSeqForm->PlayAnimation( ANIPART_MANTLE , 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); m_pSeqForm->PlayAnimation( ANIPART_FABRIC , 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); m_pSeqForm->PlayAnimation( ANIPART_LONGSKIRT , 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); m_pSeqForm->PlayAnimation( ANIPART_MIDSKIRT , 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); m_pSeqForm->PlayAnimation( ANIPART_SHORTSKIRT , 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); if( IsFullExpression() ) { m_pSeqForm->PlayAnimation( ANIPART_WEAPON_LEFT , 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); m_pSeqForm->PlayAnimation( ANIPART_WEAPON_RIGHT , 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); } } else { m_pSeqForm->PlayAnimation( ANIPART_BIPED, 0, strKey.c_str(), KSeqForm::SEQTYPE_LOOP ); } m_pSeqForm->SetAttachBone(); // K3DMatrix matPos; // K3DMatrixIdentity( matPos ); // K3DMatrixRotationZ( matPos, -90 / 180.f * K3D_PI ); // m_pSeqForm->SetTransform( matPos ); m_sizeTarget = sizeTarget; if( m_spRenderTarget == NULL ) { int nExpX, nExpY; K3DRenderDevice::GetSquareSize( m_sizeTarget.width, m_sizeTarget.height, nExpX, nExpY ); m_spRenderTarget = KDeviceManager::GetDeviceManager()->GetRenderDevice()->CreateRenderTarget( nExpX, nExpY, 1, K3DFMT_A8R8G8B8, K3DRenderTarget::DEPTH_ENABLE ); } #ifdef _RAC m_pViewport->SetViewArea( KRect( KPoint(0, 0), m_sizeTarget ) ); //m_pViewport->SetVertexAspect(1.f); #endif m_rcRegion.right = m_rcRegion.left + m_sizeTarget.width; m_rcRegion.bottom = m_rcRegion.top + m_sizeTarget.height; m_spRes->SetTexture( m_spRenderTarget, NULL ); m_prSprite.SetRes( m_spRes ); m_prSprite.SetVisibility( 1.0f ); K3DMatrix mat; K3DMatrixIdentity( mat ); mat.SetPosVector( K3DVertex( m_rcRegion.left, m_rcRegion.top, m_fZPos ) ); m_prSprite.SetTransform( mat ); m_prSprite.SetTargetSize( m_sizeTarget.width, m_sizeTarget.height ); m_bRenderValid = true; m_bPosValid = false; /// 2011.01.11 - prodongi if (m_fullScene) { m_bPosValid = true; setFullSceneCamPos(); } else if( IsAutoTargetMode() ) { _CID( GETBONEMATRIX2 ); KMsgGET_BONEMATRIX2 msg; const int detail[] = { DETAIL_HEAD, DETAIL_BODY2, DETAIL_BODY1, }; int nSize = _countof( detail ); for( int x = 0; x < nSize; ++x ) { msg.nDetailIndex = detail[x]; m_pSeqForm->Perform( 0, id_GETBONEMATRIX2, msg ); if( msg.pBoneMat != NULL ) break; } if( msg.pBoneMat != NULL ) { K3DVertex pos; K3DMatrixGetPosVector( pos, *msg.pBoneMat ); if( K3DVectorLength(pos) > 0.f ) m_bPosValid = true; m_cam.SetTargetPos( pos.x, pos.y, pos.z ); } else { _CID( GETBONEMATRIX ); K3DVertex pos( 0, 0, 0 ); KMsgGET_BONEMATRIX msg; msg.strBoneName = "Head"; msg.nBoneMatIndex = 0; m_pSeqForm->Perform( 0, id_GETBONEMATRIX, msg ); if ( msg.pBoneMat == NULL ) { _CID( GETBONENAMELIST ); KMsgGET_BONENAMELIST msg; m_pSeqForm->Perform( 0, id_GETBONENAMELIST, msg ); if ( msg.vBoneMatrixList.size() > 0 ) K3DMatrixGetPosVector( pos, *msg.vBoneMatrixList[0] ); } else K3DMatrixGetPosVector( pos, *msg.pBoneMat ); SetCamTargetPos( pos ); } } // _oprint( "KUIControl3DStatic::SetSeqForm End\n" ); } else { m_spRenderTarget = NULL; m_spRes->SetTexture(NULL, NULL); SAFE_DELETE( m_pSeqForm ); m_bRenderValid = false; } //처음 프레임엔 안보임. #ifdef _RAC m_pViewport->ClearRegisteredList(); #endif } void KUIControl3DStatic::Process(DWORD dwTime) { if ( m_pSeqForm ) m_pSeqForm->Process( dwTime ); } void KUIControl3DStatic::Render(KViewportObject * pViewport, bool isFront ) { if ( m_bShowFlag && m_spRenderTarget != NULL) { if ( m_bRenderValid && m_pSeqForm ) { #ifdef _RAC m_pViewport->ClearRegisteredList(); if( IsEnableLight() ) { m_pViewport->AddLight( m_pLight ); } m_pSeqForm->Render( m_pViewport ); #endif if( m_bPosValid ) { #ifdef _RAC m_pViewport->SetCamera(&m_cam); m_pViewport->Render( m_spRenderTarget, 0, true ); pViewport->Register( &m_prSprite ); #endif } } } } /// 2011.01.11 - prodongi void KUIControl3DStatic::setFullSceneSize(float const* visibleCube) { m_fullSceneWidth = fabs(visibleCube[3] - visibleCube[0]); m_fullSceneHeight = fabs(visibleCube[5] - visibleCube[2]); m_fullSceneCenter.x = visibleCube[3] + visibleCube[0]; m_fullSceneCenter.y = visibleCube[4] + visibleCube[1]; m_fullSceneCenter.z = visibleCube[5] + visibleCube[2]; m_fullSceneCenter *= 0.5f; } void KUIControl3DStatic::setFullSceneCamPos() { float fov, h1; float fovy = m_cam.GetFOV() * 0.5f; float d2 = m_pViewport->GetFarClip() - m_pViewport->GetNearClip(); if (m_fullSceneHeight > m_fullSceneWidth) { h1 = m_fullSceneHeight; fov = fovy; } else { h1 = m_fullSceneWidth; fov = fovy * m_pViewport->GetVertexAspect(); } float h2 = d2 * ::tanf(fov); float d1 = h1 * (d2/h2); /// 쫌더 확대되도록 0.7만큼 땡겨 준다 (0.7은 테스트 후에 나온 값이다) d1 *= 0.7f; /// 방향은 고정으로 여김 K3DVector dir(0.0f, 1.0f, 0.0f); K3DVector camTPos = m_fullSceneCenter; K3DVector camPos = m_fullSceneCenter - (dir * d1); m_cam.SetCamPos(camPos.x, camPos.y, camPos.z); m_cam.SetTargetPos(camTPos.x, camTPos.y, camTPos.z); }