void UModel::CalculateUniqueVertCount() { NumUniqueVertices = Points.Num(); if(NumUniqueVertices == 0 && Polys != NULL) { TArray<FVector> UniquePoints; for(int32 PolyIndex(0); PolyIndex < Polys->Element.Num(); ++PolyIndex) { for(int32 VertIndex(0); VertIndex < Polys->Element[PolyIndex].Vertices.Num(); ++VertIndex) { bool bAlreadyAdded(false); for(int32 UniqueIndex(0); UniqueIndex < UniquePoints.Num(); ++UniqueIndex) { if(Polys->Element[PolyIndex].Vertices[VertIndex] == UniquePoints[UniqueIndex]) { bAlreadyAdded = true; break; } } if(!bAlreadyAdded) { UniquePoints.Push(Polys->Element[PolyIndex].Vertices[VertIndex]); } } } NumUniqueVertices = UniquePoints.Num(); } }
static void AddDependency( CVertInfo *dependencies, int sideLength, CVertIndex const &nodeIndex, CVertIndex const &dependency, int iMaxPower, bool bCheckNeighborDependency, bool bAddReverseDependency ) { int iNodeIndex = VertIndex( nodeIndex, iMaxPower ); CVertInfo *pNode = &dependencies[iNodeIndex]; int iDep = GetFreeDependency( pNode->m_Dependencies, sizeof(pNode->m_Dependencies)/sizeof(pNode->m_Dependencies[0]) ); pNode->m_Dependencies[iDep].m_iVert = dependency; pNode->m_Dependencies[iDep].m_iNeighbor = -1; if( bAddReverseDependency ) { CVertInfo *pDep = &dependencies[VertIndex( dependency, iMaxPower )]; iDep = GetFreeDependency( pDep->m_ReverseDependencies, CVertInfo::NUM_REVERSE_DEPENDENCIES ); pDep->m_ReverseDependencies[iDep].m_iVert = nodeIndex; pDep->m_ReverseDependencies[iDep].m_iNeighbor = -1; } // Edge verts automatically add a dependency for the neighbor. // Internal verts wind up in here twice anyway so it doesn't need to if( bCheckNeighborDependency ) { int iConnection = GetEdgeIndexFromPoint( nodeIndex, iMaxPower ); if( iConnection != -1 ) { Assert( !pNode->m_Dependencies[1].IsValid() ); CVertIndex delta( nodeIndex.x - dependency.x, nodeIndex.y - dependency.y ); CVertIndex newIndex( nodeIndex.x + delta.x, nodeIndex.y + delta.y ); int fullSideLength = (1 << iMaxPower) + 1; pNode->m_Dependencies[1].m_iVert = WrapVertIndex( CVertIndex( newIndex.x, newIndex.y ), fullSideLength ); pNode->m_Dependencies[1].m_iNeighbor = iConnection; } } }
// ----------------------------------------------------------------------------- // // This little beastie generate decal fragments // ----------------------------------------------------------------------------- // void CDispInfo::GenerateDecalFragments_R( CVertIndex const &nodeIndex, int iNodeBitIndex, unsigned short decalHandle, CDispDecalBase *pDispDecal, int iLevel ) { // Get the node info for this node... Assert( iNodeBitIndex < m_pPowerInfo->m_NodeCount ); DispNodeInfo_t const& nodeInfo = m_pNodeInfo[iNodeBitIndex]; int iNodeIndex = VertIndex( nodeIndex ); // Don't bother adding decals if the node doesn't have decal info. if( !pDispDecal->m_NodeIntersect.Get( iNodeBitIndex ) ) return; // Recurse into child nodes, but only if they have triangles. if ( ( iLevel+1 < m_Power ) && (nodeInfo.m_Flags & DispNodeInfo_t::CHILDREN_HAVE_TRIANGLES) ) { int iChildNodeBit = iNodeBitIndex + 1; for( int iChild=0; iChild < 4; iChild++ ) { CVertIndex const &childNode = m_pPowerInfo->m_pChildVerts[iNodeIndex].m_Verts[iChild]; bool bActiveChild = m_ActiveVerts.Get( VertIndex( childNode ) ) != 0; if ( bActiveChild ) GenerateDecalFragments_R( childNode, iChildNodeBit, decalHandle, pDispDecal, iLevel + 1 ); iChildNodeBit += m_pPowerInfo->m_NodeIndexIncrements[iLevel]; } } // Create the decal fragments on the node triangles bool isShadow = (pDispDecal->m_Flags & CDispDecalBase::DECAL_SHADOW) != 0; int index = nodeInfo.m_FirstTesselationIndex; for ( int i = 0; i < nodeInfo.m_Count; i += 3 ) { if (isShadow) TestAddDecalTri( &m_Indices[index + i], decalHandle, static_cast<CDispShadowDecal*>(pDispDecal) ); else TestAddDecalTri( &m_Indices[index + i], decalHandle, static_cast<CDispDecal*>(pDispDecal) ); } }