#include "stdafx.h" #include "KPrimitivePathEffect.h" #include "KRenderDeviceDX.h" // KLinePrimitive KLinePrimitive::KLinePrimitive() { m_numVerts = 0; m_pVerts = NULL; //m_bDrawPr = false; // m_bDrawPr = true; } KLinePrimitive::~KLinePrimitive() { Clear(); } void KLinePrimitive::Clear() { SAFE_DELETE_ARRAY(m_pVerts); m_numVerts = 0; } void KLinePrimitive::Update(PfxPrVertex* pVerts, int numVerts) { Clear(); if(!pVerts || numVerts < 2) return; m_pVerts = new PfxPrVertex[numVerts]; if(!m_pVerts) { m_numVerts = 0; return; } memcpy(m_pVerts, pVerts, sizeof(PfxPrVertex) * numVerts); m_numVerts = numVerts; } void KLinePrimitive::Render( KViewportObject *viewport, K3DRenderDevice *dev, bool bUseAccum ) { if(!m_pVerts || !m_numVerts) return; //dev->SetTransformIdentity(K3DRenderDevice::TS_WORLD); //dev->SetVertexShaderDefault(); //if(m_bDrawPr) //{ // dev->DrawLineStrip(D3DFVF_XYZ | D3DFVF_DIFFUSE, m_pVerts, m_numVerts, sizeof(SVertex)); //} dev->DrawLineStrip(D3DFVF_XYZ | D3DFVF_DIFFUSE, m_pVerts, m_numVerts, sizeof(PfxPrVertex)); } // Path를 그릴 것인가.. //void KLinePrimitive::SetPrDrawMode(bool bDrawPr) //{ // m_bDrawPr = bDrawPr; //} // KQuadPrimitive KQuadPrimitive::KQuadPrimitive() { m_numVerts = 0; m_pVerts = NULL; //m_fRadius = 1.0f; // 나중에 에디터에서 설정할 수 있게 하자 m_fSize = 1.0f; } KQuadPrimitive::~KQuadPrimitive() { Clear(); } void KQuadPrimitive::SetSize(float fSize) { //m_fRadius = fRadius; m_fSize = fSize; } void KQuadPrimitive::Clear() { SAFE_DELETE_ARRAY(m_pVerts); m_numVerts = 0; } void KQuadPrimitive::Update(PfxPrVertex* pVerts, int numVerts) { Clear(); if(!pVerts || !numVerts) return; m_pVerts = new PfxPrVertex[numVerts]; if(!m_pVerts) { m_numVerts = 0; return; } memcpy(m_pVerts, pVerts, sizeof(PfxPrVertex) * numVerts); m_numVerts = numVerts; } // 졸라 느림.. 에디터에서만 쓰자 void KQuadPrimitive::Render( KViewportObject *viewport, K3DRenderDevice *dev, bool bUseAccum ) { if(!m_pVerts || !m_numVerts) return; float x1, x2, y1, y2, z; DWORD c; PfxPrVertex v[4]; for(int i = 0; i < m_numVerts; i++) { x1 = m_pVerts[i].pos.x - m_fSize; x2 = m_pVerts[i].pos.x + m_fSize; y1 = m_pVerts[i].pos.y - m_fSize; y2 = m_pVerts[i].pos.y + m_fSize; z = m_pVerts[i].pos.z; c = m_pVerts[i].color; v[0].pos.x = x1; v[0].pos.y = y1; v[0].pos.z = z; v[0].color = c; v[1].pos.x = x1; v[1].pos.y = y2; v[1].pos.z = z; v[1].color = c; v[2].pos.x = x2; v[2].pos.y = y2; v[2].pos.z = z; v[2].color = c; v[3].pos.x = x2; v[3].pos.y = y1; v[3].pos.z = z; v[3].color = c; dev->DrawTriangleFan(D3DFVF_XYZ | D3DFVF_DIFFUSE, v, 4, sizeof(PfxPrVertex)); } } // KPolyLinePrimitive KPolyLinePrimitive::KPolyLinePrimitive() { m_pPrVerts = NULL; //m_numVerts = 0; for(int i = 0; i < 4; i++) { m_FirstPrVerts[i].pos.x = 0.0f; m_FirstPrVerts[i].pos.y = 0.0f; m_FirstPrVerts[i].pos.z = 0.0f; m_FirstPrVerts[i].color = 0; m_LastPrVerts[i].pos.x = 0.0f; m_LastPrVerts[i].pos.y = 0.0f; m_LastPrVerts[i].pos.z = 0.0f; m_LastPrVerts[i].color = 0; } m_fWidth = 0.0f; m_bOverrideFirstPrVerts = FALSE; m_bOverrideLastPrVerts = FALSE; m_dwColor = 0; m_nFirstDrawQuad = 0; m_nLastDrawQuad = 0; m_fTotalPathLength = 0.0f; } KPolyLinePrimitive::~KPolyLinePrimitive() { Clear(); } void KPolyLinePrimitive::Clear() { m_vPathVerts.erase(m_vPathVerts.begin(), m_vPathVerts.end()); m_vPathNormals.erase(m_vPathNormals.begin(), m_vPathNormals.end()); SAFE_DELETE_ARRAY(m_pPrVerts); m_bOverrideFirstPrVerts = FALSE; m_bOverrideLastPrVerts = FALSE; m_nFirstDrawQuad = 0; m_nLastDrawQuad = 0; m_fTotalPathLength = 0.0f; } void KPolyLinePrimitive::AddPathVert(K3DVector vPos) { PfxPathVertex pathVert; pathVert.vPos = vPos; int numVerts = m_vPathVerts.size(); if(numVerts >= 1) { K3DVector v = vPos - m_vPathVerts[numVerts - 1].vPos; m_fTotalPathLength += v.Magnitude(); } pathVert.fLength = m_fTotalPathLength; m_vPathVerts.push_back(pathVert); } void KPolyLinePrimitive::AddPathNormal(K3DVector vNormal) { m_vPathNormals.push_back(vNormal); } // _KSeqPathEffect가 Update() 할 때 한번만 호출 void KPolyLinePrimitive::Update() { //Clear(); int numPathVerts = m_vPathVerts.size(); if(numPathVerts < 2 || numPathVerts != m_vPathNormals.size()) { //assert(0); Clear(); return; } int numPrVerts = (numPathVerts - 1) * 4; m_pPrVerts = new PfxPlPrVertex[numPrVerts]; if(!m_pPrVerts) { Clear(); return; } K3DVector vTan, vBiNorm, vNorm, v1, v2, v3, v4; for(int i = 0; i < numPathVerts - 1; i++) { if(i == 0) { vBiNorm = m_vPathVerts[1].vPos - m_vPathVerts[0].vPos; } else { vBiNorm = m_vPathVerts[i + 1].vPos - m_vPathVerts[i - 1].vPos; } Normalize(vBiNorm); vNorm = m_vPathNormals[i]; Normalize(vNorm); vTan = CrossProduct(vBiNorm, vNorm); vTan *= m_fWidth; v1 = m_vPathVerts[i].vPos - vTan; v4 = m_vPathVerts[i].vPos + vTan; if(i == numPathVerts - 2) { vBiNorm = m_vPathVerts[numPathVerts - 1].vPos - m_vPathVerts[numPathVerts - 2].vPos; } else { vBiNorm = m_vPathVerts[i + 2].vPos - m_vPathVerts[i].vPos; } Normalize(vBiNorm); vTan = CrossProduct(vBiNorm, vNorm); vTan *= m_fWidth; v2 = m_vPathVerts[i + 1].vPos - vTan; v3 = m_vPathVerts[i + 1].vPos + vTan; m_pPrVerts[i * 4 + 0].pos = *((D3DXVECTOR3*) &v1); m_pPrVerts[i * 4 + 1].pos = *((D3DXVECTOR3*) &v2); m_pPrVerts[i * 4 + 2].pos = *((D3DXVECTOR3*) &v3); m_pPrVerts[i * 4 + 3].pos = *((D3DXVECTOR3*) &v4); m_pPrVerts[i * 4 + 0].color = m_dwColor; m_pPrVerts[i * 4 + 1].color = m_dwColor; m_pPrVerts[i * 4 + 2].color = m_dwColor; m_pPrVerts[i * 4 + 3].color = m_dwColor; } m_nFirstDrawQuad = 0; m_nLastDrawQuad = numPathVerts - 2; } void KPolyLinePrimitive::UpdateUV(float fStart, float fEnd) { float fU1, fU2, fV1, fV2; fV1 = 0.0f; fV2 = 1.0f; for(int i = m_nFirstDrawQuad; i <= m_nLastDrawQuad; i++) { fU1 = ((m_vPathVerts[i].fLength / m_fTotalPathLength) - fStart) / (fEnd - fStart); fU2 = ((m_vPathVerts[i + 1].fLength / m_fTotalPathLength) - fStart) / (fEnd - fStart); m_pPrVerts[i * 4 + 0].u = fU1; m_pPrVerts[i * 4 + 0].v = fV1; m_pPrVerts[i * 4 + 1].u = fU2; m_pPrVerts[i * 4 + 1].v = fV1; m_pPrVerts[i * 4 + 2].u = fU2; m_pPrVerts[i * 4 + 2].v = fV2; m_pPrVerts[i * 4 + 3].u = fU1; m_pPrVerts[i * 4 + 3].v = fV2; } } // _KSeqPathEffect가 Render() 할 때마다 매번 호출 void KPolyLinePrimitive::Update(float fStart, float fEnd) { int numPathVerts = m_vPathVerts.size(); if(numPathVerts < 2 || numPathVerts != m_vPathNormals.size()) return; if(!m_pPrVerts) return; if(fStart < 0.0f) fStart = 0.0f; if(fStart > 1.0f) fStart = 1.0f; if(fEnd < 0.0f) fEnd = 0.0f; if(fEnd > 1.0f) fEnd = 1.0f; if(fStart == fEnd) return; if(fStart > fEnd) { float fTemp = fStart; fStart = fEnd; fEnd = fTemp; } K3DVector vTemp; K3DVertex vStart, vEnd; int nStart = GetPathVert(fStart, vStart); vTemp = vStart - m_vPathVerts[nStart].vPos; if(vTemp.Magnitude() < 0.1f) { m_bOverrideFirstPrVerts = FALSE; m_nFirstDrawQuad = nStart; } else { m_bOverrideFirstPrVerts = TRUE; m_nFirstDrawQuad = nStart + 1; } int nEnd = GetPathVert(fEnd, vEnd); vTemp = vEnd - m_vPathVerts[nEnd].vPos; if(vTemp.Magnitude() < 0.1f) { m_bOverrideLastPrVerts = FALSE; m_nLastDrawQuad = nEnd - 1; } else { m_bOverrideLastPrVerts = TRUE; m_nLastDrawQuad = nEnd - 1; } K3DVector vTan, vBiNorm, vNorm, v1, v2, v3, v4; if(nStart == nEnd) // 예외처리 { vBiNorm = m_vPathVerts[nStart + 1].vPos - m_vPathVerts[nStart].vPos; Normalize(vBiNorm); vNorm = m_vPathNormals[nStart]; Normalize(vNorm); vTan = CrossProduct(vBiNorm, vNorm); vTan *= m_fWidth; v1 = vStart - vTan; v4 = vStart + vTan; //vBiNorm = m_vPathVerts[nEnd + 1].vPos - m_vPathVerts[nEnd].vPos; //Normalize(vBiNorm); //vTan = CrossProduct(vBiNorm, vNorm); //vTan *= m_fWidth; v2 = vEnd - vTan; v3 = vEnd + vTan; m_FirstPrVerts[0].pos = *((D3DXVECTOR3*) &v1); m_FirstPrVerts[1].pos = *((D3DXVECTOR3*) &v2); m_FirstPrVerts[2].pos = *((D3DXVECTOR3*) &v3); m_FirstPrVerts[3].pos = *((D3DXVECTOR3*) &v4); m_FirstPrVerts[0].color = m_dwColor; m_FirstPrVerts[1].color = m_dwColor; m_FirstPrVerts[2].color = m_dwColor; m_FirstPrVerts[3].color = m_dwColor; float fU1, fU2, fV1, fV2; fV1 = 0.0f; fV2 = 1.0f; //fU1 = fStart; //fU2 = fEnd; fU1 = 0.0f; fU2 = 1.0f; m_FirstPrVerts[0].u = fU1; m_FirstPrVerts[0].v = fV1; m_FirstPrVerts[1].u = fU2; m_FirstPrVerts[1].v = fV1; m_FirstPrVerts[2].u = fU2; m_FirstPrVerts[2].v = fV2; m_FirstPrVerts[3].u = fU1; m_FirstPrVerts[3].v = fV2; m_bOverrideFirstPrVerts = TRUE; m_bOverrideLastPrVerts = FALSE; return; } if(m_bOverrideFirstPrVerts) { vBiNorm = m_vPathVerts[nStart + 1].vPos - m_vPathVerts[nStart].vPos; Normalize(vBiNorm); vNorm = m_vPathNormals[nStart]; Normalize(vNorm); vTan = CrossProduct(vBiNorm, vNorm); vTan *= m_fWidth; v1 = vStart - vTan; v4 = vStart + vTan; if(nStart == numPathVerts - 2) { vBiNorm = m_vPathVerts[numPathVerts - 1].vPos - m_vPathVerts[numPathVerts - 2].vPos; } else { vBiNorm = m_vPathVerts[nStart + 2].vPos - m_vPathVerts[nStart].vPos; } Normalize(vBiNorm); vTan = CrossProduct(vBiNorm, vNorm); vTan *= m_fWidth; v2 = m_vPathVerts[nStart + 1].vPos - vTan; v3 = m_vPathVerts[nStart + 1].vPos + vTan; m_FirstPrVerts[0].pos = *((D3DXVECTOR3*) &v1); m_FirstPrVerts[1].pos = *((D3DXVECTOR3*) &v2); m_FirstPrVerts[2].pos = *((D3DXVECTOR3*) &v3); m_FirstPrVerts[3].pos = *((D3DXVECTOR3*) &v4); m_FirstPrVerts[0].color = m_dwColor; m_FirstPrVerts[1].color = m_dwColor; m_FirstPrVerts[2].color = m_dwColor; m_FirstPrVerts[3].color = m_dwColor; float fU1, fU2, fV1, fV2; fV1 = 0.0f; fV2 = 1.0f; //fU1 = fStart; fU1 = 0.0f; fU2 = ((m_vPathVerts[nStart + 1].fLength / m_fTotalPathLength) - fStart) / (fEnd - fStart); m_FirstPrVerts[0].u = fU1; m_FirstPrVerts[0].v = fV1; m_FirstPrVerts[1].u = fU2; m_FirstPrVerts[1].v = fV1; m_FirstPrVerts[2].u = fU2; m_FirstPrVerts[2].v = fV2; m_FirstPrVerts[3].u = fU1; m_FirstPrVerts[3].v = fV2; } if(m_bOverrideLastPrVerts) { if(nEnd == 0) // 위에서 예외처리를 하므로 이 코드에 도달하지 않는다. { //vBiNorm = m_vPathVerts[1].vPos - m_vPathVerts[0].vPos; assert(0); } else // nEnd = numPathVerts - 1 은 fEnd가 1.0f일 때에만 성립하므로 nEnd + 1이 참조에러를 내지 않는다. (fEnd == 1.0f 일때 m_bOverrideLastPrVerts == FALSE 이므로) { vBiNorm = m_vPathVerts[nEnd + 1].vPos - m_vPathVerts[nEnd - 1].vPos; } Normalize(vBiNorm); vNorm = m_vPathNormals[nEnd]; Normalize(vNorm); vTan = CrossProduct(vBiNorm, vNorm); vTan *= m_fWidth; v1 = m_vPathVerts[nEnd].vPos - vTan; v4 = m_vPathVerts[nEnd].vPos + vTan; vBiNorm = m_vPathVerts[nEnd + 1].vPos - m_vPathVerts[nEnd].vPos; Normalize(vBiNorm); vTan = CrossProduct(vBiNorm, vNorm); vTan *= m_fWidth; v2 = vEnd - vTan; v3 = vEnd + vTan; m_LastPrVerts[0].pos = *((D3DXVECTOR3*) &v1); m_LastPrVerts[1].pos = *((D3DXVECTOR3*) &v2); m_LastPrVerts[2].pos = *((D3DXVECTOR3*) &v3); m_LastPrVerts[3].pos = *((D3DXVECTOR3*) &v4); m_LastPrVerts[0].color = m_dwColor; m_LastPrVerts[1].color = m_dwColor; m_LastPrVerts[2].color = m_dwColor; m_LastPrVerts[3].color = m_dwColor; float fU1, fU2, fV1, fV2; fV1 = 0.0f; fV2 = 1.0f; fU1 = ((m_vPathVerts[nEnd].fLength / m_fTotalPathLength) - fStart) / (fEnd - fStart); //fU2 = fEnd; fU2 = 1.0f; m_LastPrVerts[0].u = fU1; m_LastPrVerts[0].v = fV1; m_LastPrVerts[1].u = fU2; m_LastPrVerts[1].v = fV1; m_LastPrVerts[2].u = fU2; m_LastPrVerts[2].v = fV2; m_LastPrVerts[3].u = fU1; m_LastPrVerts[3].v = fV2; } UpdateUV(fStart, fEnd); } int KPolyLinePrimitive::GetPathVert(float fPos, K3DVertex& vRes) { if(fPos < 0.0f || fPos > 1.0f) return -1; // 에러 int n; int numPathVerts = m_vPathVerts.size(); if(fPos == 1.0f) // 예외 처리 { vRes = m_vPathVerts[numPathVerts - 1].vPos; return (numPathVerts - 1); } fPos *= m_fTotalPathLength; // 절대 좌표값으로 바꾼다. for(n = 0; n < numPathVerts; n++) { if(m_vPathVerts[n].fLength > fPos) break; } --n; float fraction = fPos - m_vPathVerts[n].fLength; K3DVector vec = m_vPathVerts[n + 1].vPos - m_vPathVerts[n].vPos; fraction /= vec.Magnitude(); vRes = m_vPathVerts[n].vPos + vec * fraction; return n; } void KPolyLinePrimitive::Render(KViewportObject* viewport, class K3DRenderDevice* dev, bool bUseAccum) { int numPathVerts = m_vPathVerts.size(); if(numPathVerts < 2 || numPathVerts != m_vPathNormals.size()) return; if(!m_pPrVerts) return; dev->SetTexture(0, m_spTexture); if(m_bOverrideFirstPrVerts) { dev->DrawTriangleFan(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1, m_FirstPrVerts, 4, sizeof(PfxPlPrVertex)); } for(int i = m_nFirstDrawQuad; i <= m_nLastDrawQuad; i++) { PfxPlPrVertex* v = &m_pPrVerts[i * 4]; dev->DrawTriangleFan(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1, v, 4, sizeof(PfxPlPrVertex)); } if(m_bOverrideLastPrVerts) { dev->DrawTriangleFan(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1, m_LastPrVerts, 4, sizeof(PfxPlPrVertex)); } } void KPolyLinePrimitive::SetWidth(float fWidth) { m_fWidth = fWidth; } void KPolyLinePrimitive::SetColor(DWORD dwColor) { m_dwColor = dwColor; } void KPolyLinePrimitive::SetTexture(K3DTexture* pTexture) { m_spTexture = pTexture; }