Files
2026-06-01 12:46:52 +02:00

496 lines
12 KiB
C++

#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);
}