AI_FollowGroup_t *CAI_FollowManager::FindCreateGroup( CBaseEntity *pTarget ) { AI_FollowGroup_t *pGroup = FindGroup( pTarget ); if ( !pGroup ) { pGroup = new AI_FollowGroup_t; pGroup->pFormation = AIGetFormation( AIF_SIMPLE ); pGroup->slotUsage.Resize( pGroup->pFormation->nSlots ); pGroup->hFollowTarget = pTarget; m_groups.AddToHead( pGroup ); } return pGroup; }
//----------------------------------------------------------------------------- // Purpose: // Input : *pFace - input face to test // *pbrush - brush to clip face against // **pOutputList - list of faces clipped from pFace // Output : Returns true if the brush completely clips the face //----------------------------------------------------------------------------- // NOTE: This assumes the brushes have already been chopped so that no solid space // is enclosed by more than one brush!! bool ClipFaceToBrush( face_t *pFace, bspbrush_t *pbrush, face_t **pOutputList ) { int planenum = pFace->planenum & (~1); int foundSide = -1; CUtlVector<int> sortedSides; int i; for ( i = 0; i < pbrush->numsides && foundSide < 0; i++ ) { int bplane = pbrush->sides[i].planenum & (~1); if ( bplane == planenum ) foundSide = i; } Vector offset = -0.5f * (pbrush->maxs + pbrush->mins); face_t *currentface = CopyFace( pFace ); if ( foundSide >= 0 ) { sortedSides.RemoveAll(); for ( i = 0; i < pbrush->numsides; i++ ) { // don't clip to bevels if ( pbrush->sides[i].bevel ) continue; if ( g_MainMap->mapplanes[pbrush->sides[i].planenum].type <= PLANE_Z ) { sortedSides.AddToHead( i ); } else { sortedSides.AddToTail( i ); } } for ( i = 0; i < sortedSides.Size(); i++ ) { int index = sortedSides[i]; if ( index == foundSide ) continue; plane_t *plane = &g_MainMap->mapplanes[pbrush->sides[index].planenum]; winding_t *frontwinding, *backwinding; ClipWindingEpsilon_Offset(currentface->w, plane->normal, plane->dist, 0.001, &frontwinding, &backwinding, offset); // only clip if some part of this face is on the back side of all brush sides if ( !backwinding || WindingIsTiny(backwinding)) { FreeFaceList( *pOutputList ); *pOutputList = NULL; break; } if ( frontwinding && !WindingIsTiny(frontwinding) ) { // add this fragment to the return list // make a face for the fragment face_t *f = NewFaceFromFace( pFace ); f->w = frontwinding; // link the fragment in f->next = *pOutputList; *pOutputList = f; } // update the current winding to be the part behind each plane FreeWinding( currentface->w ); currentface->w = backwinding; } // free the bit that is left in solid or not clipped (if we broke out early) FreeFace( currentface ); // if we made it all the way through and didn't produce any fragments then the whole face was clipped away if ( !*pOutputList && i == sortedSides.Size() ) { return true; } } return false; }
void PhonemeEditor::CloseCaption_MergeSelected( void ) { CountSelected(); if ( m_nSelectedPhraseCount < 2 ) { Con_Printf( "CloseCaption_MergeSelected: requires 2 or more selected phrases\n" ); return; } if ( !CloseCaption_AreSelectedPhrasesContiguous() ) { Con_Printf( "CloseCaption_MergeSelected: selected phrases must be contiguous\n" ); return; } SetDirty( true ); PushUndo(); CUtlVector< CCloseCaptionPhrase * > selected; float beststart = 100000.0f; float bestend = -100000.0f; int c = m_Tags.GetCloseCaptionPhraseCount( CC_ENGLISH ); int i; int insertslot = c -1; // Walk backwards and remove for ( i = c - 1; i >= 0; i-- ) { CCloseCaptionPhrase *phrase = m_Tags.GetCloseCaptionPhrase( CC_ENGLISH, i ); if ( !phrase || !phrase->GetSelected() ) continue; if ( phrase->GetStartTime() < beststart ) { beststart = phrase->GetStartTime(); } if ( phrase->GetEndTime() > bestend ) { bestend = phrase->GetEndTime(); } selected.AddToHead( new CCloseCaptionPhrase( *phrase ) ); // Remember the earliest slot if ( i < insertslot ) { insertslot = i; } m_Tags.RemoveCloseCaptionPhrase( CC_ENGLISH, i ); } if ( selected.Count() <= 0 ) return; CCloseCaptionPhrase *newphrase = new CCloseCaptionPhrase( selected[ 0 ]->GetStream() ); Assert( newphrase ); wchar_t sz[ 4096 ]; delete selected[ 0 ]; for ( i = 1; i < selected.Count(); i++ ) { _snwprintf( sz, sizeof( sz ), newphrase->GetStream() ); // Phrases don't have leading/trailing spaces so it should be safe to just append a space here wcscat( sz, L" " ); wcscat( sz, selected[ i ]->GetStream() ); newphrase->SetStream( sz ); delete selected[ i ]; } selected.RemoveAll(); m_Tags.InsertCloseCaptionPhraseAtIndex( CC_ENGLISH, newphrase, insertslot ); newphrase->SetSelected( true ); newphrase->SetStartTime( beststart ); newphrase->SetEndTime( bestend ); PushRedo(); redraw(); }