void CMesh::BuildCollapseBuffer(bool bExplicitVertexCount, UINT uiMaxCollapses, CArray<uint8_t> const &arrUsedVertices, CProgressiveGeometry *pProgGeom) { int iCollapse, iPos; CArray<UINT> arrCollapses; CArray<uint16_t> arrTriIndices; UINT uiSrcMapFlags = (pProgGeom->m_pIB->m_uiFlags & CResource::RF_KEEPSYSTEMCOPY) ? CResource::RMF_SYSTEM_ONLY : 0; uint8_t *pSrcIndices = pProgGeom->m_pIB->Map(0, uiSrcMapFlags); arrTriIndices.SetCount(pProgGeom->GetIBIndexCount()); memcpy(arrTriIndices.m_pArray, pSrcIndices, arrTriIndices.m_iCount * sizeof(uint16_t)); pProgGeom->m_pIB->Unmap(); CIndexChain kChain; kChain.Init(arrTriIndices.m_pArray, arrTriIndices.m_iCount, pProgGeom->GetVBVertexCount(), bExplicitVertexCount); for (iCollapse = 0; iCollapse < (int) Util::Min<UINT>(m_arrCollapses.m_iCount, uiMaxCollapses); iCollapse++) { if (m_arrCollapses[iCollapse].m_iCollapseToIndex < 0) break; int iVertIndex, iCollapseToIndex, iBaseIndex; iVertIndex = m_arrReverseReorder[m_arrCollapses[iCollapse].m_iVertexIndex]; if (!arrUsedVertices[iVertIndex]) continue; iCollapseToIndex = m_arrReverseReorder[m_arrCollapses[iCollapse].m_iCollapseToIndex]; ASSERT(arrUsedVertices[iCollapseToIndex]); iBaseIndex = arrCollapses.m_iCount; arrCollapses.Append(iVertIndex); arrCollapses.Append(iCollapseToIndex); if (bExplicitVertexCount) // Reserve space for maximum vertex index arrCollapses.SetCount(arrCollapses.m_iCount + 1); iPos = kChain.m_arrVertexChain[iVertIndex]; ASSERT(iPos >= 0); while (iPos >= 0 && iPos < arrTriIndices.m_iCount) { arrCollapses.Append(iPos); ASSERT(arrTriIndices[iPos] == iVertIndex); arrTriIndices[iPos] = iCollapseToIndex; ASSERT(iPos < kChain.m_arrChains[iPos] || kChain.m_arrChains[iPos] < 0); iPos = kChain.m_arrChains[iPos]; } // Shrink index buffer while (arrTriIndices.m_iCount && CGeometry::IsTriangleDegenerate(&arrTriIndices[arrTriIndices.m_iCount - 3])) arrTriIndices.SetCount(arrTriIndices.m_iCount - 3); kChain.MergeChains(iVertIndex, iCollapseToIndex, arrTriIndices.m_iCount); if (bExplicitVertexCount) arrCollapses[iBaseIndex + 2] = kChain.GetLastActiveVertex(); arrCollapses.Append(CProgressiveGeometry::INVALID_INDEX); } pProgGeom->SetCollapses(arrCollapses.m_iCount, arrCollapses.m_pArray, bExplicitVertexCount); }
void CIndexChain::Init(uint16_t *pIndices, int iIndexCount, int iVertexCount, bool bTrackVertices) { int i; m_arrChains.SetCount(iIndexCount); m_arrVertexChain.SetCount(iVertexCount); memset(m_arrVertexChain.m_pArray, -1, m_arrVertexChain.m_iCount * sizeof(int)); for (i = iIndexCount - 1; i >= 0; i--) { m_arrChains[i] = m_arrVertexChain[pIndices[i]]; m_arrVertexChain[pIndices[i]] = i; if (bTrackVertices) m_avlVertices.AddUnique(pIndices[i]); } }
void CMesh::TTriangle::RecordCollapse(CArray<TCollapsedTriangle> &arrCollapsedTriangles) { int iCol; iCol = arrCollapsedTriangles.m_iCount; arrCollapsedTriangles.SetCount(iCol + 1); arrCollapsedTriangles[iCol].m_iIndex = m_iIndex; /* for (int iVert = 0; iVert < 3; iVert++) arrCollapsedTriangles[iCol].m_iMaterials[iVert] = m_pVertices[iVert]->m_iMaterial; */ }