// X3DEffectSphere.cpp: implementation of the CX3DEffectSphere class. // ////////////////////////////////////////////////////////////////////// #include "X3DEffect.h" #include "X3DEffectSphere.h" #include "SceneStateMgr.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CX3DEffectSphere::CX3DEffectSphere() { m_dwSrcBlending = D3DBLEND_SRCALPHA; m_dwDestBlending = D3DBLEND_ONE; m_bTexAni = FALSE; m_lpVertices = NULL; m_lpVerticesBlend = NULL; m_lpVerticeIndex = NULL; } CX3DEffectSphere::~CX3DEffectSphere() { if(m_lpVerticeIndex) { m_lpVerticeIndex->Release(); m_lpVerticeIndex = NULL; } if(m_lpVerticesBlend) { m_lpVerticesBlend->Release(); m_lpVerticesBlend = NULL; } if(m_lpVertices) { m_lpVertices->Release(); m_lpVertices = NULL; } } void CX3DEffectSphere::Create(unsigned long dwStartFrame, unsigned long dwEndFrame) { m_dwStartFrame = dwStartFrame; m_dwEndFrame = dwEndFrame; } BOOL CX3DEffectSphere::CreateBuffer() { if(m_lpVerticeIndex) { m_lpVerticeIndex->Release(); m_lpVerticeIndex = NULL; } if(m_lpVerticesBlend) { m_lpVerticesBlend->Release(); m_lpVerticesBlend = NULL; } if(m_lpVertices) { m_lpVertices->Release(); m_lpVertices = NULL; } if(m_bUpperVis && m_bLowerVis) m_dwTotalSegment = m_dwSegment * 2; else if(m_bUpperVis || m_bLowerVis) m_dwTotalSegment = m_dwSegment; else return FALSE; m_lpD3DDevice->CreateVertexBuffer( (m_dwSidePlane + 1) * (m_dwSegment + 1) * 2 * sizeof(LVertex), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, LVERTEXFVF, D3DPOOL_DEFAULT, &m_lpVertices ); m_lpD3DDevice->CreateVertexBuffer( (m_dwSidePlane + 1) * (m_dwSegment + 1) * 2 * sizeof(LVertex), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, LVERTEXFVF, D3DPOOL_DEFAULT, &m_lpVerticesBlend ); m_lpD3DDevice->CreateIndexBuffer( m_dwSidePlane * m_dwTotalSegment * 2 * 3 * sizeof(unsigned short), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_lpVerticeIndex); if(m_dwTotalSegment == m_dwSegment) { m_dwNumVertex = (m_dwSidePlane + 1) * (m_dwSegment + 1); } else { m_dwNumVertex = (m_dwSidePlane + 1) * (m_dwSegment + 1) * 2; } m_dwPrimitive = m_dwSidePlane * m_dwTotalSegment * 2; unsigned short *pVerticeIndex; m_lpVerticeIndex->Lock(0, m_dwSidePlane * m_dwTotalSegment * 2 * 3 * sizeof(unsigned short), (unsigned char **)&pVerticeIndex, 0); unsigned long i, j, ti = 0, tv = 0; unsigned long temp, t1, t2; // Upper if(m_bUpperVis) { for(j = 0; j < m_dwSegment; j++) { for(i = 0; i < m_dwSidePlane; i++) { temp = j * (m_dwSidePlane * 6) + i * 6; t1 = (m_dwSidePlane + 1) * j + i; t2 = (m_dwSidePlane + 1) * (j + 1) + i; if(m_bUpperUp) { // Up pVerticeIndex[temp + 0] = t1 + 0; pVerticeIndex[temp + 1] = t1 + 1; pVerticeIndex[temp + 2] = t2; pVerticeIndex[temp + 3] = t1 + 1; pVerticeIndex[temp + 4] = t2 + 1; pVerticeIndex[temp + 5] = t2; } else { // Center pVerticeIndex[temp + 0] = t1 + 0; pVerticeIndex[temp + 1] = t2; pVerticeIndex[temp + 2] = t1 + 1; pVerticeIndex[temp + 3] = t2; pVerticeIndex[temp + 4] = t2 + 1; pVerticeIndex[temp + 5] = t1 + 1; } } } ti = m_dwSidePlane * m_dwSegment * 2 * 3; tv = (m_dwSidePlane + 1) * (m_dwSegment + 1); } // Lower if(m_bLowerVis) { for(j = 0; j < m_dwSegment; j++) { for(i = 0; i < m_dwSidePlane; i++) { temp = j * (m_dwSidePlane * 6) + i * 6 + ti; t1 = (m_dwSidePlane + 1) * j + i; t2 = (m_dwSidePlane + 1) * (j + 1) + i; if(m_bLowerUp) { // Up pVerticeIndex[temp + 0] = tv + t1 + 0; pVerticeIndex[temp + 1] = tv + t2; pVerticeIndex[temp + 2] = tv + t1 + 1; pVerticeIndex[temp + 3] = tv + t2; pVerticeIndex[temp + 4] = tv + t2 + 1; pVerticeIndex[temp + 5] = tv + t1 + 1; } else { // Center pVerticeIndex[temp + 0] = tv + t1 + 0; pVerticeIndex[temp + 1] = tv + t1 + 1; pVerticeIndex[temp + 2] = tv + t2; pVerticeIndex[temp + 3] = tv + t1 + 1; pVerticeIndex[temp + 4] = tv + t2 + 1; pVerticeIndex[temp + 5] = tv + t2; } } } } m_lpVerticeIndex->Unlock(); return TRUE; } void CX3DEffectSphere::Render(void) { if(!m_bVisibility) return; if(m_lpVertices == NULL) return; matrix matWorld; matWorld.MakeIdent(); quaternion *quatAxis = ((CX3DEffect *)m_lpLocalEffect)->GetAxis(); if(quatAxis) { z3d::MatrixRotationQuaternion(matWorld, (*quatAxis)); } if(((CX3DEffect *)m_lpLocalEffect)->GetCenter()) { vector3 *vecTemp = ((CX3DEffect *)m_lpLocalEffect)->GetCenter(); matWorld._41 = vecTemp->x; matWorld._42 = vecTemp->y; matWorld._43 = vecTemp->z; } m_lpD3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX *)&matWorld); CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,FALSE); m_lpD3DDevice->SetTexture(0, GetTexture()); CSceneStateMgr::_SetD3DRenderState(D3DRS_SRCBLEND, m_dwSrcBlending); CSceneStateMgr::_SetD3DRenderState(D3DRS_DESTBLEND, m_dwDestBlending); m_lpD3DDevice->SetStreamSource(0, m_lpVertices, sizeof(LVertex)); m_lpD3DDevice->SetVertexShader(LVERTEXFVF); m_lpD3DDevice->SetIndices(m_lpVerticeIndex, 0); m_lpD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVertex, 0, m_dwPrimitive); if(m_bTexAni) { CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,FALSE); CSceneStateMgr::_SetD3DRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); CSceneStateMgr::_SetD3DRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); m_lpD3DDevice->SetStreamSource(0, m_lpVerticesBlend, sizeof(LVertex)); m_lpD3DDevice->SetVertexShader(LVERTEXFVF); m_lpD3DDevice->SetIndices(m_lpVerticeIndex, 0); m_lpD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVertex, 0, m_dwPrimitive); }/**/ } BOOL CX3DEffectSphere::Interpolation(float fFrame) { if(m_lpVertices == NULL) return FALSE; /////////////////////////////////////////////////////////////////////////////////// if(!m_lstCenter.Interpolation(fFrame, m_vecCenter)) return FALSE; if(!m_lstAxis.InterpolationQ(fFrame, m_quatAxis)) return FALSE; if(!m_lstHeightFactor.Interpolation(fFrame, m_fHeightFactor)) return FALSE; if(!m_lstRadius.Interpolation(fFrame, m_fRadius)) return FALSE; if(m_Scale[0] != 1.0f) { m_fRadius *= m_Scale[0]; m_vecCenter.x *=m_Scale[0]; m_vecCenter.z *=m_Scale[0]; m_vecCenter.y *=(m_Scale[0]); } if(!m_lstUpperFactor.Interpolation(fFrame, m_fUpperFactor)) return FALSE; if(!m_lstLowerFactor.Interpolation(fFrame, m_fLowerFactor)) return FALSE; if(!m_lstColor.InterpolationC(fFrame, m_lColor)) return FALSE; if(m_bTexAni) { if(!m_lstTexFrame.Interpolation(fFrame, m_fTexFrame)) return FALSE; } else { if(!m_lstStartU.Interpolation(fFrame, m_fStartU)) return FALSE; if(!m_lstStartV.Interpolation(fFrame, m_fStartV)) return FALSE; if(!m_lstTileU.Interpolation(fFrame, m_fTileU)) return FALSE; if(!m_lstTileV.Interpolation(fFrame, m_fTileV)) return FALSE; } /////////////////////////////////////////////////////////////////////////////////// if(m_bVisibility) { { LVertex *pVertices, *pVerticesBlend; if(FAILED( m_lpVertices->Lock( 0, (m_dwSidePlane + 1) * (m_dwSegment + 1) * 2 * sizeof(LVertex), (unsigned char **)&pVertices, D3DLOCK_DISCARD ) ) ) return FALSE; if(FAILED( m_lpVerticesBlend->Lock( 0, (m_dwSidePlane + 1) * (m_dwSegment + 1) * 2 * sizeof(LVertex), (unsigned char **)&pVerticesBlend, D3DLOCK_DISCARD ) ) ) return FALSE; unsigned long i, tempi, j, t1, tv = 0; float degree, hdegree, height, hcos; float divangle = FLOAT_PHI * 2.0f / m_dwSidePlane; float f1, f2; float fStartU, fStartV, fEndU, fEndV; float fStartBU, fStartBV, fEndBU, fEndBV; if(m_bTexAni) { f1 = (((long)m_fTexFrame) % 4) * 0.25; f2 = (((long)m_fTexFrame) / 4) * 0.25; fStartU = f1; fStartV = f2; f1 = (((long)ceilf(m_fTexFrame)) % 4) * 0.25; f2 = (((long)ceilf(m_fTexFrame)) / 4) * 0.25; fStartBU = f1; fStartBV = f2; fEndU = fEndBU = 0.25f; fEndV = fEndBV = 0.25f; } else { fStartBU = fStartU = m_fStartU; fStartBV = fStartV = m_fStartV; fEndBU = fEndU = m_fTileU - fStartBU; fEndBV = fEndV = m_fTileV - fStartBV; } float fHEV = fEndV / 2.0f, fSV = fHEV + fStartV, fDSV = fSV * 2.0f; float fHEBV = fEndBV / 2.0f, fSBV = fHEBV + fStartBV, fDSBV = fSBV * 2.0f; float fSegTemp, fSegBTemp; if(m_bUpperVis) { for(j = 0; j <= m_dwSegment; j++) { if(m_bUpperUp) hdegree = (FLOAT_PHI / 2.0f) - ((j * FLOAT_PHI) / (2.0f * m_dwSegment) * m_fUpperFactor); else hdegree = ((j * FLOAT_PHI) / (2.0f * m_dwSegment)) * m_fUpperFactor; height = m_fRadius * m_fHeightFactor * sinf(hdegree); hcos = cosf(hdegree); fSegTemp = fHEV * j / m_dwSegment; fSegBTemp = fHEBV * j / m_dwSegment; for(i = 0; i <= m_dwSidePlane; i++) { if(i == m_dwSidePlane) tempi = 0; else tempi = i; degree = tempi * divangle; t1 = (m_dwSidePlane + 1) * j + i; pVertices[t1].v = vector3(m_fRadius * cosf(degree) * hcos, height, m_fRadius * sinf(degree) * hcos); z3d::VectorRotate(pVertices[t1].v, pVertices[t1].v, m_quatAxis); pVertices[t1].v += m_vecCenter; pVerticesBlend[t1].v = pVertices[t1].v; pVertices[t1].tu = fStartU + fEndU * (float)i / m_dwSidePlane; pVerticesBlend[t1].tu = fStartBU + fEndBU * (float)i / m_dwSidePlane; if(m_bUpperUp) { if(m_bUpperTex) { pVertices[t1].tv = fStartV + fSegTemp * m_fUpperFactor; pVerticesBlend[t1].tv = fStartBV + fSegBTemp * m_fUpperFactor; } else { pVertices[t1].tv = fStartV + fSegTemp; pVerticesBlend[t1].tv = fStartBV + fSegBTemp; } } else { if(m_bUpperTex) { pVertices[t1].tv = (fStartV + fSV) - ((fStartV + fSegTemp) * m_fUpperFactor); pVerticesBlend[t1].tv = (fStartBV + fSBV) - ((fStartBV + fSegBTemp) * m_fUpperFactor); } else { pVertices[t1].tv = fSV - fSegTemp; pVerticesBlend[t1].tv = fSBV - fSegBTemp; } } } } tv = (m_dwSidePlane + 1) * (m_dwSegment + 1); } if(m_bLowerVis) { for(j = 0; j <= m_dwSegment; j++) { if(m_bLowerUp) hdegree = (FLOAT_PHI / 2.0f) - ((j * FLOAT_PHI) / (2.0f * m_dwSegment) * m_fLowerFactor); else hdegree = ((j * FLOAT_PHI) / (2.0f * m_dwSegment)) * m_fLowerFactor; height = m_fRadius * m_fHeightFactor * sinf(hdegree); hcos = cosf(hdegree); fSegTemp = fHEV * j / m_dwSegment; fSegBTemp = fHEBV * j / m_dwSegment; for(i = 0; i <= m_dwSidePlane; i++) { if(i == m_dwSidePlane) tempi = 0; else tempi = i; degree = tempi * divangle; t1 = tv + (m_dwSidePlane + 1) * j + i; pVertices[t1].v = vector3(m_fRadius * cosf(degree) * hcos, -height, m_fRadius * sinf(degree) * hcos); z3d::VectorRotate(pVertices[t1].v, pVertices[t1].v, m_quatAxis); pVertices[t1].v += m_vecCenter; pVerticesBlend[t1].v = pVertices[t1].v; pVertices[t1].tu = fStartU + fEndU * (float)i / m_dwSidePlane; pVerticesBlend[t1].tu = fStartBU + fEndBU * (float)i / m_dwSidePlane; if(m_bLowerUp) { if(m_bLowerTex) { pVertices[t1].tv = fDSV - ((fStartV + fSegTemp) * m_fLowerFactor); pVerticesBlend[t1].tv = fDSBV - ((fStartBV + fSegBTemp) * m_fLowerFactor); } else { pVertices[t1].tv = fDSV - (fStartV + fSegTemp); pVerticesBlend[t1].tv = fDSBV - (fStartBV + fSegBTemp); } } else { if(m_bLowerTex) { pVertices[t1].tv = fSV + fSegTemp * m_fLowerFactor; pVerticesBlend[t1].tv = fSBV + fSegBTemp * m_fLowerFactor; } else { pVertices[t1].tv = fSV + fSegTemp; pVerticesBlend[t1].tv = fSBV + fSegBTemp; } } } } } pVertices[0].diff = m_lColor; pVertices[0].spec = color(0xFF, 0xFF, 0xFF, 0xFF); pVerticesBlend[0].diff =pVertices[0].diff; pVerticesBlend[0].spec =pVertices[0].spec; if(m_bTexAni) { pVertices[0].diff.a *= (floorf(m_fTexFrame + 1.0f) - m_fTexFrame); pVerticesBlend[0].diff.a *= (m_fTexFrame - floorf(m_fTexFrame)); } if(m_dwTotalSegment == m_dwSegment) { for(i = 1; i < (m_dwSidePlane + 1) * (m_dwSegment + 1); i++) { pVertices[i].diff = pVertices[0].diff; pVertices[i].spec = pVertices[0].spec; pVerticesBlend[i].diff = pVerticesBlend[0].diff; pVerticesBlend[i].spec = pVerticesBlend[0].spec; } } else { for(i = 1; i < (m_dwSidePlane + 1) * (m_dwSegment + 1) * 2; i++) { pVertices[i].diff = pVertices[0].diff; pVertices[i].spec = pVertices[0].spec; pVerticesBlend[i].diff = pVerticesBlend[0].diff; pVerticesBlend[i].spec = pVerticesBlend[0].spec; } } m_lpVerticesBlend->Unlock(); m_lpVertices->Unlock(); } } return TRUE; } void CX3DEffectSphere::Load(FILE *fp, const char *strOriginalPath) { fread(&m_bTexAni, 4, 1, fp); fread(&m_dwSrcBlending, 4, 1, fp); fread(&m_dwDestBlending, 4, 1, fp); m_lstAxis.Load(fp, m_quatAxis); m_lstCenter.Load(fp, m_vecCenter); fread(&m_dwSidePlane, 4, 1, fp); fread(&m_dwSegment, 4, 1, fp); fread(&m_bUpperTex, 4, 1, fp); fread(&m_bUpperUp, 4, 1, fp); fread(&m_bUpperVis, 4, 1, fp); fread(&m_bLowerTex, 4, 1, fp); fread(&m_bLowerUp, 4, 1, fp); fread(&m_bLowerVis, 4, 1, fp); m_lstColor.Load(fp, m_lColor); m_lstHeightFactor.Load(fp, m_fHeightFactor); m_lstRadius.Load(fp, m_fRadius); if(m_Scale[0] != 1.0f) { m_fRadius *= m_Scale[0]; m_vecCenter.x *=m_Scale[0]; m_vecCenter.z *=m_Scale[0]; m_vecCenter.y *=(m_Scale[0]); } m_lstUpperFactor.Load(fp, m_fUpperFactor); m_lstLowerFactor.Load(fp, m_fLowerFactor); m_lstStartU.Load(fp, m_fStartU); m_lstStartV.Load(fp, m_fStartV); m_lstTileU.Load(fp, m_fTileU); m_lstTileV.Load(fp, m_fTileV); m_lstTexFrame.Load(fp, m_fTexFrame); } void CX3DEffectSphere::Save(FILE *fp, const char *strOriginalPath) { fwrite(&m_bTexAni, 4, 1, fp); fwrite(&m_dwSrcBlending, 4, 1, fp); fwrite(&m_dwDestBlending, 4, 1, fp); m_lstAxis.Save(fp); m_lstCenter.Save(fp); fwrite(&m_dwSidePlane, 4, 1, fp); fwrite(&m_dwSegment, 4, 1, fp); fwrite(&m_bUpperTex, 4, 1, fp); fwrite(&m_bUpperUp, 4, 1, fp); fwrite(&m_bUpperVis, 4, 1, fp); fwrite(&m_bLowerTex, 4, 1, fp); fwrite(&m_bLowerUp, 4, 1, fp); fwrite(&m_bLowerVis, 4, 1, fp); m_lstColor.Save(fp); m_lstHeightFactor.Save(fp); m_lstRadius.Save(fp); m_lstUpperFactor.Save(fp); m_lstLowerFactor.Save(fp); m_lstStartU.Save(fp); m_lstStartV.Save(fp); m_lstTileU.Save(fp); m_lstTileV.Save(fp); m_lstTexFrame.Save(fp); }