1813 lines
49 KiB
C++
1813 lines
49 KiB
C++
#include "stdafx.h"
|
||
#include "KRenderDefine.h"
|
||
#include "krenderobjectMesh.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"
|
||
|
||
#include "k3dpccp.h"
|
||
|
||
#include "KRenderObjectBone.h"
|
||
#include <toolkit/SafeTickCount.h>
|
||
|
||
namespace {
|
||
DWORD interpolateColor(DWORD color0, DWORD color1, float div)
|
||
// return = color1*div + color0*(1-div)
|
||
{
|
||
float a0,r0,g0,b0;
|
||
float a1,r1,g1,b1;
|
||
float invdiv=1.f-div;
|
||
|
||
a0=(float)((color0>>24)&0xff);
|
||
r0=(float)((color0>>16)&0xff);
|
||
g0=(float)((color0>>8)&0xff);
|
||
b0=(float)(color0&0xff);
|
||
|
||
a1=(float)((color1>>24)&0xff);
|
||
r1=(float)((color1>>16)&0xff);
|
||
g1=(float)((color1>>8)&0xff);
|
||
b1=(float)(color1&0xff);
|
||
|
||
DWORD a, r, g, b;
|
||
a = (DWORD)(a0*invdiv + a1*div);
|
||
r = (DWORD)(r0*invdiv + r1*div);
|
||
g = (DWORD)(g0*invdiv + g1*div);
|
||
b = (DWORD)(b0*invdiv + b1*div);
|
||
|
||
if (a>0xff) a=0xff;
|
||
if (r>0xff) r=0xff;
|
||
if (g>0xff) g=0xff;
|
||
if (b>0xff) b=0xff;
|
||
|
||
return (a<<24) | (r<<16) | (g<<8) | b;
|
||
}
|
||
|
||
const short KEEP_TIME_WINK = 50;
|
||
const int OLDMORPH_MESH_CHCKTIME = 1000;
|
||
const int EFFECT_LIFE_TIME = 1000.f;
|
||
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
// KMeshSeqObject Implement
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
bool KMeshSeqObject::m_sVisbleCube = false;
|
||
|
||
|
||
KMeshSeqObject::KMeshSeqObject()
|
||
{
|
||
K3DMatrixIdentity(m_matLocal);
|
||
K3DMatrixIdentity(m_matRoot);
|
||
K3DMatrixIdentity(m_matResult);
|
||
K3DMatrixIdentity(m_matUV);
|
||
|
||
m_pAlterMtl = NULL;
|
||
m_dwColors[0] = m_dwColors[1] = m_dwColors[2] = m_dwColors[3] = 0;
|
||
m_fVisResult = 1.0f;
|
||
|
||
m_nBoneMatCount = 0;
|
||
m_pBoneMatList = NULL;
|
||
|
||
m_nPrMeshCount = 0;
|
||
m_pPrMesh = NULL;
|
||
|
||
m_bForceTransparent = false;
|
||
m_bIsMakeBoundCube = false;
|
||
|
||
numFrames=0;
|
||
|
||
m_bUseTextureAlpha = true;
|
||
|
||
m_nMorphPrimitiveCount = 0;
|
||
|
||
_morphInit();
|
||
|
||
checkTime = 0;
|
||
previousTime = 0;
|
||
|
||
m_bUseWink = false;
|
||
m_bFlipWink = false;
|
||
m_spWinkTexture = NULL;
|
||
|
||
m_bUseDefaultTexture = true; // sonador 1.8.10 아바타 텍스쳐 그룹 적용(페이스 컷 포함)
|
||
|
||
//#ifndef NDEBUG
|
||
// _oprint( "KMeshSeqObject !! 0x%08X\n", &m_prMesh );
|
||
//#endif
|
||
}
|
||
|
||
KMeshSeqObject::~KMeshSeqObject()
|
||
{
|
||
_oldmorphClear();
|
||
|
||
if( !morph_primitivelist.empty() )
|
||
{
|
||
for( unsigned int i(0); morph_primitivelist.size()>i; i++ )
|
||
{
|
||
delete [] morph_primitivelist[i];
|
||
}
|
||
morph_primitivelist.clear();
|
||
}
|
||
|
||
SAFE_DELETE_VECTOR(m_vCacheKeyList);
|
||
delete[] m_pPrMesh;
|
||
}
|
||
|
||
void KMeshSeqObject::SetMeshRes( K3DMeshResource *pMesh )
|
||
{
|
||
assert( m_spResMesh == NULL );
|
||
|
||
if(m_pPrMesh != NULL)
|
||
{
|
||
delete[] m_pPrMesh;
|
||
m_pPrMesh = NULL;
|
||
}
|
||
|
||
m_spResMesh = pMesh;
|
||
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
m_interval.Expand( m_spResMesh->GetInterval() );
|
||
m_nPrMeshCount = m_spResMesh->GetResCount();
|
||
m_pPrMesh = new KMeshPrimitive[m_nPrMeshCount];
|
||
|
||
for(int i = 0; i < m_nPrMeshCount; ++i)
|
||
{
|
||
K3DResVertexAnimation* pVA = m_spResMesh->GetRes( i );
|
||
m_pPrMesh[i].SetIndexBuffer( pVA->GetIndexBuffer() );
|
||
m_pPrMesh[i].SetPrimitivesCount( pVA->GetPrimitiveCount() );
|
||
m_pPrMesh[i].SetTexture( pVA->GetTexturePack() );
|
||
m_pPrMesh[i].SetBlendMode( pVA->GetBlendMode() );
|
||
m_pPrMesh[i].SetMaterial( pVA->GetMaterial() );
|
||
|
||
if( m_spResMesh->GetWeightResCount() > 0 )
|
||
{
|
||
K3DWeight* pWeight = m_spResMesh->GetWeightRes(i);
|
||
m_pPrMesh[i].SetWeight( pWeight );
|
||
m_pPrMesh[i].SetVSMode( true );
|
||
}
|
||
|
||
// m_pPrMesh[i].SetBoundOcclusion( &m_boundOcclusion );
|
||
}
|
||
|
||
m_boundSphere = m_spResMesh->GetBoundSphere();
|
||
m_boundCube = m_spResMesh->GetBoundCube();
|
||
}
|
||
}
|
||
|
||
bool ExistCheckVector( std::vector<const char*> & vList, K3DTexture * pTex )
|
||
{
|
||
std::vector<const char*>::iterator it = vList.begin();
|
||
for(; it != vList.end(); it++)
|
||
{
|
||
if( _stricmp( (*it), pTex->GetName() ) == 0 )
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
K3DBoundRotCube * KMeshSeqObject::GetCube()
|
||
{
|
||
//TODO : 고쳐야 하는 부분 임.
|
||
#ifdef _RAC //게임에서만 적용
|
||
m_boundCube.SetTransform(m_matResult);
|
||
#endif
|
||
|
||
return &m_boundCube;
|
||
}
|
||
|
||
K3DBoundSphere* KMeshSeqObject::GetSphere()
|
||
{
|
||
//TODO : 고쳐야 하는 부분 임.
|
||
#ifdef _RAC //게임에서만 적용
|
||
m_boundSphere.SetTransform(m_matResult);
|
||
#endif
|
||
|
||
return &m_boundSphere;
|
||
}
|
||
|
||
template< typename T > static inline T _min( const T& a, const T& b ) { return a < b ? a : b; }
|
||
template< typename T > static inline T _max( const T& a, const T& b ) { return a > b ? a : b; }
|
||
|
||
static inline void K3DVectorMultiply( K3DVector& out, const K3DMatrix& TM, const K3DVector& in )
|
||
{
|
||
out.x = (TM.m00*in.x) + (TM.m10*in.y) + (TM.m20*in.z) + TM.m30;
|
||
out.y = (TM.m01*in.x) + (TM.m11*in.y) + (TM.m21*in.z) + TM.m31;
|
||
out.z = (TM.m02*in.x) + (TM.m12*in.y) + (TM.m22*in.z) + TM.m32;
|
||
}
|
||
|
||
void KMeshSeqObject::_makeBoundCube( KBoneSeqObject * pBoneSeq )
|
||
{
|
||
K3DMatrix iden;
|
||
K3DMatrixIdentity(iden);
|
||
K3DBoundRotCube cube, t_cube;
|
||
|
||
for ( int n=0 ; n<m_spResMesh->GetResCount(); ++n )
|
||
{
|
||
bool bFirst = true;
|
||
K3DVector cube_min(1000,1000,1000), cube_max(-1000,-1000,-1000);
|
||
|
||
K3DResVertexAnimation *va = m_spResMesh->GetRes(n);
|
||
|
||
K3DResVertexAnimation::Key *key1 = NULL, *key2 = NULL;
|
||
va->GetData( m_dwTime, key1, key2 );
|
||
|
||
if( key1 == NULL || !key1->m_spVB->IsValidVtx() ) continue;
|
||
|
||
DWORD dwVtxCount = key1->m_spVB->GetVertexCount();
|
||
DWORD dwVtxFormat = key1->m_spVB->GetVertexFormat();
|
||
DWORD dwVtxStride = key1->m_spVB->GetVertexStride();
|
||
|
||
// K3DFVF_XYZ | K3DFVF_NORMAL 은 항상 존재
|
||
char *pTempBuf = NULL;
|
||
int size = dwVtxCount; //Size 사용 안함.
|
||
key1->m_spVB->Lock( (void**)&pTempBuf, size );
|
||
if( pTempBuf == NULL ) continue;
|
||
|
||
K3DWeight* pWeight = m_spResMesh->GetWeightRes(n);
|
||
K3DMatrix * pMeshNodeTM = m_spResMesh->GetNodeTM(n);
|
||
|
||
//한곳에 모음
|
||
K3DVector * pOutVtx = new K3DVector[size];
|
||
for( int i(0); size>i; ++i )
|
||
pOutVtx[i] = K3DVector(0,0,0);
|
||
|
||
struct BONE_INDEX
|
||
{
|
||
K3DBone * pBone;
|
||
const char * pBoneName;
|
||
int nBoneIndex;
|
||
|
||
BONE_INDEX()
|
||
{
|
||
pBone = NULL;
|
||
pBoneName = NULL;
|
||
nBoneIndex = -1;
|
||
}
|
||
};
|
||
|
||
std::vector< BONE_INDEX > cache_list;
|
||
|
||
if( pWeight )
|
||
{
|
||
//pWeight->m_nTotal는 뼈수와 같다.
|
||
for( int j(0); pWeight->m_nTotal>j; ++j )
|
||
{
|
||
for( int k(0); pWeight[j].m_nWeight>k; ++k )
|
||
{
|
||
K3DMatrix * pBoneList = (pBoneSeq) ? pBoneSeq->GetBoneCacheTM() : NULL;
|
||
K3DBone * pBone = NULL;
|
||
K3DMeshTM * pMeshTM = NULL;
|
||
|
||
for( unsigned int i(0); cache_list.size()>i; ++i )
|
||
{
|
||
if( !::_strnicmp( cache_list[i].pBoneName, pWeight[j].m_szBoneName, strlen(pWeight[j].m_szBoneName) ) )
|
||
{
|
||
pBone = cache_list[i].pBone;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if( pBone == NULL )
|
||
{
|
||
if( pBoneSeq )
|
||
{
|
||
BONE_INDEX bone_index;
|
||
pBone = pBoneSeq->GetBone( pWeight[j].m_szBoneName, bone_index.nBoneIndex );
|
||
bone_index.pBone = pBone;
|
||
bone_index.pBoneName = pWeight[j].m_szBoneName;
|
||
|
||
cache_list.push_back( bone_index );
|
||
}
|
||
}
|
||
|
||
pMeshTM = m_spResMesh->GetMeshTM( pWeight[j].m_szBoneName );
|
||
|
||
if( pBone == NULL || pMeshTM == NULL ) continue;
|
||
|
||
int nVertexIndex = (int)pWeight[j].m_pVertexIndex[k]; //버텍스를 찾고
|
||
float fWeight = pWeight[j].m_pVertexWeight[k]; //가중치를 적용
|
||
// K3DVector OffSetVtx = pWeight[j].m_pOffsetVector[k]; //OffSet Vector;
|
||
|
||
assert(nVertexIndex <= static_cast<int>(dwVtxCount));
|
||
|
||
//Local 버텍스 임.
|
||
K3DVector *vtx = (K3DVector*)(&pTempBuf[nVertexIndex*dwVtxStride]);
|
||
|
||
K3DVector *Outvtx = &pOutVtx[nVertexIndex];
|
||
|
||
K3DVector baseVtx, vec;
|
||
baseVtx = K3DVector(0,0,0);
|
||
vec = K3DVector(0,0,0);
|
||
|
||
K3DMatrix smat;
|
||
K3DMatrixIdentity(smat);
|
||
|
||
K3DMatrixMultiply( smat, pMeshTM->mTM, *pBone->GetCacheTM() );
|
||
K3DVectorMultiply( vec, smat, *vtx );
|
||
K3DVectorScale( vec, vec, fWeight );
|
||
K3DVectorAdd( *Outvtx, *Outvtx, vec );
|
||
|
||
if( bFirst )
|
||
{
|
||
cube_min = K3DVector(Outvtx->x, Outvtx->y, Outvtx->z);
|
||
cube_max = K3DVector(Outvtx->x, Outvtx->y, Outvtx->z);
|
||
bFirst = false;
|
||
}
|
||
|
||
// make axis aligned cube
|
||
cube_min.x = _min(cube_min.x , Outvtx->x);
|
||
cube_min.y = _min(cube_min.y , Outvtx->y);
|
||
cube_min.z = _min(cube_min.z , Outvtx->z);
|
||
cube_max.x = _max(cube_max.x , Outvtx->x);
|
||
cube_max.y = _max(cube_max.y , Outvtx->y);
|
||
cube_max.z = _max(cube_max.z , Outvtx->z);
|
||
}
|
||
}
|
||
|
||
t_cube = K3DBoundRotCube( cube_min.x, cube_max.x, cube_min.y, cube_max.y, cube_min.z, cube_max.z );
|
||
t_cube.SetTransform(iden);
|
||
if( n==0 )
|
||
cube = t_cube;
|
||
else
|
||
cube.AddCube(t_cube);
|
||
}
|
||
|
||
delete [] pOutVtx;
|
||
key1->m_spVB->Unlock();
|
||
|
||
m_boundCube = cube;
|
||
}
|
||
}
|
||
|
||
void StringFormat( std::string & str, const char *fmt, ... )
|
||
{
|
||
char p[1024];
|
||
va_list ap;
|
||
va_start(ap, fmt);
|
||
_vsnprintf(p, 1024, fmt, ap);
|
||
va_end(ap);
|
||
str = p;
|
||
}
|
||
|
||
void GetTexInfo( K3DTexture* pTex, std::string& strInfo )
|
||
{
|
||
if( pTex )
|
||
{
|
||
StringFormat( strInfo, "|Fmt:%d Size:(%d %d) Mip:%d|", pTex->GetFormat(), pTex->GetWidth(), pTex->GetHeight(), pTex->GetMipsLevels() );
|
||
}
|
||
}
|
||
|
||
void *KMeshSeqObject::Perform( KID id, KArg& msg )
|
||
{
|
||
_CID( SETDEFORM_BONE );
|
||
_CID( GETMESH_ANIINFO );
|
||
_CID( GETMESH_NAME );
|
||
_CID( GETMESH_INFO );
|
||
_CID( CHANGE_MESH_TEXTURE );
|
||
_CID( GETMESH_TRI );
|
||
_CID( GETMESH_VERTEXBUFFERS );
|
||
_CID( GETMESH_INDEXBUFFERS );
|
||
_CID( GETMESH_POLYCOUNT );
|
||
_CID( GETMESH_TEXNAME );
|
||
_CID( SETRENDER_FLAG );
|
||
_CID( SETFORCERENDER_FLAG );
|
||
_CID( REQ_BOUNDBOX );
|
||
_CID( REQ_BOUNDBOXEX );
|
||
_CID( REQ_BOUNDSPHERE );
|
||
_CID( SET_LIGHT_MAP );
|
||
_CID( GET_SEQOBJECT );
|
||
_CID( SET_MORPHMESH );
|
||
_CID( GET_MORPHMESH );
|
||
_CID( SET_FIX_TEXTURE);
|
||
_CID( SET_COLORIZE );
|
||
_CID( SET_USE_TEXALPHA );
|
||
_CID( SET_UV_MODIFY );
|
||
_CID( SET_WINK_TEXTURE );
|
||
_CID( GET_MATRIX );
|
||
_CID( GET_PERFORMANCEINFO );
|
||
_CID( SET_BLENDMODE ); // sonador 4.1.2 아바타 머리카락 알바 버그 재수정(ALPHABLENDTWOPASS)
|
||
|
||
_CID( SET_MTETEX ); //gmpbigsun( 2012_11_30 ) : mte
|
||
|
||
if ( id == id_SETDEFORM_BONE )
|
||
{
|
||
KMsgSET_DEFORM *deform = static_cast<KMsgSET_DEFORM*>(&msg);
|
||
setBone( deform->nBoneCount, deform->pMatBoneList );
|
||
|
||
//같은 화일의 메쉬 그룹 안에 피직이 안 된 것이 존재 할 수 있음.
|
||
//Make Bound
|
||
if( m_spResMesh->GetWeightResCount() != m_spResMesh->GetResCount() )
|
||
{
|
||
_oprint( "Not MakeBoundCube : %s\n", deform->pBoneSeq->GetResourceName() );
|
||
return (void*)0;
|
||
}
|
||
|
||
if( !m_bIsMakeBoundCube )
|
||
{
|
||
_makeBoundCube( deform->pBoneSeq );
|
||
m_bIsMakeBoundCube = true;
|
||
}
|
||
return (void*)1;
|
||
}
|
||
else if ( id == id_GETMESH_ANIINFO )
|
||
{
|
||
KMsgGET_MESHANI_INFO * meshani_info = static_cast<KMsgGET_MESHANI_INFO*>(&msg);
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
// if( _stricmp( meshani_info->strFindName.c_str(), m_spResMesh->GetName() ) == 0 )
|
||
{
|
||
if( meshani_info->nStart < m_spResMesh->GetInterval().GetStart() )
|
||
meshani_info->nStart = m_spResMesh->GetInterval().GetStart();
|
||
|
||
if( meshani_info->nEnd < m_spResMesh->GetInterval().GetEnd() )
|
||
meshani_info->nEnd = m_spResMesh->GetInterval().GetEnd();
|
||
}
|
||
}
|
||
}
|
||
else if ( id == id_GETMESH_NAME )
|
||
{
|
||
KMsgGET_MESHNAME *meshname = static_cast<KMsgGET_MESHNAME*>(&msg);
|
||
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
for( int i(0); m_spResMesh->GetResCount()>i; i++ )
|
||
{
|
||
meshname->vNameList.push_back( m_spResMesh->GetName() );
|
||
}
|
||
}
|
||
}
|
||
else if( id == id_GETMESH_INFO )
|
||
{
|
||
KMsgGET_MESHINFO* meshinfo = static_cast<KMsgGET_MESHINFO*>(&msg);
|
||
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
if( m_spResMesh->GetResCount() > 0 )
|
||
{
|
||
KMsgGET_MESHINFO::MESH_INFO mesh;
|
||
mesh.szMeshName = m_spResMesh->GetName();
|
||
|
||
if( m_pPrMesh )
|
||
{
|
||
for( int x = 0; x < m_nPrMeshCount; ++x )
|
||
{
|
||
// sonador #2.2.2.1 프랍 텍스쳐 바리에이션 문제 리포팅 처리
|
||
mesh.vTextureList.push_back( ( m_pPrMesh[x].GetDiffuseTexture() != NULL ? m_pPrMesh[x].GetDiffuseTexture()->GetName() : "" ) );
|
||
}
|
||
}
|
||
|
||
meshinfo->vMeshList.push_back( mesh );
|
||
}
|
||
}
|
||
}
|
||
else if( id == id_CHANGE_MESH_TEXTURE )
|
||
{
|
||
static NX3LoadPack pack;
|
||
pack.Init();
|
||
|
||
KMsgCHANGE_MESH_TEXTURE* mesh_info = static_cast<KMsgCHANGE_MESH_TEXTURE*>(&msg);
|
||
|
||
if(m_spResMesh == NULL ) return (void*)0;
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
// 아이템 텍스쳐 변경 관련
|
||
if (mesh_info->bForceChange)
|
||
{
|
||
if( ( m_nPrMeshCount < (int)mesh_info->vTextureList.size() ) || mesh_info->vTextureList.empty() )
|
||
{
|
||
//기본 텍스처로 돌려 놓은다
|
||
for( int x = 0; x < m_nPrMeshCount; ++x )
|
||
{
|
||
if( m_pPrMesh[x].GetDiffuseTexture() != NULL )
|
||
{
|
||
K3DResVertexAnimation* pVA = m_spResMesh->GetRes( x );
|
||
|
||
if( m_pPrMesh[x].GetDiffuseTexture() != pVA->GetTexturePack()->spTexture )
|
||
m_pPrMesh[x].SetTexture( pVA->GetTexturePack() );
|
||
}
|
||
}
|
||
// sonador 1.8.10 아바타 텍스쳐 그룹 적용(페이스 컷 포함)
|
||
m_bUseDefaultTexture = true;
|
||
return (void*)0;
|
||
}
|
||
m_bUseDefaultTexture = false;
|
||
for( int x = 0; x < m_nPrMeshCount; ++x )
|
||
{
|
||
m_pPrMesh[x].SetDiffuseTexture( KTextureManager::GetManager()->GetTexture( mesh_info->vTextureList[0], &pack ) );
|
||
|
||
// 얼굴 텍스처 설정.
|
||
// 망토 텍스처에 문제가 있을 수도... kappamind, 2009.12.16
|
||
K3DResVertexAnimation* pVA = m_spResMesh->GetRes( x );
|
||
pVA->GetTexturePack()->spTexture = KTextureManager::GetManager()->GetTexture( mesh_info->vTextureList[0], &pack );
|
||
|
||
}
|
||
return (void*)0;
|
||
}
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
if( strcmp( m_spResMesh->GetName(), mesh_info->szMeshName ) != 0 ) return (void*)0;
|
||
|
||
if( ( m_nPrMeshCount < (int)mesh_info->vTextureList.size() ) || mesh_info->vTextureList.empty() )
|
||
{
|
||
//기본 텍스처로 돌려 놓은다
|
||
for( int x = 0; x < m_nPrMeshCount; ++x )
|
||
{
|
||
if( m_pPrMesh[x].GetDiffuseTexture() != NULL )
|
||
{
|
||
K3DResVertexAnimation* pVA = m_spResMesh->GetRes( x );
|
||
|
||
if( m_pPrMesh[x].GetDiffuseTexture() != pVA->GetTexturePack()->spTexture )
|
||
m_pPrMesh[x].SetTexture( pVA->GetTexturePack() );
|
||
}
|
||
}
|
||
// sonador 1.8.10 아바타 텍스쳐 그룹 적용(페이스 컷 포함)
|
||
m_bUseDefaultTexture = true;
|
||
return (void*)0;
|
||
}
|
||
|
||
std::string strTextureName;
|
||
std::string strFxTextureName;
|
||
|
||
std::vector< const char* >::iterator itTextureList = mesh_info->vTextureList.begin();
|
||
for( int x = 0; itTextureList != mesh_info->vTextureList.end(); ++itTextureList, ++x )
|
||
{
|
||
strTextureName = (*itTextureList);
|
||
if( strcmp( strTextureName.c_str(), "" ) != 0 )
|
||
{
|
||
if( m_pPrMesh[x].GetDiffuseTexture() != NULL )
|
||
m_pPrMesh[x].SetDiffuseTexture( KTextureManager::GetManager()->GetTexture( strTextureName.c_str(), &pack ) );
|
||
|
||
std::string::size_type pos = strTextureName.rfind( ".dds" );
|
||
if( pos != std::string::npos )
|
||
{
|
||
strTextureName.erase( pos, strTextureName.length()-pos );
|
||
|
||
if( m_pPrMesh[x].GetSpecularTexture() != NULL )
|
||
{
|
||
strFxTextureName = strTextureName;
|
||
strFxTextureName += "_spec.dds";
|
||
|
||
m_pPrMesh[x].SetSpecularTexture( KTextureManager::GetManager()->GetTexture( strFxTextureName.c_str(), &pack ) );
|
||
}
|
||
|
||
if( m_pPrMesh[x].GetBumpTexture() != NULL )
|
||
{
|
||
strFxTextureName = strTextureName;
|
||
strFxTextureName += "_bump.dds";
|
||
|
||
m_pPrMesh[x].SetBumpTexture( KTextureManager::GetManager()->GetTexture( strFxTextureName.c_str(), &pack ) );
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if( m_pPrMesh[x].GetDiffuseTexture() != NULL )
|
||
{
|
||
K3DResVertexAnimation* pVA = m_spResMesh->GetRes( x );
|
||
m_pPrMesh[x].SetTexture( pVA->GetTexturePack() );
|
||
}
|
||
}
|
||
}
|
||
// sonador 1.8.10 아바타 텍스쳐 그룹 적용(페이스 컷 포함)
|
||
m_bUseDefaultTexture = false;
|
||
}
|
||
else if ( id == id_GETMESH_TRI )
|
||
{
|
||
KMsgGET_GETMESH_TRI *triangle = static_cast<KMsgGET_GETMESH_TRI*>(&msg);
|
||
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
realizeTime();
|
||
for(int i = 0; i < m_spResMesh->GetResCount(); i++)
|
||
{
|
||
K3DResVertexAnimation *rmesh = m_spResMesh->GetRes(i);
|
||
K3DResVertexAnimation::Key *key1, *key2;
|
||
rmesh->GetData(0, key1, key2);
|
||
if( rmesh != NULL )
|
||
{
|
||
K3DMatrix mat;
|
||
K3DMatrixIdentity( mat );
|
||
K3DMatrixMultiply( mat, m_matLocal, triangle->mat );
|
||
|
||
if( rmesh->GetIndexArray() )
|
||
{
|
||
for(int t = 0; t < (int)rmesh->GetIndexArray()->GetCnt(); ++t)
|
||
{
|
||
K3DVector pos;
|
||
K3DVectorTransform(pos, key1->m_spVB_array->GetArray()[rmesh->GetIndexArray()->GetArray()[t]], mat);
|
||
triangle->pListTriangles->push_back(pos);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if ( id == id_GETMESH_VERTEXBUFFERS )
|
||
{
|
||
KMsgGET_MESHVERTEXBUFFERS* msgGMVB = static_cast<KMsgGET_MESHVERTEXBUFFERS*>(&msg);
|
||
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
MESHVERTEXBUFFERSTRUCT* pVbStruct = new MESHVERTEXBUFFERSTRUCT;
|
||
|
||
int size = m_spResMesh->GetResCount();
|
||
|
||
pVbStruct->nVBCount = size;
|
||
pVbStruct->pVBs = (K3DVertexBuffer**) new K3DVertexBufferDX*[size];
|
||
|
||
for(int i = 0; i < size; i++)
|
||
{
|
||
K3DResVertexAnimation::Key *key1, *key2;
|
||
m_spResMesh->GetRes(i)->GetData(0, key1, key2);
|
||
pVbStruct->pVBs[i] = key1->m_spVB;
|
||
}
|
||
|
||
pVbStruct->matLocal = m_matLocal;
|
||
|
||
msgGMVB->vVbStruct.push_back(pVbStruct);
|
||
}
|
||
}
|
||
else if ( id == id_GETMESH_INDEXBUFFERS )
|
||
{
|
||
KMsgGET_MESHINDEXBUFFERS* msgGMIB = static_cast<KMsgGET_MESHINDEXBUFFERS*>(&msg);
|
||
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
MESHINDEXBUFFERSTRUCT* pIbStruct = new MESHINDEXBUFFERSTRUCT;
|
||
|
||
int size = m_spResMesh->GetResCount();
|
||
|
||
pIbStruct->nIBCount = size;
|
||
pIbStruct->pIBs = (K3DIndexBuffer**) new K3DIndexBufferDX*[size];
|
||
|
||
for(int i = 0; i < size; i++)
|
||
{
|
||
pIbStruct->pIBs[i] = m_spResMesh->GetRes(i)->GetIndexBuffer();
|
||
}
|
||
|
||
msgGMIB->vIbStruct.push_back(pIbStruct);
|
||
}
|
||
}
|
||
else if ( id == id_GETMESH_POLYCOUNT )
|
||
{
|
||
KMsgGET_MESHPOLYCOUNT *polycount = static_cast<KMsgGET_MESHPOLYCOUNT*>(&msg);
|
||
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
for(int i = 0; i < m_spResMesh->GetResCount(); i++)
|
||
{
|
||
polycount->nPolyCount += m_spResMesh->GetRes(i)->GetIndexBuffer()->GetIndexCount() / 3;
|
||
}
|
||
}
|
||
}
|
||
else if ( id == id_GETMESH_TEXNAME )
|
||
{
|
||
KMsgGET_MESHTEXNAME* texname = static_cast<KMsgGET_MESHTEXNAME*>(&msg);
|
||
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
for(int i = 0; i < m_spResMesh->GetResCount(); i++)
|
||
{
|
||
TEXPACK* pTexpack = m_spResMesh->GetRes(i)->GetTexturePack();
|
||
|
||
if( pTexpack->spTexture != NULL)
|
||
{
|
||
if( ExistCheckVector( texname->vNameList, pTexpack->spTexture ) == false )
|
||
{
|
||
texname->vNameList.push_back(pTexpack->spTexture->GetName());
|
||
}
|
||
}
|
||
|
||
if(pTexpack->spTexture_Bump != NULL)
|
||
{
|
||
if( ExistCheckVector( texname->vNameList, pTexpack->spTexture_Bump ) == false )
|
||
{
|
||
texname->vNameList.push_back(pTexpack->spTexture_Bump->GetName());
|
||
}
|
||
}
|
||
|
||
if(pTexpack->spTexture_Illumin != NULL)
|
||
{
|
||
if( ExistCheckVector( texname->vNameList, pTexpack->spTexture_Illumin ) == false )
|
||
{
|
||
texname->vNameList.push_back(pTexpack->spTexture_Illumin->GetName());
|
||
}
|
||
}
|
||
|
||
if(pTexpack->spTexture_Specular != NULL)
|
||
{
|
||
if( ExistCheckVector( texname->vNameList, pTexpack->spTexture_Specular ) == false )
|
||
{
|
||
texname->vNameList.push_back(pTexpack->spTexture_Specular->GetName());
|
||
}
|
||
}
|
||
|
||
if(pTexpack->spTexture_SpecularColor != NULL)
|
||
{
|
||
if( ExistCheckVector( texname->vNameList, pTexpack->spTexture_SpecularColor ) == false )
|
||
{
|
||
texname->vNameList.push_back(pTexpack->spTexture_SpecularColor->GetName());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if ( id == id_SETRENDER_FLAG )
|
||
{
|
||
KMsgSET_RENDERFLAG * renderflagmsg = static_cast<KMsgSET_RENDERFLAG*>(&msg);
|
||
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
if( renderflagmsg->pName == NULL )
|
||
{
|
||
m_bRenderFlag = renderflagmsg->bRenderFlag;
|
||
}
|
||
else
|
||
{
|
||
for( int i(0); m_spResMesh->GetResCount()>i; i++ )
|
||
{
|
||
if( strstr( m_spResMesh->GetName(), renderflagmsg->pName ) != NULL )
|
||
{
|
||
m_bRenderFlag = renderflagmsg->bRenderFlag;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if ( id == id_SETFORCERENDER_FLAG )
|
||
{
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
m_bRenderFlag = FALSE;
|
||
}
|
||
}
|
||
else if ( id == id_REQ_BOUNDBOX )
|
||
{
|
||
realizeTransform();
|
||
|
||
KMsgREQ_BOUNDBOX *boundReq = static_cast<KMsgREQ_BOUNDBOX*>(&msg);
|
||
boundReq->AddBound( GetCube() );
|
||
return (void*)1;
|
||
}
|
||
else if ( id == id_REQ_BOUNDBOXEX )
|
||
{
|
||
realizeTransform();
|
||
|
||
KMsgREQ_BOUNDBOXEX * boundReqEx = static_cast<KMsgREQ_BOUNDBOXEX*>(&msg);
|
||
|
||
if( strcmp( boundReqEx->pSearchName, m_spResMesh->GetName() ) == 0 )
|
||
{
|
||
boundReqEx->AddBound( GetCube() );
|
||
return (void*)1;
|
||
}
|
||
}
|
||
else if ( id == id_REQ_BOUNDSPHERE )
|
||
{
|
||
realizeTransform();
|
||
|
||
KMsgREQ_BOUNDSPHERE *boundReq = static_cast<KMsgREQ_BOUNDSPHERE*>(&msg);
|
||
boundReq->AddBound( GetSphere() );
|
||
return (void*)1;
|
||
}
|
||
else if ( id == id_SET_LIGHT_MAP )
|
||
{
|
||
|
||
KMsgSET_LIGHTMAP *pLightMapSet = static_cast<KMsgSET_LIGHTMAP*>(&msg);
|
||
|
||
int count = m_spResMesh->GetResCount();
|
||
|
||
for(int i = 0; i < count; ++i)
|
||
{
|
||
|
||
K3DResVertexAnimation* pRes = m_spResMesh->GetRes(i);
|
||
|
||
if(strlen(pLightMapSet->GetPrefixTexName() ) == 0)
|
||
{
|
||
m_pPrMesh[i].SetLightMapTexture(NULL);
|
||
}
|
||
else
|
||
{
|
||
DWORD idx = pRes->GetLightMapIndex();
|
||
|
||
static char name[_MAX_PATH];
|
||
_snprintf_s(name, _MAX_PATH, "%s_Light_%d_%d_%d.tga", pLightMapSet->GetPrefixTexName(),idx, pLightMapSet->GetSegmentIdx(),
|
||
pLightMapSet->GetPropIdx());
|
||
|
||
static NX3LoadPack pack; // 어이없는 인-_-자 이지만 lod 지원을 위해서 어쩔수 없이 넣어주는 센스
|
||
if( KTextureManager::GetManager()->IsExistTexture( name, &pack ) )
|
||
{
|
||
m_pPrMesh[i].SetLightMapTexture(KTextureManager::GetManager()->GetTexture( name, &pack ) );
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
else if ( id == id_GET_SEQOBJECT )
|
||
{
|
||
KMsgGET_SEQOBJECT * getSeqMsg = static_cast<KMsgGET_SEQOBJECT*>(&msg);
|
||
|
||
if(m_spResMesh != NULL)
|
||
{
|
||
for( int i(0); m_spResMesh->GetResCount()>i; i++ )
|
||
{
|
||
if( strstr( m_spResMesh->GetName(), getSeqMsg->pName ) != NULL )
|
||
{
|
||
getSeqMsg->pSeqObject = this;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if( id == id_GET_MORPHMESH )
|
||
{
|
||
KMsgGET_MORPHMESH * getMorph = static_cast<KMsgGET_MORPHMESH*>(&msg);
|
||
getMorph->bIsValid = true;
|
||
|
||
getMorph->numFrames = numFrames;
|
||
getMorph->loopWindowSize = loopWindowSize;
|
||
getMorph->markFrame = markFrame;
|
||
|
||
getMorph->animationDelay = animationDelay;
|
||
|
||
getMorph->startColor0 = startColor0;
|
||
getMorph->startColor1 = startColor1;
|
||
getMorph->markColor0 = markColor0;
|
||
getMorph->markColor1 = markColor1;
|
||
getMorph->endColor0 = endColor0;
|
||
getMorph->endColor1 = endColor1;
|
||
|
||
getMorph->startSizeOffset = startSizeOffset;
|
||
getMorph->markSizeOffset = markSizeOffset;
|
||
getMorph->endSizeOffset = endSizeOffset;
|
||
|
||
getMorph->strTexture = strFxTexture;
|
||
}
|
||
else if( id == id_SET_MORPHMESH )
|
||
{
|
||
KMsgSET_MORPHMESH * setMorph = static_cast<KMsgSET_MORPHMESH*>(&msg);
|
||
|
||
if( setMorph->bShow == false )
|
||
{
|
||
_morphInit();
|
||
return NULL;
|
||
}
|
||
|
||
if( setMorph->nSetFlag == 0 )
|
||
{
|
||
_morphInit();
|
||
_morphDefaultSet(); //Test
|
||
}
|
||
else
|
||
{
|
||
_morphClear();
|
||
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_FRAME ) numFrames = setMorph->numFrames;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_LOOP ) loopWindowSize = setMorph->loopWindowSize;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_DELAY ) animationDelay = setMorph->animationDelay;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_MARK ) markFrame = setMorph->markFrame;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_ADDITIVE ) additive = setMorph->additive;
|
||
|
||
//기본 값 설정
|
||
if( numFrames <= 0 ) numFrames = 32;
|
||
if( loopWindowSize <= 0 ) loopWindowSize = 6;
|
||
if( animationDelay <= 0 ) animationDelay = 100;
|
||
if( markFrame <= 0 ) markFrame = 8;
|
||
|
||
markFrame = setMorph->markFrame;
|
||
|
||
if( markFrame > numFrames )
|
||
{
|
||
assert( 0 && "markFrame Invalid" );
|
||
markFrame = numFrames;
|
||
}
|
||
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_SC0 ) startColor0 = setMorph->startColor0;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_SC1 ) startColor1 = setMorph->startColor1;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_MC0 ) markColor0 = setMorph->markColor0;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_MC1 ) markColor1 = setMorph->markColor1;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_EC0 ) endColor0 = setMorph->endColor0;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_EC1 ) endColor1 = setMorph->endColor1;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_SSIZE ) startSizeOffset = setMorph->startSizeOffset;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_MSIZE ) markSizeOffset = setMorph->markSizeOffset;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_ESIZE ) endSizeOffset = setMorph->endSizeOffset;
|
||
if( setMorph->nSetFlag & KMsgSET_MORPHMESH::FLAG_TEXTURE) strFxTexture = setMorph->strTexture;
|
||
}
|
||
|
||
_morphMeshMake();
|
||
}
|
||
else if( id == id_SET_FIX_TEXTURE )
|
||
{
|
||
if( stricmp( m_spResMesh->GetName(), "grid" ) == 0 )
|
||
return NULL;
|
||
|
||
KMsgSET_FIXTEXTURE * setFixTexture = static_cast<KMsgSET_FIXTEXTURE*>(&msg);
|
||
|
||
m_bForceTransparent = setFixTexture->bForceTransparent;
|
||
|
||
int count = m_spResMesh->GetResCount();
|
||
if( count > 0 )
|
||
{
|
||
if( setFixTexture->bUseFix )
|
||
{
|
||
for(int i = 0; i < count; ++i)
|
||
{
|
||
m_pPrMesh[i].SetFixMapTexture( setFixTexture->pTexture );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for(int i = 0; i < count; ++i)
|
||
{
|
||
m_pPrMesh[i].SetFixMapTexture(NULL);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//눈 깜박임 제거
|
||
//2009-04-14 : hunee
|
||
/*else if( id == id_SET_WINK_TEXTURE )
|
||
{
|
||
KMsgSET_WINKTEXTURE* setWinkTexture = static_cast<KMsgSET_WINKTEXTURE*>(&msg);
|
||
|
||
m_bUseWink = setWinkTexture->bUseWink;
|
||
m_spWinkTexture = setWinkTexture->pTexture;
|
||
checkTime = setWinkTexture->nWinkTime;
|
||
m_bFlipWink = false;
|
||
}*/
|
||
else if( id == id_SET_COLORIZE )
|
||
{
|
||
KMsgSET_COLORIZE* setColorize = static_cast<KMsgSET_COLORIZE*>(&msg);
|
||
_oprint("[id_SET_COLORIZE] setColorize->color[0]: %u, setColorize->color[1]: %u, setColorize->color[2]: %u, setColorize->color[3]: %u\n", setColorize->color[0], setColorize->color[1], setColorize->color[2], setColorize->color[3]);
|
||
SetColor( setColorize->color[0], setColorize->color[1], setColorize->color[2], setColorize->color[3], setColorize->nMode );
|
||
}
|
||
else if( id == id_SET_USE_TEXALPHA )
|
||
{
|
||
KMsgSET_USE_TEXALPHA* setUseAlpha = static_cast<KMsgSET_USE_TEXALPHA*>(&msg);
|
||
m_bUseTextureAlpha = setUseAlpha->bIsUseTexAlpha;
|
||
}
|
||
else if( id == id_SET_UV_MODIFY )
|
||
{ //
|
||
if( stricmp( m_spResMesh->GetName(), "grid" ) == 0 )
|
||
return NULL;
|
||
|
||
KMsgSET_UV_MODIFY* setUVModify = static_cast<KMsgSET_UV_MODIFY*>(&msg);
|
||
|
||
int nHalfWidth = setUVModify->nW/2;
|
||
int nHalfHeight = setUVModify->nH/2;
|
||
int nTargetHalfWidth = setUVModify->nTargetW/2;
|
||
int nTargetHalfHeight = setUVModify->nTargetH/2;
|
||
|
||
float uv[4][2];
|
||
uv[0][0] = (float)((nHalfWidth -nTargetHalfWidth )+0.5f)/setUVModify->nW;
|
||
uv[0][1] = (float)((nHalfHeight-nTargetHalfHeight)+0.5f)/setUVModify->nH;
|
||
|
||
uv[1][0] = (float)((nHalfWidth -nTargetHalfWidth )+0.5f)/setUVModify->nW;
|
||
uv[1][1] = (float)((nHalfHeight+nTargetHalfHeight)-0.5f)/setUVModify->nH;
|
||
|
||
uv[2][0] = (float)((nHalfWidth +nTargetHalfWidth )-0.5f)/setUVModify->nW;
|
||
uv[2][1] = (float)((nHalfHeight+nTargetHalfHeight)-0.5f)/setUVModify->nH;
|
||
|
||
uv[3][0] = (float)((nHalfWidth +nTargetHalfWidth )-0.5f)/setUVModify->nW;
|
||
uv[3][1] = (float)((nHalfHeight-nTargetHalfHeight)+0.5f)/setUVModify->nH;
|
||
|
||
|
||
|
||
int count = m_spResMesh->GetResCount();
|
||
for ( int n=0 ; n<count; ++n )
|
||
{
|
||
K3DResVertexAnimation *va = m_spResMesh->GetRes(n);
|
||
|
||
K3DResVertexAnimation::Key *key1 = NULL;
|
||
|
||
int nKeyCount = va->GetKeyCount();
|
||
|
||
for( int i(0); nKeyCount>i; i++ )
|
||
{
|
||
K3DResVertexAnimation::Key& key = va->GetKey( i );
|
||
|
||
if( !key.m_spVB->IsValidVtx() ) continue;
|
||
|
||
DWORD dwVtxCount = key.m_spVB->GetVertexCount();
|
||
DWORD dwVtxFormat = key.m_spVB->GetVertexFormat();
|
||
DWORD dwVtxStride = key.m_spVB->GetVertexStride();
|
||
|
||
if( dwVtxCount != 4 ) continue;
|
||
|
||
// K3DFVF_XYZ | K3DFVF_NORMAL 은 항상 존재
|
||
K3DBLENDEDBUMPVERTEX * pTempBuf = NULL;
|
||
int size = dwVtxCount; //Size 사용 안함.
|
||
key.m_spVB->Lock( (void**)&pTempBuf, size );
|
||
if( pTempBuf == NULL ) continue;
|
||
|
||
for( int n=0; 4>n; n++ )
|
||
{
|
||
pTempBuf[n].texcoord.x = uv[0][0];
|
||
pTempBuf[n].texcoord.y = uv[0][1];
|
||
n++;
|
||
pTempBuf[n].texcoord.x = uv[1][0];
|
||
pTempBuf[n].texcoord.y = uv[1][1];
|
||
n++;
|
||
pTempBuf[n].texcoord.x = uv[2][0];
|
||
pTempBuf[n].texcoord.y = uv[2][1];
|
||
n++;
|
||
pTempBuf[n].texcoord.x = uv[3][0];
|
||
pTempBuf[n].texcoord.y = uv[3][1];
|
||
n++;
|
||
}
|
||
|
||
key.m_spVB->Unlock();
|
||
}
|
||
}
|
||
}
|
||
else if( id == id_GET_MATRIX )
|
||
{
|
||
KMsgGET_MATRIX* getMatrix = static_cast<KMsgGET_MATRIX*>(&msg);
|
||
|
||
CalcMatrix();
|
||
|
||
getMatrix->matLocal = &m_matLocal;
|
||
getMatrix->matRoot = &m_matRoot;
|
||
getMatrix->bSuc = true;
|
||
}
|
||
|
||
else if( id == id_GET_PERFORMANCEINFO )
|
||
{
|
||
KMsgGET_PERFORMANCEINFO* getPerformanceinfo = static_cast<KMsgGET_PERFORMANCEINFO*>(&msg);
|
||
getPerformanceinfo->nSeqCount++;
|
||
getPerformanceinfo->nMeshCount++;
|
||
|
||
for ( int i=0 ; i<m_spResMesh->GetResCount() ; ++i )
|
||
{
|
||
K3DResVertexAnimation* va = m_spResMesh->GetRes(i);
|
||
|
||
TEXPACK* pTexPack = va->GetTexturePack();
|
||
|
||
std::string strInfo;
|
||
GetTexInfo( pTexPack->spTexture , strInfo );
|
||
GetTexInfo( pTexPack->spTexture_Bump , strInfo );
|
||
GetTexInfo( pTexPack->spTexture_Illumin , strInfo );
|
||
GetTexInfo( pTexPack->spTexture_Specular , strInfo );
|
||
GetTexInfo( pTexPack->spTexture_SpecularColor, strInfo );
|
||
GetTexInfo( pTexPack->spTexture_Light , strInfo );
|
||
GetTexInfo( pTexPack->spTexture_Fix , strInfo );
|
||
|
||
if( strInfo.length() > 0 )
|
||
getPerformanceinfo->vTexList.push_back( strInfo );
|
||
|
||
for( int j(0); va->GetKeyCount()>j; j++ )
|
||
{
|
||
std::string strVertexInfo;
|
||
K3DResVertexAnimation::Key& key = va->GetKey( j );
|
||
|
||
StringFormat( strVertexInfo, "|Fmt:%d Stride:%d Cnt:%d|", key.m_spVB->GetVertexFormat(), key.m_spVB->GetVertexStride(), key.m_spVB->GetVertexCount() );
|
||
|
||
if( strVertexInfo.length() > 0 )
|
||
getPerformanceinfo->vVertexList.push_back( strVertexInfo );
|
||
}
|
||
}
|
||
}
|
||
// sonador 4.1.2 아바타 머리카락 알바 버그 재수정(ALPHABLENDTWOPASS)
|
||
else if( id == id_SET_BLENDMODE )
|
||
{
|
||
KMsgSET_BLENDMODE* commandSetBlendMode = static_cast< KMsgSET_BLENDMODE* >( &msg );
|
||
m_pPrMesh->SetBlendMode( commandSetBlendMode->blendMode );
|
||
}
|
||
else if( id == id_SET_MTETEX )
|
||
{
|
||
KMsgSET_MTETEX* setMteTex = static_cast< KMsgSET_MTETEX* >( &msg );
|
||
SetMTETexture( setMteTex->pTexture );
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
void KMeshSeqObject::setBone( int nCount, K3DMatrix *pMatList )
|
||
{
|
||
m_nBoneMatCount = nCount;
|
||
m_pBoneMatList = pMatList;
|
||
|
||
K3DMatrix * pOffSetMat = m_spResMesh->GetMeshTMArray();
|
||
|
||
for(int i = 0; i < m_nPrMeshCount; ++i)
|
||
{
|
||
m_pPrMesh[i].SetBlendedInfo( m_nBoneMatCount, pOffSetMat, m_pBoneMatList );
|
||
}
|
||
|
||
bool bMorphRender = !morph_primitivelist.empty();
|
||
if( bMorphRender && m_nMorphPrimitiveCount == m_spResMesh->GetResCount() )
|
||
{
|
||
for(int i = 0; i < m_nPrMeshCount; ++i)
|
||
{
|
||
for (int n=0; n < numFrames; n++) {
|
||
morph_primitivelist[i][n].SetBlendedInfo( m_nBoneMatCount, pOffSetMat, m_pBoneMatList );
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
void KMeshSeqObject::SetMatrixRes( K3DResMeshMatrixAnimation *pResMatrix )
|
||
{
|
||
assert( m_spResMatrix == NULL );
|
||
|
||
m_spResMatrix = pResMatrix;
|
||
|
||
if(m_spResMatrix != NULL)
|
||
{
|
||
m_interval.Expand( m_spResMatrix->GetInterval() );
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::SetVisibilityRes( K3DResMeshVisibilityAnimation *pResVis )
|
||
{
|
||
assert( m_spResVis == NULL);
|
||
|
||
m_spResVis = pResVis;
|
||
|
||
if(m_spResVis != NULL)
|
||
{
|
||
m_interval.Expand( m_spResVis->GetInterval() );
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::SetUVAniRes( K3DResMeshUVAnimation *pResUV )
|
||
{
|
||
assert( m_spResUV == NULL);
|
||
|
||
m_spResUV = pResUV;
|
||
|
||
if( m_spResUV != NULL )
|
||
{
|
||
int nUvMode = m_spResUV->GetMode();
|
||
|
||
if( m_spResMesh != NULL )
|
||
{
|
||
for( int i = 0; i < m_nPrMeshCount; i++ )
|
||
{
|
||
int nBlendMode = m_pPrMesh[ i ].GetBlendMode();
|
||
if( nBlendMode == K3DMaterial::MBM_ALPHABLEND || nBlendMode == K3DMaterial::MBM_ADDITIVE )
|
||
nBlendMode += nUvMode;
|
||
m_pPrMesh[ i ].SetBlendMode( nBlendMode );
|
||
}
|
||
}
|
||
|
||
m_interval.Expand( m_spResUV->GetInterval() );
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::SetAlterMaterial( K3DMaterial* pMtl)
|
||
{
|
||
m_pAlterMtl = pMtl;
|
||
|
||
if(NULL == m_spResMesh)
|
||
return;
|
||
|
||
for(int i = 0; i < m_nPrMeshCount; ++i)
|
||
{
|
||
if(m_pAlterMtl != NULL)
|
||
m_pPrMesh[i].SetMaterial(m_pAlterMtl);
|
||
else
|
||
m_pPrMesh[i].SetMaterial(m_spResMesh->GetRes(i)->GetMaterial() );
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::updateColors()
|
||
{
|
||
// TODO: Add resource option loading (in progress)
|
||
NX3LoadPack loadpack;
|
||
loadpack.Init();
|
||
|
||
for ( int i = 0 ; i < m_spResMesh->GetResCount() ; ++i )
|
||
{
|
||
K3DResVertexAnimation *va = m_spResMesh->GetRes(i);
|
||
K3DTexture *oldtex = va->GetTexturePack()->spTexture;
|
||
|
||
if( oldtex )
|
||
{
|
||
K3DTexture* curtex = m_pPrMesh[i].GetDiffuseTexture();
|
||
// 2010.06.18 – Without filename checking, colorizing may use a previously loaded (different) texture – prodongi
|
||
if (strcmp(oldtex->GetName(), curtex->GetName()) != 0)
|
||
oldtex = curtex;
|
||
|
||
if( m_nColorizedMode == K3DTexture::COLORIZED_DEF || m_nColorizedMode == K3DTexture::COLORIZED_KEEP_ALPHA
|
||
|| m_nColorizedMode == K3DTexture::COLORIZED_GRAY )
|
||
{
|
||
K3DTexture *newtex = KTextureManager::GetManager()->GetTexture( oldtex, &loadpack,
|
||
m_dwColors[0], m_dwColors[1], m_dwColors[2], m_dwColors[3], 0, m_nColorizedMode );
|
||
|
||
if(oldtex != newtex)
|
||
{
|
||
K3DTexture* diffTex = m_pPrMesh[i].GetDiffuseTexture();
|
||
|
||
TEXPACK texpack = *va->GetTexturePack();
|
||
texpack.spTexture = newtex; //SmartPoint 에서 oldtex는 Release 된다.
|
||
va->SetTexturePack( &texpack );
|
||
m_pPrMesh[i].SetTexture( va->GetTexturePack() );
|
||
}
|
||
}
|
||
else if( m_nColorizedMode == K3DTexture::COLORIZED_USEALPHA )
|
||
{
|
||
if( strstr( oldtex->GetName(), "_color" ) )
|
||
{
|
||
K3DTexture *newtex = KTextureManager::GetManager()->GetTexture( oldtex, &loadpack,
|
||
m_dwColors[0], m_dwColors[1], m_dwColors[2], m_dwColors[3], 0, m_nColorizedMode );
|
||
|
||
if(oldtex != newtex)
|
||
{
|
||
TEXPACK texpack = *va->GetTexturePack();
|
||
texpack.spTexture = newtex; //SmartPoint 에서 oldtex는 Release 된다.
|
||
va->SetTexturePack( &texpack );
|
||
m_pPrMesh[i].SetTexture( va->GetTexturePack() );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::SetColor( DWORD c1, DWORD c2 /* = 0 */, DWORD c3 /* = 0 */, DWORD c4 /* = 0 */, short nMode /*= 0*/ )
|
||
{
|
||
if ( m_dwColors[0] != c1 || m_dwColors[1] != c2 || m_dwColors[2] != c3 || m_dwColors[3] != c4 || m_nColorizedMode != nMode )
|
||
{
|
||
m_nColorizedMode = nMode;
|
||
m_dwColors[0] = c1;
|
||
m_dwColors[1] = c2;
|
||
m_dwColors[2] = c3;
|
||
m_dwColors[3] = c4;
|
||
_oprint("[KMeshSeqObject::SetColor] (after id_SET_COLORIZE): m_dwColors[0]: %u, m_dwColors[1]: %u, m_dwColors[2]: %u, m_dwColors[3]: %u\n", m_dwColors[0], m_dwColors[1], m_dwColors[2], m_dwColors[3]);
|
||
updateColors();
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::realizeTransform()
|
||
{
|
||
realizeTime();
|
||
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;
|
||
}
|
||
|
||
void KMeshSeqObject::ClipTest( const K3DVector* pFrustum)
|
||
{
|
||
realizeTransform();
|
||
|
||
m_boundCube.SetTransform( m_matResult );
|
||
//m_bIsClip = pFrustrum->ISContainCube(m_boundCube) == K3DFrustum::FRUSTUM_OUT;
|
||
m_bIsClip = KPCCP::nonuniformcube_collide_nonuniformcube(pFrustum, m_boundCube.GetVertices()) == false;
|
||
|
||
//m_boundSphere.SetTransform( m_matResult );
|
||
//m_bIsClip = pFrustrum->IsContaineSphere(m_boundSphere) == K3DFrustum::FRUSTUM_OUT;
|
||
}
|
||
|
||
void KMeshSeqObject::CalcMatrix()
|
||
{
|
||
if(m_pMatParent != NULL)
|
||
{
|
||
if(m_pMatAttach != NULL)
|
||
{
|
||
//m_matRoot = *m_pMatParent;
|
||
K3DMatrix matTemp;
|
||
|
||
if( m_bRotationLock )
|
||
{
|
||
//위치만 얻는다.
|
||
//K3DMatrixIdentity( m_matLocal );
|
||
//m_matLocal._41 = m_pMatAttach->_41;
|
||
//m_matLocal._42 = m_pMatAttach->_42;
|
||
//m_matLocal._43 = m_pMatAttach->_43;
|
||
|
||
K3DMatrixIdentity( matTemp );
|
||
matTemp._41 = m_pMatAttach->_41;
|
||
matTemp._42 = m_pMatAttach->_42;
|
||
matTemp._43 = m_pMatAttach->_43;
|
||
}
|
||
else
|
||
{
|
||
//m_matLocal = *m_pMatAttach;
|
||
matTemp = *m_pMatAttach;
|
||
}
|
||
|
||
K3DMatrixMultiply( m_matRoot, matTemp, *m_pMatParent );
|
||
}
|
||
else
|
||
{
|
||
if( m_bRotationLock )
|
||
{
|
||
K3DMatrixIdentity( m_matRoot );
|
||
m_matRoot._41 = m_pMatParent->_41;
|
||
m_matRoot._42 = m_pMatParent->_42;
|
||
m_matRoot._43 = m_pMatParent->_43;
|
||
}
|
||
else
|
||
{
|
||
m_matRoot = *m_pMatParent;
|
||
}
|
||
|
||
}
|
||
//K3DMatrixMultiply( m_matResult, m_matLocal, *m_pMatParent );
|
||
K3DMatrixMultiply( m_matResult, m_matLocal, m_matRoot );
|
||
}
|
||
else
|
||
{
|
||
K3DMatrixIdentity( m_matRoot );
|
||
m_matResult = m_matLocal;
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::SetMTETexture( K3DTexture* pTex )
|
||
{
|
||
for( int i = 0; i < m_nPrMeshCount; ++i )
|
||
{
|
||
m_pPrMesh[i].SetMTETexture( pTex );
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::Render( KViewportObject *viewport, DWORD flag, const K3DMatrix * pAttachMat )
|
||
{
|
||
realizeTime();
|
||
|
||
float vis = m_fVisResult * m_fMasterVisibility;
|
||
if ( vis > .9f )
|
||
m_bIsTransparent = false;
|
||
else
|
||
m_bIsTransparent = true;
|
||
|
||
//강제 알파 설정
|
||
if( m_bForceTransparent )
|
||
m_bIsTransparent = true;
|
||
|
||
if( vis <= 0.f )
|
||
return; //투명한 놈이므로 안 그림
|
||
|
||
CalcMatrix();
|
||
|
||
if( m_bRenderFlag == false ) return; //Render 하지 않는다.
|
||
|
||
#ifdef _RAC
|
||
if( /*m_pBoneMatList == NULL ||*/ m_spResMesh->GetWeightResCount() == 0 )
|
||
#else
|
||
if( m_pBoneMatList == NULL || m_spResMesh->GetWeightResCount() == 0 )
|
||
#endif
|
||
{
|
||
_defSetTransform( flag );
|
||
|
||
int i=0 ;
|
||
for ( int i=0 ; i<m_spResMesh->GetResCount() ; ++i )
|
||
{
|
||
K3DResVertexAnimation *va = m_spResMesh->GetRes(i);
|
||
if( _defRender( i, va, flag, vis ) )
|
||
{
|
||
if( m_sVisbleCube )
|
||
{
|
||
m_boundCube.Render( viewport );
|
||
viewport->RegisterWire( &m_prCenterWire );
|
||
}
|
||
|
||
// m_boundOcclusion.SetVertices( m_boundCube.GetOriginVertices() );
|
||
viewport->Register( &m_pPrMesh[i], flag );
|
||
}
|
||
}
|
||
|
||
bool bMorphRender = !morph_primitivelist.empty();
|
||
if( bMorphRender && m_nMorphPrimitiveCount == m_spResMesh->GetResCount() )
|
||
{
|
||
for ( int i=0 ; i<m_spResMesh->GetResCount() ; ++i )
|
||
{
|
||
for (int n=currentFrame; n < numFrames; n+=loopWindowSize) {
|
||
viewport->Register( &morph_primitivelist[i][n], 0 );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else //BoneSeq으로 스킨
|
||
{
|
||
if( m_spResMesh->GetWeightResCount() != m_spResMesh->GetResCount() )
|
||
{
|
||
//주의 : 매쉬 덩어리와, 가중치 덩어리는 항상 같아야 한다.
|
||
_oprint( "If the bone and flesh are not the same, it's a big problem~ Weight: %d, Res: %d \n", m_spResMesh->GetWeightResCount(), m_spResMesh->GetResCount() );
|
||
return;
|
||
}
|
||
//VS HW
|
||
// assert( m_pBoneSeq->GetBoneCount() == m_spResMesh->GetMeshTMCount() && "뼈와 살이 같지 않다~" );
|
||
|
||
_defSetTransform( flag );
|
||
|
||
//Shader Const
|
||
for ( int i=0 ; i<m_spResMesh->GetResCount(); ++i )
|
||
{
|
||
K3DResVertexAnimation *va = m_spResMesh->GetRes(i);
|
||
if( _defRender( i, va, flag, vis ) )
|
||
{
|
||
if( m_sVisbleCube )
|
||
{
|
||
m_boundCube.Render( viewport );
|
||
viewport->RegisterWire( &m_prCenterWire );
|
||
}
|
||
|
||
// m_boundOcclusion.SetVertices( m_boundCube.GetOriginVertices() );
|
||
viewport->Register( &m_pPrMesh[i], flag );
|
||
}
|
||
}
|
||
|
||
bool bMorphRender = !morph_primitivelist.empty();
|
||
if( bMorphRender && m_nMorphPrimitiveCount == m_spResMesh->GetResCount() )
|
||
{
|
||
for ( int i=0 ; i<m_spResMesh->GetResCount(); ++i )
|
||
{
|
||
for (int n=currentFrame; n < numFrames; n+=loopWindowSize) {
|
||
viewport->Register( &morph_primitivelist[i][n], 0 );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::_defSetTransform( DWORD flag )
|
||
{
|
||
for(int i = 0; i < m_nPrMeshCount; ++i)
|
||
{
|
||
m_pPrMesh[i].SetTransform( &m_matLocal, &m_matRoot );
|
||
m_pPrMesh[i].SetUVTransform( &m_matUV );
|
||
m_pPrMesh[i].SetRenderState( m_nRenderState );
|
||
}
|
||
|
||
bool bMorphRender = !morph_primitivelist.empty();
|
||
if( bMorphRender && m_nMorphPrimitiveCount == m_spResMesh->GetResCount() )
|
||
{
|
||
for(int i = 0; i < m_nPrMeshCount; ++i)
|
||
{
|
||
for (int n=currentFrame; n < numFrames; n+=loopWindowSize) {
|
||
morph_primitivelist[i][n].SetTransform(&m_matLocal, &m_matRoot);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//공통 랜더 설정
|
||
bool KMeshSeqObject::_defRender( int i, K3DResVertexAnimation *va, DWORD flag, float vis )
|
||
{
|
||
// Vertex Animation이 사용되지 않는다면 밑의 코드도 불필요!!
|
||
////////////////////////////////////////////////////////////////////////////
|
||
K3DResVertexAnimation::Key *key1 = NULL, *key2 = NULL;
|
||
va->GetData( m_dwTime, key1, key2 );
|
||
m_pPrMesh[i].SetVertexBuffer( key1->m_spVB );
|
||
////////////////////////////////////////////////////////////////////////////
|
||
|
||
m_pPrMesh[i].SetVisibility( vis );
|
||
m_pPrMesh[i].SetDiffuseAlpha( vis > .9f ? false : true ); //스페큘러 때문에 DiffuseAlpha 감지가 필요함.
|
||
|
||
if( m_bUseTextureAlpha )
|
||
m_pPrMesh[i].SetTransparent( m_bIsTransparent || va->IsTransparent() );
|
||
else
|
||
m_pPrMesh[i].SetTransparent( m_bIsTransparent );
|
||
|
||
m_pPrMesh[i].SetSkinDiffuse( m_SkinDiffuse );
|
||
|
||
m_boundCube.SetTransform( m_matResult );
|
||
const K3DVector *cube = m_boundCube.GetVertices();
|
||
K3DVector vCenterPos = K3DVector(0.f, 0.f, 0.f);
|
||
K3DVector pos = K3DVector(0.f, 0.f, 0.f);
|
||
if( m_pMatParent && m_pMatAttach )
|
||
{
|
||
K3DMatrix matResult;
|
||
K3DMatrixMultiply( matResult, *m_pMatAttach, *m_pMatParent );
|
||
pos = K3DVector(0.f, 0.f, 0.f);
|
||
K3DMatrixGetPosVector( pos, matResult );
|
||
vCenterPos = cube[0] + (0.5f*(cube[7] - cube[0]));
|
||
m_pPrMesh[i].SetCenterPosition( vCenterPos );
|
||
}
|
||
else if( m_pMatParent )
|
||
{
|
||
pos = K3DVector(0.f, 0.f, 0.f);
|
||
K3DMatrixGetPosVector( pos, *m_pMatParent );
|
||
vCenterPos = cube[0] + (0.5f*(cube[7] - cube[0]));
|
||
m_pPrMesh[i].SetCenterPosition( vCenterPos );
|
||
}
|
||
else
|
||
{
|
||
vCenterPos = 0.5f*(cube[7] - cube[0]);
|
||
m_pPrMesh[i].SetCenterPosition( vCenterPos );
|
||
}
|
||
|
||
bool bMorphRender = !morph_primitivelist.empty();
|
||
if( bMorphRender && m_nMorphPrimitiveCount == m_spResMesh->GetResCount() )
|
||
{
|
||
K3DVector vmin, vmax;
|
||
vmax = cube[7];
|
||
vmin = cube[0];
|
||
|
||
for (int n=currentFrame; n < numFrames; n+=loopWindowSize) {
|
||
vCenterPos = vmin + (0.5f*(vmax - vmin));
|
||
morph_primitivelist[i][n].SetCenterPosition( vCenterPos );
|
||
vmax += ((i * 1.f)+0.2f);
|
||
vmin -= ((i * 1.f)+0.2f);
|
||
}
|
||
}
|
||
|
||
if( m_sVisbleCube )
|
||
{
|
||
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) );
|
||
|
||
vVectorX = pos;
|
||
vVectorY = pos;
|
||
vVectorZ = pos;
|
||
vVectorX.x += 3.f;
|
||
vVectorY.y += 3.f;
|
||
vVectorZ.z += 3.f;
|
||
//Ori Pos
|
||
m_prCenterWire.AddLine( pos, vVectorX, KColor(255,0,0,255) );
|
||
m_prCenterWire.AddLine( pos, vVectorY, KColor(255,0,0,255) );
|
||
m_prCenterWire.AddLine( pos, vVectorZ, KColor(255,0,0,255) );
|
||
}
|
||
|
||
return (key1->m_spVB && key1->m_spVB->IsValidVtx() && !key1->m_spVB->IsLock() );
|
||
}
|
||
|
||
KSeqObject* KMeshSeqObject::Clone()
|
||
{
|
||
KMeshSeqObject *obj = new KMeshSeqObject;
|
||
obj->SetMeshRes( m_spResMesh );
|
||
obj->SetMatrixRes( m_spResMatrix );
|
||
obj->SetVisibilityRes( m_spResVis );
|
||
obj->SetUVAniRes( m_spResUV );
|
||
// sonador 1.8.10 아바타 텍스쳐 그룹 적용(페이스 컷 포함)
|
||
if( !m_bUseDefaultTexture )
|
||
{
|
||
for( int n( 0 ); n < obj->m_nPrMeshCount; ++n )
|
||
obj->m_pPrMesh[ n ].SetTexture( this->m_pPrMesh[ n ].GetTexPack() );
|
||
obj->m_bUseDefaultTexture = false;
|
||
}
|
||
return obj;
|
||
}
|
||
|
||
const short aIntWinkTime[] = { 27, 23, 15, 37, 19, 20, 43, 35, 49, 9 };
|
||
|
||
void KMeshSeqObject::realizeTime()
|
||
{
|
||
if ( m_dwRealizedTime == m_dwTime )
|
||
return;
|
||
|
||
// Ignore dwTime and use system-time instead
|
||
DWORD dwTime=GetSafeTickCount();
|
||
|
||
if (!morph_primitivelist.empty())
|
||
{
|
||
currentFrame = (dwTime / (animationDelay+1)) % loopWindowSize;
|
||
|
||
previousTime = dwTime;
|
||
|
||
if( checkTime == 0 )
|
||
checkTime = dwTime;
|
||
|
||
if( (dwTime - checkTime) > OLDMORPH_MESH_CHCKTIME )
|
||
{
|
||
_oldmorphClear();
|
||
checkTime = dwTime;
|
||
}
|
||
}
|
||
else
|
||
{ //위의 타임 변수를 공유 하기 때문에 위 기능과 동시에 안됨.(같이 되게 하려면, 변수 분리)
|
||
if( m_bUseWink )
|
||
{
|
||
if( previousTime == 0 )
|
||
previousTime = dwTime;
|
||
|
||
int count = m_spResMesh->GetResCount();
|
||
if( count > 0 )
|
||
{
|
||
if( m_bFlipWink )
|
||
{
|
||
if( (dwTime - previousTime) > KEEP_TIME_WINK )
|
||
{
|
||
for(int i = 0; i < count; ++i)
|
||
m_pPrMesh[i].SetDiffuseTexture( m_spBackUpDiffTexture );
|
||
m_bFlipWink = false;
|
||
|
||
previousTime = dwTime;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if( (dwTime - previousTime) > checkTime )
|
||
{
|
||
short nRandIndex = rand()%10;
|
||
short nValue = rand()%100;
|
||
|
||
if( aIntWinkTime[nRandIndex] > nValue )
|
||
{
|
||
for(int i = 0; i < count; ++i)
|
||
{
|
||
m_spBackUpDiffTexture = m_pPrMesh[i].GetDiffuseTexture();
|
||
m_pPrMesh[i].SetDiffuseTexture( m_spWinkTexture );
|
||
}
|
||
m_bFlipWink = true;
|
||
}
|
||
|
||
previousTime = dwTime;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
m_dwRealizedTime = m_dwTime;
|
||
|
||
if( m_pBoneMatList == NULL || m_spResMesh->GetWeightResCount() == 0 )
|
||
{
|
||
//Effect 등 뼈없는 넘들이 사용 한다.
|
||
//나중에 Bone을 사용하는 Effect를 추가 하자~
|
||
if ( m_spResVis != NULL )
|
||
{
|
||
m_spResVis->GetVisibility(static_cast<int>(m_dwTime), &m_fVisResult);
|
||
}
|
||
|
||
if ( m_spResMatrix != NULL )
|
||
{
|
||
m_spResMatrix->GetLerpMatrix(static_cast<int>(m_dwTime), &m_matLocal);
|
||
}
|
||
|
||
if ( m_spResUV != NULL )
|
||
{
|
||
m_spResUV->GetLerpMatrix(static_cast<int>(m_dwTime), &m_matUV);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
KMeshPrimitive* KMeshSeqObject::getMeshPrimitive(int nIndex)
|
||
{
|
||
if (nIndex<0 || nIndex>=m_nPrMeshCount) return NULL;
|
||
return &(m_pPrMesh[nIndex]);
|
||
}
|
||
|
||
void KMeshSeqObject::_morphMeshMake()
|
||
{
|
||
assert(morph_primitivelist.empty());
|
||
|
||
int i;
|
||
float f, h;
|
||
|
||
for( int j=0; m_nPrMeshCount>j; j++ )
|
||
{
|
||
K3DResVertexAnimation *va = m_spResMesh->GetRes(j);
|
||
K3DResVertexAnimation::Key *key1 = NULL, *key2 = NULL;
|
||
|
||
va->GetData( m_dwTime, key1, key2 );
|
||
if( key1 == NULL || !key1->m_spVB->IsValidVtx() )
|
||
continue;
|
||
m_pPrMesh[j].SetVertexBuffer( key1->m_spVB );
|
||
|
||
FxResizedPrimitive* primitiveArray = new FxResizedPrimitive[numFrames];
|
||
|
||
assert(primitiveArray!=NULL);
|
||
|
||
//const char * p_FX = strstr( m_spResMesh->GetName(), "_fx" );
|
||
|
||
//if( p_FX == NULL )
|
||
//{
|
||
// for (i=0; i<numFrames; i++)
|
||
// primitiveArray[i].SetEnable( false );
|
||
//}
|
||
//else
|
||
{
|
||
//// 0프레임에서 (markFrame-1)프레임까지 primitive생성
|
||
h=(float)markFrame;
|
||
for (i=0; i<markFrame; i++) {
|
||
f=((float)i)/h; // [0, markFrame-1] 구간에 대해
|
||
primitiveArray[i].init(&m_pPrMesh[j], startSizeOffset*(1.f-f) + markSizeOffset*f
|
||
, interpolateColor(startColor0, markColor0, f)
|
||
, interpolateColor(startColor1, markColor1, f)
|
||
, strFxTexture.c_str(), additive
|
||
);
|
||
}
|
||
|
||
//// markFrame부터 (numFrames-1)프레임까지 primitive생성
|
||
h=(float)(numFrames-markFrame);
|
||
for (i=markFrame; i<numFrames; i++) {
|
||
f=((float)(i-markFrame))/h; // [markFrame, numFrames-1] 구간에 대해
|
||
primitiveArray[i].init(&m_pPrMesh[j], markSizeOffset*(1.f-f) + endSizeOffset*f
|
||
, interpolateColor(markColor0, endColor0, f)
|
||
, interpolateColor(markColor1, endColor1, f)
|
||
);
|
||
}
|
||
}
|
||
|
||
morph_primitivelist.push_back( primitiveArray );
|
||
m_nMorphPrimitiveCount = (int)morph_primitivelist.size();
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::_morphClear()
|
||
{
|
||
if( !morph_primitivelist.empty() )
|
||
{
|
||
for( unsigned int i(0); morph_primitivelist.size()>i; i++ )
|
||
{
|
||
clear_morph_primitivelist.push_back( morph_primitivelist[i] );
|
||
}
|
||
morph_primitivelist.clear();
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::_oldmorphClear()
|
||
{
|
||
if( !clear_morph_primitivelist.empty() )
|
||
{
|
||
for( unsigned int i(0); clear_morph_primitivelist.size()>i; i++ )
|
||
{
|
||
delete [] clear_morph_primitivelist[i];
|
||
}
|
||
clear_morph_primitivelist.clear();
|
||
}
|
||
}
|
||
|
||
void KMeshSeqObject::_morphInit()
|
||
{
|
||
_morphClear();
|
||
|
||
numFrames =0;
|
||
loopWindowSize=0;
|
||
markFrame =0;
|
||
|
||
animationDelay=0;
|
||
|
||
startColor0=startColor1=0xffffffff;
|
||
markColor0=markColor1 =0x80808080;
|
||
endColor0=endColor1 =0x00000000;
|
||
|
||
startSizeOffset=0.f;
|
||
markSizeOffset =0.f;
|
||
endSizeOffset =0.f;
|
||
|
||
currentFrame=0;
|
||
previousTime=0xffffffff;
|
||
|
||
additive = 0;
|
||
|
||
//땜방 텍스쳐 임
|
||
strFxTexture="LensFlare_01.dds";
|
||
}
|
||
|
||
void KMeshSeqObject::_morphDefaultSet()
|
||
{
|
||
const DWORD color0_mark=0x40e00000;
|
||
const DWORD color1_mark=0x20400000;
|
||
|
||
const DWORD color0_end=0x00000000;
|
||
const DWORD color1_end=0x004040c0;
|
||
|
||
/* // Red to green
|
||
const DWORD color0_mark=0x40e04040;
|
||
const DWORD color1_mark=0x20804040;
|
||
|
||
const DWORD color0_end=0x00000000;
|
||
const DWORD color1_end=0x00408040;
|
||
*/
|
||
|
||
//
|
||
// Set default parameters
|
||
//
|
||
numFrames = 32; // 전체 애니메이션 프레임 수. 대충 16~32
|
||
loopWindowSize = 6; // 반복될 애니메이션 간의 간격. 대충 4~8
|
||
animationDelay = 100; // 프레임 애니메이션 속도 (애니메이션 프레임 간의 시간간격)
|
||
|
||
markFrame = 8; // markFrame : 중간의 어떤 적절한 프레임. 애니메이션 경계를 주기 위해 사용
|
||
|
||
startColor0 = 0x00000000;
|
||
startColor1 = 0x00000000; // 0번 프레임의 컬러
|
||
markColor0 = color0_mark;
|
||
markColor1 = color1_mark;// (markFrame)번 프레임의 컬러
|
||
endColor0 = color0_end;
|
||
endColor1 = color1_end; // (numFrames-1)번 프레임의 컬러
|
||
|
||
startSizeOffset = 0.01f; // 0번 프레임의 메쉬 확대 크기. 대충 +0.01정도?
|
||
markSizeOffset = 0.10f; // (markFrame)번 프레임의 메쉬 크기.
|
||
endSizeOffset = 0.6f; // (numFrames-1)번 프레임의 메쉬 크기. 대충 +0.6정도?
|
||
}
|