void CGameGibManager::AddGibToLRU( CBaseAnimating *pEntity ) { int i, next; if ( pEntity == NULL ) return; //Find stale gibs. for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { next = m_LRU.Next(i); if ( m_LRU[i].Get() == NULL ) { m_LRU.Remove(i); } } // We're not tracking gibs at the moment if ( m_iCurrentMaxPieces <= 0 ) return; while ( m_LRU.Count() >= m_iCurrentMaxPieces ) { i = m_LRU.Head(); //TODO: Make this fade out instead of pop. UTIL_Remove( m_LRU[i] ); m_LRU.Remove(i); } m_LRU.AddToTail( pEntity ); m_iLastFrame = gpGlobals->framecount; }
// ----------------------------------------------------------------------------- // // Add/remove decals // ----------------------------------------------------------------------------- // DispDecalHandle_t CDispInfo::NotifyAddDecal( decal_t *pDecal ) { // FIXME: Add decal retirement... // if( m_Decals.Size() < MAX_DISP_DECALS ) // return; // Create a new decal, link it in DispDecalHandle_t h = s_DispDecals.Alloc( true ); // When linking, insert it in sorted order based on material enumeration ID // This will help us when rendering later int last = DISP_DECAL_HANDLE_INVALID; int i = m_FirstDecal; int enumerationId = pDecal->material->GetEnumerationID(); while( i != s_DispDecals.InvalidIndex() ) { int testId = s_DispDecals[i].m_pDecal->material->GetEnumerationID(); if (enumerationId <= testId) break; last = i; i = s_DispDecals.Next(i); } // NOTE: when the list is used in multimode, we can't use LinkBefore( i, INVALID_INDEX ), // since the Head and Tail of the linked list are meaningless... if ( last != DISP_DECAL_HANDLE_INVALID ) s_DispDecals.LinkAfter( last, h ); else { s_DispDecals.LinkBefore( m_FirstDecal, h ); m_FirstDecal = h; } CDispDecal *pDispDecal = &s_DispDecals[h]; pDispDecal->m_pDecal = pDecal; pDispDecal->m_FirstFragment = DISP_DECAL_FRAGMENT_HANDLE_INVALID; pDispDecal->m_nVerts = 0; pDispDecal->m_nTris = 0; // Setup a basis for it. CDecalVert *pOutVerts = NULL; R_SetupDecalClip( pOutVerts, pDispDecal->m_pDecal, MSurf_Plane( m_ParentSurfID ).normal, pDispDecal->m_pDecal->material, pDispDecal->m_TextureSpaceBasis, pDispDecal->m_DecalWorldScale ); // Recurse and precalculate which nodes this thing can touch. SetupDecalNodeIntersect( m_pPowerInfo->m_RootNode, 0, // node bit index into CDispDecal::m_NodeIntersects pDispDecal, 0 ); return h; }
//----------------------------------------------------------------------------- // Purpose: // Input : *focus - //----------------------------------------------------------------------------- void CInputWin32::PanelDeleted(VPANEL focus) { HInputContext i; for (i = m_Contexts.Head(); i != m_Contexts.InvalidIndex(); i = m_Contexts.Next(i) ) { PanelDeleted( focus, m_Contexts[i] ); } PanelDeleted( focus, m_DefaultInputContext ); }
void CGroundLine::DrawAllGroundLines() { VPROF("CGroundLine::DrawAllGroundLines()"); unsigned short i; for( i = s_GroundLines.Head(); i != s_GroundLines.InvalidIndex(); i = s_GroundLines.Next(i) ) { s_GroundLines[i]->Draw(); } }
void CDispInfo::ClearAllShadowDecalFragments() { // Iterate over all shadow decals on the displacement DispShadowHandle_t h = m_FirstShadowDecal; while( h != DISP_SHADOW_HANDLE_INVALID ) { ClearShadowDecalFragments( h ); h = s_DispShadowDecals.Next(h); } }
void CVGui::DestroyAllContexts( ) { HContext next; HContext i = m_Contexts.Head(); while (i != m_Contexts.InvalidIndex()) { next = m_Contexts.Next(i); DestroyContext( i ); i = next; } }
//----------------------------------------------------------------------------- // Enumerate elements in a particular leaf //----------------------------------------------------------------------------- int CBSPTreeData::CountElementsInLeaf( int leaf ) { int i; int nCount = 0; for( i = m_Leaf[leaf].m_FirstElement; i != m_LeafElements.InvalidIndex(); i = m_LeafElements.Next(i) ) { ++nCount; } return nCount; }
void CDispInfo::RemoveShadowDecal( DispShadowHandle_t h ) { // Any fragments we got we don't need ClearShadowDecalFragments(h); // Reset the head of the list if (m_FirstShadowDecal == h) m_FirstShadowDecal = s_DispShadowDecals.Next(h); // Blow away the decal s_DispShadowDecals.Free( h ); }
void CBSPTreeData::RemoveFromTree( BSPTreeDataHandle_t handle ) { // Iterate over the list of all leaves the handle is in unsigned short i = m_Handles[handle].m_LeafList; while (i != m_HandleLeafList.InvalidIndex()) { int leaf = m_HandleLeafList[i].m_Leaf; unsigned short leafElement = m_HandleLeafList[i].m_LeafElementIndex; // Unhook the handle from the leaf handle list if (leafElement == m_Leaf[leaf].m_FirstElement) m_Leaf[leaf].m_FirstElement = m_LeafElements.Next(leafElement); m_LeafElements.Free(leafElement); unsigned short prevNode = i; i = m_HandleLeafList.Next(i); m_HandleLeafList.Free(prevNode); } m_Handles[handle].m_LeafList = m_HandleLeafList.InvalidIndex(); }
void TimeoutJobIDs() { double flCurTime = Plat_FloatTime(); int iNext; for ( int i=g_JobMemories.Head(); i != g_JobMemories.InvalidIndex(); i=iNext ) { iNext = g_JobMemories.Next( i ); if ( (flCurTime - g_JobMemories[i].m_Time) > JOB_MEMORY_DURATION ) g_JobMemories.Remove( i ); } }
bool FindJobMemory( int id[4] ) { int iNext; for ( int i=g_JobMemories.Head(); i != g_JobMemories.InvalidIndex(); i=iNext ) { iNext = g_JobMemories.Next( i ); CJobMemory *pJob = &g_JobMemories[i]; if ( memcmp( pJob->m_ID, id, sizeof( pJob->m_ID ) ) == 0 ) return true; } return false; }
static bool EventCollidesWithRows( CUtlLinkedList< CChoreoEvent*, int >& list, CChoreoEvent *event, char *trackName, size_t trackNameLength ) { float st = event->GetStartTime(); float ed = event->GetEndTime(); for ( int i = list.Head(); i != list.InvalidIndex(); i = list.Next( i ) ) { CChoreoEvent *test = list[ i ]; float teststart = test->GetStartTime(); float testend = test->GetEndTime(); // See if spans overlap if ( teststart >= ed ) continue; if ( testend <= st ) continue; // Now see if they deal with the same flex controller int tc = event->GetNumFlexAnimationTracks(); for ( int track = 0; track < tc; ++track ) { CFlexAnimationTrack *t = event->GetFlexAnimationTrack( track ); if ( !t->IsTrackActive() ) { continue; } int sampleCountNormal = t->GetNumSamples( 0 ); int sampleCountBalance = 0; if ( t->IsComboType() ) { sampleCountBalance = t->GetNumSamples( 1 ); } if ( !sampleCountNormal && !sampleCountBalance ) continue; // Otherwise, see if the test track has this as an active track if ( IsFlexTrackBeingUsed( test, t->GetFlexControllerName() ) ) { Q_strncpy( trackName, t->GetFlexControllerName(), trackNameLength ); return true; } } return false; } return false; }
//----------------------------------------------------------------------------- // Clears shadow decal fragment lists //----------------------------------------------------------------------------- void CDispInfo::ClearShadowDecalFragments( DispShadowHandle_t h ) { // Iterate over all fragments associated with each shadow decal CDispShadowDecal& decal = s_DispShadowDecals[h]; DispShadowFragmentHandle_t f = decal.m_FirstFragment; DispShadowFragmentHandle_t next; while( f != DISP_SHADOW_FRAGMENT_HANDLE_INVALID ) { next = s_DispShadowFragments.Next(f); s_DispShadowFragments.Free(f); f = next; } // Blat out the list decal.m_FirstFragment = DISP_SHADOW_FRAGMENT_HANDLE_INVALID; // Mark is as not computed decal.m_Flags &= ~CDispDecalBase::FRAGMENTS_COMPUTED; // Update the number of triangles in the decal decal.m_nTris = 0; decal.m_nVerts = 0; }
//----------------------------------------------------------------------------- // Enumerate elements in a particular leaf //----------------------------------------------------------------------------- bool CBSPTreeData::EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, int context ) { #ifdef DBGFLAG_ASSERT // The enumeration method better damn well not change this list... int nCount = CountElementsInLeaf(leaf); #endif unsigned short idx = m_Leaf[leaf].m_FirstElement; while (idx != m_LeafElements.InvalidIndex()) { BSPTreeDataHandle_t handle = m_LeafElements[idx]; if (!pEnum->EnumerateElement( m_Handles[handle].m_UserId, context )) { Assert( CountElementsInLeaf(leaf) == nCount ); return false; } idx = m_LeafElements.Next(idx); } Assert( CountElementsInLeaf(leaf) == nCount ); return true; }
// ----------------------------------------------------------------------------- // // Adds shadow rendering data to a particular mesh builder // ----------------------------------------------------------------------------- // int DispInfo_AddShadowsToMeshBuilder( CMeshBuilder& meshBuilder, DispShadowHandle_t h, int baseIndex ) { #ifndef SWDS if ( !r_DrawDisp.GetBool() ) { return baseIndex; } CDispShadowDecal* pShadowDecal = &s_DispShadowDecals[h]; int shadow = pShadowDecal->m_Shadow; ShadowInfo_t const& info = g_pShadowMgr->GetInfo( shadow ); // It had better be computed by now... Assert( pShadowDecal->m_Flags & CDispDecalBase::FRAGMENTS_COMPUTED ); #ifdef _DEBUG int triCount = 0; int vertCount = 0; #endif DispShadowFragmentHandle_t f = pShadowDecal->m_FirstFragment; while ( f != DISP_SHADOW_FRAGMENT_HANDLE_INVALID ) { CDispShadowFragment& fragment = s_DispShadowFragments[f]; // Add in the vertices + indices, use two loops to minimize tests... int i; for ( i = 0; i < fragment.m_nVerts - 2; ++i ) { meshBuilder.Position3fv( fragment.m_Verts[i].Base() ); // Transform + offset the texture coords Vector2D texCoord; Vector2DMultiply( fragment.m_TCoords[i].AsVector2D(), info.m_TexSize, texCoord ); texCoord += info.m_TexOrigin; meshBuilder.TexCoord2fv( 0, texCoord.Base() ); unsigned char c = g_pShadowMgr->ComputeDarkness( fragment.m_TCoords[i].z, info ); meshBuilder.Color4ub( c, c, c, c ); meshBuilder.AdvanceVertex(); meshBuilder.Index( baseIndex ); meshBuilder.AdvanceIndex(); meshBuilder.Index( i + baseIndex + 1 ); meshBuilder.AdvanceIndex(); meshBuilder.Index( i + baseIndex + 2 ); meshBuilder.AdvanceIndex(); #ifdef _DEBUG ++triCount; ++vertCount; #endif } for ( ; i < fragment.m_nVerts; ++i ) { meshBuilder.Position3fv( fragment.m_Verts[i].Base() ); // Transform + offset the texture coords Vector2D texCoord; Vector2DMultiply( fragment.m_TCoords[i].AsVector2D(), info.m_TexSize, texCoord ); texCoord += info.m_TexOrigin; meshBuilder.TexCoord2fv( 0, texCoord.Base() ); unsigned char c = g_pShadowMgr->ComputeDarkness( fragment.m_TCoords[i].z, info ); meshBuilder.Color4ub( c, c, c, c ); meshBuilder.AdvanceVertex(); #ifdef _DEBUG ++vertCount; #endif } baseIndex += fragment.m_nVerts; f = s_DispShadowFragments.Next(f); } #ifdef _DEBUG Assert( triCount == pShadowDecal->m_nTris ); Assert( vertCount == pShadowDecal->m_nVerts ); #endif return baseIndex; #else return 0; #endif }
void DispInfo_DrawDecals( CDispInfo *visibleDisps[MAX_MAP_DISPINFO], int nVisibleDisps ) { #ifndef SWDS VPROF("DispInfo_DrawDecals"); if( !nVisibleDisps ) return; int nTrisDrawn = 0; // FIXME: We should bucket all decals (displacement + otherwise) // and sort them by material enum id + lightmap // To do this, we need to associate a sort index from 0-n for all // decals we've seen this level. Then we add those decals to the // appropriate search list, (sorted by lightmap id)? for( int i=0; i < nVisibleDisps; i++ ) { CDispInfo *pDisp = visibleDisps[i]; // Don't bother if there's no decals if( pDisp->m_FirstDecal == DISP_DECAL_HANDLE_INVALID ) continue; materialSystemInterface->BindLightmapPage( pDisp->m_pMesh->m_pGroup->m_LightmapPageID ); // At the moment, all decals in a single displacement are sorted by material // so we get a little batching at least DispDecalHandle_t d = pDisp->m_FirstDecal; while( d != DISP_DECAL_HANDLE_INVALID ) { CDispDecal& decal = s_DispDecals[d]; // Compute decal fragments if we haven't already.... if ((decal.m_Flags & CDispDecalBase::FRAGMENTS_COMPUTED) == 0) { pDisp->GenerateDecalFragments( pDisp->m_pPowerInfo->m_RootNode, 0, d, &decal ); } // Don't draw if there's no triangles if (decal.m_nTris == 0) { d = s_DispDecals.Next(d); continue; } // Now draw all the fragments with this material. IMaterial* pMaterial = decal.m_pDecal->material; IMesh *pMesh = materialSystemInterface->GetDynamicMesh( true, NULL, NULL, pMaterial ); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, decal.m_nVerts, decal.m_nTris * 3 ); int baseIndex = 0; DispDecalFragmentHandle_t f = decal.m_FirstFragment; while (f != DISP_DECAL_FRAGMENT_HANDLE_INVALID) { CDispDecalFragment& fragment = s_DispDecalFragments[f]; int v; for ( v = 0; v < fragment.m_nVerts - 2; ++v) { meshBuilder.Position3fv( fragment.m_pVerts[v].m_vPos.Base() ); meshBuilder.TexCoord2fv( 0, fragment.m_pVerts[v].m_tCoords.Base() ); meshBuilder.TexCoord2fv( 1, fragment.m_pVerts[v].m_LMCoords.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Index( baseIndex ); meshBuilder.AdvanceIndex(); meshBuilder.Index( v + baseIndex + 1 ); meshBuilder.AdvanceIndex(); meshBuilder.Index( v + baseIndex + 2 ); meshBuilder.AdvanceIndex(); } meshBuilder.Position3fv( fragment.m_pVerts[v].m_vPos.Base() ); meshBuilder.TexCoord2fv( 0, fragment.m_pVerts[v].m_tCoords.Base() ); meshBuilder.TexCoord2fv( 1, fragment.m_pVerts[v].m_LMCoords.Base() ); meshBuilder.AdvanceVertex(); ++v; meshBuilder.Position3fv( fragment.m_pVerts[v].m_vPos.Base() ); meshBuilder.TexCoord2fv( 0, fragment.m_pVerts[v].m_tCoords.Base() ); meshBuilder.TexCoord2fv( 1, fragment.m_pVerts[v].m_LMCoords.Base() ); meshBuilder.AdvanceVertex(); baseIndex += fragment.m_nVerts; f = s_DispDecalFragments.Next(f); } meshBuilder.End( false, true ); nTrisDrawn += decal.m_nTris * pMaterial->GetNumPasses(); d = s_DispDecals.Next(d); } } g_EngineStats.IncrementCountedStat( ENGINE_STATS_DECAL_TRIANGLES, nTrisDrawn ); #endif }