1512 lines
33 KiB
C++
1512 lines
33 KiB
C++
#include "stdafx.h"
|
|
#include "KSeqPathEffect.h"
|
|
#include <mmo/ArTime.h>
|
|
#include "K3DTypes.h"
|
|
#include "TerrainMapEngine.h"
|
|
#include "KViewport.h"
|
|
|
|
|
|
|
|
CTerrainMapEngine* _KSeqPathEffect::m_pTerrainEngine = NULL;
|
|
CTerrainMapEngine* KSeqPathEffectChain::m_pTerrainEngine = NULL;
|
|
|
|
|
|
// KResEffectEmitter
|
|
|
|
// 에디터에서만 사용
|
|
KResource* KResEffectEmitter::Clone()
|
|
{
|
|
KResEffectEmitter* res = new KResEffectEmitter;
|
|
|
|
res->SetStartTime(m_dwStartTime);
|
|
res->SetLifeTime(m_nLifeTime);
|
|
res->SetStartPos(m_fStartPos);
|
|
res->SetVelocity(m_fVelocity);
|
|
|
|
res->SetDirectional(m_bDirectional);
|
|
|
|
int size = (int)m_vAniNames.size();
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
res->AddAniName(m_vAniNames[i].c_str(), m_vAniFileNames[i].c_str());
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
// 에디터에서만 사용
|
|
KResource* KResPathEffect::Clone()
|
|
{
|
|
KResPathEffect* res = new KResPathEffect;
|
|
|
|
int size = (int)m_vPoints.size();
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
K3DPoint p = m_vPoints[i];
|
|
res->AddPoints(&p, 1);
|
|
}
|
|
|
|
res->SetOfsZ(m_fOfsZ);
|
|
res->SetTotalPointVectorLength(m_fTotalPointVectorLength);
|
|
|
|
size = (int)m_vEmitters.size();
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
KResEffectEmitter* resEmitter = (KResEffectEmitter*) m_vEmitters[i]->Clone();
|
|
res->AddEmitter(resEmitter);
|
|
}
|
|
|
|
res->SetStartTime(m_dwStartTime);
|
|
res->SetLifeTime(m_dwLifeTime);
|
|
|
|
res->SetHasPolyLine(m_bHasPolyLine);
|
|
res->SetPolyLineWidth(m_fPolyLineWidth);
|
|
res->SetPolyLineColor(m_dwPolyLineColor);
|
|
res->SetPolyLineTexName(m_strPolyLineTexName.c_str());
|
|
|
|
return res;
|
|
}
|
|
|
|
// 다~ 지운다
|
|
void KResPathEffect::DelEmitters()
|
|
{
|
|
|
|
m_vEmitters.erase(m_vEmitters.begin(), m_vEmitters.end());
|
|
}
|
|
|
|
// 일부만 지운다
|
|
void KResPathEffect::DelEmitters(int nId, int numEmitters)
|
|
{
|
|
m_vEmitters.erase(m_vEmitters.begin() + nId, m_vEmitters.begin() + nId + numEmitters);
|
|
}
|
|
|
|
// 다~ 지운다
|
|
void KResPathEffect::DelPoints()
|
|
{
|
|
m_vPoints.erase(m_vPoints.begin(), m_vPoints.end());
|
|
m_fTotalPointVectorLength = 0.0f;
|
|
}
|
|
|
|
// 일부만 지운다
|
|
void KResPathEffect::DelPoints(int nId, int numPoint)
|
|
{
|
|
m_vPoints.erase(m_vPoints.begin() + nId, m_vPoints.begin() + nId + numPoint);
|
|
m_fTotalPointVectorLength = CalcPointVectorLength(0, m_vPoints.size() - 1);
|
|
}
|
|
|
|
void KResPathEffect::AddPoints(K3DPoint* pPoints, int numPoints)
|
|
{
|
|
int oldCap = m_vPoints.capacity();
|
|
int newCap = m_vPoints.size() + numPoints;
|
|
if(oldCap < newCap) m_vPoints.reserve(newCap);
|
|
//newCap = m_vPoints.capacity(); // 임시 코드
|
|
|
|
for(int i = 0; i < numPoints; i++)
|
|
{
|
|
m_vPoints.push_back(pPoints[i]);
|
|
|
|
// 새로 추가된 벡터의 길이를 전체 길이에 더한다
|
|
int size = (int)m_vPoints.size();
|
|
if(size >= 2)
|
|
{
|
|
float dx = m_vPoints[size - 1].x - m_vPoints[size - 2].x;
|
|
float dy = m_vPoints[size - 1].y - m_vPoints[size - 2].y;
|
|
|
|
m_fTotalPointVectorLength += sqrtf(dx * dx + dy * dy);
|
|
}
|
|
}
|
|
}
|
|
|
|
void KResPathEffect::InsertPoints(int nId, K3DPoint* pPoints, int numPoints)
|
|
{
|
|
int oldCap = (int)m_vPoints.capacity();
|
|
int newCap = (int)m_vPoints.size() + numPoints;
|
|
if(oldCap < newCap) m_vPoints.reserve(newCap);
|
|
|
|
for(int i = 0; i < numPoints; i++)
|
|
{
|
|
m_vPoints.insert(m_vPoints.begin() + nId + i, pPoints[i]);
|
|
|
|
//// 새로 추가된 벡터의 길이를 전체 길이에 더한다
|
|
//int size = m_vPoints.size();
|
|
//if(size >= 2)
|
|
//{
|
|
// float dx = m_vPoints[size - 1].x - m_vPoints[size - 2].x;
|
|
// float dy = m_vPoints[size - 1].y - m_vPoints[size - 2].y;
|
|
|
|
// m_fTotalPointVectorLength += sqrtf(dx * dx + dy * dy);
|
|
//}
|
|
|
|
m_fTotalPointVectorLength = CalcPointVectorLength(0, m_vPoints.size() - 1);
|
|
}
|
|
}
|
|
|
|
float KResPathEffect::CalcPointVectorLength(int nStart, int nEnd)
|
|
{
|
|
//m_fTotalPointVectorLength = 0.0f;
|
|
|
|
//int size = m_vPoints.size();
|
|
//if(size < 2) return;
|
|
|
|
if(nEnd >= (int) m_vPoints.size()) assert(0);
|
|
if(nStart < 0) assert(0);
|
|
if(nStart > nEnd) assert(0);
|
|
if(nStart == nEnd) return 0.0f;
|
|
|
|
float fRes = 0.0f;
|
|
|
|
for(int i = nStart; i < nEnd; i++)
|
|
{
|
|
float dx = m_vPoints[i + 1].x - m_vPoints[i].x;
|
|
float dy = m_vPoints[i + 1].y - m_vPoints[i].y;
|
|
|
|
fRes += sqrtf(dx * dx + dy * dy);
|
|
}
|
|
|
|
return fRes;
|
|
}
|
|
|
|
// 좀 느리다.. 에디터용으로만 쓰자.
|
|
int KResPathEffect::GetPoint(float fPos, K3DPoint& pRes)
|
|
{
|
|
if(fPos < 0.0f || fPos > 1.0f) return -1; // 에러
|
|
|
|
int numPoints = (int)m_vPoints.size();
|
|
int n;
|
|
|
|
if(fPos == 1.0f) // 예외 처리
|
|
{
|
|
pRes = m_vPoints[numPoints - 1];
|
|
return (numPoints - 1);
|
|
}
|
|
|
|
fPos *= m_fTotalPointVectorLength; // 절대 좌표값으로 바꾼다.
|
|
|
|
for(n = 0; n < numPoints; n++)
|
|
{
|
|
//if(m_vPoints[n].fLength > fPos) break;
|
|
if(CalcPointVectorLength(0, n) > fPos) break;
|
|
}
|
|
|
|
--n;
|
|
|
|
//float fraction = fPos - m_vVerts[n].fLength;
|
|
float fraction = fPos - CalcPointVectorLength(0, n);
|
|
|
|
K3DPoint vec = m_vPoints[n + 1] - m_vPoints[n];
|
|
float mag = sqrtf(vec.x * vec.x + vec.y * vec.y);
|
|
fraction /= mag;
|
|
|
|
pRes = m_vPoints[n] + vec * fraction;
|
|
|
|
return n;
|
|
}
|
|
|
|
//void KResPathEffect::SetStartTime()
|
|
//{
|
|
// m_dwStartTime = GetSafeTickCount();
|
|
//}
|
|
//
|
|
//DWORD KResPathEffect::GetStartTime()
|
|
//{
|
|
// return m_dwStartTime;
|
|
//}
|
|
|
|
|
|
// KResPathEffectChain
|
|
|
|
|
|
//void KResPathEffectChain::Clear()
|
|
//{
|
|
// // 리소스 릴리즈는 Seq 시리즈에서..
|
|
//
|
|
//
|
|
// //m_vPathEffects.erase(m_vPathEffects.begin(), m_vPathEffects.end());
|
|
// DelPathEffects();
|
|
//}
|
|
//
|
|
//// 다~ 지운다
|
|
//void KResPathEffectChain::DelPathEffects()
|
|
//{
|
|
// m_vPathEffects.erase(m_vPathEffects.begin(), m_vPathEffects.end());
|
|
//}
|
|
//
|
|
//// 일부만 지운다
|
|
//void KResPathEffectChain::DelPathEffects(int nId, int numPathEffects)
|
|
//{
|
|
// m_vPathEffects.erase(m_vPathEffects.begin() + nId, m_vPathEffects.begin() + nId + numPathEffects);
|
|
//}
|
|
|
|
|
|
//void KResPathEffectChain::AddPathEffect(KResPathEffect* pPathEffect)
|
|
//{
|
|
// //int oldCap = m_vPoints.capacity();
|
|
// //int newCap = m_vPoints.size() + numPoints;
|
|
// //if(oldCap < newCap) m_vPoints.reserve(newCap);
|
|
//
|
|
// m_vPathEffects.push_back(pPathEffect);
|
|
//}
|
|
|
|
|
|
// KEffectEmitter
|
|
|
|
KEffectEmitter::KEffectEmitter()
|
|
{
|
|
m_bActive = FALSE;
|
|
//m_bActive = TRUE;
|
|
m_dwCurrTime = 0xFFFFFFFF;
|
|
m_fCurrPos = 0.0f;
|
|
m_pSeqModel = NULL;
|
|
m_dwStartTime = 0;
|
|
m_nLifeTime = -1;
|
|
}
|
|
|
|
KEffectEmitter::~KEffectEmitter()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void KEffectEmitter::Clear()
|
|
{
|
|
DelSeqModel();
|
|
}
|
|
|
|
void KEffectEmitter::DelSeqModel()
|
|
{
|
|
SAFE_DELETE(m_pSeqModel);
|
|
}
|
|
|
|
void KEffectEmitter::SetRes(KResEffectEmitter* pRes)
|
|
{
|
|
Clear();
|
|
m_spRes = pRes;
|
|
|
|
assert(m_spRes != NULL);
|
|
|
|
m_fCurrPos = m_spRes->GetStartPos();
|
|
CreateSeqModel();
|
|
|
|
m_dwStartTime = m_spRes->GetStartTime();
|
|
m_nLifeTime = m_spRes->GetLifeTime();
|
|
}
|
|
|
|
KResEffectEmitter* KEffectEmitter::GetRes()
|
|
{
|
|
return m_spRes;
|
|
}
|
|
|
|
void KEffectEmitter::CreateSeqModel()
|
|
{
|
|
DelSeqModel();
|
|
|
|
int size = m_spRes->GetNumAnis();
|
|
if(size <= 0) return;
|
|
|
|
KSeqModel* pModel = new KSeqModel;
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
const char* szAniName = m_spRes->GetAniName(i);
|
|
const char* szFileName = m_spRes->GetAniFileName(i);
|
|
|
|
if(strcmp(szAniName, PFX_NONX3) == 0) continue;
|
|
if(strcmp(szFileName, PFX_NONX3) == 0) continue;
|
|
|
|
pModel->AddAnimation(szAniName, szFileName);
|
|
}
|
|
|
|
m_pSeqModel = pModel;
|
|
}
|
|
|
|
void KEffectEmitter::Update(DWORD dwTime)
|
|
{
|
|
//dwTime -= m_dwStartTime;
|
|
//if(dwTime < m_spRes->GetStartTime()) m_dwCurrTime = 0xFFFFFFFF;
|
|
//else m_dwCurrTime = dwTime - m_spRes->GetStartTime();
|
|
if(dwTime < m_dwStartTime) m_dwCurrTime = 0xFFFFFFFF;
|
|
else m_dwCurrTime = dwTime - m_dwStartTime;
|
|
|
|
BOOL bActive;
|
|
|
|
if(m_dwCurrTime == 0xFFFFFFFF)
|
|
{
|
|
bActive = FALSE;
|
|
// 알파값 처리도 여기서 하자.
|
|
}
|
|
//else if(m_spRes->GetLifeTime() < 0)
|
|
else if(m_nLifeTime < 0)
|
|
//if(m_spRes->GetLifeTime() < 0)
|
|
{
|
|
bActive = TRUE;
|
|
// 알파값 처리도 여기서 하자.
|
|
}
|
|
//else if((int) m_dwCurrTime > m_spRes->GetLifeTime())
|
|
else if((int) m_dwCurrTime > m_nLifeTime)
|
|
{
|
|
bActive = FALSE;
|
|
// 알파값 처리도 여기서 하자.
|
|
}
|
|
else
|
|
{
|
|
bActive = TRUE;
|
|
// 알파값 처리도 여기서 하자.
|
|
}
|
|
|
|
//m_fCurrPos = m_fStartPos + (m_fVelocity * (float) m_dwCurrTime; / 1000.0f);
|
|
//if(m_fCurrPos < 0.0f) m_fCurrPos = 0.0f;
|
|
//if(m_fCurrPos > 1.0f) m_fCurrPos = 1.0f;
|
|
|
|
if(bActive)
|
|
{
|
|
//m_fCurrPos = m_spRes->GetStartPos() + (m_spRes->GetVelocity() * (float) m_dwCurrTime; / 1000.0f);
|
|
//if(m_fCurrPos < 0.0f) m_fCurrPos = 0.0f;
|
|
//if(m_fCurrPos > 1.0f) m_fCurrPos = 1.0f;
|
|
|
|
if(!m_bActive) // 지금 막 active 되었다.
|
|
{
|
|
if(m_pSeqModel) m_pSeqModel->PlayAnimation((DWORD) ((float) m_dwCurrTime / 4.8f), "default", KSeqModel::SEQTYPE_LOOP);
|
|
}
|
|
else
|
|
{
|
|
if(m_pSeqModel) m_pSeqModel->Process((DWORD) ((float) m_dwCurrTime / 4.8f));
|
|
}
|
|
}
|
|
|
|
m_bActive = bActive;
|
|
}
|
|
|
|
BOOL KEffectEmitter::IsActive()
|
|
{
|
|
return m_bActive;
|
|
}
|
|
|
|
//void KEffectEmitter::SetActive(BOOL bActive)
|
|
//{
|
|
// m_bActive = bActive;
|
|
//}
|
|
|
|
float KEffectEmitter::GetPos()
|
|
{
|
|
return m_fCurrPos;
|
|
}
|
|
|
|
void KEffectEmitter::SetPos(float fPos)
|
|
{
|
|
m_fCurrPos = fPos;
|
|
}
|
|
|
|
//void KEffectEmitter::SetSeqModel(KSeqModel* pSeqModel)
|
|
//{
|
|
// m_pSeqModel = pSeqModel;
|
|
//}
|
|
|
|
KSeqModel* KEffectEmitter::GetSeqModel()
|
|
{
|
|
return m_pSeqModel;
|
|
}
|
|
|
|
//float KEffectEmitter::GetAlpha()
|
|
//{
|
|
//}
|
|
|
|
DWORD KEffectEmitter::GetCurrTime()
|
|
{
|
|
return m_dwCurrTime;
|
|
}
|
|
|
|
void KEffectEmitter::CalcTimes(float fScale)
|
|
{
|
|
m_dwStartTime = (DWORD) ((float) m_spRes->GetStartTime() * fScale);
|
|
|
|
if(m_spRes->GetLifeTime() < 0)
|
|
{
|
|
m_nLifeTime = -1;
|
|
}
|
|
else
|
|
{
|
|
m_nLifeTime = (int) ((float) m_spRes->GetLifeTime() * fScale);
|
|
}
|
|
}
|
|
|
|
DWORD KEffectEmitter::GetStartTime()
|
|
{
|
|
return m_dwStartTime;
|
|
}
|
|
|
|
int KEffectEmitter::GetLifeTime()
|
|
{
|
|
return m_nLifeTime;
|
|
}
|
|
|
|
|
|
// _KSeqPathEffect
|
|
|
|
_KSeqPathEffect::_KSeqPathEffect()
|
|
{
|
|
m_spRes = NULL;
|
|
m_fTotalVertVectorLength = 0.0f;
|
|
m_dwDrawMode = 0;
|
|
//m_pTerrainEngine = NULL;
|
|
m_bActive = FALSE;
|
|
//m_bActive = TRUE;
|
|
//K3DMatrixIdentity(m_Mat);
|
|
m_pMat = NULL;
|
|
m_dwStartTime = 0;
|
|
m_dwLifeTime = 0;
|
|
}
|
|
|
|
_KSeqPathEffect::~_KSeqPathEffect()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void _KSeqPathEffect::Clear()
|
|
{
|
|
m_vVerts.erase(m_vVerts.begin(), m_vVerts.end());
|
|
m_fTotalVertVectorLength = 0.0f;
|
|
|
|
// DelSeqModels();
|
|
DelEmitters();
|
|
DelPolyLineTex();
|
|
}
|
|
|
|
void _KSeqPathEffect::DelEmitters()
|
|
{
|
|
int size = m_vEmitters.size();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
SAFE_DELETE(m_vEmitters[i]);
|
|
}
|
|
|
|
m_vEmitters.erase(m_vEmitters.begin(), m_vEmitters.end());
|
|
}
|
|
|
|
void _KSeqPathEffect::SetRes(KResPathEffect* pRes)
|
|
{
|
|
Clear();
|
|
|
|
m_spRes = pRes;
|
|
|
|
if(m_spRes == NULL)
|
|
return;
|
|
|
|
int size = m_spRes->GetNumEmitters();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
KEffectEmitter* pEmitter = new KEffectEmitter;
|
|
pEmitter->SetRes(m_spRes->GetEmitter(i));
|
|
m_vEmitters.push_back(pEmitter);
|
|
}
|
|
|
|
m_prPolyLine.SetWidth(m_spRes->GetPolyLineWidth());
|
|
m_prPolyLine.SetColor(m_spRes->GetPolyLineColor());
|
|
CreatePolyLineTex();
|
|
|
|
m_dwStartTime = m_spRes->GetStartTime();
|
|
m_dwLifeTime = m_spRes->GetLifeTime();
|
|
}
|
|
|
|
KResPathEffect* _KSeqPathEffect::GetRes()
|
|
{
|
|
return m_spRes;
|
|
}
|
|
|
|
void _KSeqPathEffect::SetTime(DWORD dwTime)
|
|
{
|
|
//if(dwTime < m_spRes->GetStartTime()) m_dwTime = 0xFFFFFFFF;
|
|
//else m_dwTime = dwTime - m_spRes->GetStartTime();
|
|
if(dwTime < m_dwStartTime) m_dwTime = 0xFFFFFFFF;
|
|
else m_dwTime = dwTime - m_dwStartTime;
|
|
}
|
|
|
|
void _KSeqPathEffect::realizeTime()
|
|
{
|
|
if(m_dwRealizedTime == m_dwTime) return;
|
|
m_dwRealizedTime = m_dwTime;
|
|
|
|
if(m_dwRealizedTime == 0xFFFFFFFF)
|
|
{
|
|
m_bActive = FALSE;
|
|
}
|
|
//else if(m_spRes->GetLifeTime() < 0)
|
|
//{
|
|
// m_bActive = TRUE;
|
|
//}
|
|
//else if(m_dwRealizedTime > m_spRes->GetLifeTime())
|
|
else if(m_dwRealizedTime > m_dwLifeTime)
|
|
{
|
|
m_bActive = FALSE;
|
|
}
|
|
else
|
|
{
|
|
m_bActive = TRUE;
|
|
}
|
|
|
|
if(!m_bActive) return;
|
|
|
|
// 에미터들 업데이트
|
|
int size = m_vEmitters.size();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
m_vEmitters[i]->Update(m_dwRealizedTime);
|
|
}
|
|
}
|
|
|
|
//BOOL _KSeqPathEffect::IsActive()
|
|
//{
|
|
// return m_bActive;
|
|
//}
|
|
|
|
void _KSeqPathEffect::AddVert(K3DVector vPos)
|
|
{
|
|
PfxPathVertex pathVert;
|
|
pathVert.vPos = vPos;
|
|
|
|
int numVert = m_vVerts.size();
|
|
if(numVert >= 1)
|
|
{
|
|
K3DVector v = vPos - m_vVerts[numVert - 1].vPos;
|
|
m_fTotalVertVectorLength += v.Magnitude();
|
|
}
|
|
|
|
pathVert.fLength = m_fTotalVertVectorLength;
|
|
|
|
m_vVerts.push_back(pathVert);
|
|
}
|
|
|
|
// 느리다.. 프리미티브는 디버그 할 때만 그리자.
|
|
void _KSeqPathEffect::UpdatePr()
|
|
{
|
|
int numVerts = (int)m_vVerts.size();
|
|
//if(numVerts < 2) return;
|
|
if(numVerts < 1) return;
|
|
|
|
int numEmitters = m_vEmitters.size();
|
|
//if(numEmitters < 2) return;
|
|
|
|
float fStartPos, fEndPos;
|
|
|
|
// 다~ 그린다.. 0.0부터 1.0까지..
|
|
if(m_dwDrawMode & DRAW_ALLPR)
|
|
{
|
|
fStartPos = 0.0f;
|
|
fEndPos = 1.0f;
|
|
}
|
|
else
|
|
{
|
|
if(numEmitters < 2) return;
|
|
|
|
// 에미터 벡터의 처음 두 개의 요소가 시작과 끝
|
|
if(!m_vEmitters[0]->IsActive() || !m_vEmitters[1]->IsActive()) return;
|
|
|
|
fStartPos = m_vEmitters[0]->GetPos();
|
|
fEndPos = m_vEmitters[1]->GetPos();
|
|
|
|
if(fStartPos >= fEndPos) return;
|
|
}
|
|
|
|
int nStart, nEnd;
|
|
K3DVector vStart, vEnd;
|
|
nStart = GetVert(fStartPos, vStart);
|
|
nEnd = GetVert(fEndPos, vEnd);
|
|
|
|
int dn = nEnd - nStart;
|
|
int size;
|
|
if(fEndPos == 1.0f) size = dn + 1;
|
|
else size = dn + 2;
|
|
|
|
// int numEmitters = m_vEmitters.size();
|
|
|
|
//KLinePrimitive::SVertex* pVerts = new KLinePrimitive::SVertex[size];
|
|
//PfxPrVertex* pVerts = new PfxPrVertex[size];
|
|
PfxPrVertex* pVerts = new PfxPrVertex[size + numEmitters];
|
|
|
|
DWORD dwColor = 0xFFFFFF00; // 노란색
|
|
|
|
//pVerts[0].pos = vStart;
|
|
pVerts[0].pos.x = vStart.x;
|
|
pVerts[0].pos.y = vStart.y;
|
|
pVerts[0].pos.z = vStart.z;
|
|
pVerts[0].color = dwColor;
|
|
|
|
for(int i = 1; i <= dn; i++)
|
|
{
|
|
//pVerts[i].pos = m_vVerts[i + nStart];
|
|
pVerts[i].pos.x = m_vVerts[i + nStart].vPos.x;
|
|
pVerts[i].pos.y = m_vVerts[i + nStart].vPos.y;
|
|
pVerts[i].pos.z = m_vVerts[i + nStart].vPos.z;
|
|
pVerts[i].color = dwColor;
|
|
}
|
|
|
|
// emEnd->GetPos() == 1.0f 이라면 마지막 점은 이미 추가가 되었다.
|
|
if(fEndPos != 1.0f)
|
|
{
|
|
//pVerts[dn + 1].pos = vEnd;
|
|
pVerts[dn + 1].pos.x = vEnd.x;
|
|
pVerts[dn + 1].pos.y = vEnd.y;
|
|
pVerts[dn + 1].pos.z = vEnd.z;
|
|
pVerts[dn + 1].color = dwColor;
|
|
}
|
|
|
|
for(int i = 0; i < numEmitters; i++)
|
|
{
|
|
K3DVector vEmitter;
|
|
int nRet = GetVert(m_vEmitters[i]->GetPos(), vEmitter);
|
|
|
|
dwColor = 0xFFFF0000; // 붉은색.. 아마도..
|
|
|
|
pVerts[size + i].pos.x = vEmitter.x;
|
|
pVerts[size + i].pos.y = vEmitter.y;
|
|
pVerts[size + i].pos.z = vEmitter.z;
|
|
pVerts[size + i].color = dwColor;
|
|
}
|
|
|
|
//if(m_dwDrawMode & DRAW_POINT) m_prQuad.Update(pVerts, size);
|
|
if(m_dwDrawMode & DRAW_POINT) m_prQuad.Update(pVerts, size + numEmitters); // 에미터 쿼드도 함께 그린다.
|
|
if(m_dwDrawMode & DRAW_LINE) m_prLine.Update(pVerts, size);
|
|
|
|
delete[] pVerts;
|
|
}
|
|
|
|
int _KSeqPathEffect::GetVert(float fPos, K3DVertex& vRes)
|
|
{
|
|
if(fPos < 0.0f || fPos > 1.0f) return -1; // 에러
|
|
|
|
int numVert = m_vVerts.size();
|
|
int n;
|
|
|
|
if(fPos == 1.0f) // 예외 처리
|
|
{
|
|
vRes = m_vVerts[numVert - 1].vPos;
|
|
return (numVert - 1);
|
|
}
|
|
|
|
fPos *= m_fTotalVertVectorLength; // 절대 좌표값으로 바꾼다.
|
|
|
|
for(n = 0; n < numVert; n++)
|
|
{
|
|
if(m_vVerts[n].fLength > fPos) break;
|
|
}
|
|
|
|
--n;
|
|
|
|
float fraction = fPos - m_vVerts[n].fLength;
|
|
|
|
K3DVector vec = m_vVerts[n + 1].vPos - m_vVerts[n].vPos;
|
|
fraction /= vec.Magnitude();
|
|
|
|
vRes = m_vVerts[n].vPos + vec * fraction;
|
|
|
|
return n;
|
|
}
|
|
|
|
void _KSeqPathEffect::SetDrawMode(DWORD dwMode)
|
|
{
|
|
m_dwDrawMode = dwMode;
|
|
}
|
|
|
|
void _KSeqPathEffect::Render(KViewportObject* viewport, DWORD flag, const K3DMatrix* pAttachMat)
|
|
{
|
|
//realizeTime(); // KSeqPathEffectChain에서 해주니까 여기선 호출할 필요 없다.
|
|
|
|
// 프리미티브는 m_bActive == FALSE 라도 그린다.
|
|
if((m_dwDrawMode & DRAW_POINT) || (m_dwDrawMode & DRAW_LINE)) UpdatePr();
|
|
if(m_dwDrawMode & DRAW_POINT) viewport->Register(&m_prQuad, KRenderObject::RENDEREFX_QUAD);
|
|
if(m_dwDrawMode & DRAW_LINE) viewport->Register(&m_prLine, KRenderObject::RENDEREFX_LINE);
|
|
if((m_dwDrawMode & DRAW_POLYLINE) && m_bActive) RenderPolyLine(viewport);
|
|
|
|
if((m_dwDrawMode & DRAW_EMITTER) && m_bActive)
|
|
{
|
|
int numEmitters = m_vEmitters.size();
|
|
|
|
for(int i = 0; i < numEmitters; i++)
|
|
{
|
|
if(m_vEmitters[i]->IsActive())
|
|
{
|
|
RenderEmitter(i, viewport);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline void K3DMatrixSetDirection( K3DMatrix &Out, const K3DVector &StartPos, const K3DVector &EndPos )
|
|
{
|
|
K3DVector xVector, yVector, zVector;
|
|
yVector = StartPos-EndPos;
|
|
Normalize(yVector);
|
|
zVector = K3DVector( 0, 0, 1 );
|
|
|
|
K3DVectorCross( xVector, zVector, yVector );
|
|
Normalize(xVector);
|
|
K3DVectorCross( zVector, xVector, yVector );
|
|
Normalize(zVector);
|
|
|
|
// K3DMatrixIdentity( Out );
|
|
|
|
Out._11 = xVector.x; Out._12 = xVector.y; Out._13 = xVector.z;
|
|
Out._21 = yVector.x; Out._22 = yVector.y; Out._23 = yVector.z;
|
|
Out._31 = zVector.x; Out._32 = zVector.y; Out._33 = zVector.z;
|
|
}
|
|
|
|
void _KSeqPathEffect::RenderEmitter(int nEmitter, KViewportObject* viewport)
|
|
{
|
|
// vPos 위치에 SeqModel을 그린다
|
|
KSeqModel* pSeqModel = m_vEmitters[nEmitter]->GetSeqModel();
|
|
if(!pSeqModel) return;
|
|
|
|
// 정점이 없어도 에미터는 그릴 수 없다
|
|
int numVerts = m_vVerts.size();
|
|
if(numVerts < 1) return;
|
|
|
|
KResEffectEmitter* pResEmitter = m_vEmitters[nEmitter]->GetRes();
|
|
if(!pResEmitter) assert(0);
|
|
|
|
float fCurrPos = pResEmitter->GetStartPos() + (pResEmitter->GetVelocity() / m_fTotalVertVectorLength * (float) m_vEmitters[nEmitter]->GetCurrTime() / 1000.0f);
|
|
if(fCurrPos < 0.0f) fCurrPos = 0.0f;
|
|
if(fCurrPos > 1.0f) fCurrPos = 1.0f;
|
|
m_vEmitters[nEmitter]->SetPos(fCurrPos);
|
|
|
|
K3DVector vPos1, vPos2;
|
|
K3DMatrix mat;
|
|
int n = GetVert(m_vEmitters[nEmitter]->GetPos(), vPos1);
|
|
//int n = GetVert(fCurrPos, vPos1);
|
|
|
|
K3DMatrixIdentity(mat);
|
|
|
|
if(numVerts == 1 || !m_vEmitters[nEmitter]->GetRes()->IsDirectional())
|
|
{
|
|
mat.SetPosVector(vPos1);
|
|
}
|
|
else // numVerts > 1 && m_vEmitters[nEmitter]->GetRes()->IsDirectional()
|
|
{
|
|
mat.SetPosVector(vPos1);
|
|
|
|
if(n < numVerts - 1)
|
|
{
|
|
vPos2 = m_vVerts[n + 1].vPos;
|
|
K3DMatrixSetDirection(mat, vPos1, vPos2);
|
|
}
|
|
else // n == numVerts - 1;
|
|
{
|
|
vPos2 = m_vVerts[n - 1].vPos;
|
|
K3DMatrixSetDirection(mat, vPos2, vPos1);
|
|
}
|
|
|
|
K3DVector vX;
|
|
K3DMatrixGetXVector(vX, mat);
|
|
vX *= -1.0f;
|
|
mat.SetXVector(vX);
|
|
|
|
K3DVector vZ;
|
|
K3DMatrixGetZVector(vZ, mat);
|
|
vZ *= -1.0f;
|
|
mat.SetZVector(vZ);
|
|
}
|
|
|
|
pSeqModel->SetTransform(mat);
|
|
|
|
pSeqModel->Render(viewport);
|
|
}
|
|
|
|
void _KSeqPathEffect::RenderPolyLine(KViewportObject* viewport)
|
|
{
|
|
int numVerts = m_vVerts.size();
|
|
if(numVerts < 2) return;
|
|
|
|
int numEmitters = m_vEmitters.size();
|
|
if(numEmitters < 2) return;
|
|
|
|
if(!m_spRes->HasPolyLine() || !m_spPolyLineTex) return;
|
|
|
|
float fStartPos, fEndPos;
|
|
|
|
// 에미터 벡터의 처음 두 개의 요소가 시작과 끝
|
|
if(!m_vEmitters[0]->IsActive() || !m_vEmitters[1]->IsActive()) return;
|
|
|
|
fStartPos = m_vEmitters[0]->GetPos();
|
|
fEndPos = m_vEmitters[1]->GetPos();
|
|
|
|
m_prPolyLine.Update(fStartPos, fEndPos);
|
|
|
|
viewport->Register(&m_prPolyLine, KRenderObject::RENDEREFX_POLYLINE);
|
|
}
|
|
|
|
void _KSeqPathEffect::SetTerrainEngine(CTerrainMapEngine* pTerrain)
|
|
{
|
|
m_pTerrainEngine = pTerrain;
|
|
}
|
|
|
|
void _KSeqPathEffect::SetMat(K3DMatrix* pMat)
|
|
{
|
|
m_pMat = pMat;
|
|
}
|
|
|
|
void _KSeqPathEffect::CreatePolyLineTex()
|
|
{
|
|
const char* szTexName = m_spRes->GetPolyLineTexName();
|
|
if(strcmp(szTexName, PFX_NOTEX) == 0) return;
|
|
|
|
//TODO : 리소스 옵션 로딩 추가 작업 중.
|
|
NX3LoadPack loadpack;
|
|
loadpack.Init();
|
|
|
|
m_spPolyLineTex = KTextureManager::GetManager()->GetTexture(szTexName, &loadpack, true, KTextureManager::GetManager()->GetMipMapBiasLevel());
|
|
m_prPolyLine.SetTexture(m_spPolyLineTex);
|
|
}
|
|
|
|
void _KSeqPathEffect::DelPolyLineTex()
|
|
{
|
|
m_prPolyLine.SetTexture(NULL);
|
|
}
|
|
|
|
void _KSeqPathEffect::CalcTimes()
|
|
{
|
|
//float fNewScale = fScale * m_fTotalVertVectorLength / m_spRes->GetTotalPointVectorLength();
|
|
float fScale = m_fTotalVertVectorLength / m_spRes->GetTotalPointVectorLength();
|
|
|
|
m_dwStartTime = (DWORD) ((float) m_spRes->GetStartTime() * fScale);
|
|
m_dwLifeTime = (DWORD) ((float) m_spRes->GetLifeTime() * fScale);
|
|
|
|
int size = m_vEmitters.size();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
m_vEmitters[i]->CalcTimes(fScale);
|
|
}
|
|
}
|
|
|
|
DWORD _KSeqPathEffect::GetStartTime()
|
|
{
|
|
return m_dwStartTime;
|
|
}
|
|
|
|
DWORD _KSeqPathEffect::GetLifeTime()
|
|
{
|
|
return m_dwLifeTime;
|
|
}
|
|
|
|
void _KSeqPathEffect::SetLifeTime(DWORD dwLifeTime)
|
|
{
|
|
m_dwLifeTime = dwLifeTime;
|
|
}
|
|
|
|
|
|
// KSeqPathEffect
|
|
|
|
KSeqPathEffect::KSeqPathEffect()
|
|
{
|
|
}
|
|
|
|
KSeqPathEffect::~KSeqPathEffect()
|
|
{
|
|
}
|
|
|
|
KSeqObject* KSeqPathEffect::Clone()
|
|
{
|
|
KSeqPathEffect *obj = new KSeqPathEffect;
|
|
obj->SetRes(m_spRes);
|
|
return obj;
|
|
}
|
|
|
|
void KSeqPathEffect::Update()
|
|
{
|
|
int oldCap = m_vVerts.capacity();
|
|
int newCap = m_spRes->GetNumPoints();
|
|
if(oldCap < newCap) m_vVerts.reserve(newCap);
|
|
|
|
m_vVerts.erase(m_vVerts.begin(), m_vVerts.end());
|
|
m_fTotalVertVectorLength = 0.0f;
|
|
|
|
if(m_dwDrawMode & DRAW_POLYLINE) m_prPolyLine.Clear();
|
|
|
|
PointsToVerts();
|
|
|
|
if(m_dwDrawMode & DRAW_POLYLINE) m_prPolyLine.Update();
|
|
}
|
|
|
|
// 느림.. 에디터용
|
|
void KSeqPathEffect::PointsToVerts()
|
|
{
|
|
int size = m_spRes->GetNumPoints();
|
|
K3DPoint* pPoints = m_spRes->GetPoints();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
K3DVector vTemp, vRes;
|
|
|
|
vTemp.x = pPoints[i].x;
|
|
vTemp.y = pPoints[i].y;
|
|
vTemp.z = 0.0f;
|
|
|
|
if(m_pMat) K3DVectorTransform(vRes, vTemp, *m_pMat);
|
|
else vRes = vTemp;
|
|
|
|
vRes.z = m_spRes->GetOfsZ();
|
|
|
|
AddVert(vRes);
|
|
|
|
if(m_dwDrawMode & DRAW_POLYLINE)
|
|
{
|
|
m_prPolyLine.AddPathVert(vRes);
|
|
m_prPolyLine.AddPathNormal(K3DVector(0.0f, 0.0f, 1.0f));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// KSeqPathEffectGround
|
|
|
|
KSeqPathEffectGround::KSeqPathEffectGround()
|
|
{
|
|
}
|
|
|
|
KSeqPathEffectGround::~KSeqPathEffectGround()
|
|
{
|
|
}
|
|
|
|
KSeqObject* KSeqPathEffectGround::Clone()
|
|
{
|
|
KSeqPathEffectGround *obj = new KSeqPathEffectGround;
|
|
obj->SetRes(m_spRes);
|
|
return obj;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
float OFS_XY = 1.0f;
|
|
}
|
|
|
|
// m_vPoints를 땅에 붙여서 m_vVerts를 얻는다. - 매 프레임마다 호출할 필요 없다. 처음 이펙트가 시작될 때나 패쓰의 변경이 있을때만 호출해주면 된다.
|
|
void KSeqPathEffectGround::Update()
|
|
{
|
|
if(!m_pTerrainEngine)
|
|
{
|
|
assert(0 && "SetTerrainEngine() 부터 먼저 호출하셔.");
|
|
return;
|
|
}
|
|
|
|
int oldCap = m_vVerts.capacity();
|
|
//int newCap = (int) (m_fTotalPointVectorLength / pTerrain->GetTileLength() * 4.0f); // 대개의 경우 4.0f는 충분한 값이다.
|
|
int newCap = (int) (m_spRes->GetTotalPointVectorLength() / m_pTerrainEngine->GetTileLength() * 4.0f); // 대개의 경우 4.0f는 충분한 값이다.
|
|
if(oldCap < newCap) m_vVerts.reserve(newCap);
|
|
|
|
m_vVerts.erase(m_vVerts.begin(), m_vVerts.end());
|
|
m_fTotalVertVectorLength = 0.0f;
|
|
|
|
if(m_dwDrawMode & DRAW_POLYLINE) m_prPolyLine.Clear();
|
|
|
|
AttachToTerrain();
|
|
|
|
if(m_dwDrawMode & DRAW_POLYLINE) m_prPolyLine.Update();
|
|
}
|
|
|
|
void KSeqPathEffectGround::AttachToTerrain()
|
|
{
|
|
//int numPoints = m_vPoints.size();
|
|
int numPoints = m_spRes->GetNumPoints();
|
|
|
|
for(int i = 0; i < numPoints - 1; i++)
|
|
{
|
|
//AttachToTerrain(m_vPoints[i], m_vPoints[i + 1]);
|
|
AttachToTerrain(m_spRes->GetPoint(i), m_spRes->GetPoint(i + 1));
|
|
}
|
|
|
|
// 마지막 점은 수동으로 벡터 변수에 넣어줘야 한다.
|
|
//int n = numPoints - 1;
|
|
K3DPoint lastPoint = m_spRes->GetPoint(numPoints - 1);
|
|
K3DVector vTemp, vTarget;
|
|
vTemp.x = lastPoint.x;
|
|
vTemp.y = lastPoint.y;
|
|
vTemp.z = 0.0f;
|
|
|
|
if(m_pMat)
|
|
{
|
|
K3DVectorTransform(vTarget, vTemp, *m_pMat);
|
|
}
|
|
else
|
|
{
|
|
vTarget = vTemp;
|
|
}
|
|
|
|
K3DVector v[3];
|
|
//m_pTerrainEngine->GetTerrainTriangle(m_vPoints[n].x, m_vPoints[n].y, v[0], v[1], v[2]);
|
|
m_pTerrainEngine->GetTerrainTriangle(vTarget.x, vTarget.y, v[0], v[1], v[2]);
|
|
|
|
// 높이 구하고
|
|
//float fTilt1 = ( m_vPoints[n].y - (v[0].y) ) / ( (v[1].y) - (v[0].y) );
|
|
//float fTilt2 = ( m_vPoints[n].y - (v[0].y) ) / ( (v[2].y) - (v[0].y) );
|
|
float fTilt1 = (vTarget.y - (v[0].y)) / ((v[1].y) - (v[0].y));
|
|
float fTilt2 = (vTarget.y - (v[0].y)) / ((v[2].y) - (v[0].y));
|
|
|
|
float z1 = v[0].z + ( v[1].z - v[0].z ) * fTilt1;
|
|
float x1 = v[0].x + ( v[1].x - v[0].x ) * fTilt1;
|
|
float z2 = v[0].z + ( v[2].z - v[0].z ) * fTilt2;
|
|
float x2 = v[0].x + ( v[2].x - v[0].x ) * fTilt2;
|
|
|
|
//float fHeight = z1 + ( z2 - z1 ) * ( m_vPoints[n].x - x1 ) / ( x2 - x1 );
|
|
float fHeight = z1 + (z2 - z1) * (vTarget.x - x1) / (x2 - x1);
|
|
|
|
// 이 점을 멤버 벡터 변수에 추가
|
|
//K3DVector vRes(m_vPoints[n].x, m_vPoints[n].y, fHeight + m_fOfsZ);
|
|
K3DVector vRes(vTarget.x, vTarget.y, fHeight + m_spRes->GetOfsZ());
|
|
//m_vVerts.push_back(vRes);
|
|
AddVert(vRes);
|
|
|
|
if(m_dwDrawMode & DRAW_POLYLINE)
|
|
{
|
|
m_prPolyLine.AddPathVert(vRes);
|
|
|
|
K3DVector vec1, vec2;
|
|
vec1 = v[1] - v[0];
|
|
vec2 = v[2] - v[0];
|
|
|
|
K3DVector normal = CrossProduct(vec1, vec2);
|
|
//K3DVector normal = CrossProduct(vec2, vec1);
|
|
Normalize(normal);
|
|
|
|
m_prPolyLine.AddPathNormal(normal);
|
|
}
|
|
}
|
|
|
|
void KSeqPathEffectGround::AttachToTerrain(K3DPoint p1, K3DPoint p2)
|
|
{
|
|
K3DVector vTemp1, vTemp2, vTarget1, vTarget2;
|
|
vTemp1.x = p1.x;
|
|
vTemp1.y = p1.y;
|
|
vTemp1.z = 0.0f;
|
|
vTemp2.x = p2.x;
|
|
vTemp2.y = p2.y;
|
|
vTemp2.z = 0.0f;
|
|
|
|
if(m_pMat)
|
|
{
|
|
K3DVectorTransform(vTarget1, vTemp1, *m_pMat);
|
|
K3DVectorTransform(vTarget2, vTemp2, *m_pMat);
|
|
}
|
|
else
|
|
{
|
|
vTarget1 = vTemp1;
|
|
vTarget2 = vTemp2;
|
|
}
|
|
|
|
K3DVector v[3];
|
|
m_pTerrainEngine->GetTerrainTriangle(vTarget1.x, vTarget1.y, v[0], v[1], v[2]);
|
|
|
|
// 높이 구하고
|
|
float fTilt1 = ( vTarget1.y - (v[0].y) ) / ( (v[1].y) - (v[0].y) );
|
|
float fTilt2 = ( vTarget1.y - (v[0].y) ) / ( (v[2].y) - (v[0].y) );
|
|
|
|
float z1 = v[0].z + ( v[1].z - v[0].z ) * fTilt1;
|
|
float x1 = v[0].x + ( v[1].x - v[0].x ) * fTilt1;
|
|
float z2 = v[0].z + ( v[2].z - v[0].z ) * fTilt2;
|
|
float x2 = v[0].x + ( v[2].x - v[0].x ) * fTilt2;
|
|
|
|
float fHeight = z1 + ( z2 - z1 ) * ( vTarget1.x - x1 ) / ( x2 - x1 );
|
|
|
|
// 이 점을 멤버 벡터 변수에 추가
|
|
//K3DVector vRes(p1.x, p1.y, fHeight + m_fOfsZ);
|
|
K3DVector vRes(vTarget1.x, vTarget1.y, fHeight + m_spRes->GetOfsZ());
|
|
//m_vVerts.push_back(vRes);
|
|
AddVert(vRes);
|
|
|
|
if(m_dwDrawMode & DRAW_POLYLINE)
|
|
{
|
|
m_prPolyLine.AddPathVert(vRes);
|
|
|
|
K3DVector vec1, vec2;
|
|
vec1 = v[1] - v[0];
|
|
vec2 = v[2] - v[0];
|
|
|
|
K3DVector normal = CrossProduct(vec1, vec2);
|
|
//K3DVector normal = CrossProduct(vec2, vec1);
|
|
Normalize(normal);
|
|
|
|
m_prPolyLine.AddPathNormal(normal);
|
|
}
|
|
|
|
// p1p2 벡터와 삼각형의 세 모서리와의 교점 및 t를 구하고
|
|
float fraction = 1.0f;
|
|
float t1, t2, denom;
|
|
//float x1 = p1.x; float x2 = p2.x;
|
|
//x1 = p1.x; x2 = p2.x;
|
|
x1 = vTarget1.x; x2 = vTarget2.x;
|
|
//float y1 = p1.y; float y2 = p2.y;
|
|
float y1 = vTarget1.y; float y2 = vTarget2.y;
|
|
float x3, x4, y3, y4;
|
|
|
|
for(int i = 0; i < 3; i++)
|
|
{
|
|
x3 = v[i].x; x4 = v[(i + 1) % 3].x;
|
|
y3 = v[i].y; y4 = v[(i + 1) % 3].y;
|
|
|
|
denom = ((y4- y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));
|
|
if(fabsf(denom) < 0.001f) continue;
|
|
|
|
t1 = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));
|
|
t1 /= denom;
|
|
if(t1 <= 0.0f || t1 >= 1.0f) continue;
|
|
|
|
t2 = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));
|
|
t2 /= denom;
|
|
if(t2 <= 0.0f || t2 >= 1.0f) continue;
|
|
|
|
if(t1 < fraction) fraction = t1;
|
|
}
|
|
|
|
//float offset = 0.1f;
|
|
//float offset = 1.0f;
|
|
|
|
// 아주 작은 값을 더해서 얻은 점을 포함하는 삼각형을 또 구한다
|
|
// 이것을 fraction >= 1.0f 일 때까지 반복
|
|
|
|
if(fraction < 1.0f)
|
|
//if(fraction < 0.999f)
|
|
{
|
|
//fraction += e; // 이렇게 하면 안되고
|
|
|
|
K3DPoint pVec = p2 - p1;
|
|
K3DPoint pNew = p1 + pVec * fraction;
|
|
|
|
K3DPoint pVecTemp = p2 - pNew;
|
|
if(sqrtf(pVecTemp.x * pVecTemp.x + pVecTemp.y * pVecTemp.y) <= OFS_XY) return;
|
|
|
|
// 이렇게 해야지
|
|
float mag = sqrtf(pVec.x * pVec.x + pVec.y * pVec.y);
|
|
pVec /= mag;
|
|
|
|
//pNew = pNew + pVec * m_fOfsXY;
|
|
pNew = pNew + pVec * OFS_XY;
|
|
|
|
AttachToTerrain(pNew, p2);
|
|
}
|
|
}
|
|
|
|
|
|
// KSeqPathEffectChain
|
|
//
|
|
// 멤버 함수 호출 순서
|
|
// 1. 생성
|
|
// 2. SetTerrainEngine() - KSeqPathEffectGround
|
|
// 3. SetType() - KSeqPathEffect
|
|
// 4. SetRes() - 로드할때 자동 호출
|
|
// 5. SetDrawMode()
|
|
// 6. SetPos()
|
|
// 7. Update() - SetPos()에서 자동 호출
|
|
// 8. SetTime() - Loop
|
|
// 9. Render() - Loop
|
|
// 10. 파괴
|
|
|
|
KSeqPathEffectChain::KSeqPathEffectChain()
|
|
{
|
|
// m_dwStartTime = 0;
|
|
m_dwDrawMode = 0;
|
|
//m_dwDrawMode = _KSeqPathEffect::DRAW_EMITTER;
|
|
//m_pTerrainEngine = NULL;
|
|
//m_dwType = TYPE_ORDINARY;
|
|
m_dwType = TYPE_GROUND;
|
|
//m_bDirectional = FALSE;
|
|
K3DMatrixIdentity(m_Mat);
|
|
}
|
|
|
|
KSeqPathEffectChain::~KSeqPathEffectChain()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void KSeqPathEffectChain::SetType(DWORD dwType)
|
|
{
|
|
m_dwType = dwType;
|
|
}
|
|
|
|
void KSeqPathEffectChain::Clear()
|
|
{
|
|
//SAFE_DELETE(m_spRes);
|
|
DelPathEffects();
|
|
//DelSeqModels();
|
|
}
|
|
|
|
KSeqObject* KSeqPathEffectChain::Clone()
|
|
{
|
|
KSeqPathEffectChain *obj = new KSeqPathEffectChain;
|
|
obj->SetType(m_dwType);
|
|
obj->SetRes(m_spRes);
|
|
return obj;
|
|
}
|
|
|
|
void KSeqPathEffectChain::SetRes(KResPathEffectChain* pRes)
|
|
{
|
|
Clear();
|
|
m_spRes = pRes;
|
|
|
|
if(m_spRes == NULL)
|
|
return;
|
|
|
|
int size = m_spRes->GetNumPathEffects();
|
|
|
|
m_interval.SetStart(0);
|
|
int nEnd = 0;
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
_KSeqPathEffect* pPathEffect = NULL;
|
|
|
|
if(m_dwType == TYPE_ORDINARY)
|
|
{
|
|
pPathEffect = new KSeqPathEffect;
|
|
}
|
|
else if(m_dwType == TYPE_GROUND)
|
|
{
|
|
pPathEffect = new KSeqPathEffectGround;
|
|
}
|
|
else
|
|
{
|
|
assert(0 && "m_dwType 에 쓰레기값이..!");
|
|
return;
|
|
}
|
|
|
|
pPathEffect->SetRes(m_spRes->GetPathEffect(i));
|
|
pPathEffect->SetDrawMode(m_dwDrawMode); // 새로 추가되는 pfx에 pfxchain의 DrawMode를 적용한다.
|
|
m_vPathEffects.push_back(pPathEffect);
|
|
|
|
if(nEnd < (int) (m_spRes->GetPathEffect(i)->GetStartTime() + m_spRes->GetPathEffect(i)->GetLifeTime()))
|
|
nEnd = (int) (m_spRes->GetPathEffect(i)->GetStartTime() + m_spRes->GetPathEffect(i)->GetLifeTime());
|
|
}
|
|
|
|
m_interval.SetEnd(nEnd);
|
|
}
|
|
|
|
KResPathEffectChain* KSeqPathEffectChain::GetRes()
|
|
{
|
|
return m_spRes;
|
|
}
|
|
|
|
void KSeqPathEffectChain::SetTime(DWORD dwTime)
|
|
{
|
|
m_dwTime = dwTime;
|
|
|
|
int size = m_vPathEffects.size();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
m_vPathEffects[i]->SetTime(m_dwTime);
|
|
}
|
|
}
|
|
|
|
void KSeqPathEffectChain::realizeTime()
|
|
{
|
|
if(m_dwRealizedTime == m_dwTime) return;
|
|
m_dwRealizedTime = m_dwTime;
|
|
|
|
int size = m_vPathEffects.size();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
m_vPathEffects[i]->realizeTime();
|
|
}
|
|
}
|
|
|
|
void KSeqPathEffectChain::Update()
|
|
{
|
|
int size = m_vPathEffects.size();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
m_vPathEffects[i]->Update();
|
|
}
|
|
}
|
|
|
|
void KSeqPathEffectChain::Render(KViewportObject* viewport, DWORD flag, const K3DMatrix* pAttachMat)
|
|
{
|
|
realizeTime();
|
|
|
|
int size = (int)m_vPathEffects.size();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
//if(m_vPathEffects[i]->IsActive())
|
|
//{
|
|
m_vPathEffects[i]->Render(viewport, flag, pAttachMat);
|
|
//}
|
|
}
|
|
}
|
|
|
|
void KSeqPathEffectChain::DelPathEffects()
|
|
{
|
|
int size = m_vPathEffects.size();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
SAFE_DELETE(m_vPathEffects[i]);
|
|
}
|
|
|
|
m_vPathEffects.erase(m_vPathEffects.begin(), m_vPathEffects.end());
|
|
}
|
|
|
|
//void KSeqPathEffectChain::SetDrawMode()
|
|
//{
|
|
// int size = m_vPathEffects.size();
|
|
//
|
|
// for(int i = 0; i < size; i++)
|
|
// {
|
|
// m_vPathEffects[i]->SetDrawMode(m_dwDrawMode);
|
|
// }
|
|
//}
|
|
|
|
//void KSeqPathEffectChain::SetDrawMode(DWORD dwDrawMode)
|
|
//{
|
|
// m_dwDrawMode = dwDrawMode;
|
|
//
|
|
// SetDrawMode();
|
|
//}
|
|
|
|
void KSeqPathEffectChain::SetDrawMode(DWORD dwDrawMode)
|
|
{
|
|
m_dwDrawMode = dwDrawMode;
|
|
|
|
int size = m_vPathEffects.size();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
m_vPathEffects[i]->SetDrawMode(m_dwDrawMode);
|
|
}
|
|
}
|
|
|
|
void KSeqPathEffectChain::SetTerrainEngine(CTerrainMapEngine* pTerrain)
|
|
{
|
|
m_pTerrainEngine = pTerrain;
|
|
|
|
//int size = m_vPathEffects.size();
|
|
|
|
//for(int i = 0; i < size; i++)
|
|
//{
|
|
// m_vPathEffects[i]->SetTerrainEngine(m_pTerrainEngine);
|
|
//}
|
|
|
|
_KSeqPathEffect::SetTerrainEngine(m_pTerrainEngine);
|
|
}
|
|
//BOOL KSeqPathEffectChain::LoadSeqModels()
|
|
//{
|
|
// if(!m_spRes) return FALSE;
|
|
//
|
|
// int size = m_spRes->GetNumSeqModels();
|
|
//
|
|
// for(int i = 0; i < size; i++)
|
|
// {
|
|
// const char* szName = m_spRes->GetSeqModelName(i);
|
|
//
|
|
// KSeqModel* pSeqModel = new KSeqModel;
|
|
// pSeqModel->
|
|
// }
|
|
//}
|
|
|
|
//void KSeqPathEffectChain::DelSeqModels()
|
|
//{
|
|
// int size = m_vSeqModels.size();
|
|
//
|
|
// for(int i = 0; i < size; i++)
|
|
// {
|
|
// SAFE_DELETE(m_vSeqModels[i]);
|
|
// }
|
|
//
|
|
// m_vSeqModels.erase(m_vSeqModels.begin(), m_vSeqModels.end());
|
|
//}
|
|
|
|
void KSeqPathEffectChain::SetPos(K3DVector vOrigin)
|
|
{
|
|
K3DMatrixIdentity(m_Mat);
|
|
m_Mat.SetPosVector(vOrigin);
|
|
|
|
int size = m_vPathEffects.size();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
m_vPathEffects[i]->SetMat(&m_Mat);
|
|
}
|
|
|
|
Update();
|
|
|
|
CalcTimes();
|
|
}
|
|
|
|
void KSeqPathEffectChain::SetPos(K3DVector vOrigin, K3DVector vTarget)
|
|
{
|
|
//if(!m_bDirectional)
|
|
if(!m_spRes->IsDirectional())
|
|
{
|
|
// 이동만..
|
|
SetPos(vOrigin);
|
|
}
|
|
else
|
|
{
|
|
// 회전, 스케일, 이동
|
|
K3DMatrix matS, matTR;
|
|
K3DMatrixIdentity(m_Mat);
|
|
K3DMatrixIdentity(matS);
|
|
K3DMatrixIdentity(matTR);
|
|
|
|
K3DVector vDir = vTarget - vOrigin;
|
|
float fScale = vDir.Magnitude() / m_spRes->GetMag();
|
|
K3DMatrixScaling(matS, fScale, fScale, fScale);
|
|
|
|
matTR.SetPosVector(vOrigin);
|
|
K3DMatrixSetDirection(matTR, vOrigin, vTarget);
|
|
|
|
K3DVector vX;
|
|
K3DMatrixGetXVector(vX, matTR);
|
|
vX *= -1.0f;
|
|
matTR.SetXVector(vX);
|
|
|
|
K3DVector vZ;
|
|
K3DMatrixGetZVector(vZ, matTR);
|
|
vZ *= -1.0f;
|
|
matTR.SetZVector(vZ);
|
|
|
|
K3DMatrixMultiply(m_Mat, matS, matTR);
|
|
|
|
int size = m_vPathEffects.size();
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
m_vPathEffects[i]->SetMat(&m_Mat);
|
|
}
|
|
|
|
Update();
|
|
|
|
CalcTimes();
|
|
}
|
|
}
|
|
|
|
void KSeqPathEffectChain::CalcTimes()
|
|
{
|
|
int size = m_vPathEffects.size();
|
|
|
|
m_interval.SetStart(0);
|
|
int nEnd = 0;
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
m_vPathEffects[i]->CalcTimes();
|
|
|
|
if(nEnd < (int) (m_vPathEffects[i]->GetStartTime() + m_vPathEffects[i]->GetLifeTime()))
|
|
nEnd = (int) (m_vPathEffects[i]->GetStartTime() + m_vPathEffects[i]->GetLifeTime());
|
|
}
|
|
|
|
m_interval.SetEnd(nEnd);
|
|
|
|
if(m_spRes->DoesEndTogether())
|
|
{
|
|
DWORD dwLifeTime;
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
dwLifeTime = (DWORD) nEnd - m_vPathEffects[i]->GetStartTime();
|
|
m_vPathEffects[i]->SetLifeTime(dwLifeTime);
|
|
}
|
|
}
|
|
}
|