#include "stdafx.h" #include "KPrimitive.h" #include "KResource.h" #include "KPrimitiveMesh.h" #include "KRenderDevice.h" #include "KViewport.h" #include "KResourceDXDynamic.h" #include "KResourceManager.h" #include #define MAX_BONES 57 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KMeshPrimitive Implement ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// KMeshPrimitive::KMeshPrimitive() { m_type = KPRIMITIVE_MESH; m_nPrimitivesCount = 0; m_pMtl = NULL; m_pWeight = NULL; m_SkinDiffuse.r = 0; m_SkinDiffuse.g = 0; m_SkinDiffuse.b = 0; m_SkinDiffuse.a = 0; Clear(); } KMeshPrimitive::~KMeshPrimitive() { Clear(); } void KMeshPrimitive::Clear() { m_nRenderState = 0; m_fVisibility = 1.0f; m_nBoneCount = 0; m_pOffSetMat = NULL; m_pBoneMat = NULL; m_pUVTransform = NULL; m_pBoundOcclusion = NULL; } #include void KMeshPrimitive::Render( KViewportObject *pViewport,K3DRenderDevice* pDev, bool bUseAccum ) { //MTE // Please tell me the default input parameters that can be used in a vertex shader if( m_bIsMTE ) { static float f1 = 0.0f; static DWORD dwBeforeTime = GetSafeTickCount(); DWORD dwCurrTime = GetSafeTickCount(); DWORD dwDelta = dwCurrTime - dwBeforeTime; f1 += (float)dwDelta / 10000.0f; dwBeforeTime = dwCurrTime; if( f1 > 1.0f ) f1 -= 1.0f; K3DVector4 uvani(f1, f1, 0, 1.0f ); pDev->SetVertexShaderConstant(CONSTANT_UVANIMATION, (float *)&uvani, 4); } else if ( m_pUVTransform ) { K3DVector4 uvani(m_pUVTransform->_31, m_pUVTransform->_32, 0, m_pUVTransform->_11); pDev->SetVertexShaderConstant(CONSTANT_UVANIMATION, (float *)&uvani, 4); } assert(m_spIB != NULL && m_spVB != NULL); _SetMatrixArrayForVS(pViewport, pDev, bUseAccum); pDev->SetVertexShaderConstant(CONSTANT_VISIBILITY, &m_fVisibility, 1); K3DVector4 diffuse(m_SkinDiffuse.r, m_SkinDiffuse.g, m_SkinDiffuse.b, m_SkinDiffuse.a != 0 ? 1.0f : 0.0f ); pDev->SetVertexShaderConstant(CONSTANT_SKIN_DIFFUSE, (float *)&diffuse, 4); if(IsUseLightMap()) { if( IsUseFixMap() ) { pDev->SetTexture( 0, m_TexPack.spTexture_Fix); pDev->SetTexture( 1, m_TexPack.spTexture_Fix); } else { pDev->SetTexture( 0, m_TexPack.spTexture_Light); pDev->SetTexture( 1, m_TexPack.spTexture ); } } else { if( IsUseFixMap() ) pDev->SetTexture( 0, m_TexPack.spTexture_Fix); else { #ifdef _SPECULAR_EDITING_ switch( g_testTextureUseType ) { case TYPE_0D1S2SC: case TYPE_0D1S2X: case TYPE_0D1X2X: pDev->SetTexture( 0, m_TexPack.spTexture ); break; case TYPE_0S1X2SC: case TYPE_0S1S2SC: case TYPE_0S1X2X: pDev->SetTexture( 0, m_TexPack.spTexture_Specular ); break; } #else pDev->SetTexture( 0, m_TexPack.spTexture ); #endif if( m_nBlendMode == K3DMaterial::MBM_ALPHABLEND_NOALPHAUVANI || m_nBlendMode == K3DMaterial::MBM_ALPHABLEND_NOCOLORUVANI || m_nBlendMode == K3DMaterial::MBM_ADDITIVE_NOALPHAUVANI || m_nBlendMode == K3DMaterial::MBM_ADDITIVE_NOCOLORUVANI ) pDev->SetTexture( 1, m_TexPack.spTexture ); } if(IsSpecular() || IsBump()) { _SetSpecularBumpTexture(pViewport, pDev); _SetHalfWay(pViewport,pDev); } //MTE if( m_bIsMTE ) { IsSpecular() ? pDev->SetTexture( 3, m_TexPack.spTexture_MTE ) : pDev->SetTexture( 1, m_TexPack.spTexture_MTE ); } } pDev->DrawIndexedTriangleVB_VS( m_spVB, m_spIB, m_nPrimitivesCount, 1 ); if ( m_pUVTransform ) { K3DVector4 uvani(0.f,0.f,0.f,1.f); pDev->SetVertexShaderConstant(CONSTANT_UVANIMATION, (float *)&uvani, 4); } } void KMeshPrimitive::_SetMatrixArrayForVS(KViewportObject* pViewport, K3DRenderDevice* pDev, bool bUseAccum) { if(m_pWeight != NULL) { static K3DMatrix matArray[MAX_BONES]; K3DMatrix world_mat; //사용된 Bone만 설정 assert( m_pWeight->m_nUseBoneCount <= MAX_BONES && "사용하는 뼈 갯수가 57개보다 많다." ); if( !m_pBoneMat || !m_pOffSetMat ) { // No bone : Reset transform matrix K3DMatrixIdentity(world_mat); pDev->SetTransform(K3DRenderDevice::TS_WORLD, &world_mat, 1); return; } if( m_bIsEffectMat ) { K3DMatrixMultiply( world_mat, *m_pEffectMat, *m_pTransform ); K3DMatrixMultiply( world_mat, world_mat, m_RootMat ); } else { K3DMatrixMultiply( world_mat, *m_pTransform, m_RootMat ); } for( int i=0; i < m_pWeight->m_nUseBoneCount; ++i) { //사용되는 실제 본의 인덱스... int nUseBoneIndex = m_pWeight->m_pUseBoneList[i]; K3DMatrixMultiply( matArray[i], m_pOffSetMat[nUseBoneIndex], m_pBoneMat[nUseBoneIndex] ); K3DMatrixMultiply( matArray[i], matArray[i], world_mat ); } pDev->SetTransform(K3DRenderDevice::TS_WORLD, matArray, m_pWeight->m_nUseBoneCount ); } else { K3DMatrix world_mat; K3DMatrixMultiply( world_mat, *m_pTransform, m_RootMat ); pDev->SetTransform(K3DRenderDevice::TS_WORLD, &world_mat, 1); } } void KMeshPrimitive::_SetSpecularBumpTexture(KViewportObject* pViewport, K3DRenderDevice* pDev) { if( IsBump() && pViewport->GetRenderBumpMapMode() ) { if( IsUseFixMap() ) { pDev->SetTexture( 1, m_TexPack.spTexture_Fix); pDev->SetTexture( 2, NULL ); } else { pDev->SetTexture( 1, m_TexPack.spTexture_Bump ); pDev->SetTexture( 2, NULL ); } } else if( ( IsSpecular() || ( IsBump() && !pViewport->GetRenderBumpMapMode() ) ) && pViewport->GetUseSpecular() ) { if( IsUseFixMap() ) { pDev->SetTexture( 1, m_TexPack.spTexture_Fix ); pDev->SetTexture( 2, m_TexPack.spTexture_Fix ); } else { #ifdef _SPECULAR_EDITING_ switch( g_testTextureUseType ) { case TYPE_0D1S2SC: pDev->SetTexture( 1, m_TexPack.spTexture_Specular ); pDev->SetTexture( 2, m_TexPack.spTexture_SpecularColor ); break; case TYPE_0D1S2X: pDev->SetTexture( 1, m_TexPack.spTexture_Specular ); pDev->SetTexture( 2, m_TexPack.spTexture_Fix ); break; case TYPE_0D1X2X: pDev->SetTexture( 1, m_TexPack.spTexture_Fix ); pDev->SetTexture( 2, m_TexPack.spTexture_Fix ); break; case TYPE_0S1X2SC: pDev->SetTexture( 1, m_TexPack.spTexture_Fix ); pDev->SetTexture( 2, m_TexPack.spTexture_SpecularColor ); break; case TYPE_0S1S2SC: pDev->SetTexture( 1, m_TexPack.spTexture_Specular ); pDev->SetTexture( 2, m_TexPack.spTexture_SpecularColor ); break; case TYPE_0S1X2X: break; } #else pDev->SetTexture( 1, m_TexPack.spTexture_Specular ); pDev->SetTexture( 2, m_TexPack.spTexture_SpecularColor ); #endif } } if( m_TexPack.spTexture_Illumin && IsBump() ) { if( IsUseFixMap() ) pDev->SetTexture( 2, m_TexPack.spTexture_Fix ); else pDev->SetTexture( 2, m_TexPack.spTexture_Illumin ); } } void KMeshPrimitive::_SetHalfWay(KViewportObject* pViewport, K3DRenderDevice* pDev) { static K3DVector halfway; static K3DMatrix world; K3DMatrixMultiply(world, *m_pTransform, m_RootMat); halfway = pViewport->GetCameraPos() - world.GetPosVector(); float mag = K3DVectorLength( halfway ); halfway.z += mag/3; halfway.y += halfway.x/3; halfway.x -= halfway.y/3; K3DVectorNormalize( halfway, halfway); m_fHalfWay[0] = halfway.x; m_fHalfWay[1] = halfway.y; m_fHalfWay[2] = halfway.z; m_fHalfWay[3] = 1.f; pDev->SetVertexShaderConstant(CONSTANT_HALFWAY, m_fHalfWay, 4); } K3DTexture *KMeshPrimitive::getTexture(const char *texname) // load texture from manager { NX3LoadPack loadpack; loadpack.Init(); if( KTextureManager::GetManager()->IsExistTexture( texname, &loadpack ) ) { return KTextureManager::GetManager() ->GetTexture( texname, &loadpack, true, KTextureManager::GetManager()->GetMipMapBiasLevel() ); } return NULL; } void KMeshPrimitive::RenderBoundOcclusion( KViewportObject* pViewport, K3DRenderDevice* pDev ) { const static WORD ctBBox[24] = { 0, 1, 0, 2, 0, 4, 7, 6, 7, 5, 7, 3, // Bounding Box 용 Index 1, 3, 1, 5, 2, 3, 2, 6, 4, 5, 4, 6 }; pDev->SetTexture( 0, NULL ); pDev->DrawIndexedPrimitiveUPLine( D3DFVF_XYZ, m_pBoundOcclusion->GetVertices(), (void*)ctBBox, 8, 12, 12 ); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KPlanUtilPrimitive Implement ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// KPlanUtilPrimitive::KPlanUtilPrimitive() { m_nVtxFormat = K3DFVF_XYZ | K3DFVF_DIFFUSE; m_nVtxStride = K3DVertexBuffer::CalcVertexStride( m_nVtxFormat ); K3DMatrixIdentity( m_matTransform ); m_Mtl.SetAmbient( K3DColor(1.f,1.f,1.f) ); m_Mtl.SetDiffuse( K3DColor(1.f,1.f,1.f) ); m_nCurCount = 0; } KPlanUtilPrimitive::~KPlanUtilPrimitive() { Clear(); } void KPlanUtilPrimitive::Clear() { int iSize = (int) m_verts.size(); m_verts.erase( m_verts.begin(), m_verts.end() ); } void KPlanUtilPrimitive::AddVertex( const K3DVector &vertex1, const K3DVector &vertex2, const K3DVector &vertex3, const KColor &diffuse ) { PLANVERTEX v1, v2, v3; v1.pos = vertex1; v1.diffuse = diffuse; v2.pos = vertex2; v2.diffuse = diffuse; v3.pos = vertex3; v3.diffuse = diffuse; m_verts.push_back( v1 ); m_verts.push_back( v2 ); m_verts.push_back( v3 ); m_nCurCount++; } void KPlanUtilPrimitive::Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum/* = true*/ ) { if( 0 < m_verts.size() ) { dev->SetTransform( K3DRenderDevice::TS_WORLD, &m_matTransform ); dev->SetMaterial( &m_Mtl ); dev->SetTexture( 0, NULL ); dev->DrawTriangles( m_nVtxFormat, &m_verts.front(), static_cast(m_verts.size()), m_nVtxStride ); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KWireUtilPrimitive Implement ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// KWireUtilPrimitive::KWireUtilPrimitive() { m_type = KPRIMITIVE_WIREUTIL; m_nVtxFormat = K3DFVF_XYZ | K3DFVF_DIFFUSE; m_nVtxStride = K3DVertexBuffer::CalcVertexStride( m_nVtxFormat ); K3DMatrixIdentity( m_matTransform ); m_Mtl.SetAmbient( K3DColor(1.f,1.f,1.f) ); m_Mtl.SetDiffuse( K3DColor(1.f,1.f,1.f) ); m_nCurCount = 0; m_nDrawType = DRAW_LINE; } KWireUtilPrimitive::~KWireUtilPrimitive() { Clear(); } void KWireUtilPrimitive::Clear() { m_nCurCount = 0; int iSize = (int) m_verts.size(); m_verts.erase( m_verts.begin(), m_verts.end() ); } void KWireUtilPrimitive::AddLine( const K3DVector &pos1, const K3DVector &pos2, const KColor &diffuse ) { WIREVERTEX v1, v2; v1.pos = pos1; v1.diffuse = diffuse; v2.pos = pos2; v2.diffuse = diffuse; m_verts.push_back( v1 ); m_verts.push_back( v2 ); m_nCurCount++; } void KWireUtilPrimitive::AddSphere( const K3DVector ¢er, float radius, const KColor& diffuse, int lineCount ) { if( lineCount < 4 ) lineCount = 4; float step = 2 * K3D_PI / lineCount; K3DVector begin_y( cosf( 0.0f ) * radius + center.x, center.y, sinf( 0.0f ) * radius + center.z ), begin_z( cosf( 0.0f ) * radius + center.x, sinf( 0.0f ) * radius + center.y, center.z ), begin_x( center.x, cosf( 0.0f ) * radius + center.y, sinf( 0.0f ) * radius + center.z ); K3DVector end; for( int i = 1; i < lineCount + 1; ++i ) { float current_radian = i * step; float current_cos = cosf( current_radian ) * radius; float current_sin = sinf( current_radian ) * radius; end.x = current_cos + center.x; end.y = center.y; end.z = current_sin + center.z; AddLine( begin_y, end, diffuse ); begin_y = end; end.x = current_cos + center.x; end.y = current_sin + center.y; end.z = center.z; AddLine( begin_z, end, diffuse ); begin_z = end; end.x = center.x; end.y = current_cos + center.y; end.z = current_sin + center.z; AddLine( begin_x, end, diffuse ); begin_x = end; } } void KWireUtilPrimitive::Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum ) { if( 0 < m_verts.size() ) { dev->SetTransform( K3DRenderDevice::TS_WORLD, &m_matTransform ); dev->SetMaterial( &m_Mtl ); dev->SetTexture( 0, NULL ); dev->DrawLines( m_nVtxFormat, &m_verts.front(), static_cast(m_verts.size()), m_nVtxStride ); } } //======================================================================= // Morphing용 //======================================================================= MorphedPrimitive::MorphedPrimitive() : KMeshPrimitive() { indexBuffer=NULL; vertexBuffer=NULL; polygonCount=0; Additive = 0; m_bIsValidMinMax = false; m_vMin = K3DVertex( 100.f, 100.f, 100.f); m_vMax = K3DVertex(-100.f,-100.f,-100.f); m_bEnableFlag = true; } MorphedPrimitive::~MorphedPrimitive() { close(); } void MorphedPrimitive::init(KMeshPrimitive *source) { if( !m_bEnableFlag ) return; // Make buffers initMesh(source); // Original init routine starts here if (indexBuffer==NULL || vertexBuffer==NULL) return; // WORKAROUND : to prevent 'smartptr burst' on deleting m_spIB / m_spVB indexBuffer->AddRef(); vertexBuffer->AddRef(); // Notify mesh informations to parent SetIndexBuffer(indexBuffer); // set m_spIB SetVertexBuffer(vertexBuffer); // set m_spVB SetPrimitivesCount(polygonCount); // Init basic members K3DMaterial *tempMaterial=new K3DMaterial; tempMaterial->Power=1.0f; SetMaterial(tempMaterial); // m_pTransform=new K3DMatrix; // K3DMatrixIdentity(m_pTransform); K3DMatrix *tempMatrix=new K3DMatrix; K3DMatrixIdentity(*tempMatrix); SetUVTransform(tempMatrix); m_vCenterPosition.x=0.f; m_vCenterPosition.y=0.f; m_vCenterPosition.z=0.f; // Set texture SetTexture(&texpack); // Set bone blending info SetBlendedInfo(source->getBoneCount(), source->getOffsetMatrix(), source->getBoneMatrix()); SetWeight(source->GetWeight()); SetVSMode( true ); // <- 의미 있는건지? // Set basic rendering parameters if( Additive == 0 ) { if (getBoneCount()==0) { // No bone SetBlendMode(K3DMaterial::MBM_ALPHATEX_EDGEENHANCE); // 렌더링 모드 : edge-enhance / no-blend } else { // use mesh blending SetBlendMode(K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_BLEND); // 렌더링 모드 : edge-enhance / mesh-blend } } else if( Additive == 1 ) { if (getBoneCount()==0) { // No bone SetBlendMode(K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_ADD); // 렌더링 모드 : edge-enhance / no-blend } else { // use mesh blending SetBlendMode(K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_BLEND_ADD); // 렌더링 모드 : edge-enhance / mesh-blend } } SetTransparent(true); // Add to Transparent primitive queue SetVisibility(1.0f); // Master alpha value } void MorphedPrimitive::close() { // clear buffers SetIndexBuffer(NULL); SetVertexBuffer(NULL); SetPrimitivesCount(0); if (indexBuffer!=NULL) { // SAFE_RELEASE(indexBuffer); indexBuffer->Release(); // Release() will delete SELF indexBuffer=NULL; } if (vertexBuffer!=NULL) { vertexBuffer->Release(); vertexBuffer=NULL; } polygonCount=0; K3DMatrix *tempMatrix=GetUVTransform(); SetUVTransform(NULL); SAFE_DELETE(tempMatrix); // SAFE_DELETE(m_pTransform); K3DMaterial *tempMaterial=GetMaterial(); SetMaterial(NULL); SAFE_DELETE(tempMaterial); // Delete textures texpack.spTexture=NULL; } void MorphedPrimitive::Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum ) { if( !m_bEnableFlag ) return; KMeshPrimitive::Render(viewport, dev, bUseAccum); } //----------------------------------------------------------- // // struct SkinMeshVertex { // 라펠즈의 버텍스 포맷 K3DVertex pos; K3DVertex normal; DWORD color; float u, v; float t0, t1, t2, t3; // tangents DWORD blendIndices; float blendWeight0, blendWeight1; }; void MorphedPrimitive::copyMesh(KMeshPrimitive *source) { if( !m_bEnableFlag ) return; close(); if (source==NULL) return; int idxCount, vtxCount, polyCount; K3DVertexBuffer *srcVertex=source->GetVertexBuffer(); K3DIndexBuffer *srcIndex=source->GetIndexBuffer(); if (srcIndex==NULL || srcVertex==NULL) return; // Check vertex format //DWORD vtxFormat=srcVertex->GetVertexFormat(); //if (vtxFormat !=...) return; idxCount=srcIndex->GetIndexCount(); vtxCount=srcVertex->GetVertexCount(); polyCount=source->GetPrimitivesCount(); assert(idxCount == polyCount*3); // Triangle set try { void *p, *pSrc; int size=0, srcSize=0; int i; // Copy indexes indexBuffer=new KIndexBufferDX_dynamic(); if (indexBuffer!=NULL) { if (!indexBuffer->create(idxCount * sizeof(WORD), D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT)) { // index buffer creation failed throw 0; } } indexBuffer->setIndexCount(idxCount); indexBuffer->Lock(&p, size); srcIndex->Lock(&pSrc, srcSize); //, D3DLOCK_READONLY); if (p!=NULL && pSrc!=NULL) { /* // Sanity check WORD *pd=(WORD *)p; WORD *ps=(WORD *)pSrc; for (i=0; iUnlock(); if (pSrc!=NULL) srcIndex->Unlock(); // Copy vertexes vertexBuffer=new KVertexBufferDX_dynamic(); if (vertexBuffer!=NULL) { // (UINT length, DWORD usage, DWORD FVF, D3DPOOL pool) if (!vertexBuffer->create(sizeof(DynamicVertex) * vtxCount, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, DynamicVertex::FVF, D3DPOOL_DEFAULT)) { throw 0; } } vertexBuffer->setVertexCount(vtxCount); vertexBuffer->Lock(&p, size, D3DLOCK_NOSYSLOCK /*| D3DLOCK_DISCARD*/); srcVertex->Lock(&pSrc, srcSize); // , D3DLOCK_READONLY); if (p!=NULL && pSrc!=NULL) { KVertexBufferDX_dynamic *pd=dynamic_cast(srcVertex); if (pd==NULL) { // Normal skinmesh vertex // Build dynamic vertex parameters SkinMeshVertex *skinMeshVertex=(SkinMeshVertex *) pSrc; DynamicVertex *dynamicVertex=(DynamicVertex *) p; for (i=0; ipos = skinMeshVertex->pos; dynamicVertex->normal = skinMeshVertex->normal; dynamicVertex->color0 = skinMeshVertex->color; dynamicVertex->color1 = 0x00; dynamicVertex->u0 = skinMeshVertex->u; dynamicVertex->v0 = skinMeshVertex->v; dynamicVertex->blendIndices = skinMeshVertex->blendIndices; dynamicVertex->blendWeight0 = skinMeshVertex->blendWeight0; dynamicVertex->blendWeight1 = skinMeshVertex->blendWeight1; dynamicVertex->blendWeight2 = 0.0f; dynamicVertex++; skinMeshVertex++; } } else { // Dynamicvertex // copy dynamic vertex parameters DynamicVertex *dynamicVertexSrc=(DynamicVertex *) pSrc; DynamicVertex *dynamicVertex=(DynamicVertex *) p; for (i=0; iUnlock(); if (pSrc!=NULL) srcVertex->Unlock(); // Set primitive count polygonCount=polyCount; } catch (int) { close(); } } void MorphedPrimitive::calculateVertexNormals() // 각 vertex의 normal을 다시 계산 { if( !m_bEnableFlag ) return; if (indexBuffer==NULL || vertexBuffer==NULL) return; DynamicVertex *vertex=NULL; WORD *index=NULL; int indexCount, vertexCount; DynamicVertex *node[3]; int n=0; int i,j; K3DVertex s, t; K3DVertex norm; while( true ) { vertexBuffer->Lock((void **)&vertex, n, D3DLOCK_NOSYSLOCK /*| D3DLOCK_DISCARD*/); if (vertex==NULL) break; indexBuffer->Lock((void **)&index, n); if (index==NULL) break; // Clear vertex normals vertexCount=vertexBuffer->GetVertexCount(); indexCount=indexBuffer->GetIndexCount(); for (i=0; ipos - node[0]->pos; t = node[2]->pos - node[1]->pos; norm=CrossProduct(t, s); // Sum normals of each nodes node[0]->normal+=norm; node[1]->normal+=norm; node[2]->normal+=norm; } // Join overlapped vertexes // Note : 이게 없으면, 시각적으로 붙어있으나 topology적으로 edge를 공유하지 않는 폴리곤은 edge가 분리된다 i.e. '찢어진다' T_T // O(n^2)므로 별로 안 효율적. 나중에 바꾸든 말든 K3DVector v; for (i=0; iUnlock(); if (index!=NULL) indexBuffer->Unlock(); } void MorphedPrimitive::offsetVertexPosition(float offset) // Move vertex position along vertex normal { if( !m_bEnableFlag ) return; DynamicVertex *vertex=NULL; int i, n=0; try { vertexBuffer->Lock((void **)&vertex, n, D3DLOCK_NOSYSLOCK /*| D3DLOCK_DISCARD*/); if (vertex==NULL) throw 0; DynamicVertex *p=vertex; n=vertexBuffer->GetVertexCount(); for (i=0; ipos.x += p->normal.x * offset; p->pos.y += p->normal.y * offset; p->pos.z += p->normal.z * offset; } } catch (int) { // empty } if (vertex!=NULL) vertexBuffer->Unlock(); } //#define _NEW_MORPH_ void MorphedPrimitive::setVertexColors(DWORD color0, DWORD color1) // 모든 vertex에 대해 색깔 변환 // Set vertex colors { if( !m_bEnableFlag ) return; DynamicVertex *vertex=NULL; int i, n=0; try { vertexBuffer->Lock((void **)&vertex, n, D3DLOCK_NOSYSLOCK /*| D3DLOCK_DISCARD*/); if (vertex==NULL) throw 0; #ifdef _NEW_MORPH_ if( m_bIsValidMinMax == false ) { DynamicVertex *p=vertex; n=vertexBuffer->GetVertexCount(); float fMax = -100.f; float fMin = 100.f; float fLength = 0.f; for (i=0; ipos ); if( fLength < fMin ) { fMin = fLength; m_vMin = p->pos; } if( fLength > fMax ) { fMax = fLength; m_vMax = p->pos; } } m_bIsValidMinMax = true; } float fMaxLength = K3DVectorLength( m_vMax - m_vMin ); float fRatio = 1.f; DynamicVertex *p=vertex; n=vertexBuffer->GetVertexCount(); K3DColor out; KColor color; for (i=0; ipos - m_vMin )/fMaxLength; // _oprint( "Color Ratio : %f\n", fRatio ); K3DColorLerp( out, K3DColor(color0), K3DColor(color1), fRatio ); p->color0=((KColor)out).color; p->color1=((KColor)out).color; } #else DynamicVertex *p=vertex; n=vertexBuffer->GetVertexCount(); for (i=0; icolor0=color0; p->color1=color1; } #endif } catch (int) { // empty } if (vertex!=NULL) vertexBuffer->Unlock(); } /* // TEMPLATE void MorphedPrimitive::for_each_vertex() { DynamicVertex *vertex=NULL; int i, n=0; try { vertexBuffer->Lock((void **)&vertex, n); if (vertex==NULL) throw 0; DynamicVertex *p=vertex; n=vertexBuffer->GetVertexCount(); for (i=0; i...... } } catch (int) { // empty } if (vertex!=NULL) vertexBuffer->Unlock(); } */ void MorphedPrimitive::initMesh(KMeshPrimitive *source) // called by init(), to initialize mesh { if( !m_bEnableFlag ) return; copyMesh(source); // // Initialization example // //if (indexBuffer==NULL || vertexBuffer==NULL) return; // validity check //calculateVertexNormals(); // Disable하고 polygon의 내부 normal사용해도 됨 (다행히도 제대로 들어 있는 듯...?) //texpack.spTexture=MorphedPrimitive::getTexture("zone005_stone003.dds"); // 텍스처 설정 //offsetVertexPosition(0.3f); // 약간 확장 //setVertexColors(0x40ffffff, 0x20c08080); // 버텍스 컬러 주기 // } //============================================================= // FxResizedPrimitive //============================================================= FxResizedPrimitive::FxResizedPrimitive() { offset=0; color0=color1=0x00000000; texName=NULL; } void FxResizedPrimitive::init(KMeshPrimitive *source, float _offset, DWORD _color0, DWORD _color1, const char *_textureName, int nAdditive) { offset=_offset; color0=_color0; color1=_color1; texName=_textureName; Additive = nAdditive; MorphedPrimitive::init(source); } void FxResizedPrimitive::initMesh(KMeshPrimitive *source) // called by init(), to initialize mesh { copyMesh(source); if (indexBuffer==NULL || vertexBuffer==NULL) return; offsetVertexPosition(offset); setVertexColors(color0, color1); if (texName!=NULL) { texpack.spTexture=KMeshPrimitive::getTexture(texName); } }