// ------------------------------------------------------------------------ // CalcUsedNodes() // specifically find the nodes that are used by the mesh AND are the most // distal nodes in the set. We don't need interior nodes since the xform evaulation // paths start at the leaves. // NOTE : t.f fix // This algorithm is actually in the packer, its here for models that are // version 21 or less. This should be removed once all models are version 22. // ------------------------------------------------------------------------ void CD3DSkelMesh::CalcUsedNodes( Model *pModel ) { std::set<uint32> node_set ; std::vector<uint32> node_list ; for( uint32 iBoneSet = 0 ; iBoneSet < m_iBoneSetCount ; iBoneSet++ ) { for( uint32 iBoneCnt = 0 ; iBoneCnt < 4 ; iBoneCnt++ ) { node_set.insert( (uint32)m_pBoneSetArray[iBoneSet].BoneSetArray[iBoneCnt]); } } std::set<uint32>::iterator set_it = node_set.begin(); // create set of terminal nodes for finding paths. for( ; set_it != node_set.end() ; set_it++ ) { uint32 iNode = *set_it ; if( iNode == 255 ) continue ; ModelNode *pModelNode = pModel->GetNode(iNode); // check if children are in the set. // if none of the children are in the set, add the node to the final list. uint32 nChildren = pModelNode->m_Children.GetSize(); uint32 iChild ; bool IsTerminalNode = true ; for( iChild = 0 ; iChild < nChildren ; iChild++ ) { // if we find a child that is in the set, quit the search. if( node_set.find( pModelNode->m_Children[iChild]->m_NodeIndex ) != node_set.end() ) { IsTerminalNode = false ; continue ; } } // if all the children didn't have a parent in the mesh's bone list, add this node // as a terminal node. if(IsTerminalNode) { node_list.push_back(*set_it); } } // transfer the new information from here to the renderobject. CreateUsedNodeList((uint32)(node_list.size())); for( uint32 iNodeCnt =0 ; iNodeCnt < node_list.size() ; iNodeCnt++ ) { m_pUsedNodeList[iNodeCnt] = node_list[iNodeCnt]; } }
void CD3DVAMesh::CalcUsedNodes( Model *pModel ) { CreateUsedNodeList(1); m_pUsedNodeList[0] = 0; }