void IFaceposerModels::CFacePoserModel::RecreateAllAnimationBitmaps() { StudioModel *model = m_pModel; if ( !model ) return; CStudioHdr *hdr = model->GetStudioHdr(); if ( !hdr ) return; g_pProgressDialog->Start( CFmtStr( "%s - Animation Thumbnails", GetShortModelName() ), "", true ); for ( int i = 0; i < hdr->GetNumSeq(); ++i ) { const mstudioseqdesc_t &seq = hdr->pSeqdesc( i ); g_pProgressDialog->UpdateText( "%s", seq.pszLabel() ); g_pProgressDialog->Update( (float)i / (float)hdr->GetNumSeq() ); RecreateAnimationBitmap( i, false ); if ( g_pProgressDialog->IsCancelled() ) { Msg( "Cancelling\n" ); break; } } g_pProgressDialog->Finish(); ReconcileAnimationBitmaps(); }
//========================================================= //========================================================= bool CAnimating::HasPoseParameter( int iSequence, int iParameter ) { CStudioHdr *pstudiohdr = GetModelPtr( ); if ( !pstudiohdr ) { return false; } if ( !pstudiohdr->SequencesAvailable() ) { return false; } if (iSequence < 0 || iSequence >= pstudiohdr->GetNumSeq()) { return false; } mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( iSequence ); if (pstudiohdr->GetSharedPoseParameter( iSequence, seqdesc.paramindex[0] ) == iParameter || pstudiohdr->GetSharedPoseParameter( iSequence, seqdesc.paramindex[1] ) == iParameter) { return true; } return false; }
void CEnvParticleScript::PrecacheAnimationEventMaterials() { CStudioHdr *hdr = GetModelPtr(); if ( hdr ) { int numseq = hdr->GetNumSeq(); for ( int i = 0; i < numseq; ++i ) { mstudioseqdesc_t& seqdesc = hdr->pSeqdesc( i ); int ecount = seqdesc.numevents; for ( int j = 0 ; j < ecount; ++j ) { const mstudioevent_t* event = (const mstudioevent_for_client_server_t*)seqdesc.pEvent( j ); if ( event->Event() == CL_EVENT_SPRITEGROUP_CREATE ) { char pAttachmentName[256]; char pSpriteName[256]; int nArgs = sscanf( event->pszOptions(), "%255s %255s", pAttachmentName, pSpriteName ); if ( nArgs == 2 ) { PrecacheMaterial( pSpriteName ); } } } } } }
// If the local player is visible (thirdperson mode, tf2 taunts, etc., then make sure that we are using the // w_ (world) model not the v_ (view) model or else the model can flicker, etc. // Otherwise, if we're not the local player, always use the world model void C_BaseCombatWeapon::EnsureCorrectRenderingModel() { C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer(); if ( localplayer && localplayer == GetOwner() && !localplayer->ShouldDrawLocalPlayer() ) { return; } MDLCACHE_CRITICAL_SECTION(); // BRJ 10/14/02 // FIXME: Remove when Yahn's client-side prediction is done // It's a hacky workaround for the model indices fighting // (GetRenderBounds uses the model index, which is for the view model) SetModelIndex( GetWorldModelIndex() ); // Validate our current sequence just in case ( in theory the view and weapon models should have the same sequences for sequences that overlap at least ) CStudioHdr *pStudioHdr = GetModelPtr(); if ( pStudioHdr && GetSequence() >= pStudioHdr->GetNumSeq() ) { SetSequence( 0 ); } }
void C_BaseAnimatingOverlay::GetRenderBounds( Vector& theMins, Vector& theMaxs ) { BaseClass::GetRenderBounds( theMins, theMaxs ); if ( !IsRagdoll() ) { CStudioHdr *pStudioHdr = GetModelPtr(); if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() ) return; int nSequences = pStudioHdr->GetNumSeq(); int i; for (i = 0; i < m_AnimOverlay.Count(); i++) { if (m_AnimOverlay[i].m_flWeight > 0.0) { if ( m_AnimOverlay[i].m_nSequence >= nSequences ) { continue; } mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ); VectorMin( seqdesc.bbmin, theMins, theMins ); VectorMax( seqdesc.bbmax, theMaxs, theMaxs ); } } } }
void StudioModel::scaleMeshes (float scale) { CStudioHdr *pStudioHdr = GetStudioHdr(); if (!pStudioHdr) return; int i, j, k; // manadatory to access correct verts SetCurrentModel(); // scale verts int tmp = m_bodynum; for (i = 0; i < pStudioHdr->numbodyparts(); i++) { mstudiobodyparts_t *pbodypart = pStudioHdr->pBodypart( i ); for (j = 0; j < pbodypart->nummodels; j++) { SetBodygroup (i, j); SetupModel (i); const mstudio_modelvertexdata_t *vertData = m_pmodel->GetVertexData(); for (k = 0; k < m_pmodel->numvertices; k++) { *vertData->Position(k) *= scale; } } } m_bodynum = tmp; // scale complex hitboxes int hitboxset = g_MDLViewer->GetCurrentHitboxSet(); mstudiobbox_t *pbboxes = pStudioHdr->pHitbox( 0, hitboxset ); for (i = 0; i < pStudioHdr->iHitboxCount( hitboxset ); i++) { VectorScale (pbboxes[i].bbmin, scale, pbboxes[i].bbmin); VectorScale (pbboxes[i].bbmax, scale, pbboxes[i].bbmax); } // scale bounding boxes for (i = 0; i < pStudioHdr->GetNumSeq(); i++) { mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( i ); Vector tmp; tmp = seqdesc.bbmin; VectorScale( tmp, scale, tmp ); seqdesc.bbmin = tmp; tmp = seqdesc.bbmax; VectorScale( tmp, scale, tmp ); seqdesc.bbmax = tmp; } // maybe scale exeposition, pivots, attachments }
int SEditModelRender::QuerySequences( char ***list ) { if ( !IsModelReady() ) return 0; MDLCACHE_CRITICAL_SECTION(); CStudioHdr *pHdr = pModelInstance->GetModelPtr(); if ( !pHdr ) return 0; CUtlVector< mstudioseqdesc_t* >hSeqs; for ( int i = 0; i < pHdr->GetNumSeq(); i++ ) if ( !( pHdr->pSeqdesc( i ).flags & STUDIO_HIDDEN ) ) hSeqs.AddToTail( &pHdr->pSeqdesc( i ) ); int numSequences = hSeqs.Count(); if ( !numSequences ) return 0; hSeqs.Sort( SequenceSort ); CUtlVector< const char* >hNameList; for ( int i = 0; i < numSequences; i++ ) { const char *seqName = NULL; const mstudioseqdesc_t &seqPtr = *hSeqs[ i ]; if ( seqPtr.pszLabel() ) seqName = seqPtr.pszLabel(); else seqName = "Unknown Sequence"; hNameList.AddToTail( seqName ); } *list = new char*[numSequences]; int iTotalLength = 0; for ( int i = 0; i < numSequences; i++ ) iTotalLength += Q_strlen( hNameList[i] ) + 1; **list = new char[ iTotalLength ]; int curpos = 0; for ( int i = 0; i < numSequences; i++ ) { int curLength = Q_strlen( hNameList[i] ) + 1; (*list)[ i ] = **list + curpos; Q_strcpy( (*list)[ i ], hNameList[i] ); curpos += curLength; } hNameList.Purge(); hSeqs.Purge(); return numSequences; }
int StudioModel::GetNumFrames( int iSequence ) { CStudioHdr *pStudioHdr = GetStudioHdr(); if ( !pStudioHdr || iSequence < 0 || iSequence >= pStudioHdr->GetNumSeq() ) { return 1; } return Studio_MaxFrame( pStudioHdr, iSequence, m_poseparameter ); }
void CEventPropertiesSequenceDialog::PopulateSequenceList( HWND wnd ) { CStudioHdr *hdr = models->GetActiveStudioModel()->GetStudioHdr(); if (hdr) { for (int i = 0; i < hdr->GetNumSeq(); i++) { SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)hdr->pSeqdesc(i).pszLabel() ); } } }
void CEventPropertiesGestureDialog::PopulateGestureList( HWND wnd ) { CStudioHdr *hdr = models->GetActiveStudioModel()->GetStudioHdr(); if (hdr) { int i; for (i = 0; i < hdr->GetNumSeq(); i++) { if (CheckSequenceType( models->GetActiveStudioModel(), i, "gesture" )) { SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)hdr->pSeqdesc(i).pszLabel() ); } } for (i = 0; i < hdr->GetNumSeq(); i++) { if (CheckSequenceType( models->GetActiveStudioModel(), i, "posture" )) { SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)hdr->pSeqdesc(i).pszLabel() ); } } } }
void ControlPanel::initSequenceChoices() { CStudioHdr *hdr = models->GetActiveStudioModel()->GetStudioHdr(); if (hdr) { cSequence->removeAll(); for (int i = 0; i < hdr->GetNumSeq(); i++) { cSequence->add (hdr->pSeqdesc(i).pszLabel()); } cSequence->select (0); } }
void IFaceposerModels::CFacePoserModel::BuildValidChecksums( CUtlRBTree< CRC32_t > &tree ) { StudioModel *model = m_pModel; if ( !model ) return; CStudioHdr *hdr = model->GetStudioHdr(); if ( !hdr ) return; for ( int i = 0; i < hdr->GetNumSeq(); i++ ) { CRC32_t crc = GetBitmapCRC( i ); tree.Insert( crc ); } }
int StudioModel::LookupActivity( const char *szActivity ) { int i; CStudioHdr *pStudioHdr = GetStudioHdr(); if ( !pStudioHdr ) return -1; for (i = 0; i < pStudioHdr->GetNumSeq(); i++) { if (!stricmp( szActivity, pStudioHdr->pSeqdesc( i ).pszActivityName() )) { return i; } } return -1; }
int StudioModel::LookupSequence( const char *szSequence ) { int i; CStudioHdr *pStudioHdr = GetStudioHdr(); if ( !pStudioHdr ) return -1; for (i = 0; i < pStudioHdr->GetNumSeq(); i++) { if (!stricmp( szSequence, pStudioHdr->pSeqdesc( i ).pszLabel() )) { return i; } } return -1; }
int StudioModel::SetSequence( int iSequence ) { CStudioHdr *pStudioHdr = GetStudioHdr(); if ( !pStudioHdr ) return 0; if (iSequence < 0) return 0; if (iSequence > pStudioHdr->GetNumSeq()) return m_sequence; m_prevsequence = m_sequence; m_sequence = iSequence; m_cycle = 0; m_sequencetime = 0.0; return m_sequence; }
void IFaceposerModels::CFacePoserModel::LoadBitmaps() { CStudioHdr *hdr = m_pModel ? m_pModel->GetStudioHdr() : NULL; if ( hdr ) { for ( int i = 0 ;i < hdr->GetNumSeq(); i++ ) { mxbitmapdata_t *bm = new mxbitmapdata_t(); AnimBitmap *entry = new AnimBitmap(); entry->needsload = true; entry->bitmap = bm; // Need to load bitmap from disk image via crc, etc. //Assert( 0 ); m_AnimationBitmaps.AddToTail( entry ); } } }
void ControlPanel::setModelInfo() { static char str[2048]; CStudioHdr *hdr = models->GetActiveStudioModel()->GetStudioHdr(); if (!hdr) return; int hbcount = 0; for ( int s = 0; s < hdr->numhitboxsets(); s++ ) { hbcount += hdr->iHitboxCount( s ); } sprintf (str, "Bones: %d\n" "Bone Controllers: %d\n" "Hit Boxes: %d in %d sets\n" "Sequences: %d\n", hdr->numbones(), hdr->numbonecontrollers(), hbcount, hdr->numhitboxsets(), hdr->GetNumSeq() ); lModelInfo1->setLabel (str); sprintf (str, "Textures: %d\n" "Skin Families: %d\n" "Bodyparts: %d\n" "Attachments: %d\n", hdr->numtextures(), hdr->numskinfamilies(), hdr->numbodyparts(), hdr->GetNumAttachments()); lModelInfo2->setLabel (str); }
CRC32_t IFaceposerModels::CFacePoserModel::GetBitmapCRC( int sequence ) { CStudioHdr *hdr = m_pModel ? m_pModel->GetStudioHdr() : NULL; if ( !hdr ) return (CRC32_t)-1; if ( sequence < 0 || sequence >= hdr->GetNumSeq() ) return (CRC32_t)-1; mstudioseqdesc_t &seqdesc = hdr->pSeqdesc( sequence ); CRC32_t crc; CRC32_Init( &crc ); // For sequences, we'll checsum a bit of data CRC32_ProcessBuffer( &crc, (void *)seqdesc.pszLabel(), Q_strlen( seqdesc.pszLabel() ) ); CRC32_ProcessBuffer( &crc, (void *)seqdesc.pszActivityName(), Q_strlen( seqdesc.pszActivityName() ) ); CRC32_ProcessBuffer( &crc, (void *)&seqdesc.flags, sizeof( seqdesc.flags ) ); //CRC32_ProcessBuffer( &crc, (void *)&seqdesc.numevents, sizeof( seqdesc.numevents ) ); CRC32_ProcessBuffer( &crc, (void *)&seqdesc.numblends, sizeof( seqdesc.numblends ) ); CRC32_ProcessBuffer( &crc, (void *)seqdesc.groupsize, sizeof( seqdesc.groupsize ) ); KeyValues *seqKeyValues = new KeyValues(""); if ( seqKeyValues->LoadFromBuffer( m_pModel->GetFileName( ), m_pModel->GetKeyValueText( sequence ) ) ) { // Yuck, but I need it in a contiguous block of memory... oh well... CUtlBuffer buf; seqKeyValues->RecursiveSaveToFile( buf, 0 ); CRC32_ProcessBuffer( &crc, ( void * )buf.Base(), buf.TellPut() ); } seqKeyValues->deleteThis(); CRC32_Final( &crc ); return crc; }
int StudioModel::SetOverlaySequence( int iLayer, int iSequence, float flWeight ) { CStudioHdr *pStudioHdr = GetStudioHdr(); if ( !pStudioHdr ) return 0; if (iSequence < 0) return 0; if (iLayer < 0 || iLayer >= MAXSTUDIOANIMLAYERS) { Assert(0); return 0; } if (iSequence > pStudioHdr->GetNumSeq()) return m_Layer[iLayer].m_sequence; m_Layer[iLayer].m_sequence = iSequence; m_Layer[iLayer].m_weight = flWeight; m_Layer[iLayer].m_playbackrate = 1.0; return iSequence; }
void IFaceposerModels::CFacePoserModel::CreateNewBitmap( char const *pchBitmapFilename, int sequence, int nSnapShotSize, bool bZoomInOnFace, CExpression *pExpression, mxbitmapdata_t *bitmap ) { MatSysWindow *pWnd = g_pMatSysWindow; if ( !pWnd ) return; StudioModel *model = m_pModel; if ( !model ) return; CStudioHdr *hdr = model->GetStudioHdr(); if ( !hdr ) return; if ( sequence < 0 || sequence >= hdr->GetNumSeq() ) return; mstudioseqdesc_t &seqdesc = hdr->pSeqdesc( sequence ); Con_ColorPrintf( FILE_COLOR, "Creating bitmap %s for sequence '%s'\n", pchBitmapFilename, seqdesc.pszLabel() ); model->ClearOverlaysSequences(); int iLayer = model->GetNewAnimationLayer(); model->SetOverlaySequence( iLayer, sequence, 1.0 ); model->SetOverlayRate( iLayer, FindPoseCycle( model, sequence ), 0.0 ); for (int i = 0; i < hdr->GetNumPoseParameters(); i++) { model->SetPoseParameter( i, 0.0 ); } float flexValues[ GLOBAL_STUDIO_FLEX_CONTROL_COUNT ] = { 0 }; if ( pExpression ) { float *settings = pExpression->GetSettings(); float *weights = pExpression->GetWeights(); // Save existing settings from model for ( LocalFlexController_t i = LocalFlexController_t(0); i < hdr->numflexcontrollers(); ++i ) { int j = hdr->pFlexcontroller( i )->localToGlobal; if ( j == -1 ) continue; flexValues[ i ] = model->GetFlexController( i ); // Set Value from passed in settings model->SetFlexController( i, settings[ j ] * weights[ j ] ); } } model->ClearLookTargets( ); QAngle oldrot, oldLight; Vector oldtrans; VectorCopy( model->m_angles, oldrot ); VectorCopy( model->m_origin, oldtrans ); VectorCopy( g_viewerSettings.lightrot, oldLight ); model->m_angles.Init(); model->m_origin.Init(); g_viewerSettings.lightrot.Init(); g_viewerSettings.lightrot.y = -180; bool bSaveGround = g_viewerSettings.showGround; g_viewerSettings.showGround = false; if ( bZoomInOnFace ) { Vector size; VectorSubtract( hdr->hull_max(), hdr->hull_min(), size ); float eyeheight = hdr->hull_min().z + 0.9 * size.z; // float width = ( size.x + size.y ) / 2.0f; model->m_origin.x = size.z * .6f; if ( hdr->GetNumAttachments() > 0 ) { for (int i = 0; i < hdr->GetNumAttachments(); i++) { const mstudioattachment_t &attachment = hdr->pAttachment( i ); int iBone = hdr->GetAttachmentBone( i ); if ( Q_stricmp( attachment.pszName(), "eyes" ) ) continue; mstudiobone_t *bone = hdr->pBone( iBone ); if ( !bone ) continue; matrix3x4_t boneToPose; MatrixInvert( bone->poseToBone, boneToPose ); matrix3x4_t attachmentPoseToLocal; ConcatTransforms( boneToPose, attachment.local, attachmentPoseToLocal ); Vector localSpaceEyePosition; VectorITransform( vec3_origin, attachmentPoseToLocal, localSpaceEyePosition ); // Not sure why this must be negative? eyeheight = -localSpaceEyePosition.z + hdr->hull_min().z; break; } } KeyValues *seqKeyValues = new KeyValues(""); if ( seqKeyValues->LoadFromBuffer( model->GetFileName( ), model->GetKeyValueText( sequence ) ) ) { // Do we have a build point section? KeyValues *pkvAllFaceposer = seqKeyValues->FindKey("faceposer"); if ( pkvAllFaceposer ) { float flEyeheight = pkvAllFaceposer->GetFloat( "eye_height", -9999.0f ); if ( flEyeheight != -9999.0f ) { eyeheight = flEyeheight; } } } model->m_origin.z += eyeheight; } else { Vector mins, maxs; model->ExtractBbox(mins, maxs); Vector size; VectorSubtract( maxs, mins, size ); float maxdim = size.x; if ( size.y > maxdim ) maxdim = size.y; if ( size.z > maxdim ) maxdim = size.z; float midpoint = mins.z + 0.5 * size.z; model->m_origin.x = 3 * maxdim; model->m_origin.z += midpoint; } pWnd->SuppressResize( true ); RECT rcClient; HWND wnd = (HWND)pWnd->getHandle(); WINDOWPLACEMENT wp; GetWindowPlacement( wnd, &wp ); GetClientRect( wnd, &rcClient ); MoveWindow( wnd, 0, 0, nSnapShotSize + 16, nSnapShotSize + 16, TRUE ); // Snapshots are taken of the back buffer; // we need to render to the back buffer but not move it to the front pWnd->SuppressBufferSwap( true ); pWnd->redraw(); pWnd->SuppressBufferSwap( false ); // make it square, assumes w > h char fullpath[ 512 ]; Q_snprintf( fullpath, sizeof( fullpath ), "%s%s", GetGameDirectory(), pchBitmapFilename ); pWnd->TakeSnapshotRect( fullpath, 0, 0, nSnapShotSize, nSnapShotSize ); // Move back to original position SetWindowPlacement( wnd, &wp ); pWnd->SuppressResize( false ); VectorCopy( oldrot, model->m_angles ); VectorCopy( oldtrans, model->m_origin ); VectorCopy( oldLight, g_viewerSettings.lightrot ); g_viewerSettings.showGround = bSaveGround; if ( pExpression ) { // Save existing settings from model for ( LocalFlexController_t i = LocalFlexController_t(0); i < hdr->numflexcontrollers(); ++i ) { int j = hdr->pFlexcontroller( i )->localToGlobal; if ( j == -1 ) continue; model->SetFlexController( i, flexValues[ i ] ); } } model->ClearOverlaysSequences(); if ( bitmap->valid ) { DeleteObject( bitmap->image ); bitmap->image = 0; bitmap->valid = false; } LoadBitmapFromFile( pchBitmapFilename, *bitmap ); }
void CAnimationLayer::DispatchAnimEvents( CBaseAnimating *eventHandler, CBaseAnimating *pOwner ) { animevent_t event; CStudioHdr *pstudiohdr = pOwner->GetModelPtr( ); if ( !pstudiohdr ) { Assert(!"CBaseAnimating::DispatchAnimEvents: model missing"); return; } if ( !pstudiohdr->SequencesAvailable() ) { return; } if ( m_nSequence >= pstudiohdr->GetNumSeq() ) return; // don't fire if here are no events if ( pstudiohdr->pSeqdesc( m_nSequence ).numevents == 0 ) { return; } // look from when it last checked to some short time in the future float flCycleRate = pOwner->GetSequenceCycleRate( m_nSequence ) * m_flPlaybackRate; float flStart = m_flLastEventCheck; float flEnd = m_flCycle; if (!m_bLooping) { // fire off events early float flLastVisibleCycle = 1.0f - (pstudiohdr->pSeqdesc( m_nSequence ).fadeouttime) * flCycleRate; if (flEnd >= flLastVisibleCycle || flEnd < 0.0) { m_bSequenceFinished = true; flEnd = 1.01f; } } m_flLastEventCheck = flEnd; /* if (pOwner->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT) { Msg( "%s:%s : checking %.2f %.2f (%d)\n", STRING(pOwner->GetModelName()), pstudiohdr->pSeqdesc( m_nSequence ).pszLabel(), flStart, flEnd, m_bSequenceFinished ); } */ // FIXME: does not handle negative framerates! int index = 0; while ( (index = GetAnimationEvent( pstudiohdr, m_nSequence, &event, flStart, flEnd, index ) ) != 0 ) { event.pSource = pOwner; // calc when this event should happen if (flCycleRate > 0.0) { float flCycle = event.cycle; if (flCycle > m_flCycle) { flCycle = flCycle - 1.0; } event.eventtime = pOwner->m_flAnimTime + (flCycle - m_flCycle) / flCycleRate + pOwner->GetAnimTimeInterval(); } // Msg( "dispatch %d (%d : %.2f)\n", index - 1, event.event, event.eventtime ); event.m_bHandledByScript = eventHandler->HandleScriptedAnimEvent( &event ); if ( eventHandler->HandleBehaviorAnimEvent( &event ) ) { event.m_bHandledByScript = true; } eventHandler->HandleAnimEvent( &event ); } }