489 lines
13 KiB
C++
489 lines
13 KiB
C++
#include "StdAfx.h"
|
|
#include "../eterLib/ResourceManager.h"
|
|
#include "../eterLib/StateManager.h"
|
|
|
|
#include "WeaponTrace.h"
|
|
|
|
CDynamicPool<CWeaponTrace> CWeaponTrace::ms_kPool;
|
|
|
|
void CWeaponTrace::DestroySystem()
|
|
{
|
|
ms_kPool.Destroy();
|
|
}
|
|
|
|
void CWeaponTrace::Delete(CWeaponTrace* pkWTDel)
|
|
{
|
|
assert(pkWTDel!=NULL && "CWeaponTrace::Delete");
|
|
|
|
pkWTDel->Clear();
|
|
ms_kPool.Free(pkWTDel);
|
|
}
|
|
|
|
CWeaponTrace* CWeaponTrace::New()
|
|
{
|
|
return ms_kPool.Alloc();
|
|
}
|
|
|
|
void CWeaponTrace::Update(float fReachScale)
|
|
{
|
|
float fElapsedTime = CTimer::Instance().GetCurrentSecond() - m_fLastUpdate;
|
|
m_fLastUpdate = CTimer::Instance().GetCurrentSecond();
|
|
|
|
if (!m_pInstance)
|
|
return;
|
|
{
|
|
// 잔상을 남기는 시간 범위 내의 점들만 유지합니다.
|
|
TTimePointList::iterator it;
|
|
for(it=m_ShortTimePointList.begin();it!=m_ShortTimePointList.end();++it)
|
|
{
|
|
it->first += fElapsedTime;
|
|
if (it->first>m_fLifeTime)
|
|
{
|
|
it++;
|
|
break;
|
|
}
|
|
}
|
|
if (it!=m_ShortTimePointList.end())
|
|
m_ShortTimePointList.erase(it,m_ShortTimePointList.end());
|
|
for(it=m_LongTimePointList.begin();it!=m_LongTimePointList.end();++it)
|
|
{
|
|
it->first += fElapsedTime;
|
|
if (it->first>m_fLifeTime)
|
|
{
|
|
it++;
|
|
break;
|
|
}
|
|
}
|
|
if (it!=m_LongTimePointList.end())
|
|
m_LongTimePointList.erase(it, m_LongTimePointList.end());
|
|
}
|
|
|
|
if (m_isPlaying && m_fz>=0.0001f)
|
|
{
|
|
D3DXMATRIX * pMatrix;
|
|
if (m_pInstance->GetCompositeBoneMatrix(m_dwModelInstanceIndex, m_iBoneIndex, &pMatrix))
|
|
{
|
|
D3DXMATRIX * pBoneMat;
|
|
m_pInstance->GetBoneMatrix(m_dwModelInstanceIndex, m_iBoneIndex, &pBoneMat);
|
|
D3DXMATRIX mat = *pMatrix;
|
|
mat._41 = pBoneMat->_41;
|
|
mat._42 = pBoneMat->_42;
|
|
mat._43 = pBoneMat->_43;
|
|
// 현재 위치를 추가합니다.
|
|
D3DXMATRIX matPoint;
|
|
D3DXMATRIX matTranslation;
|
|
D3DXMATRIX matRotation;
|
|
|
|
//D3DXMatrixTranslation(&matTranslation, 0.0f, m_fLength, 0.0f);
|
|
D3DXMatrixTranslation(&matTranslation, 0.0f, 0.0f, m_fLength*fReachScale);
|
|
D3DXMatrixRotationZ(&matRotation, D3DXToRadian(m_fRotation));
|
|
|
|
|
|
matPoint = /**pMatrix*/mat * matRotation;
|
|
/*TPDTVertex PDTVertex;
|
|
PDTVertex.position.x = m_fx + matPoint._41;
|
|
PDTVertex.position.y = m_fy + matPoint._42;
|
|
PDTVertex.position.z = m_fz + matPoint._43;
|
|
PDTVertex.diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 0.1f);
|
|
m_PDTVertexVector.push_back(PDTVertex);*/
|
|
m_ShortTimePointList.push_front(
|
|
TTimePoint(
|
|
0.0f,
|
|
D3DXVECTOR3(
|
|
m_fx + matPoint._41,
|
|
m_fy + matPoint._42,
|
|
m_fz + matPoint._43
|
|
)
|
|
)
|
|
);
|
|
|
|
matPoint = matTranslation * matPoint;
|
|
/*PDTVertex.position.x = m_fx + matPoint._41;
|
|
PDTVertex.position.y = m_fy + matPoint._42;
|
|
PDTVertex.position.z = m_fz + matPoint._43;
|
|
PDTVertex.diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 0.1f);
|
|
m_PDTVertexVector.push_back(PDTVertex);*/
|
|
m_LongTimePointList.push_front(
|
|
TTimePoint(
|
|
0.0f,
|
|
D3DXVECTOR3(
|
|
m_fx + matPoint._41,
|
|
m_fy + matPoint._42,
|
|
m_fz + matPoint._43
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
//if (!BuildVertex())
|
|
// return;
|
|
}
|
|
|
|
bool CWeaponTrace::BuildVertex()
|
|
{
|
|
const int max_size = 300;
|
|
// calculate speed
|
|
float h[max_size];
|
|
float stk[max_size];
|
|
int sp=0;
|
|
D3DXVECTOR3 r[max_size];
|
|
|
|
if (m_LongTimePointList.size()<=1)
|
|
return false;
|
|
|
|
|
|
//Tracef("## %f %f %f\n", m_LongTimePointList[0].second.x, m_LongTimePointList[0].second.y, m_LongTimePointList[0].second.z);
|
|
|
|
/*m_LongTimePointList.clear();
|
|
m_LongTimePointList.push_back(TTimePoint(0.00,D3DXVECTOR3(0,0,0)));
|
|
m_LongTimePointList.push_back(TTimePoint(0.01,D3DXVECTOR3(0,1,0)));
|
|
m_LongTimePointList.push_back(TTimePoint(0.04,D3DXVECTOR3(0,1,0)));
|
|
m_LongTimePointList.push_back(TTimePoint(0.05,D3DXVECTOR3(0,0,0)));
|
|
m_ShortTimePointList = m_LongTimePointList;
|
|
|
|
*/
|
|
std::vector<TPDTVertex> m_ShortVertexVector, m_LongVertexVector;
|
|
|
|
float length = min(m_fLifeTime, m_LongTimePointList.back().first);
|
|
|
|
int n = m_LongTimePointList.size()-1;
|
|
assert(n<max_size-1);
|
|
|
|
// cubic spline
|
|
|
|
for(int loop = 0; loop<=1; ++loop)
|
|
{
|
|
TTimePointList & Input = (loop) ? m_LongTimePointList : m_ShortTimePointList;
|
|
std::vector<TPDTVertex> & Output = (loop) ? m_LongVertexVector : m_ShortVertexVector;
|
|
TTimePointList::iterator it;
|
|
int i;
|
|
|
|
for(i=0;i<n;++i)
|
|
{
|
|
h[i] = Input[i+1].first - Input[i].first;
|
|
r[i] = (Input[i+1].second - Input[i].second)*(3/h[i]);
|
|
}
|
|
r[n] = D3DXVECTOR3(0.0f,0.0f,0.0f);
|
|
for(i=n;i>0;i--)
|
|
{
|
|
r[i]+=r[i-1];
|
|
}
|
|
|
|
float rate = 0.5f;
|
|
r[0] *= 0.5f;
|
|
stk[sp++] = rate;
|
|
for(i=1;i<n;i++)
|
|
{
|
|
r[i]-=r[i-1];
|
|
rate = 1/(4-rate);
|
|
r[i] *= rate;
|
|
stk[sp++]=rate;
|
|
}
|
|
r[n]-=r[n-1];
|
|
rate = 1/(2-rate);
|
|
r[n]*=rate;
|
|
|
|
for(i=n-1;i>=0;i--)
|
|
{
|
|
r[i] -= stk[--sp] * r[i+1];
|
|
}
|
|
|
|
int base = 0;
|
|
D3DXVECTOR3 a,b,c,d;
|
|
D3DXVECTOR3 v3Tmp = Input[base+1].second-Input[base].second;
|
|
float timebase=0,timenext=h[base], dt=m_fSamplingTime;
|
|
a = Input[base].second;
|
|
b = r[base];
|
|
c = ( 3*v3Tmp - r[base+1]*h[base] - (2*h[base])*r[base] )
|
|
* (1/(h[base]*h[base]));
|
|
d = ( -2*v3Tmp + (r[base+1]+r[base])*h[base])
|
|
* (1/(h[base]*h[base]*h[base]));
|
|
|
|
for(float t = 0; t<=length; t+=dt)
|
|
{
|
|
while (t>timenext)
|
|
{
|
|
timebase = timenext;
|
|
base++;
|
|
if (base>=n) break;
|
|
D3DXVECTOR3 v3Tmp = Input[base+1].second-Input[base].second;
|
|
a = Input[base].second;
|
|
b = r[base];
|
|
c = ( 3*v3Tmp - r[base+1]*h[base] - (2*h[base])*r[base] )
|
|
* (1/(h[base]*h[base]));
|
|
d = ( -2*v3Tmp + (r[base+1]+r[base])*h[base])
|
|
* (1/(h[base]*h[base]*h[base]));
|
|
|
|
timenext+=h[base];
|
|
if (loop)
|
|
{
|
|
//Tracef("%f:%f %f %f\n",Input[base].first,Input[base].second.x,Input[base].second.y,Input[base].second.z);
|
|
}
|
|
}
|
|
if (base>n) break;
|
|
float cc = t - timebase;
|
|
|
|
TPDTVertex v;
|
|
//v.diffuse = D3DXCOLOR(0.3f,0.8f,1.0f, (loop)?max(1.0f-(t/m_fLifeTime),0.0f)/2:0.0f );
|
|
float ttt = min(max((t+Input[0].first)/m_fLifeTime,0.0f),1.0f);
|
|
v.diffuse = D3DXCOLOR(0.3f,0.8f,1.0f, (loop)?min(max((1.0f-ttt)*(1.0f-ttt)/2.5-0.1f,0.0f),1.0f):0.0f );
|
|
//v.diffuse = D3DXCOLOR(0.0f,0.0f,0.0f, (loop)?min(max((1.0f-ttt)*(1.0f-ttt)-0.1f,0.0f),1.0f):0.0f );
|
|
//v.diffuse = 0xffffffff;
|
|
v.position = a+cc*(b+cc*(c+cc*d)); // next position
|
|
v.texCoord.x = t/m_fLifeTime;
|
|
v.texCoord.y = loop ? 0 : 1;
|
|
Output.push_back(v);
|
|
if (loop)
|
|
{
|
|
// Tracef("%f %f %f\n", timebase,t,timenext);
|
|
//Tracef("a:%f %f %f\nb:%f %f %f \nc:%f %f %f \nd:%f %f %f, \n",,a.x,a.y,a.z,b.x,b.y,b.z,c.x,c.y,c.z,d.x,d.y,d.z);
|
|
|
|
//Tracef("%f %f %f\n",v.position.x,v.position.y,v.position.z);
|
|
/*D3DXMATRIX * pBoneMat;
|
|
m_pInstance->GetBoneMatrix(m_dwModelInstanceIndex, 55, &pBoneMat);
|
|
D3DXVECTOR3 vbone(m_fx+pBoneMat->_41,m_fy+pBoneMat->_42,m_fz+pBoneMat->_43);
|
|
float len = D3DXVec3Length(&(v.position-vbone));*/
|
|
}
|
|
}
|
|
}
|
|
|
|
// build vertex
|
|
|
|
m_PDTVertexVector.clear();
|
|
|
|
/*
|
|
TTimePointList::iterator lit1,lit2, sit1,sit2;
|
|
|
|
lit2 = lit1 = m_LongTimePointList.begin();
|
|
++lit2;
|
|
|
|
sit2 = sit1 = m_ShortTimePointList.begin();
|
|
++sit2;
|
|
*/
|
|
std::vector<TPDTVertex>::iterator lit,sit;
|
|
for(lit = m_LongVertexVector.begin(), sit = m_ShortVertexVector.begin();
|
|
lit != m_LongVertexVector.end();
|
|
++lit,++sit)
|
|
{
|
|
m_PDTVertexVector.push_back(*lit);
|
|
m_PDTVertexVector.push_back(*sit);
|
|
/*float len = D3DXVec3Length(&(lit->position - sit->position));
|
|
if (len>160)
|
|
Tracef("dist:%f\n",len);*/
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CWeaponTrace::Render()
|
|
{
|
|
//if (!m_isPlaying)
|
|
// return;
|
|
//if (m_CurvingTraceVector.size() < 4)
|
|
// return;
|
|
|
|
if (!BuildVertex())
|
|
return;
|
|
|
|
if (m_PDTVertexVector.size()<4)
|
|
return;
|
|
|
|
|
|
LPDIRECT3DTEXTURE8 lpTexture=NULL;
|
|
|
|
// Have to optimize
|
|
D3DXMATRIX matWorld;
|
|
D3DXMatrixIdentity(&matWorld);
|
|
|
|
STATEMANAGER.SaveTransform(D3DTS_WORLD, &matWorld);
|
|
STATEMANAGER.SaveVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
|
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
|
|
|
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
|
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
|
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
|
|
|
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
|
STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000011);
|
|
STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
|
|
|
|
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, TRUE);
|
|
STATEMANAGER.SaveRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
|
|
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
|
|
|
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
|
|
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
|
|
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, (m_bUseTexture)?D3DTOP_SELECTARG2:D3DTOP_SELECTARG1);
|
|
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
|
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
|
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
|
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
|
|
//STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
|
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, (m_bUseTexture)?D3DTOP_SELECTARG2:D3DTOP_SELECTARG1);
|
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
|
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
|
STATEMANAGER.SetTexture(0, lpTexture);
|
|
STATEMANAGER.SetTexture(1, NULL);
|
|
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,
|
|
int(m_PDTVertexVector.size() - 2),
|
|
&m_PDTVertexVector[0],
|
|
sizeof(TPDTVertex));
|
|
|
|
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
|
|
|
|
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE);
|
|
STATEMANAGER.RestoreRenderState(D3DRS_ZFUNC);
|
|
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
|
|
|
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
|
|
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF);
|
|
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC);
|
|
|
|
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
|
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
|
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
|
|
|
STATEMANAGER.RestoreTransform(D3DTS_WORLD);
|
|
STATEMANAGER.RestoreVertexShader();
|
|
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
|
}
|
|
|
|
void CWeaponTrace::UseAlpha()
|
|
{
|
|
m_bUseTexture = false;
|
|
}
|
|
|
|
void CWeaponTrace::UseTexture()
|
|
{
|
|
m_bUseTexture = true;
|
|
}
|
|
|
|
void CWeaponTrace::SetTexture(const char * c_szFileName)
|
|
{
|
|
CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("lot_ade10-2.tga");
|
|
m_ImageInstance.SetImagePointer(pImage);
|
|
|
|
//CGraphicTexture * pTexture = m_ImageInstance.GetTexturePointer();
|
|
//m_lpTexture = pTexture->GetD3DTexture();
|
|
}
|
|
|
|
bool CWeaponTrace::SetWeaponInstance(CGraphicThingInstance * pInstance, DWORD dwModelIndex, const char * c_szBoneName)
|
|
{
|
|
pInstance->Update();
|
|
pInstance->DeformNoSkin();
|
|
|
|
D3DXVECTOR3 v3Min;
|
|
D3DXVECTOR3 v3Max;
|
|
if (!pInstance->GetBoundBox(dwModelIndex, &v3Min, &v3Max))
|
|
return false;
|
|
|
|
m_iBoneIndex = 0;
|
|
m_dwModelInstanceIndex = dwModelIndex;
|
|
|
|
m_pInstance = pInstance;
|
|
D3DXMATRIX * pmat;
|
|
pInstance->GetBoneMatrix(dwModelIndex, 0, &pmat);
|
|
D3DXVECTOR3 v3Bone(pmat->_41,pmat->_42,pmat->_43);
|
|
|
|
m_fLength =
|
|
sqrtf(
|
|
fMAX(
|
|
D3DXVec3LengthSq(&(v3Bone-v3Min)),
|
|
D3DXVec3LengthSq(&(v3Bone-v3Max))
|
|
)
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
void CWeaponTrace::SetPosition(float fx, float fy, float fz)
|
|
{
|
|
m_fx = fx;
|
|
m_fy = fy;
|
|
m_fz = fz;
|
|
}
|
|
|
|
void CWeaponTrace::SetRotation(float fRotation)
|
|
{
|
|
m_fRotation = fRotation;
|
|
}
|
|
|
|
void CWeaponTrace::SetLifeTime(float fLifeTime)
|
|
{
|
|
m_fLifeTime = fLifeTime;
|
|
}
|
|
|
|
void CWeaponTrace::SetSamplingTime(float fSamplingTime)
|
|
{
|
|
m_fSamplingTime = fSamplingTime;
|
|
}
|
|
|
|
void CWeaponTrace::TurnOn()
|
|
{
|
|
m_isPlaying = TRUE;
|
|
}
|
|
void CWeaponTrace::TurnOff()
|
|
{
|
|
m_isPlaying = FALSE;
|
|
//Clear();
|
|
}
|
|
|
|
void CWeaponTrace::Clear()
|
|
{
|
|
//m_PDTVertexVector.clear();
|
|
//m_CurvingTraceVector.clear();
|
|
|
|
m_ShortTimePointList.clear();
|
|
m_LongTimePointList.clear();
|
|
Initialize();
|
|
}
|
|
|
|
void CWeaponTrace::Initialize()
|
|
{
|
|
m_pInstance = NULL;
|
|
m_dwModelInstanceIndex = 0;
|
|
|
|
m_fx = 0.0f;
|
|
m_fy = 0.0f;
|
|
m_fz = 0.0f;
|
|
m_fRotation = 0.0f;
|
|
|
|
m_fLifeTime = 0.18f;
|
|
//m_fLifeTime = 3.0f;
|
|
m_fSamplingTime = 0.003f;
|
|
//m_fLifeTime = 3.0f;
|
|
//m_fSamplingTime = 0.003f;
|
|
|
|
m_isPlaying = FALSE;
|
|
|
|
m_bUseTexture = false;
|
|
|
|
m_iBoneIndex = 0;
|
|
|
|
m_fLastUpdate = CTimer::Instance().GetCurrentSecond();
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
//const int c_iSplineCount = 8;
|
|
//m_SplineValueVector.clear();
|
|
//m_SplineValueVector.resize(c_iSplineCount);
|
|
|
|
//for (int i = 0; i < c_iSplineCount; ++i)
|
|
//{
|
|
// float fValue = float(i) / float(c_iSplineCount);
|
|
// m_SplineValueVector[i].fValue1 = fValue;
|
|
// m_SplineValueVector[i].fValue2 = fValue * fValue;
|
|
// m_SplineValueVector[i].fValue3 = fValue * fValue * fValue;
|
|
//}
|
|
|
|
}
|
|
|
|
CWeaponTrace::CWeaponTrace()
|
|
{
|
|
Initialize();
|
|
}
|
|
CWeaponTrace::~CWeaponTrace()
|
|
{
|
|
}
|