RpClump *CClumpModelInfo::CreateInstance() { if (GetRwObject() == NULL) { return NULL; } AddRef(); RpClump *pCloned = RpClumpClone((RpClump*)GetRwObject()); RpAtomic *pFirst = GetFirstAtomic(pCloned); if (pFirst) { if(RpSkinGeometryGetSkin(pFirst->geometry) != NULL) { if(!dwUnknownFlag10) { RpHAnimHierarchy *pHAnim = GetAnimHierarchyFromClump(pCloned); RpClumpForAllAtomics(pCloned, SetAtomicHAnimHierarchyCB, pHAnim); RtAnimAnimation *pAnim = RpAnimBlendCreateAnimationForHierarchy(pHAnim); RtAnimInterpolatorSetCurrentAnim(pHAnim->currentAnim, pAnim); pHAnim->flags = rpHANIMHIERARCHYUPDATEMODELLINGMATRICES | rpHANIMHIERARCHYUPDATELTMS; } } } if (GetIsRoad()) { RpAnimBlendClumpInit(pCloned); CAnimBlendHierarchy *pAnim = CAnimManager::GetAnimationByID(GetHashKey(), &CAnimManager::AnimBlocks[m_AnimId]); if (pAnim) { CAnimManager::BlendAnimation(pCloned, pAnim, 2, 1.0f); } } RemoveRef(); return pCloned; }
/////////////////////////////////////// // // Save a ref to this clump // /////////////////////////////////////// void SaveClump ( RpClump* pClump, CPedClothesDesc* pClothesDesc ) { UpdateCacheSize (); // Remove up to 2 unused if over limit if ( GetNumCached () >= m_uiMaxSize ) if ( RemoveOldestUnused () ) if ( GetNumCached () >= m_uiMaxSize ) RemoveOldestUnused (); RpClump * pClumpCopy = RpClumpClone ( pClump ); SSavedClumpInfo info; info.pClump = pClumpCopy; #ifdef CLOTHES_REF_TEST RpGeometry* pGeometry = ( ( RpAtomic* ) ( ( info.pClump->atomics.root.next ) - 0x8 ) )->geometry; pGeometry->refs += 20; #endif info.clothedDesc = *pClothesDesc; info.bUnused = false; info.iCacheRevision = m_iCacheRevision; savedClumpList.push_back ( info ); m_Stats.uiNumTotal++; }
/////////////////////////////////////// // // Find a clump which can be used for the provided clothes desc. // Returns NULL if can't be done // /////////////////////////////////////// RpClump* FindMatchAndUse ( CPedClothesDesc* pClothesDesc ) { for ( std::vector < SSavedClumpInfo >::iterator iter = savedClumpList.begin () ; iter != savedClumpList.end () ; ++iter ) { SSavedClumpInfo& info = *iter; if ( info.clothedDesc == *pClothesDesc ) { if ( info.bUnused ) { info.bUnused = false; m_Stats.uiNumUnused--; } m_Stats.uiCacheHit++; RpClump * pCopy = RpClumpClone ( info.pClump ); return pCopy; } } m_Stats.uiCacheMiss++; return NULL; }
/////////////////////////////////////// // // Find a clump which can be used for the provided clothes desc. // Returns NULL if can't be done // /////////////////////////////////////// RpClump* FindMatchAndUse ( CPedClothesDesc* pClothesDesc ) { for ( std::vector < SSavedClumpInfo >::iterator iter = savedClumpList.begin () ; iter != savedClumpList.end () ; ++iter ) { SSavedClumpInfo& info = *iter; if ( info.iCacheRevision != m_iCacheRevision ) continue; // Don't match if it was generated with different custom clothes textures if ( info.clothedDesc == *pClothesDesc ) { if ( info.bUnused ) { info.bUnused = false; m_Stats.uiNumUnused--; } m_Stats.uiCacheHit++; RpClump * pCopy = RpClumpClone ( info.pClump ); return pCopy; } } m_Stats.uiCacheMiss++; return NULL; }