237 lines
5.7 KiB
C++
237 lines
5.7 KiB
C++
#include "stdafx.h"
|
|
/*
|
|
SFxMesh.cpp
|
|
라펠즈 FX용 기본 primitive/model
|
|
2005/06, by JiYoung
|
|
*/
|
|
|
|
//#include <stdafx.h>
|
|
|
|
|
|
#include "SFxMesh.h"
|
|
#include "KViewPort.h"
|
|
|
|
#include <assert.h>
|
|
#include <toolkit/SafeTickCount.h>
|
|
|
|
#include "SDebug_Util.h"
|
|
|
|
//====================================================
|
|
// Utilities
|
|
//====================================================
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=============================================================
|
|
// FxAnimatedEdgeGlow
|
|
//=============================================================
|
|
|
|
FxAnimatedEdgeGlow::FxAnimatedEdgeGlow ()
|
|
{
|
|
numFrames=0;
|
|
primitiveArray=NULL;
|
|
close();
|
|
}
|
|
|
|
FxAnimatedEdgeGlow::~FxAnimatedEdgeGlow ()
|
|
{
|
|
close();
|
|
}
|
|
|
|
void FxAnimatedEdgeGlow::setParams( // init()에서 사용할 기초 파라미터들
|
|
int _numFrames // 전체 애니메이션 프레임 수. 대충 16~32
|
|
, int _loopWindowSize // 반복될 애니메이션 간의 간격. 대충 4~8
|
|
, int _animationDelay // 프레임 advance사이의 간격
|
|
, int _markFrame // 중간의 어떤 적절한 프레임. 애니메이션 경계를 주기 위해 사용
|
|
, DWORD _startColor0, DWORD _startColor1 // 0번 프레임의 컬러
|
|
, DWORD _markColor0, DWORD _markColor1 // (markFrame)번 프레임의 컬러
|
|
, DWORD _endColor0, DWORD _endColor1 // (numFrames-1)번 프레임의 컬러
|
|
, float _startSizeOffset // 0번 프레임의 메쉬 크기. 대충 +0.01정도?
|
|
, float _markSizeOffset // (markFrame)번 프레임의 메쉬 크기.
|
|
, float _endSizeOffset // (numFrames-1)번 프레임의 메쉬 크기. 대충 +0.3정도?
|
|
)
|
|
{
|
|
numFrames = _numFrames;
|
|
loopWindowSize = _loopWindowSize;
|
|
animationDelay = _animationDelay;
|
|
markFrame = _markFrame;
|
|
|
|
startColor0 = _startColor0; startColor1 = _startColor1;
|
|
markColor0 = _markColor0; markColor1 = _markColor1;
|
|
endColor0 = _endColor0; endColor1 = _endColor1;
|
|
|
|
startSizeOffset = _startSizeOffset;
|
|
markSizeOffset = _markSizeOffset;
|
|
endSizeOffset = _endSizeOffset;
|
|
}
|
|
|
|
|
|
void FxAnimatedEdgeGlow::init(KMeshPrimitive *source)
|
|
{
|
|
assert(primitiveArray==NULL);
|
|
|
|
int i;
|
|
float f, h;
|
|
|
|
|
|
// 현재 Texture가 없다!!!!!!!!
|
|
// 적당한 이름!!!!!!!
|
|
const char *textureName="LensFlare_01.dds";
|
|
|
|
primitiveArray=new FxResizedPrimitive[numFrames];
|
|
|
|
assert(primitiveArray!=NULL);
|
|
|
|
// 0프레임에서 (markFrame-1)프레임까지 primitive생성
|
|
|
|
h=(float)markFrame;
|
|
for (i=0; i<markFrame; i++) {
|
|
f=((float)i)/h; // [0, markFrame-1] 구간에 대해
|
|
primitiveArray[i].init(source, startSizeOffset*(1.f-f) + markSizeOffset*f
|
|
, interpolateColor(startColor0, markColor0, f)
|
|
, interpolateColor(startColor1, markColor1, f)
|
|
, textureName
|
|
);
|
|
}
|
|
|
|
// 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(source, markSizeOffset*(1.f-f) + endSizeOffset*f
|
|
, interpolateColor(markColor0, endColor0, f)
|
|
, interpolateColor(markColor1, endColor1, f)
|
|
);
|
|
}
|
|
|
|
// Save local matrix
|
|
if (source->GetTransform()!=NULL) {
|
|
// setLocalMatrix(source->GetTransform());
|
|
|
|
/* //!!TEST
|
|
// transform의 inverse matrix를 설정해 본다 (갸오~
|
|
K3DMatrix out;
|
|
float determinant;
|
|
if (NULL != K3DMatrixInverse( &out, &determinant, source->GetTransform())) {
|
|
setLocalMatrix(&out);
|
|
} else {
|
|
K3DMatrixIdentity(matLocal);
|
|
}
|
|
*/
|
|
K3DMatrixIdentity(matLocal);
|
|
} else {
|
|
K3DMatrixIdentity(matLocal);
|
|
}
|
|
}
|
|
|
|
|
|
void FxAnimatedEdgeGlow::close()
|
|
{
|
|
if (primitiveArray!=NULL) {
|
|
delete [] primitiveArray;
|
|
primitiveArray=NULL;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
int FxAnimatedEdgeGlow::Process(DWORD dwTime)
|
|
{
|
|
if (primitiveArray==NULL) return 0;
|
|
|
|
// Ignore dwTime and use system-time instead
|
|
dwTime=GetSafeTickCount();
|
|
|
|
currentFrame = (dwTime / (animationDelay+1)) % loopWindowSize;
|
|
|
|
previousTime = dwTime;
|
|
|
|
return MorphedModel::Process(dwTime);
|
|
}
|
|
|
|
void FxAnimatedEdgeGlow::Render( KViewportObject *viewport, DWORD flag, const K3DMatrix * pAttachMat)
|
|
{
|
|
if (primitiveArray!=NULL) {
|
|
K3DMatrix mat;
|
|
int i;
|
|
|
|
if ( m_pMatAttach != NULL && m_pMatParent != NULL )
|
|
{
|
|
K3DMatrix matTemp;
|
|
K3DMatrixMultiply( matTemp, *m_pMatAttach, *m_pMatParent );
|
|
K3DMatrixMultiply( m_matRoot, m_matTransform, matTemp );
|
|
}
|
|
else if ( m_pMatParent != NULL )
|
|
K3DMatrixMultiply( m_matRoot, m_matTransform, *m_pMatParent );
|
|
else
|
|
m_matRoot = matLocal;
|
|
|
|
//// Get local x parent
|
|
//if (m_pMatParent!=NULL) {
|
|
// K3DMatrixMultiply( mat, m_matTransform, *m_pMatParent);
|
|
//} else {
|
|
// mat=m_matTransform;
|
|
//}
|
|
|
|
//K3DMatrixMultiply(m_matResult, matLocal, mat);
|
|
|
|
for (i=currentFrame; i < numFrames; i+=loopWindowSize) {
|
|
primitiveArray[i].SetTransform(&m_matTransform, &m_matRoot);
|
|
viewport->Register( &primitiveArray[i], 0 );
|
|
}
|
|
}
|
|
}
|
|
|