Models on VGUI Panels

From Valve Developer Community
Revision as of 00:11, 12 March 2006 by Ging (talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, 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"
}