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

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