Models on VGUI Panels
Jump to navigation
Jump to search
Basic code dump for model render in vgui panel :
sdk_clientmode.cpp
void UpdateClassImageEntity( const char *pModelName, int x, int y, int width, int height );
CHandle<C_BaseAnimatingOverlay> g_ClassImagePlayer; // player CHandle<C_BaseAnimating> g_ClassImageWeapon; // weapon
// Utility to determine if the vgui panel is visible bool WillPanelBeVisible( vgui::VPANEL hPanel ) { while ( hPanel ) { if ( !vgui::ipanel()->IsVisible( hPanel ) ) return false; hPanel = vgui::ipanel()->GetParent( hPanel ); } return true; }
// Called to see if we should be creating or recreating the model instances bool ShouldRecreateClassImageEntity( C_BaseAnimating *pEnt, const char *pNewModelName ) { if ( !pNewModelName || !pNewModelName[0] ) return false; if ( !pEnt ) return true;
const model_t *pModel = pEnt->GetModel();
if ( !pModel ) return true; const char *pName = modelinfo->GetModelName( pModel );
if ( !pName ) return true; // reload only if names are different return( Q_stricmp( pName, pNewModelName ) != 0 ); }
void ClientModeSDKNormal::PostRenderVGui() { // If the team menu is up, then we will render the model of the character that is currently selected. for ( int i=0; i < g_ClassImagePanels.Count(); i++ ) { CClassImagePanel *pPanel = g_ClassImagePanels[i]; if ( WillPanelBeVisible( pPanel->GetVPanel() ) ) { // Ok, we have a visible class image panel. int x, y, w, h; pPanel->GetBounds( x, y, w, h ); pPanel->LocalToScreen( x, y );
// Allow for the border. x += 3; y += 5; w -= 2; h -= 10;
UpdateClassImageEntity( g_ClassImagePanels[i]->m_ModelName, x, y, w, h ); return; } } }
void UpdateClassImageEntity( const char *pModelName, int x, int y, int width, int height ) { C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
if ( !pLocalPlayer ) return;
const char *pWeaponName = "models/weapons/f2000/w_f2000.mdl"; const char *pWeaponSequence = "Idle_Upper_Aug";
C_BaseAnimatingOverlay *pPlayerModel = g_ClassImagePlayer.Get();
// Does the entity even exist yet? bool recreatePlayer = ShouldRecreateClassImageEntity( pPlayerModel, pModelName ); if ( recreatePlayer ) { if ( pPlayerModel ) pPlayerModel->Remove();
pPlayerModel = new C_BaseAnimatingOverlay; pPlayerModel->InitializeAsClientEntity( pModelName, RENDER_GROUP_OPAQUE_ENTITY ); pPlayerModel->AddEffects( EF_NODRAW ); // don't let the renderer draw the model normally
// have the player stand idle pPlayerModel->SetSequence( pPlayerModel->LookupSequence( "Idle_lower" ) ); pPlayerModel->SetPoseParameter( 0, 0.0f ); // move_yaw pPlayerModel->SetPoseParameter( 1, 10.0f ); // body_pitch, look down a bit pPlayerModel->SetPoseParameter( 2, 0.0f ); // body_yaw pPlayerModel->SetPoseParameter( 3, 0.0f ); // move_y pPlayerModel->SetPoseParameter( 4, 0.0f ); // move_x, walk forward
g_ClassImagePlayer = pPlayerModel; }
C_BaseAnimating *pWeaponModel = g_ClassImageWeapon.Get();
// Does the entity even exist yet? if ( recreatePlayer || ShouldRecreateClassImageEntity( pWeaponModel, pWeaponName ) ) { if ( pWeaponModel ) pWeaponModel->Remove();
pWeaponModel = new C_BaseAnimating; pWeaponModel->InitializeAsClientEntity( pWeaponName, RENDER_GROUP_OPAQUE_ENTITY ); pWeaponModel->AddEffects( EF_NODRAW ); // don't let the renderer draw the model normally pWeaponModel->FollowEntity( pPlayerModel ); // attach to player model g_ClassImageWeapon = pWeaponModel; }
Vector origin = pLocalPlayer->EyePosition(); Vector lightOrigin = origin;
// find a spot inside the world for the dlight's origin, or it won't illuminate the model Vector testPos( origin.x - 100, origin.y, origin.z + 100 ); trace_t tr; UTIL_TraceLine( origin, testPos, MASK_OPAQUE, pLocalPlayer, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction == 1.0f ) { lightOrigin = tr.endpos; } else { // Now move the model away so we get the correct illumination lightOrigin = tr.endpos + Vector( 1, 0, -1 ); // pull out from the solid Vector start = lightOrigin; Vector end = lightOrigin + Vector( 100, 0, -100 ); UTIL_TraceLine( start, end, MASK_OPAQUE, pLocalPlayer, COLLISION_GROUP_NONE, &tr ); origin = tr.endpos; }
float ambient = engine->GetLightForPoint( origin, true ).Length();
// Make a light so the model is well lit. // use a non-zero number so we cannibalize ourselves next frame dlight_t *dl = effects->CL_AllocDlight( LIGHT_INDEX_TE_DYNAMIC+1 );
dl->flags = DLIGHT_NO_WORLD_ILLUMINATION; dl->origin = lightOrigin; // Go away immediately so it doesn't light the world dl->die = gpGlobals->curtime + 0.1f; too.
dl->color.r = dl->color.g = dl->color.b = 250; if ( ambient < 1.0f ) { dl->color.exponent = 1 + (1 - ambient) * 2; } dl->radius = 400;
// move player model in front of our view pPlayerModel->SetAbsOrigin( origin ); pPlayerModel->SetAbsAngles( QAngle( 0, 210, 0 ) );
// set upper body animation pPlayerModel->m_SequenceTransitioner.Update( pPlayerModel->GetModelPtr(), pPlayerModel->LookupSequence( "walk_lower" ), pPlayerModel->GetCycle(), pPlayerModel->GetPlaybackRate(), gpGlobals->realtime, false, true );
// Now, blend the lower and upper (aim) anims together pPlayerModel->SetNumAnimOverlays( 2 ); int numOverlays = pPlayerModel->GetNumAnimOverlays();
for ( int i=0; i < numOverlays; ++i ) { C_AnimationLayer *layer = pPlayerModel->GetAnimOverlay( i );
layer->flCycle = pPlayerModel->GetCycle();
if ( i ) layer->nSequence = pPlayerModel->LookupSequence( pWeaponSequence ); else layer->nSequence = pPlayerModel->LookupSequence( "walk_lower" ); layer->flPlaybackrate = 1.0; layer->flWeight = 1.0f; layer->SetOrder( i ); }
pPlayerModel->FrameAdvance( gpGlobals->frametime );
// Now draw it. CViewSetup view; view.x = x; view.y = y; view.width = width; view.height = height;
view.m_bOrtho = false; view.fov = 54;
view.origin = origin + Vector( -110, -5, -5 );
Vector vMins, vMaxs; pPlayerModel->C_BaseAnimating::GetRenderBounds( vMins, vMaxs ); view.origin.z += ( vMins.z + vMaxs.z ) * 0.55f;
view.angles.Init(); view.m_vUnreflectedOrigin = view.origin; view.zNear = VIEW_NEARZ; view.zFar = 1000; view.m_bForceAspectRatio1To1 = false;
Frustum dummyFrustum; render->ViewSetup3D( &view, dummyFrustum );
pPlayerModel->DrawModel( STUDIO_RENDER );
if ( pWeaponModel ) { pWeaponModel->DrawModel( STUDIO_RENDER ); } }
teammenu.h
class CClassImagePanel : public vgui::ImagePanel { public:
typedef vgui::ImagePanel BaseClass;
CClassImagePanel( vgui::Panel *pParent, const char *pName ); virtual ~CClassImagePanel(); virtual void ApplySettings( KeyValues *inResourceData ); virtual void Paint();
public: char m_ModelName[128]; };
extern CUtlVector<CClassImagePanel*> g_ClassImagePanels;
teammenu.cpp
CUtlVector<CClassImagePanel*> g_ClassImagePanels;
CClassImagePanel::CClassImagePanel( vgui::Panel *pParent, const char *pName ) : vgui::ImagePanel( pParent, pName ) { g_ClassImagePanels.AddToTail( this ); m_ModelName[0] = 0; }
CClassImagePanel::~CClassImagePanel() { g_ClassImagePanels.FindAndRemove( this ); }
void CClassImagePanel::ApplySettings( KeyValues *inResourceData ) { const char *pName = inResourceData->GetString( "3DModel" ); if ( pName ) { Q_strncpy( m_ModelName, pName, sizeof( m_ModelName ) ); }
BaseClass::ApplySettings( inResourceData ); }
void CClassImagePanel::Paint() { BaseClass::Paint(); }
Panel *TeamMenu::CreateControlByName(const char *controlName) { if ( Q_stricmp( controlName, "ClassImagePanel" ) == 0 ) { return new CClassImagePanel( NULL, controlName ); }
return BaseClass::CreateControlByName( controlName ); }
teammenu.res
"classimage" { "ControlName" "ClassImagePanel" "fieldName" "classimage" "xpos" "270" "ypos" "170" "wide" "512" "tall" "384" "autoResize" "0" "pinCorner" "0" "visible" "1" "enabled" "1" "textAlignment" "west" "3DModel" "models/player/iris.mdl" "scaleImage" "1" "zpos" "1" }