1830 lines
48 KiB
C++
1830 lines
48 KiB
C++
#include "stdafx.h"
|
|
#include "krenderobjectMesh.h"
|
|
#include "krenderobjectEtc.h"
|
|
#include "K3DCamera.h"
|
|
#include "KRenderDeviceDX.h"
|
|
#include "KDeviceManager.h"
|
|
#include "KResourceManager.h"
|
|
//#include "K3DFrustum.h"
|
|
#include "GameDefine.h"
|
|
#include "KResource.h"
|
|
#include "KViewport.h"
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KCameraSeq Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
KCameraSeq::KCameraSeq()
|
|
{
|
|
m_ViewCamera = new K3DCamera;
|
|
m_ViewCamera->Reset();
|
|
}
|
|
|
|
KCameraSeq::~KCameraSeq()
|
|
{
|
|
SAFE_DELETE(m_ViewCamera);
|
|
}
|
|
|
|
void KCameraSeq::SetRes( K3DResCamera *pRes)
|
|
{
|
|
m_spRes = pRes;
|
|
|
|
if(m_spRes != NULL)
|
|
{
|
|
m_interval.Expand( m_spRes->GetInterval() );
|
|
}
|
|
}
|
|
|
|
void *KCameraSeq::Perform( KID id, KArg& msg )
|
|
{
|
|
_CID( REQ_INTERSECTIONLINE );
|
|
_CID( SET_CAMERARENDER );
|
|
_CID( GET_CAMERASEQ );
|
|
|
|
if ( id == id_REQ_INTERSECTIONLINE )
|
|
{
|
|
realizeTime();
|
|
|
|
KMsgREQ_INTERLINE *reqmsg = static_cast<KMsgREQ_INTERLINE*>(&msg);
|
|
|
|
int scrx = reqmsg->nScrx;
|
|
int scry = reqmsg->nScry;
|
|
KViewportObject *pViewport = reqmsg->pViewport;
|
|
float fNearClip = pViewport->GetNearClip();
|
|
float fFarClip = pViewport->GetFarClip();
|
|
|
|
float scx = static_cast<float>(scrx - pViewport->GetViewportX()) / static_cast<float>(pViewport->GetViewportWidth()-1) * 2.f - 1.f;
|
|
float scy = -(static_cast<float>(scry - pViewport->GetViewportY()) / static_cast<float>(pViewport->GetViewportHeight()-1) * 2.f - 1.f);
|
|
|
|
// get inverse of the camera view matrix into invMat
|
|
K3DMatrix invMat;
|
|
K3DMatrixInverse( invMat, m_matView );
|
|
|
|
K3DVertex vtx;
|
|
|
|
float sx = (scx)*fNearClip*tanf(m_fFOV*pViewport->GetVertexAspect()*0.5f);
|
|
float sy = (scy)*fNearClip*tanf(m_fFOV*0.5f);
|
|
|
|
vtx.x = sx; vtx.y = sy; vtx.z = -fNearClip;
|
|
K3DVectorTransform(reqmsg->vNear, vtx, invMat);
|
|
|
|
sx = (scx)*fFarClip*tanf(m_fFOV*pViewport->GetVertexAspect()*0.5f);
|
|
sy = (scy)*fFarClip*tanf(m_fFOV*0.5f);
|
|
|
|
vtx.x = sx; vtx.y = sy; vtx.z = -fFarClip;
|
|
K3DVectorTransform(reqmsg->vFar, vtx, invMat);
|
|
return (void*)1;
|
|
}
|
|
else if( id == id_SET_CAMERARENDER )
|
|
{
|
|
KMsgSET_CAMERARENDER *reqmsg = static_cast<KMsgSET_CAMERARENDER*>(&msg);
|
|
m_bRenderFlag = reqmsg->bRenderFlag;
|
|
return (void*)1;
|
|
}
|
|
else if ( id == id_GET_CAMERASEQ )
|
|
{
|
|
KMsgGET_CAMERASEQ *reqmsg = static_cast<KMsgGET_CAMERASEQ*>(&msg);
|
|
reqmsg->pCamSeq = this;
|
|
return (void*)1;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void KCameraSeq::Render( KViewportObject *viewport, DWORD flag, const K3DMatrix * pAttachMat )
|
|
{
|
|
if( !m_bRenderFlag ) return;
|
|
|
|
realizeTime();
|
|
K3DMatrix projection;
|
|
if( m_ViewCamera->IsCoordinateRightHand() )
|
|
K3DMatrixPerspectiveFovRH( projection, m_fFOV,
|
|
viewport->GetVertexAspect(), viewport->GetNearClip(), viewport->GetFarClip() );
|
|
else
|
|
K3DMatrixPerspectiveFovLH( projection, m_fFOV,
|
|
viewport->GetVertexAspect(), viewport->GetNearClip(), viewport->GetFarClip() );
|
|
|
|
viewport->SetCamera(m_ViewCamera);
|
|
}
|
|
|
|
|
|
KSeqObject* KCameraSeq::Clone()
|
|
{
|
|
KCameraSeq *obj = new KCameraSeq;
|
|
obj->SetRes( m_spRes );
|
|
return obj;
|
|
}
|
|
|
|
void KCameraSeq::realizeTime()
|
|
{
|
|
if ( m_dwRealizedTime == m_dwTime ) return;
|
|
m_dwRealizedTime = m_dwTime;
|
|
|
|
K3DResCamera::Key *key1 = NULL, *key2 = NULL;
|
|
m_spRes->GetData( m_dwTime, key1, key2 );
|
|
|
|
K3DVector respos, resview, resup;
|
|
if ( key2 != NULL )
|
|
{
|
|
int ctime = m_dwTime - key1->time;
|
|
float ratio = (float)ctime / float(key2->time - key1->time);
|
|
K3DVectorLerp( respos, key1->pos, key2->pos, ratio );
|
|
K3DVectorLerp( resview, key1->view, key2->view, ratio );
|
|
K3DVectorLerp( resup, key1->up, key2->up, ratio );
|
|
m_fFOV = key1->fov + ((key2->fov - key1->fov) * ratio);
|
|
}
|
|
else
|
|
{
|
|
respos = key1->pos;
|
|
resview = key1->view;
|
|
resup = key1->up;
|
|
m_fFOV = key1->fov;
|
|
}
|
|
K3DVector at = respos + resview;
|
|
m_vCamPos = respos;
|
|
K3DMatrixLookAtRH( m_matView, respos, at, resup );
|
|
|
|
m_ViewCamera->SetCamPos(m_vCamPos.x, m_vCamPos.y, m_vCamPos.z);
|
|
m_ViewCamera->SetTargetPos(at.x, at.y, at.z);
|
|
m_ViewCamera->SetUpVector(resup.x, resup.y, resup.z);
|
|
m_ViewCamera->SetFOV(m_fFOV);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KLightSeq Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
KLightSeq::KLightSeq()
|
|
{
|
|
}
|
|
|
|
KLightSeq::~KLightSeq()
|
|
{
|
|
}
|
|
|
|
void KLightSeq::SetRes( K3DResLight *pRes )
|
|
{
|
|
m_spRes = pRes;
|
|
|
|
if(m_spRes != NULL)
|
|
{
|
|
m_interval.Expand( m_spRes->GetInterval() );
|
|
}
|
|
}
|
|
|
|
void * KLightSeq::Perform( KID id, KArg& msg )
|
|
{
|
|
_CID( REQ_LIGHT );
|
|
if( id == id_REQ_LIGHT )
|
|
{
|
|
K3DResLight::Key *key1 = NULL, *key2 = NULL;
|
|
m_spRes->GetData( 0, key1, key2 );
|
|
if ( key2 != NULL )
|
|
{
|
|
int ctime = m_dwTime - key1->time;
|
|
float ratio = (float)ctime / float(key2->time - key1->time);
|
|
|
|
memcpy( &m_Light, &key1->light, sizeof(m_Light) );
|
|
|
|
K3DVectorLerp( m_Light.position, key1->light.position, key2->light.position, ratio );
|
|
K3DVectorLerp( m_Light.direction, key1->light.direction, key2->light.direction, ratio );
|
|
K3DColorLerp( m_Light.diffuse, key1->light.diffuse, key2->light.diffuse, ratio );
|
|
m_Light.range = key1->light.range + ((key2->light.range - key1->light.range) * ratio);
|
|
}
|
|
else
|
|
{
|
|
memcpy( &m_Light, &key1->light, sizeof(m_Light) );
|
|
}
|
|
|
|
KMsgREQ_LIGHT *pmsg = static_cast<KMsgREQ_LIGHT*>(&msg);
|
|
pmsg->m_pLightList.push_back( &m_Light );
|
|
return (void*)1;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void KLightSeq::Render( KViewportObject *viewport, DWORD flag, const K3DMatrix * pAttachMat )
|
|
{
|
|
K3DResLight::Key *key1 = NULL, *key2 = NULL;
|
|
m_spRes->GetData( m_dwTime, key1, key2 );
|
|
|
|
if ( key2 != NULL )
|
|
{
|
|
int ctime = m_dwTime - key1->time;
|
|
float ratio = (float)ctime / float(key2->time - key1->time);
|
|
|
|
memcpy( &m_Light, &key1->light, sizeof(m_Light) );
|
|
|
|
K3DVectorLerp( m_Light.position, key1->light.position, key2->light.position, ratio );
|
|
K3DVectorLerp( m_Light.direction, key1->light.direction, key2->light.direction, ratio );
|
|
K3DColorLerp( m_Light.diffuse, key1->light.diffuse, key2->light.diffuse, ratio );
|
|
m_Light.range = key1->light.range + ((key2->light.range - key1->light.range) * ratio);
|
|
}
|
|
else
|
|
{
|
|
memcpy( &m_Light, &key1->light, sizeof(m_Light) );
|
|
}
|
|
viewport->AddLight( &m_Light );
|
|
}
|
|
|
|
|
|
KSeqObject* KLightSeq::Clone()
|
|
{
|
|
KLightSeq *obj = new KLightSeq;
|
|
obj->SetRes( m_spRes );
|
|
return obj;
|
|
}
|
|
|
|
void KLightSeq::realizeTime()
|
|
{
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KSpriteSeq Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
KSpriteSeq::KSpriteSeq()
|
|
{
|
|
K3DMatrixIdentity(m_matLocal);
|
|
}
|
|
|
|
KSpriteSeq::~KSpriteSeq()
|
|
{
|
|
}
|
|
|
|
int KSpriteSeq::GetFrameCount()
|
|
{
|
|
return m_spRes->GetKeyCount();
|
|
}
|
|
|
|
KResSprite *KSpriteSeq::GetFrame( int nFrame )
|
|
{
|
|
return m_spRes->GetSpriteByFrame(nFrame);
|
|
}
|
|
|
|
int KSpriteSeq::GetCurrentIndex()
|
|
{
|
|
return m_spRes->GetIndexNumber(m_dwTime);
|
|
}
|
|
|
|
KResSprite* KSpriteSeq::GetCurrentFrame()
|
|
{
|
|
KResSpriteAnimation::Key *key1 = NULL, *key2 = NULL;
|
|
m_spRes->GetData( m_dwTime, key1, key2 );
|
|
|
|
if(key1)
|
|
return key1->spSprite;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
LPCSTR KSpriteSeq::GetSeqName()
|
|
{
|
|
return m_spRes->GetName();
|
|
}
|
|
void KSpriteSeq::SetRes( KResSpriteAnimation *res )
|
|
{
|
|
assert(m_spRes == NULL);
|
|
m_spRes = res;
|
|
|
|
if(m_spRes != NULL)
|
|
{
|
|
m_interval = m_spRes->GetInterval();
|
|
}
|
|
}
|
|
KResSpriteAnimation* KSpriteSeq::GetRes()
|
|
{
|
|
return m_spRes;
|
|
}
|
|
|
|
void * KSpriteSeq::Perform( KID id, KArg& msg )
|
|
{
|
|
_CID( SET_RENDER_SIZE );
|
|
if( id == id_SET_RENDER_SIZE )
|
|
{
|
|
KMsgSET_RENDER_SIZE *pmsg = static_cast<KMsgSET_RENDER_SIZE*>(&msg);
|
|
m_sizeRender = pmsg->sizeRender;
|
|
if ( m_spRes != NULL )
|
|
{
|
|
int nFrames = m_spRes->GetKeyCount();
|
|
for ( int i=0 ; i<nFrames ; ++i )
|
|
{
|
|
KResSpriteAnimation::Key &key = m_spRes->GetKey( i );
|
|
key.spSprite->SetSize( static_cast<float>(m_sizeRender.cx), static_cast<float>(m_sizeRender.cy) );
|
|
}
|
|
}
|
|
return (void*)1;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void KSpriteSeq::Render( KViewportObject *viewport, DWORD flag, const K3DMatrix * pAttachMat )
|
|
{
|
|
KResSpriteAnimation::Key *key1 = NULL, *key2 = NULL;
|
|
m_spRes->GetData( m_dwTime, key1, key2 );
|
|
|
|
K3DPoint offset = key1->spSprite->GetOffset();
|
|
K3DMatrix mat = m_matLocal;
|
|
mat._41 += offset.x;
|
|
mat._42 += offset.y;
|
|
K3DMatrix matTrans = key1->spSprite->GetTransform();
|
|
|
|
mat *= matTrans;
|
|
|
|
if ( m_pMatAttach != NULL && m_pMatParent != NULL )
|
|
{
|
|
K3DMatrix matTemp;
|
|
K3DMatrixMultiply( matTemp, *m_pMatAttach, *m_pMatParent );
|
|
K3DMatrixMultiply( m_matResult, m_matLocal, matTemp );
|
|
}
|
|
else if ( m_pMatParent != NULL )
|
|
K3DMatrixMultiply( m_matResult, m_matLocal, *m_pMatParent );
|
|
else
|
|
m_matResult = m_matLocal;
|
|
|
|
m_prSprite.SetRes(key1->spSprite );
|
|
m_prSprite.SetVisibility(m_fMasterVisibility * key1->spSprite->GetVisibility());
|
|
m_prSprite.SetTransform(m_matResult);
|
|
//m_prSprite.UpdateSprite();
|
|
viewport->Register( &m_prSprite );
|
|
}
|
|
|
|
KSeqObject* KSpriteSeq::Clone()
|
|
{
|
|
KSpriteSeq *obj = new KSpriteSeq;
|
|
obj->SetRes( m_spRes );
|
|
return obj;
|
|
}
|
|
|
|
void KSpriteSeq::realizeTime()
|
|
{
|
|
if ( m_dwRealizedTime == m_dwTime ) return;
|
|
m_dwRealizedTime = m_dwTime;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KEventBoxSeq Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
KEventBoxSeq::KEventBoxSeq()
|
|
{
|
|
m_nType = KEVTYPE_BOX;
|
|
}
|
|
|
|
KEventBoxSeq::~KEventBoxSeq()
|
|
{
|
|
}
|
|
|
|
KSeqObject *KEventBoxSeq::Clone()
|
|
{
|
|
KEventBoxSeq *obj = new KEventBoxSeq;
|
|
obj->SetRes( m_spRes );
|
|
return obj;
|
|
}
|
|
|
|
const char *KEventBoxSeq::GetName()
|
|
{
|
|
if ( m_spRes != NULL )
|
|
{
|
|
return m_spRes->GetName();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void KEventBoxSeq::SetRes( K3DResEventBox *res )
|
|
{
|
|
assert(m_spRes == NULL);
|
|
m_spRes = res;
|
|
|
|
if ( m_spRes != NULL )
|
|
{
|
|
m_interval = m_spRes->GetInterval();
|
|
}
|
|
}
|
|
|
|
void KEventBoxSeq::Render( KViewportObject *viewport, DWORD flag, const K3DMatrix * pAttachMat )
|
|
{
|
|
//realizeTime();
|
|
//m_bCube.Render( viewport );
|
|
}
|
|
|
|
const K3DBoundRotCube &KEventBoxSeq::GetCube()
|
|
{
|
|
realizeTime();
|
|
return m_bCube;
|
|
}
|
|
|
|
void *KEventBoxSeq::Perform( KID id, KArg& msg )
|
|
{
|
|
_CID( REQ_EVBOX );
|
|
if ( id == id_REQ_EVBOX )
|
|
{
|
|
KMsgREQ_EVBOX *reqmsg = static_cast<KMsgREQ_EVBOX*>(&msg);
|
|
reqmsg->AddBox( this );
|
|
return (void*)1;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void KEventBoxSeq::realizeTime()
|
|
{
|
|
if ( m_dwRealizedTime == m_dwTime ) return;
|
|
m_dwRealizedTime = m_dwTime;
|
|
if ( m_spRes != NULL )
|
|
{
|
|
m_spRes->GetData( m_dwTime, &m_bCube );
|
|
}
|
|
}
|
|
|
|
void KEventBoxSeq::SetParentTransform( const K3DMatrix *pMatParent, const K3DMatrix *pMatAttach, BOOL bRotationLock )
|
|
{
|
|
KEventSeq::SetParentTransform( pMatParent, pMatAttach, bRotationLock );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KEventPointSeq Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool KEventPointSeq::m_sIsRender = false;
|
|
|
|
KEventPointSeq::KEventPointSeq()
|
|
{
|
|
m_nType = KEVTYPE_BOX;
|
|
m_bCube = K3DBoundRotCube( -1, 1, -1, 1, -1, 1 );
|
|
|
|
K3DMatrixIdentity( m_matPoint );
|
|
}
|
|
|
|
KEventPointSeq::~KEventPointSeq()
|
|
{
|
|
}
|
|
|
|
KSeqObject *KEventPointSeq::Clone()
|
|
{
|
|
KEventPointSeq *obj = new KEventPointSeq;
|
|
obj->SetRes( m_spRes );
|
|
return obj;
|
|
}
|
|
|
|
const char *KEventPointSeq::GetName()
|
|
{
|
|
if ( m_spRes != NULL)
|
|
{
|
|
return m_spRes->GetName();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void KEventPointSeq::SetRes( K3DResEventPoint *res )
|
|
{
|
|
assert(m_spRes == NULL);
|
|
m_spRes = res;
|
|
|
|
if ( m_spRes != NULL)
|
|
{
|
|
m_interval = m_spRes->GetInterval();
|
|
}
|
|
}
|
|
|
|
void KEventPointSeq::Render( KViewportObject *viewport, DWORD flag, const K3DMatrix * pAttachMat )
|
|
{
|
|
if( m_sIsRender )
|
|
{
|
|
realizeTime();
|
|
|
|
// m_prAxisWire01.Clear();
|
|
m_prAxisWire02.Clear();
|
|
|
|
K3DMatrix matResult;
|
|
K3DMatrixIdentity( matResult );
|
|
if ( m_pMatAttach != NULL && m_pMatParent != NULL )
|
|
{
|
|
//K3DMatrix Mat1 = *m_pMatAttach;
|
|
//K3DVector vVectorX, vVectorY, vVectorZ;
|
|
//AxisCalculation( Mat1, vVectorX, vVectorY, vVectorZ );
|
|
//m_prAxisWire01.AddLine( *K3DMatrixGetPosVector( Mat1 ), vVectorX, KColor(255,0,0,255) );
|
|
//m_prAxisWire01.AddLine( *K3DMatrixGetPosVector( Mat1 ), vVectorY, KColor(0,255,0,255) );
|
|
//m_prAxisWire01.AddLine( *K3DMatrixGetPosVector( Mat1 ), vVectorZ, KColor(0,0,255,255) );
|
|
|
|
//예전 코드 ( 문제 있음 )
|
|
// K3DMatrixMultiply( matResult, *m_pMatAttach, *m_pMatParent );
|
|
// K3DMatrixMultiply( matResult, m_matPoint, matResult );
|
|
|
|
//새로운 코드
|
|
K3DMatrixMultiply( matResult, m_matPoint, *m_pMatAttach );
|
|
K3DMatrixMultiply( matResult, matResult, *m_pMatParent );
|
|
}
|
|
else if ( m_pMatParent != NULL )
|
|
{
|
|
//예전 코드
|
|
K3DMatrixMultiply( matResult, matResult, *m_pMatParent );
|
|
|
|
//새로운 코드
|
|
// K3DMatrixMultiply( matResult, m_matPoint, *m_pMatParent );
|
|
}
|
|
else
|
|
{
|
|
matResult = m_matPoint;
|
|
}
|
|
|
|
K3DMatrix Mat1 = matResult;
|
|
K3DVector vVectorX, vVectorY, vVectorZ;
|
|
AxisCalculation( Mat1, vVectorX, vVectorY, vVectorZ, 2.f );
|
|
m_prAxisWire02.AddLine( Mat1.GetPosVector(), vVectorX, KColor(255,0,0,255) );
|
|
m_prAxisWire02.AddLine( Mat1.GetPosVector(), vVectorY, KColor(0,255,0,255) );
|
|
m_prAxisWire02.AddLine( Mat1.GetPosVector(), vVectorZ, KColor(0,0,255,255) );
|
|
|
|
m_bCube.SetTransform( matResult );
|
|
m_bCube.Render( viewport );
|
|
|
|
// viewport->RegisterWire( &m_prAxisWire01 );
|
|
viewport->RegisterWire( &m_prAxisWire02 );
|
|
}
|
|
}
|
|
|
|
const K3DMatrix &KEventPointSeq::GetPoint()
|
|
{
|
|
realizeTime();
|
|
return m_matPoint;
|
|
}
|
|
|
|
void *KEventPointSeq::Perform( KID id, KArg& msg )
|
|
{
|
|
_CID( REQ_EVPOINT );
|
|
if ( id == id_REQ_EVPOINT )
|
|
{
|
|
KMsgREQ_EVPOINT *reqmsg = static_cast<KMsgREQ_EVPOINT*>(&msg);
|
|
reqmsg->AddPoint( this );
|
|
return (void*)1;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void KEventPointSeq::realizeTime()
|
|
{
|
|
if ( m_dwRealizedTime == m_dwTime ) return;
|
|
m_dwRealizedTime = m_dwTime;
|
|
if ( m_spRes != NULL )
|
|
{
|
|
K3DMatrixIdentity( m_matPoint );
|
|
m_spRes->GetData( m_dwTime, &m_matPoint );
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KFXSeq Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void KFXSeq::GetUVAniRect( int nCurFrame, int nFrameCount )
|
|
{
|
|
int width = int(1.f/m_fTRight);
|
|
//int height = int(1.f/m_fTBottom);
|
|
|
|
assert( nFrameCount );
|
|
int txtpos = nCurFrame%nFrameCount;
|
|
|
|
int px = txtpos%width;
|
|
int py = txtpos/width;
|
|
|
|
m_fLeft+=m_fTRight*px;
|
|
m_fRight+=m_fTRight*px;
|
|
|
|
m_fTop+=m_fTBottom*py;
|
|
m_fBottom+=m_fTBottom*py;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KFXBillboardSeq Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool KFXBillboardSeq::m_sVisbleCube = false;
|
|
|
|
KFXBillboardSeq::KFXBillboardSeq()
|
|
{
|
|
m_nType = KFXTYPE_BILLBOARD;
|
|
}
|
|
|
|
KFXBillboardSeq::~KFXBillboardSeq()
|
|
{
|
|
}
|
|
|
|
KSeqObject *KFXBillboardSeq::Clone()
|
|
{
|
|
KFXBillboardSeq *obj = new KFXBillboardSeq;
|
|
obj->SetRes( m_spRes );
|
|
|
|
const K3DVertex* pVtx = m_boundCube.GetOriginVertices();
|
|
obj->SetCube( pVtx[0].x, pVtx[7].x, pVtx[0].y, pVtx[7].y, pVtx[0].z, pVtx[7].z );
|
|
|
|
return obj;
|
|
}
|
|
|
|
void KFXBillboardSeq::SetRes( KResFXBillboard *res )
|
|
{
|
|
assert(m_spRes == NULL);
|
|
m_spRes = res;
|
|
|
|
if(m_spRes != NULL)
|
|
{
|
|
m_interval = m_spRes->GetInterval();
|
|
m_prBillboard.SetBillboardRes( m_spRes );
|
|
m_prBillboard.SetTransparent( true );
|
|
m_prBillboard.SetFixedAxis( m_spRes->GetFixedAxis() );
|
|
if( m_spRes->GetAdditiveRenderMode() )
|
|
m_prBillboard.SetBlendMode( K3DMaterial::MBM_ADDTIVE_BILLBOARD );
|
|
else
|
|
m_prBillboard.SetBlendMode( K3DMaterial::MBM_BILLBOARD );
|
|
}
|
|
}
|
|
|
|
void KFXBillboardSeq::SetCube( float minx, float maxx, float miny, float maxy, float minz, float maxz )
|
|
{
|
|
m_boundCube = K3DBoundRotCube( minx, maxx, miny, maxy, minz, maxz );
|
|
}
|
|
|
|
void KFXBillboardSeq::Render( KViewportObject *viewport, DWORD flag, const K3DMatrix * pAttachMat )
|
|
{
|
|
realizeTime();
|
|
|
|
if( !m_bRenderFlag ) return;
|
|
|
|
if( m_fVisResult <= 0.f )
|
|
return; //투명한 놈이므로 안 그림
|
|
|
|
if ( m_spRes != NULL )
|
|
{
|
|
m_prBillboard.SetColor( KColor( 255, 255, 255, unsigned char(255.f * (m_fVisResult * m_fMasterVisibility)) ) );
|
|
if ( m_spRes->GetUVAnimation() )
|
|
{
|
|
int nMaxFrame = m_spRes->GetUVAniMaxFrame();
|
|
float fUVRatio = 1.0f / sqrtf( (float)nMaxFrame );
|
|
assert( nMaxFrame );
|
|
int nLoopFrame = m_spRes->GetUvLoopFrame();
|
|
if( nLoopFrame == 0 )
|
|
nLoopFrame = m_spRes->GetRangeEnd();
|
|
int nAniCount = int(( nMaxFrame / ( float ) nLoopFrame ) * m_dwTime);
|
|
if ( nAniCount >= nMaxFrame )
|
|
nAniCount %= nMaxFrame;
|
|
|
|
int width = int(1.f / fUVRatio);
|
|
int txtpos = nAniCount % nMaxFrame;
|
|
|
|
int px = txtpos % width;
|
|
int py = txtpos / width;
|
|
|
|
float l, r, t, b;
|
|
l = fUVRatio * px;
|
|
r = fUVRatio + fUVRatio * px;
|
|
|
|
t = fUVRatio * py;
|
|
b = fUVRatio + fUVRatio * py;
|
|
m_prBillboard.SetUV( l, t, r, b );
|
|
}
|
|
else
|
|
{
|
|
m_prBillboard.SetUV( .0f, .0f, 1.0f, 1.0f );
|
|
}
|
|
|
|
K3DMatrix mat = m_matTransform;
|
|
K3DMatrix matResult;
|
|
|
|
if ( m_pMatAttach != NULL && m_pMatParent != NULL )
|
|
{
|
|
K3DMatrix matTemp;
|
|
K3DMatrixMultiply( matTemp, *m_pMatAttach, *m_pMatParent );
|
|
K3DMatrixMultiply( matResult, mat, matTemp );
|
|
}
|
|
else if ( m_pMatParent != NULL )
|
|
K3DMatrixMultiply( matResult, mat, *m_pMatParent );
|
|
else
|
|
matResult = mat;
|
|
|
|
m_boundCube.SetTransform( matResult );
|
|
|
|
const K3DVector *cube = m_boundCube.GetVertices();
|
|
K3DVector vCenterPos = K3DVector(0.f, 0.f, 0.f);
|
|
vCenterPos = cube[0] + (0.5f*(cube[7] - cube[0]));
|
|
|
|
m_prBillboard.SetRootMat( &matResult );
|
|
m_prBillboard.SetCenterPosition( vCenterPos );
|
|
|
|
m_prBillboard.SetTransform( matResult );
|
|
m_prBillboard.SetAngle( 2.0f * K3D_PI * m_spRes->GetRotateSpeed() * ( float ) m_dwTime / 9600.0f );
|
|
|
|
if( flag == KRenderObject::RENDEREFX_AFTER_SPRITE )
|
|
viewport->Register( &m_prBillboard, flag );
|
|
else
|
|
viewport->Register( &m_prBillboard, KRenderObject::RENDEREFX_NONE );
|
|
|
|
if( m_sVisbleCube )
|
|
{
|
|
m_boundCube.Render( viewport );
|
|
|
|
m_prCenterWire.Clear();
|
|
K3DVector vVectorX, vVectorY, vVectorZ;
|
|
vVectorX = vCenterPos;
|
|
vVectorY = vCenterPos;
|
|
vVectorZ = vCenterPos;
|
|
vVectorX.x += 3.f;
|
|
vVectorY.y += 3.f;
|
|
vVectorZ.z += 3.f;
|
|
//CenterPos
|
|
m_prCenterWire.AddLine( vCenterPos, vVectorX, KColor(255,0,0,255) );
|
|
m_prCenterWire.AddLine( vCenterPos, vVectorY, KColor(0,255,0,255) );
|
|
m_prCenterWire.AddLine( vCenterPos, vVectorZ, KColor(0,0,255,255) );
|
|
|
|
viewport->RegisterWire( &m_prCenterWire );
|
|
}
|
|
}
|
|
}
|
|
|
|
void *KFXBillboardSeq::Perform( KID id, KArg& msg )
|
|
{
|
|
_CID( SETFORCERENDER_FLAG );
|
|
_CID( SETRENDER_FLAG );
|
|
_CID( GETMESH_ANIINFO );
|
|
|
|
if( id == id_SETFORCERENDER_FLAG)
|
|
{
|
|
m_bRenderFlag = FALSE;
|
|
}
|
|
else if( id == id_SETRENDER_FLAG )
|
|
{
|
|
KMsgSET_RENDERFLAG * renderflagmsg = static_cast<KMsgSET_RENDERFLAG*>(&msg);
|
|
m_bRenderFlag = renderflagmsg->bRenderFlag;
|
|
}
|
|
else if( id == id_GETMESH_ANIINFO )
|
|
{
|
|
KMsgGET_MESHANI_INFO * meshani_info = static_cast<KMsgGET_MESHANI_INFO*>(&msg);
|
|
|
|
if( m_spRes != NULL )
|
|
{
|
|
{
|
|
if( meshani_info->nStart < m_spRes->GetInterval().GetStart() )
|
|
meshani_info->nStart = m_spRes->GetInterval().GetStart();
|
|
|
|
if( meshani_info->nEnd < m_spRes->GetInterval().GetEnd() )
|
|
meshani_info->nEnd = m_spRes->GetInterval().GetEnd();
|
|
}
|
|
}
|
|
}
|
|
return (void*)1;
|
|
}
|
|
|
|
void KFXBillboardSeq::realizeTime()
|
|
{
|
|
if ( m_dwRealizedTime == m_dwTime ) return;
|
|
m_dwRealizedTime = m_dwTime;
|
|
if ( m_spRes != NULL )
|
|
{
|
|
m_spRes->GetData( m_dwTime, &m_fVisResult, &m_matTransform );
|
|
}
|
|
if ( m_dwTime > unsigned int(m_spRes->GetRangeEnd() + 160) )
|
|
m_fVisResult = 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KFXParticleObject Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class KFXParticleObject
|
|
{
|
|
public:
|
|
KFXParticleObject() { m_nLifeTime = 0; m_nCurTime = 0; m_bNewParticle = false; }
|
|
virtual ~KFXParticleObject() {}
|
|
virtual void Init( const K3DMatrix *pMatParent, KResFXParticle *res, float fRadius, int nLifeTime, int nCreateTime, const K3DVector &startpos, const K3DVector &vec, const K3DVector &velocity )
|
|
{
|
|
// m_pMatParent = pMatParent;
|
|
m_pRes = res;
|
|
m_fRadius = fRadius;
|
|
m_nLifeTime = nLifeTime;
|
|
m_nCreateTime = nCreateTime;
|
|
m_nCurTime = 0;
|
|
m_vecStart = startpos;
|
|
m_vecVector = vec;
|
|
m_vecVelocity = velocity;
|
|
m_fTop = m_fLeft = 0.f;
|
|
m_fBottom = m_fRight = 1.0f;
|
|
if ( m_pRes->GetUVAnimation() )
|
|
{
|
|
m_fUVRatio = 1.0f / sqrtf( (float)m_pRes->GetUVAniMaxFrame() );
|
|
}
|
|
|
|
m_bNewParticle = true;
|
|
}
|
|
void ChangeVector( const K3DVector &vec, const K3DVector &vel )
|
|
{
|
|
m_vecVector = vec;
|
|
m_vecVelocity = vel;
|
|
}
|
|
void Process( int time )
|
|
{
|
|
m_nCurTime = abs(time - m_nCreateTime);
|
|
|
|
_ProcessParticlePos();
|
|
_ProcessUVAnimation();
|
|
_ProcessTransformVisibility();
|
|
}
|
|
const K3DVector &GetPos()
|
|
{
|
|
return m_vecPos;
|
|
}
|
|
const KColor &GetColor()
|
|
{
|
|
return m_colParticle;
|
|
}
|
|
float GetWidth()
|
|
{
|
|
return m_fWidth;
|
|
}
|
|
float GetHeight()
|
|
{
|
|
return m_fHeight;
|
|
}
|
|
bool IsLife()
|
|
{
|
|
return m_nLifeTime > m_nCurTime;
|
|
}
|
|
int GetLife()
|
|
{
|
|
return m_nLifeTime - m_nCurTime;
|
|
}
|
|
void GetUV( float *_left, float *_top, float *_right, float *_bottom )
|
|
{
|
|
*_left = m_fLeft; *_top = m_fTop; *_right = m_fRight; *_bottom = m_fBottom;
|
|
}
|
|
bool IsNewParticle() { return m_bNewParticle; }
|
|
void UsedParticle() { m_bNewParticle = false; }
|
|
|
|
protected:
|
|
virtual void _ProcessParticlePos()
|
|
{
|
|
float nTime = m_nCurTime / 160.f;
|
|
m_vecPos.x = ( m_vecVector.x * powf( m_vecVelocity.x, nTime )) * nTime;
|
|
m_vecPos.y = ( m_vecVector.y * powf( m_vecVelocity.y, nTime )) * nTime;
|
|
m_vecPos.z = ( m_vecVector.z * powf( m_vecVelocity.z, nTime )) * nTime;
|
|
K3DVector NorVec;
|
|
NorVec = m_vecVector;
|
|
Normalize( NorVec );
|
|
m_vecOldPos = m_vecPos;
|
|
m_vecPos += m_fRadius * NorVec;
|
|
m_vecPos += m_vecStart;
|
|
}
|
|
void _ProcessUVAnimation()
|
|
{
|
|
if ( m_pRes && m_pRes->GetUVAnimation() )
|
|
{
|
|
int nMaxFrame = m_pRes->GetUVAniMaxFrame();
|
|
assert( nMaxFrame );
|
|
int nLoopFrame = m_pRes->GetUvLoopFrame();
|
|
if( nLoopFrame == 0 )
|
|
nLoopFrame = m_nLifeTime;
|
|
int nAniCount = int(( nMaxFrame / ( float ) m_nLifeTime ) * m_nCurTime);
|
|
if ( nAniCount >= nMaxFrame )
|
|
nAniCount %= nMaxFrame;
|
|
|
|
int width = int(1.f / m_fUVRatio);
|
|
int txtpos = nAniCount % nMaxFrame;
|
|
|
|
int px = txtpos % width;
|
|
int py = txtpos / width;
|
|
|
|
m_fLeft = m_fUVRatio * px;
|
|
m_fRight = m_fLeft + m_fUVRatio;
|
|
|
|
m_fTop = m_fUVRatio * py;
|
|
m_fBottom = m_fTop + m_fUVRatio;
|
|
}
|
|
else if( !m_pRes )
|
|
{
|
|
_oprint( "_ProcessUVAnimation() m_pRes == NULL\n" );
|
|
}
|
|
}
|
|
|
|
void _ProcessTransformVisibility()
|
|
{
|
|
K3DMatrix matTransform;
|
|
float vis;
|
|
|
|
int dattime = int((float)((float)m_nCurTime/m_nLifeTime) * m_pRes->GetInterval().GetLength());
|
|
m_pRes->GetData( dattime, &vis, &matTransform );
|
|
m_colParticle = KColor( 255, 255, 255, unsigned char(vis * 255 ));
|
|
|
|
// Process Matrix Transfom
|
|
/* if ( m_pMatParent )
|
|
K3DMatrixMultiply( &matTransform, &mat, m_pMatParent );
|
|
else matTransform = mat;*/
|
|
|
|
// calc radius
|
|
const K3DVertex *pV = m_pRes->GetVertices();
|
|
K3DVector transVtx[4];
|
|
int i;
|
|
for( i=0 ; i < 4 ; ++i )
|
|
{
|
|
K3DVectorTransform( transVtx[i], pV[i], matTransform );
|
|
}
|
|
//K3DVector vWidth = transVtx[0] - transVtx[1];
|
|
//K3DVector vHeight = transVtx[1] - transVtx[3];
|
|
//m_fWidth = K3DVectorLength( vWidth );
|
|
m_fWidth = min( K3DVectorLength( transVtx[1] - transVtx[3] ), K3DVectorLength( transVtx[1]- transVtx[2]) ); // dirty workaround by Tyburn -_-;
|
|
//m_fHeight = K3DVectorLength( vHeight );
|
|
m_fHeight = K3DVectorLength( transVtx[0] - transVtx[1] );
|
|
}
|
|
const K3DMatrix* m_pMatParent;
|
|
|
|
// Particle Object는 실시간에 몇천개씩 생겼다 사라지므로 일부러 Smart Pointer 사용안함
|
|
// Parent에 묶여있는 상태이므로 안전성은 보장된다.
|
|
KResFXParticle* m_pRes;
|
|
|
|
float m_fUVRatio;
|
|
float m_fLeft, m_fRight, m_fTop, m_fBottom;
|
|
float m_fRadius;
|
|
KColor m_colParticle;
|
|
float m_fWidth,m_fHeight;
|
|
int m_nLifeTime;
|
|
int m_nCurTime;
|
|
int m_nCreateTime;
|
|
K3DVector m_vecPos;
|
|
K3DVector m_vecOldPos;
|
|
K3DVector m_vecStart;
|
|
K3DVector m_vecVector;
|
|
K3DVector m_vecVelocity;
|
|
bool m_bNewParticle;
|
|
};
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KFXGravityParticleObject Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class KFXGravityParticleObject : public KFXParticleObject
|
|
{
|
|
public:
|
|
KFXGravityParticleObject() { m_fGravityAccel = 9.8f; m_vecGravity = K3DVector(0,0,-1); }
|
|
virtual ~KFXGravityParticleObject() {}
|
|
virtual void Init( const K3DMatrix *pMatParent, KResFXParticle *res, float fRadius, int nLifeTime, int nCreateTime, const K3DVector &startpos, const K3DVector &vec, const K3DVector &velocity )
|
|
{
|
|
KFXParticleObject::Init(pMatParent,res,false,nLifeTime,nCreateTime,startpos,vec,velocity);
|
|
m_fGravityAccel = res->GetGravityAccel();
|
|
m_vecGravity = res->GetGravity();
|
|
}
|
|
|
|
protected:
|
|
virtual void _ProcessParticlePos()
|
|
{
|
|
float nTime = m_nCurTime / 160.f;
|
|
|
|
K3DVector temp;
|
|
temp = m_vecGravity;
|
|
Normalize(temp);
|
|
temp *= m_fGravityAccel;
|
|
|
|
m_vecPos.x = float( m_vecVector.x * nTime + 0.5 * temp.x * pow(nTime, 2) );
|
|
m_vecPos.y = float( m_vecVector.y * nTime + 0.5 * temp.y * pow(nTime, 2) );
|
|
m_vecPos.z = float( m_vecVector.z * nTime + 0.5 * temp.z * pow(nTime, 2) );
|
|
|
|
K3DVector NorVec;
|
|
NorVec = m_vecVector;
|
|
Normalize( NorVec );
|
|
m_vecOldPos = m_vecPos;
|
|
m_vecPos += m_fRadius * NorVec;
|
|
m_vecPos += m_vecStart;
|
|
}
|
|
|
|
float m_fGravityAccel;
|
|
K3DVector m_vecGravity;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KFXReverseParticleObject Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class KFXReverseParticleObject : public KFXParticleObject
|
|
{
|
|
public:
|
|
KFXReverseParticleObject(){}
|
|
virtual ~KFXReverseParticleObject() {}
|
|
protected:
|
|
virtual void _ProcessParticlePos()
|
|
{
|
|
int tempTime = m_nCurTime;
|
|
tempTime = m_nLifeTime - tempTime;
|
|
float nTime = tempTime / 160.f;
|
|
|
|
m_vecPos.x = ( m_vecVector.x * powf( m_vecVelocity.x, nTime )) * nTime;
|
|
m_vecPos.y = ( m_vecVector.y * powf( m_vecVelocity.y, nTime )) * nTime;
|
|
m_vecPos.z = ( m_vecVector.z * powf( m_vecVelocity.z, nTime )) * nTime;
|
|
|
|
K3DVector NorVec;
|
|
NorVec = m_vecVector;
|
|
Normalize( NorVec );
|
|
m_vecOldPos = m_vecPos;
|
|
m_vecPos += m_fRadius * NorVec;
|
|
m_vecPos += m_vecStart;
|
|
}
|
|
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KFXParticleSeq Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
KFXParticleSeq::KFXParticleSeq(DWORD dwParticleType)
|
|
{
|
|
m_nType = KFXTYPE_PARTICLE;
|
|
m_dwParticleType = dwParticleType;
|
|
m_bInited = false;
|
|
m_ppParticles = NULL;
|
|
m_nParticleCount = 0;
|
|
|
|
m_pMatAttach = NULL;
|
|
m_pMatParent = NULL;
|
|
}
|
|
|
|
KFXParticleSeq::~KFXParticleSeq()
|
|
{
|
|
_ClearObject();
|
|
}
|
|
|
|
KSeqObject *KFXParticleSeq::Clone()
|
|
{
|
|
KFXParticleSeq *obj = new KFXParticleSeq(m_dwParticleType);
|
|
obj->SetRes( m_spRes );
|
|
return obj;
|
|
}
|
|
|
|
|
|
void KFXParticleSeq::SetRes( KResFXParticle *res )
|
|
{
|
|
assert(m_spRes == NULL);
|
|
|
|
m_spRes = res;
|
|
|
|
if(m_spRes != NULL)
|
|
{
|
|
m_interval = m_spRes->GetInterval();
|
|
m_prParticle.SetParticleRes( m_spRes );
|
|
m_prParticle.SetTransparent( true );
|
|
if( m_spRes->GetAdditiveRenderMode() )
|
|
m_prParticle.SetBlendMode( K3DMaterial::MBM_ADDTIVE_BILLBOARD );
|
|
else
|
|
m_prParticle.SetBlendMode( K3DMaterial::MBM_BILLBOARD );
|
|
|
|
m_prParticle.SetAttachParent( m_spRes->IsAttachParent() );
|
|
}
|
|
}
|
|
|
|
void KFXParticleSeq::Render( KViewportObject *viewport, DWORD flag, const K3DMatrix * pAttachMat )
|
|
{
|
|
realizeTime();
|
|
|
|
if( !m_bRenderFlag ) return;
|
|
|
|
static KFXParticlePrimitive::_PARTICLE particle;
|
|
|
|
if ( m_ppParticles )
|
|
{
|
|
m_prParticle.ResetParticleCount();
|
|
int nDrawCount = 0;
|
|
for( int i = 0 ; i < m_nParticleCount ; ++i )
|
|
{
|
|
KFXParticleObject *ptc = m_ppParticles[i];
|
|
if( ptc->IsLife() == true )
|
|
{
|
|
ptc->Process( m_dwMyTime );
|
|
|
|
particle.pos = ptc->GetPos();
|
|
particle.color = ptc->GetColor();
|
|
particle.fWidth = ptc->GetWidth();
|
|
particle.fHeight = ptc->GetHeight();
|
|
ptc->GetUV( &particle.l, &particle.t, &particle.r, &particle.b );
|
|
|
|
m_prParticle.SetParticleInfo( nDrawCount, particle );
|
|
|
|
if( ptc->IsNewParticle() )
|
|
{
|
|
m_prParticle.NewParticle( nDrawCount );
|
|
ptc->UsedParticle();
|
|
}
|
|
|
|
++nDrawCount;
|
|
}
|
|
}
|
|
if( flag == KRenderObject::RENDEREFX_AFTER_SPRITE )
|
|
viewport->Register( &m_prParticle, flag );
|
|
else
|
|
viewport->Register( &m_prParticle, KRenderObject::RENDEREFX_NONE );
|
|
}
|
|
}
|
|
|
|
void *KFXParticleSeq::Perform( KID id, KArg& msg )
|
|
{
|
|
_CID( SETFORCERENDER_FLAG );
|
|
_CID( GETMESH_ANIINFO );
|
|
|
|
if( id == id_SETFORCERENDER_FLAG)
|
|
{
|
|
m_bRenderFlag = FALSE;
|
|
}
|
|
else if( id == id_GETMESH_ANIINFO )
|
|
{
|
|
KMsgGET_MESHANI_INFO * meshani_info = static_cast<KMsgGET_MESHANI_INFO*>(&msg);
|
|
if( m_spRes != NULL )
|
|
{
|
|
// if( _stricmp( meshani_info->strFindName.c_str(), m_pResMesh->GetName() ) == 0 )
|
|
{
|
|
if( meshani_info->nStart < m_spRes->GetInterval().GetStart() )
|
|
meshani_info->nStart = m_spRes->GetInterval().GetStart();
|
|
|
|
if( meshani_info->nEnd < m_spRes->GetInterval().GetEnd() )
|
|
meshani_info->nEnd = m_spRes->GetInterval().GetEnd();
|
|
}
|
|
}
|
|
}
|
|
return (void*)1;
|
|
}
|
|
|
|
void KFXParticleSeq::realizeTime()
|
|
{
|
|
if(m_spRes == NULL)
|
|
return;
|
|
|
|
if ( m_bInited == false )
|
|
{
|
|
_Initialize();
|
|
m_dwOldTime = m_dwTime;
|
|
m_dwOldCreateTime = m_spRes->GetRangeStart();
|
|
m_dwMyTime = 0;
|
|
}
|
|
int nInterval = m_dwTime - m_dwOldTime;
|
|
if ( nInterval < 0 )
|
|
{
|
|
nInterval = m_interval.GetEnd() - m_dwOldTime + m_dwTime;
|
|
if ( m_spRes->IsLoop() == false )
|
|
{
|
|
_ClearObject();
|
|
m_bInited = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
m_dwMyTime += nInterval;
|
|
|
|
if( (int(m_dwMyTime) - int(m_dwOldCreateTime)) >= m_spRes->GetCreateTime() )
|
|
{
|
|
if ( (unsigned int)m_spRes->GetRangeStart() <= m_dwMyTime && (( m_spRes->IsLoop() == true )
|
|
|| ( m_spRes->IsLoop() == false && (unsigned int)m_spRes->GetRangeEnd() > m_dwMyTime )) )
|
|
{
|
|
int count = (m_dwMyTime - m_dwOldCreateTime) / m_spRes->GetCreateTime();
|
|
|
|
//gmpbigsun( 20131125 ) : 아래코드는 파티클 생성시간을 같도록 강제로 만들어버린것이다
|
|
//의도를 알수없으나, 상당히 잘못된 코드임. 주석처리된것으로 바꾸면 랜덤생성인것임.
|
|
//파티클 수정
|
|
//2009-21-26 : hunee
|
|
//m_dwOldCreateTime = m_dwMyTime - ((m_dwMyTime-m_dwOldCreateTime) % m_spRes->GetCreateTime());
|
|
m_dwOldCreateTime = m_dwMyTime - (m_dwMyTime - m_dwOldCreateTime);
|
|
for( int i = 0 ; i < m_nParticleCount ; ++i )
|
|
{
|
|
KFXParticleObject *ptc = m_ppParticles[i];
|
|
if( ptc->IsLife() == false )
|
|
{
|
|
_CreateParticle( i , m_spRes->GetCreateTime() );
|
|
if ( (--count) == 0 ) break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
m_dwOldTime = m_dwTime;
|
|
|
|
K3DMatrix matResult;
|
|
K3DMatrixIdentity( matResult );
|
|
|
|
if ( m_pMatAttach != NULL && m_pMatParent != NULL )
|
|
{
|
|
K3DMatrix matTemp;
|
|
K3DMatrixMultiply( matTemp, *m_pMatAttach, *m_pMatParent );
|
|
K3DMatrixMultiply( matResult, matResult, matTemp );
|
|
}
|
|
else if ( m_pMatParent != NULL )
|
|
K3DMatrixMultiply( matResult, matResult, *m_pMatParent );
|
|
|
|
m_prParticle.SetRootMat( &matResult );
|
|
m_prParticle.SetCenterPosition( K3DVector( matResult._41, matResult._42, matResult._43 ) );
|
|
}
|
|
|
|
/// Get random vector (vertex) from given direction vector and angle.
|
|
static inline K3DVector K3DVectorGetRandom( const K3DVector &vec, float fAngle )
|
|
{
|
|
K3DVector Result, Sample;
|
|
float fRadius, fTheta, fPitch;
|
|
float fNewRadius, fNewTheta, fNewPitch;
|
|
Sample = K3DVector( 0, 0, 1 );
|
|
fRadius = sqrtf( ( Sample.x * Sample.x ) + ( Sample.y * Sample.y ) + ( Sample.z * Sample.z ) );
|
|
fPitch = acosf( Sample.z / fRadius );
|
|
if( Sample.x == 0.000000f ) fTheta = 90 * K3D_PI / 180.f;
|
|
else fTheta = ( Sample.x > 0.f ) ? atanf( Sample.y / Sample.x ) : atanf( Sample.y / Sample.x ) + K3D_PI;
|
|
|
|
int nUnit = int( fAngle * 10.f );
|
|
float fRandPitch = fAngle - ( 0.1f * ( rand()%(nUnit * 2) ) );
|
|
// float fRandTheta = fAngle - ( 0.1f * ( rand()%(nUnit * 2) ) );
|
|
float fRandTheta = 180 - ( 1.0f * ( rand()%(180*2) ) );
|
|
fRandPitch = fRandPitch * K3D_PI / 180.f;
|
|
fRandTheta = fRandTheta * K3D_PI / 180.f;
|
|
|
|
fNewRadius = fRadius;
|
|
fNewPitch = fPitch + fRandPitch;
|
|
// fNewTheta = fTheta + fRandTheta;
|
|
fNewTheta = fRandTheta;
|
|
Result.x = fNewRadius * cosf( fNewTheta ) * sinf( fNewPitch );
|
|
Result.y = fNewRadius * sinf( fNewTheta ) * sinf( fNewPitch );
|
|
Result.z = fNewRadius * cosf( fNewPitch );
|
|
Normalize( Result );
|
|
///////////////////////////////////////
|
|
///////////////////////////////////////
|
|
K3DVector va;
|
|
K3DMatrix mat;
|
|
float fDot = K3DVectorDot( Sample, vec );
|
|
float ffAngle = acosf( fDot );
|
|
K3DVectorCross( va, Sample, vec );
|
|
K3DMatrixRotationAxis( mat, va, ffAngle );
|
|
K3DVector Res;
|
|
K3DVectorTransform( Res, Result, mat );
|
|
return Res;
|
|
}
|
|
|
|
void KFXParticleSeq::_CreateParticle( int index, int TimeUnit )
|
|
{
|
|
if( index < 0 || index >= m_nParticleCount ) return;
|
|
|
|
/* K3DMatrix mat;
|
|
m_spRes->GetData( m_dwTime, &m_fVisResult, &mat );
|
|
|
|
if ( m_pMatParent )
|
|
K3DMatrixMultiply( &m_matTransform, &mat, m_pMatParent );
|
|
else
|
|
m_matTransform = mat;*/
|
|
|
|
m_spRes->GetData( m_dwTime, &m_fVisResult, &m_matTransform );
|
|
|
|
// calc radius
|
|
const K3DVertex *pV = m_spRes->GetVertices();
|
|
K3DVector transVtx[4];
|
|
int i;
|
|
for( i=0 ; i < 4 ; ++i )
|
|
{
|
|
K3DVectorTransform( transVtx[i], pV[i], m_matTransform );
|
|
}
|
|
K3DVector vRadius = transVtx[0] - transVtx[1];
|
|
m_fRadius = K3DVectorLength( vRadius );
|
|
|
|
//K3DMatrixGetZVector( m_vecVector, m_matTransform );
|
|
K3DVectorTransformNormal( m_vecVector, m_spRes->GetNormal(), m_matTransform );
|
|
Normalize( m_vecVector );
|
|
|
|
m_vecVelocity = m_spRes->GetVelocity();
|
|
|
|
KFXParticleObject *ptc = m_ppParticles[index];
|
|
K3DVector pos;
|
|
K3DMatrixGetPosVector( pos, m_matTransform );
|
|
K3DVector vVec = K3DVectorGetRandom( m_vecVector, m_spRes->GetSpreadAngle() );
|
|
K3DVector vBeginSpeed = m_spRes->GetBeginSpeed();
|
|
vVec *= _GetRandom( vBeginSpeed.x, vBeginSpeed.y );
|
|
int nLifeTime = m_spRes->GetLifeTime() + (rand() % (m_spRes->GetLifeTimeVariation() - m_spRes->GetLifeTime()));
|
|
ptc->Init( m_pMatParent, m_spRes, m_fRadius, nLifeTime, m_dwMyTime, pos, vVec, m_vecVelocity );
|
|
}
|
|
|
|
|
|
void KFXParticleSeq::_Initialize()
|
|
{
|
|
_ClearObject();
|
|
if ( m_spRes )
|
|
{
|
|
m_nParticleCount = (m_spRes->GetLifeTime() + m_spRes->GetLifeTimeVariation()) / m_spRes->GetCreateTime();
|
|
m_prParticle.SetParticleCount( m_nParticleCount );
|
|
_GenerateObject();
|
|
m_bInited = true;
|
|
}
|
|
}
|
|
|
|
float KFXParticleSeq::_GetRandom( float min, float variation )
|
|
{
|
|
float Result;
|
|
if( variation == 0.f ) return min;
|
|
Result = min + ( rand() % (int)(variation) );
|
|
return Result;
|
|
}
|
|
|
|
void KFXParticleSeq::_GenerateObject()
|
|
{
|
|
assert( m_nParticleCount && "Particle Zero Count" );
|
|
|
|
if( !m_nParticleCount ) return;
|
|
|
|
switch(m_dwParticleType)
|
|
{
|
|
case KPARTICLE_DEFAULT:
|
|
{
|
|
m_ppParticles = new KFXParticleObject*[m_nParticleCount];
|
|
for(int i = 0; i < m_nParticleCount; ++i)
|
|
{
|
|
m_ppParticles[i] = new KFXParticleObject;
|
|
}
|
|
break;
|
|
}
|
|
case KPARTICLE_GRAVITY:
|
|
{
|
|
m_ppParticles = reinterpret_cast<KFXParticleObject **>( new KFXGravityParticleObject*[m_nParticleCount] );
|
|
for(int i = 0; i < m_nParticleCount; ++i)
|
|
{
|
|
m_ppParticles[i] = new KFXGravityParticleObject;
|
|
}
|
|
break;
|
|
}
|
|
case KPARTICLE_REVERSE:
|
|
{
|
|
m_ppParticles = reinterpret_cast<KFXParticleObject **>( new KFXReverseParticleObject*[m_nParticleCount] );
|
|
for(int i = 0; i < m_nParticleCount; ++i)
|
|
{
|
|
m_ppParticles[i] = new KFXReverseParticleObject;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
assert(false && "Invalid Particle Type");
|
|
}
|
|
|
|
}
|
|
}
|
|
void KFXParticleSeq::_ClearObject()
|
|
{
|
|
if ( m_ppParticles )
|
|
{
|
|
for(int i = 0 ; i < m_nParticleCount; ++i)
|
|
SAFE_DELETE(m_ppParticles[i]);
|
|
|
|
SAFE_DELETE_ARRAY(m_ppParticles);
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KFXAferImagerSeq Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
namespace
|
|
{
|
|
const int FRAME_PER_VTX = 1;
|
|
const int SPLINE_ARGUMENT = 4;
|
|
}
|
|
|
|
KFXAfterImageSeq::KFXAfterImageSeq()
|
|
{
|
|
m_bOldValidate = false;
|
|
m_pMatLerp = NULL;
|
|
|
|
m_dwVertexCount = 0;
|
|
m_dwLastSplinePushCount = 0;
|
|
m_dwLastNormalLineCount = 0;
|
|
m_pVertexListOne = m_pVertexListTwo = NULL;
|
|
|
|
K3DMatrixIdentity( m_matOld );
|
|
K3DMatrixIdentity( m_matRoot );
|
|
K3DMatrixIdentity( m_matLocal );
|
|
}
|
|
|
|
KFXAfterImageSeq::~KFXAfterImageSeq()
|
|
{
|
|
SAFE_DELETE_ARRAY(m_pMatLerp);
|
|
SAFE_DELETE_ARRAY(m_pVertexListOne);
|
|
SAFE_DELETE_ARRAY(m_pVertexListTwo);
|
|
}
|
|
|
|
KSeqObject *KFXAfterImageSeq::Clone()
|
|
{
|
|
KFXAfterImageSeq *obj = new KFXAfterImageSeq;
|
|
obj->SetRes( m_spRes );
|
|
return obj;
|
|
}
|
|
|
|
void KFXAfterImageSeq::SetRes( KResFXAfterImage *pRes )
|
|
{
|
|
assert(m_spRes == NULL);
|
|
m_spRes = pRes;
|
|
|
|
if(m_spRes != NULL)
|
|
{
|
|
m_interval = m_spRes->GetInterval();
|
|
|
|
// 한 Frame당 4개씩 Spline 보간
|
|
m_prAfterImage.Initialize(m_spRes->GetFrameNumber() * FRAME_PER_VTX );
|
|
m_prAfterImage.SetTexture(m_spRes->GetTexture());
|
|
|
|
m_pMatLerp = new K3DMatrix[ max( m_spRes->GetFrameNumber(), FRAME_PER_VTX ) ];
|
|
|
|
// Catmull-rom Spline을 위한 Vertex
|
|
m_pVertexListOne = new K3DVertex[m_spRes->GetFrameNumber()];
|
|
m_pVertexListTwo = new K3DVertex[m_spRes->GetFrameNumber()];
|
|
|
|
m_prAfterImage.SetBlendMode( m_spRes->GetBlendMode() );
|
|
}
|
|
}
|
|
|
|
void KFXAfterImageSeq::Render( KViewportObject *pViewport, DWORD flag, const K3DMatrix * pAttachMat )
|
|
{
|
|
realizeTime();
|
|
|
|
float vis = m_fMasterVisibility * m_fVisResult;
|
|
if( vis <= 0.f )
|
|
return;
|
|
|
|
if ( m_pMatAttach != NULL && m_pMatParent != NULL )
|
|
{
|
|
m_matRoot = *m_pMatParent;
|
|
m_matLocal = *m_pMatAttach;
|
|
|
|
K3DMatrix matResult;
|
|
K3DMatrixMultiply( matResult, *m_pMatAttach, *m_pMatParent );
|
|
m_prAfterImage.SetRootMat( &matResult );
|
|
m_prAfterImage.SetCenterPosition( K3DVector( matResult._41, matResult._42, matResult._43 ) );
|
|
}
|
|
else if ( m_pMatParent != NULL )
|
|
{
|
|
m_matRoot = *m_pMatParent;
|
|
m_prAfterImage.SetRootMat( &m_matRoot );
|
|
m_prAfterImage.SetCenterPosition( K3DVector( m_matRoot._41, m_matRoot._42, m_matRoot._43 ) );
|
|
}
|
|
|
|
m_prAfterImage.SetVisibility( vis );
|
|
|
|
pViewport->Register(&m_prAfterImage, KRenderObject::RENDEREFX_NONE );
|
|
}
|
|
|
|
void* KFXAfterImageSeq::Perform( int id, KArg& msg)
|
|
{
|
|
_CID( AFTER_IMAGE_MOVE );
|
|
if ( id == id_AFTER_IMAGE_MOVE )
|
|
{
|
|
KMsgAfterImage_MOVE * pMoveMsg = static_cast<KMsgAfterImage_MOVE*>(&msg);
|
|
this->m_prAfterImage.SetMoveAdded(pMoveMsg->GetMoveAdded() );
|
|
|
|
K3DVertex vPos;
|
|
K3DMatrixGetPosVector(vPos, m_matOld);
|
|
vPos+= pMoveMsg->GetMoveAdded();
|
|
m_matOld.SetPosVector(vPos);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void KFXAfterImageSeq::realizeTime()
|
|
{
|
|
// realize 할 필요 없음 (이미 했으므로)
|
|
if ( m_dwRealizedTime == m_dwTime )
|
|
return;
|
|
|
|
if( m_spRes == NULL)
|
|
return;
|
|
|
|
// Old Matrix값의 초기화
|
|
if( m_bOldValidate == false )
|
|
{
|
|
m_bOldValidate = true;
|
|
|
|
return;
|
|
}
|
|
|
|
int nInterval = static_cast<int>(m_dwTime - m_dwRealizedTime);
|
|
|
|
if(nInterval < 0)
|
|
nInterval += m_interval.GetLength();
|
|
|
|
// 추가될 Spline Frame의 갯수
|
|
int dwAddFrames = min( nInterval / m_spRes->GetFrameTime(), m_spRes->GetFrameNumber() );
|
|
|
|
if( dwAddFrames == 0)
|
|
{
|
|
_PushNormalLine( nInterval );
|
|
return;
|
|
}
|
|
//// Spline을 만들수 없을때는 리턴
|
|
//if( m_dwVertexCount + dwAddFrames < SPLINE_ARGUMENT)
|
|
// return;
|
|
|
|
_MakeLerpMatrix(dwAddFrames, nInterval);
|
|
|
|
// 새로운 vertex를 얻어서 저장. (시간이 늦은 vertex부터 추가하자)
|
|
K3DSPRITEVERTEX vtx0, vtx1;
|
|
for(int i = dwAddFrames - 1; i >= 0; --i)
|
|
{
|
|
int nTime = static_cast<int>( m_dwTime - (i * m_spRes->GetFrameTime()) );
|
|
|
|
// 시간이 한번 loop 를 돈 경우
|
|
if(nTime < 0)
|
|
nTime += m_interval.GetLength();
|
|
|
|
m_spRes->GetData(nTime, vtx0, vtx1, m_pMatLerp[i], m_fVisResult);
|
|
|
|
DWORD dwIndex = m_dwVertexCount % (m_spRes->GetFrameNumber());
|
|
m_pVertexListOne[dwIndex] = vtx0.pos;
|
|
m_pVertexListTwo[dwIndex] = vtx1.pos;
|
|
m_dwVertexCount++;
|
|
}
|
|
|
|
// Spline을 만들수 없을때는 리턴
|
|
if( m_dwVertexCount + dwAddFrames < SPLINE_ARGUMENT)
|
|
return;
|
|
|
|
// Spline 생성
|
|
_PushSpline( dwAddFrames);
|
|
|
|
// 새로운 vertex가 추가 되었던 시간을 기록한다.
|
|
m_dwRealizedTime = m_dwTime;
|
|
}
|
|
|
|
void KFXAfterImageSeq::_MakeLerpMatrix(DWORD dwAddFrames, int nInterval)
|
|
{
|
|
// i 가 작은 값이 current time 가깝고, i 가 커질수록 old time에 근접한다.
|
|
for(unsigned int i = 0; i < dwAddFrames; ++i)
|
|
{
|
|
K3DMatrixIdentity(m_pMatLerp[i]);
|
|
DWORD dwDiff = abs( nInterval - (int)i * m_spRes->GetFrameTime() );
|
|
float fWeight = static_cast<float>(dwDiff)/ static_cast<float>( nInterval );
|
|
|
|
// 예전에 이동했던 값과 비교해서 matrix 보간
|
|
if ( m_pMatParent != NULL )
|
|
K3DMatrixLerp(m_pMatLerp[i], m_matOld, m_matOld, fWeight);
|
|
}
|
|
}
|
|
|
|
void KFXAfterImageSeq::_PushNormalLine(int nInterval)
|
|
{
|
|
// 추가될 Spline Frame의 갯수
|
|
DWORD dwFrameTime = m_spRes->GetFrameTime() / FRAME_PER_VTX;
|
|
|
|
if(dwFrameTime <= 0)
|
|
return;
|
|
|
|
DWORD dwAddFrames = min( (DWORD)nInterval / dwFrameTime, (DWORD)FRAME_PER_VTX );
|
|
|
|
if( dwAddFrames == 0)
|
|
return;
|
|
|
|
m_prAfterImage.PopVertex( m_dwLastNormalLineCount);
|
|
|
|
m_dwLastNormalLineCount = dwAddFrames;
|
|
_MakeLerpMatrix(dwAddFrames, nInterval);
|
|
|
|
m_prAfterImage.ReserveVtx( dwAddFrames );
|
|
K3DSPRITEVERTEX vtx0, vtx1;
|
|
for(int i = dwAddFrames - 1; i >= 0; --i)
|
|
{
|
|
int nTime = static_cast<int>( m_dwTime - (i * dwFrameTime) );
|
|
|
|
// 시간이 한번 loop 를 돈 경우
|
|
if(nTime < 0)
|
|
nTime += m_interval.GetLength();
|
|
|
|
m_spRes->GetData(nTime, vtx0, vtx1, m_pMatLerp[i], m_fVisResult);
|
|
m_prAfterImage.PushVertex( vtx0, vtx1);
|
|
}
|
|
|
|
m_prAfterImage.UpdateVertex();
|
|
}
|
|
|
|
void KFXAfterImageSeq::_PushSpline(DWORD dwAddFrames)
|
|
{
|
|
m_prAfterImage.PopVertex( m_dwLastSplinePushCount + m_dwLastNormalLineCount);
|
|
m_dwLastSplinePushCount = 0;
|
|
m_dwLastNormalLineCount = 0;
|
|
|
|
DWORD dwMaxFrameNumber = m_spRes->GetFrameNumber();
|
|
DWORD dwOldVertexCount = m_dwVertexCount - dwAddFrames;
|
|
const float fScaleLargeUnit = 1.f / (float)FRAME_PER_VTX;
|
|
|
|
DWORD dwOffset = 0;
|
|
|
|
if( dwMaxFrameNumber < dwAddFrames + SPLINE_ARGUMENT)
|
|
dwOffset = SPLINE_ARGUMENT -1 - dwMaxFrameNumber + dwAddFrames;
|
|
// 예전에 저장된 Frame의 Vertex count가 Spline Argument를 만족하지 못함.
|
|
if( dwOldVertexCount < SPLINE_ARGUMENT)
|
|
dwOffset = SPLINE_ARGUMENT -1 - dwOldVertexCount;
|
|
|
|
//dwAddFrames -= dwOffset;
|
|
if( dwAddFrames >= dwOffset )
|
|
dwAddFrames -= dwOffset;
|
|
else
|
|
return;
|
|
|
|
DWORD dwIndexList[SPLINE_ARGUMENT];
|
|
|
|
// 더해지는 Frame 만큼 Spline 생성
|
|
K3DSPRITEVERTEX vtx0, vtx1;
|
|
|
|
m_dwLastSplinePushCount = FRAME_PER_VTX + 1;
|
|
m_prAfterImage.ReserveVtx( dwAddFrames * FRAME_PER_VTX + m_dwLastSplinePushCount );
|
|
|
|
for(unsigned int i = 0; i < dwAddFrames; ++i)
|
|
{
|
|
// 가장 최근 Frame은 Index 값이 낮음.
|
|
for(DWORD m = 0; m < SPLINE_ARGUMENT; ++m)
|
|
dwIndexList[m] = (dwOldVertexCount + i + dwOffset - m) % dwMaxFrameNumber;
|
|
|
|
// Frame 별로 넣어주자.
|
|
for(DWORD k = 0; k < FRAME_PER_VTX; ++k)
|
|
{
|
|
K3DVectorCatMullRom(vtx0.pos, m_pVertexListOne[dwIndexList[3] ],
|
|
m_pVertexListOne[dwIndexList[2] ], m_pVertexListOne[dwIndexList[1] ],
|
|
m_pVertexListOne[dwIndexList[0] ], fScaleLargeUnit * k);
|
|
|
|
K3DVectorCatMullRom(vtx1.pos, m_pVertexListTwo[dwIndexList[3] ],
|
|
m_pVertexListTwo[dwIndexList[2] ], m_pVertexListTwo[dwIndexList[1] ],
|
|
m_pVertexListTwo[dwIndexList[0] ], fScaleLargeUnit * k);
|
|
|
|
m_prAfterImage.PushVertex(vtx0, vtx1);
|
|
}
|
|
}
|
|
|
|
// 마지막 연결부위 (이 부분은 넣었다 뺐다 한다)
|
|
for(DWORD m = 0; m < SPLINE_ARGUMENT; ++m)
|
|
dwIndexList[m] = (m_dwVertexCount - 1 - m) % dwMaxFrameNumber;
|
|
|
|
for(DWORD k = 0; k < m_dwLastSplinePushCount; ++k)
|
|
{
|
|
K3DVectorCatMullRom(vtx0.pos, m_pVertexListOne[dwIndexList[2] ],
|
|
m_pVertexListOne[dwIndexList[1] ], m_pVertexListOne[dwIndexList[0] ],
|
|
m_pVertexListOne[dwIndexList[0] ], fScaleLargeUnit * k);
|
|
|
|
K3DVectorCatMullRom(vtx1.pos, m_pVertexListTwo[dwIndexList[2] ],
|
|
m_pVertexListTwo[dwIndexList[1] ], m_pVertexListTwo[dwIndexList[0] ],
|
|
m_pVertexListTwo[dwIndexList[0] ], fScaleLargeUnit * k);
|
|
|
|
m_prAfterImage.PushVertex(vtx0, vtx1);
|
|
}
|
|
|
|
m_prAfterImage.UpdateVertex();
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KSeqTextureRender Implement
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
KSeqTextureRender::KSeqTextureRender()
|
|
{
|
|
m_bSourceRenderFlag =true;
|
|
m_pSeqSource = NULL;
|
|
m_pRenderTarget = NULL;
|
|
m_pCamera = NULL;
|
|
m_sizeTarget = KSize( 256, 256 );
|
|
m_formatTarget = K3DFMT_A8R8G8B8;
|
|
m_pViewport = NULL;
|
|
|
|
// Default Render Freq is 60frame.
|
|
SetRenderFreq(KSEQ_RENDER_60);
|
|
m_dwTime = 0;
|
|
K3DMatrixIdentity(m_matLocal);
|
|
}
|
|
|
|
KSeqTextureRender::~KSeqTextureRender()
|
|
{
|
|
m_vtUserLight.clear();
|
|
SAFE_DELETE(m_pViewport);
|
|
SAFE_DELETE(m_pSeqSource);
|
|
}
|
|
|
|
void KSeqTextureRender::Initialize( KSeqObject *src, const KSize &targetSize, const K3DFORMAT &texformat)
|
|
{
|
|
m_sizeTarget = targetSize;
|
|
m_formatTarget = texformat;
|
|
m_pSeqSource = src;
|
|
|
|
KViewportStruct vp;
|
|
vp.Width = targetSize.cx;
|
|
vp.Height = targetSize.cy;
|
|
vp.X = vp.Y = 0;
|
|
vp.MinZ = 0;
|
|
vp.MaxZ = 1.0f;
|
|
m_pViewport = new KViewportObject(KViewportObject::VIEWPORT_GAME, true, true);
|
|
m_pViewport->Initilaize( KDeviceManager::GetDeviceManager()->GetRenderDevice(), vp, 1, 50000 );
|
|
m_pViewport->SetFillColor( K3DColor(0,0,0) );
|
|
m_pViewport->SetSceneAmbient( KColor( 250, 250, 250, 255 ) );
|
|
m_interval = m_pSeqSource->GetInterval();
|
|
|
|
KResSprite * pResSprite = new KResSprite;
|
|
//m_pRenderTarget = KDeviceManager::GetDeviceManager()->GetRenderDevice()->CreateRenderTarget( targetSize.cx, targetSize.cy, 1, m_formatTarget, true );
|
|
m_pRenderTarget = KDeviceManager::GetDeviceManager()->GetRenderDevice()->CreateRenderTarget( targetSize.cx, targetSize.cy, 1, m_formatTarget, K3DRenderTarget::DEPTH_ENABLE );
|
|
pResSprite->SetTexture(m_pRenderTarget,NULL);
|
|
m_prSprite.SetRes(pResSprite);
|
|
m_prSprite.SetTargetSize((float)m_sizeTarget.cx,(float)m_sizeTarget.cy);
|
|
}
|
|
|
|
void KSeqTextureRender::SetUserCamera( K3DCamera *pCam )
|
|
{
|
|
m_bSourceRenderFlag = true;
|
|
m_pCamera = pCam;
|
|
}
|
|
void KSeqTextureRender::AddUserLight(K3DLight * pLight)
|
|
{
|
|
m_bSourceRenderFlag = true;
|
|
m_vtUserLight.push_back(pLight);
|
|
}
|
|
void KSeqTextureRender::SetRenderFreq(DWORD dwRenderFreq)
|
|
{
|
|
switch(dwRenderFreq)
|
|
{
|
|
case KSEQ_RENDER_ALL:
|
|
m_dwRenderFrameTime = 1;
|
|
break;
|
|
case KSEQ_RENDER_60:
|
|
m_dwRenderFrameTime = 1000 / 60;
|
|
break;
|
|
case KSEQ_RENDER_30:
|
|
m_dwRenderFrameTime = 1000 / 30;
|
|
break;
|
|
case KSEQ_RENDER_ONCE:
|
|
m_dwRenderFrameTime = 0;
|
|
break;
|
|
default:
|
|
{
|
|
assert(false && "Render Freq Argument is false");
|
|
}
|
|
}
|
|
}
|
|
|
|
void KSeqTextureRender::SetAddictive(bool bUseAddictive)
|
|
{
|
|
m_prSprite.SetAdditiveRenderMode(bUseAddictive);
|
|
}
|
|
|
|
void KSeqTextureRender::Render( KViewportObject *viewport, DWORD flag, const K3DMatrix * pAttachMat )
|
|
{
|
|
realizeTime();
|
|
if(m_pRenderTarget == NULL)
|
|
return;
|
|
|
|
if ( m_pMatParent != NULL )
|
|
K3DMatrixMultiply( m_matResult, m_matLocal, *m_pMatParent );
|
|
else
|
|
m_matResult = m_matLocal;
|
|
|
|
m_prSprite.SetTransform( m_matResult );
|
|
m_prSprite.SetVisibility( m_fMasterVisibility );
|
|
|
|
if(!m_bSourceRenderFlag)
|
|
{
|
|
viewport->Register( &m_prSprite);
|
|
return;
|
|
}
|
|
|
|
m_pViewport->SetFillColor( KColor(0,0,0,0) );
|
|
|
|
if ( m_pCamera == NULL)
|
|
{
|
|
{ assert(false && "Must Set Camera!"); }
|
|
}
|
|
|
|
//m_pCamera->Render( m_pViewport );
|
|
m_pViewport->SetCamera(m_pCamera);
|
|
for(int i = 0; i < (int)m_vtUserLight.size(); ++i)
|
|
{
|
|
m_pViewport->AddLight(m_vtUserLight.at(i) );
|
|
}
|
|
|
|
m_pSeqSource->Render( m_pViewport );
|
|
m_pViewport->Render( m_pRenderTarget );
|
|
viewport->Register( &m_prSprite);
|
|
|
|
m_bSourceRenderFlag = false;
|
|
|
|
}
|
|
|
|
|
|
KSeqObject* KSeqTextureRender::Clone()
|
|
{
|
|
KSeqTextureRender *obj = new KSeqTextureRender;
|
|
obj->Initialize( m_pSeqSource, m_sizeTarget,m_formatTarget );
|
|
return obj;
|
|
}
|
|
|
|
void KSeqTextureRender::realizeTime()
|
|
{
|
|
|
|
if ( m_dwRealizedTime == m_dwTime || m_dwRenderFrameTime == 0 || m_dwTime - m_dwRealizedTime < m_dwRenderFrameTime )
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_bSourceRenderFlag = true;
|
|
m_dwRealizedTime = m_dwTime;
|
|
if ( m_pSeqSource != NULL )
|
|
{
|
|
m_pSeqSource->SetTime( m_dwRealizedTime );
|
|
m_pSeqSource->realizeTime();
|
|
}
|
|
}
|