summaryrefslogtreecommitdiff
path: root/utils/hlfaceposer/controlpanel.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/hlfaceposer/controlpanel.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/hlfaceposer/controlpanel.cpp')
-rw-r--r--utils/hlfaceposer/controlpanel.cpp976
1 files changed, 976 insertions, 0 deletions
diff --git a/utils/hlfaceposer/controlpanel.cpp b/utils/hlfaceposer/controlpanel.cpp
new file mode 100644
index 0000000..e97cc7b
--- /dev/null
+++ b/utils/hlfaceposer/controlpanel.cpp
@@ -0,0 +1,976 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+#include "ControlPanel.h"
+#include "ViewerSettings.h"
+#include "StudioModel.h"
+#include "IStudioRender.h"
+#include "MatSysWin.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mxtk/mx.h>
+#include <mxtk/mxBmp.h>
+#include "FlexPanel.h"
+#include "mxExpressionTray.h"
+#include "PhonemeEditor.h"
+#include "hlfaceposer.h"
+#include "expclass.h"
+#include "mxExpressionTab.h"
+#include "ExpressionTool.h"
+#include "MDLViewer.h"
+#include "choreowidgetdrawhelper.h"
+#include "faceposer_models.h"
+#include "ifaceposerworkspace.h"
+#include "choreoview.h"
+#include "GestureTool.h"
+#include "RampTool.h"
+#include "SceneRampTool.h"
+#include "phonemeextractor/PhonemeExtractor.h"
+#include "tier1/KeyValues.h"
+
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+extern char g_appTitle[];
+
+ControlPanel *g_pControlPanel = 0;
+
+//-----------------------------------------------------------------------------
+// Purpose: A simple subclass so we can paint the window background
+//-----------------------------------------------------------------------------
+class CControlPanelTabWindow : public mxWindow
+{
+public:
+ CControlPanelTabWindow( mxWindow *parent, int x, int y, int w, int h ) :
+ mxWindow( parent, x, y, w, h )
+ {
+ FacePoser_AddWindowStyle( this, WS_CLIPSIBLINGS | WS_CLIPCHILDREN );
+ };
+
+ virtual bool PaintBackground( void )
+ {
+ CChoreoWidgetDrawHelper drawHelper( this );
+
+ RECT rc;
+ drawHelper.GetClientRect( rc );
+
+ drawHelper.DrawFilledRect( GetSysColor( COLOR_BTNFACE ), rc );
+ return false;
+ }
+};
+
+ControlPanel::ControlPanel (mxWindow *parent)
+: IFacePoserToolWindow( "ControlPanel", "Control Panel" ), mxWindow( parent, 0, 0, 0, 0 ), tab( 0 )
+{
+ // create tabcontrol with subdialog windows
+ tab = new mxTab (this, 0, 0, 0, 0, IDC_TAB);
+
+ CControlPanelTabWindow *wRender = new CControlPanelTabWindow (this, 0, 0, 0, 0);
+ tab->add (wRender, "Render");
+ cRenderMode = new mxChoice (wRender, 5, 5, 100, 22, IDC_RENDERMODE);
+ cRenderMode->add ("Wireframe");
+ cRenderMode->add ("Flatshaded");
+ cRenderMode->add ("Smoothshaded");
+ cRenderMode->add ("Textured");
+ cRenderMode->select (3);
+ mxToolTip::add (cRenderMode, "Select Render Mode");
+
+ slModelGap = new mxSlider( wRender, 220, 5, 140, 20, IDC_MODELSPACING );
+ slModelGap->setRange( 0.0f, 64.0f, 256 );
+ slModelGap->setValue( 16 );
+ mxToolTip::add (slModelGap, "Select Model Spacing" );
+ new mxLabel (wRender, 220, 25, 140, 20, "Model Spacing");
+
+ cbAllWindowsDriveSpeech = new mxCheckBox( wRender, 220, 45, 140, 20, "All tools drive mouth", IDC_TOOLSDRIVEMOUTH );
+ cbAllWindowsDriveSpeech->setChecked( g_viewerSettings.faceposerToolsDriveMouth );
+
+ cbGround = new mxCheckBox (wRender, 110, 5, 100, 20, "Ground", IDC_GROUND);
+ cbGround->setEnabled( true );
+ cbMovement = new mxCheckBox (wRender, 110, 25, 100, 20, "Movement", IDC_MOVEMENT);
+ cbMovement->setEnabled( false );
+ cbBackground = new mxCheckBox (wRender, 110, 45, 100, 20, "Background", IDC_BACKGROUND);
+ cbBackground->setEnabled( false );
+ new mxCheckBox (wRender, 110, 65, 100, 20, "Hit Boxes", IDC_HITBOXES);
+ new mxCheckBox (wRender, 5, 65, 100, 20, "Bones", IDC_BONES);
+ mxCheckBox *cbAttachments = new mxCheckBox (wRender, 5, 45, 100, 20, "Attachments", IDC_ATTACHMENTS);
+ cbAttachments->setEnabled( false );
+
+ CControlPanelTabWindow *wSequence = new CControlPanelTabWindow (this, 0, 0, 0, 0);
+ tab->add (wSequence, "Sequence");
+ cSequence = new mxChoice (wSequence, 5, 5, 200, 22, IDC_SEQUENCE);
+ mxToolTip::add (cSequence, "Select Sequence");
+
+
+ slSpeedScale = new mxSlider (wSequence, 5, 32, 200, 18, IDC_SPEEDSCALE);
+ slSpeedScale->setRange (0.0, 5.0 );
+ slSpeedScale->setValue (0.0);
+ mxToolTip::add (slSpeedScale, "Speed Scale");
+ lSpeedScale = new mxLabel( wSequence, 5, 50, 200, 18 );
+ lSpeedScale->setLabel( "Speed scale" );
+
+ CControlPanelTabWindow *wBody = new CControlPanelTabWindow (this, 0, 0, 0, 0);
+ tab->add (wBody, "Body");
+ cBodypart = new mxChoice (wBody, 5, 5, 100, 22, IDC_BODYPART);
+ mxToolTip::add (cBodypart, "Choose a bodypart");
+ cSubmodel = new mxChoice (wBody, 110, 5, 100, 22, IDC_SUBMODEL);
+ mxToolTip::add (cSubmodel, "Choose a submodel of current bodypart");
+ cController = new mxChoice (wBody, 5, 30, 100, 22, IDC_CONTROLLER);
+ mxToolTip::add (cController, "Choose a bone controller");
+ slController = new mxSlider (wBody, 105, 32, 100, 18, IDC_CONTROLLERVALUE);
+ slController->setRange (0, 45);
+ mxToolTip::add (slController, "Change current bone controller value");
+ lModelInfo1 = new mxLabel (wBody, 220, 5, 120, 100, "No Model.");
+ lModelInfo2 = new mxLabel (wBody, 340, 5, 120, 100, "");
+ cSkin = new mxChoice (wBody, 5, 55, 100, 22, IDC_SKINS);
+ mxToolTip::add (cSkin, "Choose a skin family");
+}
+
+ControlPanel::~ControlPanel()
+{
+}
+
+bool ControlPanel::CanClose( void )
+{
+ workspacefiles->StartStoringFiles( IWorkspaceFiles::EXPRESSION );
+ for ( int i = 0 ; i < expressions->GetNumClasses(); i++ )
+ {
+ CExpClass *cl = expressions->GetClass( i );
+ if ( cl )
+ {
+ workspacefiles->StoreFile( IWorkspaceFiles::EXPRESSION, cl->GetFileName() );
+ }
+ }
+ workspacefiles->FinishStoringFiles( IWorkspaceFiles::EXPRESSION );
+ // Now close them all, or abort exit if user doesn't want to close any that have changed
+ return Closeall();
+}
+
+void ControlPanel::OnDelete()
+{
+}
+
+void ControlPanel::PositionControls( int width, int height )
+{
+ if ( tab )
+ {
+ tab->setBounds( 0, GetCaptionHeight(), width, height );
+ }
+}
+
+void ControlPanel::redraw()
+{
+ if ( !ToolCanDraw() )
+ return;
+
+ CChoreoWidgetDrawHelper helper( this, GetSysColor( COLOR_BTNFACE ) );
+ HandleToolRedraw( helper );
+
+ BaseClass::redraw();
+}
+
+int
+ControlPanel::handleEvent (mxEvent *event)
+{
+ MDLCACHE_CRITICAL_SECTION_( g_pMDLCache );
+
+ int iret = 0;
+
+ if ( HandleToolEvent( event ) )
+ {
+ return iret;
+ }
+
+ switch ( event->event )
+ {
+ case mxEvent::Size:
+ {
+ PositionControls( event->width, event->height );
+ iret = 1;
+ }
+ break;
+ case mxEvent::Action:
+ {
+ iret = 1;
+ switch (event->action)
+ {
+ case IDC_TOOLSDRIVEMOUTH:
+ {
+ g_viewerSettings.faceposerToolsDriveMouth = ((mxCheckBox *)event->widget)->isChecked();
+ }
+ break;
+ case IDC_TAB:
+ {
+ g_viewerSettings.showTexture = (tab->getSelectedIndex() == 3);
+ }
+ break;
+
+ case IDC_RENDERMODE:
+ {
+ int index = cRenderMode->getSelectedIndex();
+ if (index >= 0)
+ {
+ setRenderMode (index);
+ }
+ }
+ break;
+
+ case IDC_GROUND:
+ setShowGround (((mxCheckBox *) event->widget)->isChecked());
+ break;
+
+ case IDC_MOVEMENT:
+ setShowMovement (((mxCheckBox *) event->widget)->isChecked());
+ break;
+
+ case IDC_BACKGROUND:
+ setShowBackground (((mxCheckBox *) event->widget)->isChecked());
+ break;
+
+ case IDC_HITBOXES:
+ g_viewerSettings.showHitBoxes = ((mxCheckBox *) event->widget)->isChecked();
+ break;
+
+ case IDC_PHYSICSMODEL:
+ g_viewerSettings.showPhysicsModel = ((mxCheckBox *) event->widget)->isChecked();
+ break;
+
+ case IDC_BONES:
+ g_viewerSettings.showBones = ((mxCheckBox *) event->widget)->isChecked();
+ break;
+
+ case IDC_ATTACHMENTS:
+ g_viewerSettings.showAttachments = ((mxCheckBox *) event->widget)->isChecked();
+ break;
+
+ case IDC_SEQUENCE:
+ {
+ int index = cSequence->getSelectedIndex();
+ if (index >= 0)
+ {
+ setSequence ( index );
+ }
+ }
+ break;
+
+ case IDC_SPEEDSCALE:
+ {
+ g_viewerSettings.speedScale = ((mxSlider *) event->widget)->getValue();
+ lSpeedScale->setLabel( va( "Speed scale %.2f", g_viewerSettings.speedScale ) );
+ }
+ break;
+
+ case IDC_PRIMARYBLEND:
+ {
+ setBlend( 0, ((mxSlider *) event->widget)->getValue() );
+ }
+ break;
+
+ case IDC_SECONDARYBLEND:
+ {
+ setBlend( 1, ((mxSlider *) event->widget)->getValue() );
+ }
+ break;
+
+ case IDC_BODYPART:
+ {
+ int index = cBodypart->getSelectedIndex();
+ if (index >= 0)
+ {
+ setBodypart (index);
+
+ }
+ }
+ break;
+
+ case IDC_SUBMODEL:
+ {
+ int index = cSubmodel->getSelectedIndex();
+ if (index >= 0)
+ {
+ setSubmodel (index);
+
+ }
+ }
+ break;
+
+ case IDC_CONTROLLER:
+ {
+ int index = cController->getSelectedIndex();
+ if (index >= 0)
+ setBoneController (index);
+ }
+ break;
+
+ case IDC_CONTROLLERVALUE:
+ {
+ int index = cController->getSelectedIndex();
+ if (index >= 0)
+ setBoneControllerValue (index, slController->getValue());
+ }
+ break;
+
+ case IDC_SKINS:
+ {
+ int index = cSkin->getSelectedIndex();
+ if (index >= 0)
+ {
+ models->GetActiveStudioModel()->SetSkin (index);
+ g_viewerSettings.skin = index;
+ g_pMatSysWindow->redraw();
+ }
+ }
+ break;
+ default:
+ iret = 0;
+ break;
+ }
+ }
+ }
+
+ return iret;
+}
+
+void ControlPanel::dumpModelInfo() { }
+
+void ControlPanel::ChangeModel( const char *filename )
+{
+ HCURSOR hPrevCursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) );
+
+ // init all the selection tabs based on the current model
+ initSequenceChoices();
+ initBodypartChoices();
+ initBoneControllerChoices();
+ initSkinChoices();
+
+ setModelInfo();
+
+ SetCloseCaptionLanguageId( g_viewerSettings.cclanguageid, true );
+
+ g_viewerSettings.m_iEditAttachment = -1;
+
+ g_viewerSettings.enableIK = true;
+ g_viewerSettings.enableTargetIK = false;
+
+ setSequence( models->GetActiveStudioModel()->GetSequence() );
+ setSpeed( g_viewerSettings.speedScale );
+
+ mx_setcwd (mx_getpath (filename));
+
+ g_pFlexPanel->initFlexes();
+
+ // centerView();
+ // CenterOnFace();
+
+ IFacePoserToolWindow::ModelChanged();
+
+ CExpClass *cl = expressions->GetActiveClass();
+ if ( cl )
+ {
+ cl->SelectExpression( cl->GetSelectedExpression() );
+ }
+
+ SetSuffix( va( " - %s.mdl", models->GetActiveModelName() ) );
+ redraw();
+
+ SetCursor( hPrevCursor );
+}
+
+
+
+void
+ControlPanel::setRenderMode (int mode)
+{
+ g_viewerSettings.renderMode = mode;
+ g_pMatSysWindow->redraw();
+}
+
+
+void
+ControlPanel::setHighlightBone( int index )
+{
+ g_viewerSettings.highlightPhysicsBone = index;
+}
+
+void
+ControlPanel::setShowGround (bool b)
+{
+ g_viewerSettings.showGround = b;
+ cbGround->setChecked (b);
+}
+
+
+
+void
+ControlPanel::setShowMovement (bool b)
+{
+ g_viewerSettings.showMovement = b;
+ cbMovement->setChecked (b);
+}
+
+
+
+void
+ControlPanel::setShowBackground (bool b)
+{
+ g_viewerSettings.showBackground = b;
+ cbBackground->setChecked (b);
+}
+
+
+
+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
+ControlPanel::setSequence (int index)
+{
+ cSequence->select (index);
+ models->GetActiveStudioModel()->SetSequence(index);
+
+ initPoseParameters( );
+}
+
+
+void
+ControlPanel::setSpeed( float value )
+{
+ g_viewerSettings.speedScale = value;
+ slSpeedScale->setValue( value );
+}
+
+
+void ControlPanel::setBlend(int index, float value )
+{
+ models->GetActiveStudioModel()->SetPoseParameter( index, value );
+}
+
+
+void
+ControlPanel::initBodypartChoices()
+{
+ CStudioHdr *hdr = models->GetActiveStudioModel()->GetStudioHdr();
+ if (hdr)
+ {
+ int i;
+ mstudiobodyparts_t *pbodyparts = hdr->pBodypart(0);
+
+ cBodypart->removeAll();
+ if (hdr->numbodyparts() > 0)
+ {
+ for (i = 0; i < hdr->numbodyparts(); i++)
+ cBodypart->add (pbodyparts[i].pszName());
+
+ cBodypart->select (0);
+
+ cSubmodel->removeAll();
+ for (i = 0; i < pbodyparts[0].nummodels; i++)
+ {
+ char str[64];
+ sprintf (str, "Submodel %d", i + 1);
+ cSubmodel->add (str);
+ }
+ cSubmodel->select (0);
+ }
+ }
+}
+
+
+
+void
+ControlPanel::setBodypart (int index)
+{
+ CStudioHdr *hdr = models->GetActiveStudioModel()->GetStudioHdr();
+ if (hdr)
+ {
+ //cBodypart->setEn
+ cBodypart->select (index);
+ if (index < hdr->numbodyparts())
+ {
+ mstudiobodyparts_t *pbodyparts = hdr->pBodypart(0);
+ cSubmodel->removeAll();
+
+ for (int i = 0; i < pbodyparts[index].nummodels; i++)
+ {
+ char str[64];
+ sprintf (str, "Submodel %d", i + 1);
+ cSubmodel->add (str);
+ }
+ cSubmodel->select (0);
+ //models->GetActiveStudioModel()->SetBodygroup (index, 0);
+ }
+ }
+}
+
+
+
+void
+ControlPanel::setSubmodel (int index)
+{
+ models->GetActiveStudioModel()->SetBodygroup (cBodypart->getSelectedIndex(), index);
+}
+
+
+
+void
+ControlPanel::initBoneControllerChoices()
+{
+ CStudioHdr *hdr = models->GetActiveStudioModel()->GetStudioHdr();
+ if (hdr)
+ {
+ cController->setEnabled (hdr->numbonecontrollers() > 0);
+ slController->setEnabled (hdr->numbonecontrollers() > 0);
+ cController->removeAll();
+
+ for (int i = 0; i < hdr->numbonecontrollers(); i++)
+ {
+ mstudiobonecontroller_t *pbonecontroller = hdr->pBonecontroller(i);
+ char str[32];
+ sprintf (str, "Controller %d", pbonecontroller->inputfield);
+ cController->add (str);
+ }
+
+ if (hdr->numbonecontrollers() > 0)
+ {
+ mstudiobonecontroller_t *pbonecontrollers = hdr->pBonecontroller(0);
+ cController->select (0);
+ slController->setRange (pbonecontrollers->start, pbonecontrollers->end);
+ slController->setValue (0);
+ }
+ }
+}
+
+
+
+void
+ControlPanel::setBoneController (int index)
+{
+ CStudioHdr *hdr = models->GetActiveStudioModel()->GetStudioHdr();
+ if (hdr)
+ {
+ mstudiobonecontroller_t *pbonecontroller = hdr->pBonecontroller(index);
+ slController->setRange ( pbonecontroller->start, pbonecontroller->end);
+ slController->setValue (0);
+ }
+}
+
+
+
+void
+ControlPanel::setBoneControllerValue (int index, float value)
+{
+ CStudioHdr *hdr = models->GetActiveStudioModel()->GetStudioHdr();
+ if (hdr)
+ {
+ mstudiobonecontroller_t *pbonecontrollers = hdr->pBonecontroller(index);
+ models->GetActiveStudioModel()->SetController (pbonecontrollers->inputfield, value);
+ }
+}
+
+
+
+void
+ControlPanel::initPoseParameters()
+{
+ CStudioHdr *hdr = models->GetActiveStudioModel()->GetStudioHdr();
+ if (hdr)
+ {
+ for (int i = 0; i < hdr->GetNumPoseParameters(); i++)
+ {
+ setBlend( i, 0.0 );
+ }
+ }
+}
+
+void
+ControlPanel::initSkinChoices()
+{
+ CStudioHdr *hdr = models->GetActiveStudioModel()->GetStudioHdr();
+ if (hdr)
+ {
+ cSkin->setEnabled (hdr->numskinfamilies() > 0);
+ cSkin->removeAll();
+
+ for (int i = 0; i < hdr->numskinfamilies(); i++)
+ {
+ char str[32];
+ sprintf (str, "Skin %d", i + 1);
+ cSkin->add (str);
+ }
+
+ cSkin->select (0);
+ models->GetActiveStudioModel()->SetSkin (0);
+ g_viewerSettings.skin = 0;
+ }
+}
+
+
+
+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);
+}
+
+
+void ControlPanel::CenterOnFace( void )
+{
+ if ( !models->GetActiveStudioModel() )
+ return;
+
+ StudioModel *mdl = models->GetActiveStudioModel();
+ if ( !mdl )
+ return;
+
+ CStudioHdr *hdr = mdl->GetStudioHdr();
+ if ( !hdr )
+ return;
+
+ setSpeed( 1.0f );
+
+ int oldSeq = models->GetActiveStudioModel()->GetSequence();
+
+ int seq = models->GetActiveStudioModel()->LookupSequence( "idle_suble" );
+ if ( seq == -1 )
+ seq = 0;
+
+ if ( seq != oldSeq )
+ {
+ Con_Printf( "Centering changed model sequence # to %d\n", seq );
+ }
+
+ setSequence( seq );
+ initPoseParameters( );
+
+ mdl->m_angles.Init();
+ mdl->m_origin.Init();
+
+ Vector size;
+ VectorSubtract( hdr->hull_max(), hdr->hull_min(), size );
+
+ float eyeheight = hdr->hull_min().z + 0.9 * size.z;
+
+ 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( mdl->GetFileName( ), mdl->GetKeyValueText( seq ) ) )
+ {
+ // 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;
+ }
+ }
+ }
+
+ seqKeyValues->deleteThis();
+
+ mdl->m_origin.x = size.z * .65f;
+ mdl->m_origin.z += eyeheight;
+
+ CUtlVector< StudioModel * > modellist;
+
+ modellist.AddToTail( models->GetActiveStudioModel() );
+
+ int i;
+ if ( models->CountVisibleModels() > 0 )
+ {
+ modellist.RemoveAll();
+ for ( i = 0; i < models->Count(); i++ )
+ {
+ if ( models->IsModelShownIn3DView( i ) )
+ {
+ modellist.AddToTail( models->GetStudioModel( i ) );
+ }
+ }
+ }
+
+ int modelcount = modellist.Count();
+ int countover2 = modelcount / 2;
+ int ydelta = GetModelGap();
+ int yoffset = -countover2 * ydelta;
+ for ( i = 0 ; i < modelcount; i++ )
+ {
+ if ( models->GetStudioHeader( i ) == hdr )
+ {
+ mdl->m_origin.y = -yoffset;
+ }
+ yoffset += ydelta;
+ }
+
+ g_pMatSysWindow->redraw();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float ControlPanel::GetModelGap( void )
+{
+ return slModelGap->getValue();
+}
+
+void
+ControlPanel::centerView()
+{
+ StudioModel *pModel = models->GetActiveStudioModel();
+ if ( !pModel )
+ return;
+
+ Vector min, max;
+ models->GetActiveStudioModel()->ExtractBbox (min, max);
+
+ float dx = max[0] - min[0];
+ float dy = max[1] - min[1];
+ float dz = max[2] - min[2];
+ float d = dx;
+ if (dy > d)
+ d = dy;
+ if (dz > d)
+ d = dz;
+ pModel->m_origin[0] = d * 1.0f;
+ pModel->m_origin[1] = 0;
+ pModel->m_origin[2] = min[2] + dz / 2;
+ pModel->m_angles[0] = 0.0f;
+ pModel->m_angles[1] = 0.0f;
+ pModel->m_angles[2] = 0.0f;
+ g_viewerSettings.lightrot.x = 0.f;
+ g_viewerSettings.lightrot.y = -180.0f;
+ g_viewerSettings.lightrot.z = 0.0f;
+ g_pMatSysWindow->redraw();
+}
+
+bool ControlPanel::Close()
+{
+ int index = g_pExpressionClass->getSelectedIndex();
+ CExpClass *cl = expressions->GetClass( index );
+ if ( !cl )
+ return true;
+
+ return expressions->CloseClass( cl );
+
+}
+
+bool ControlPanel::Closeall()
+{
+ bool retval = true;
+
+ while ( expressions->GetNumClasses() > 0 )
+ {
+ CExpClass *cl = expressions->GetClass( 0 );
+ if ( !cl )
+ break;
+
+ if ( !expressions->CloseClass( cl ) )
+ {
+ return false;
+ }
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void ControlPanel::Copy( void )
+{
+ g_pFlexPanel->CopyControllerSettings();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void ControlPanel::Paste( void )
+{
+ g_pFlexPanel->PasteControllerSettings();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void ControlPanel::Undo( void )
+{
+ CExpClass *active = expressions->GetActiveClass();
+ if ( !active )
+ return;
+ int index = active->GetSelectedExpression();
+ if ( index != -1 )
+ {
+ UndoExpression( index );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void ControlPanel::Redo( void )
+{
+ CExpClass *active = expressions->GetActiveClass();
+ if ( !active )
+ return;
+ int index = active->GetSelectedExpression();
+ if ( index != -1 )
+ {
+ RedoExpression( index );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void ControlPanel::UndoExpression( int index )
+{
+ if ( index == -1 )
+ return;
+
+ CExpClass *active = expressions->GetActiveClass();
+ if ( !active )
+ return;
+
+ CExpression *exp = active->GetExpression( index );
+ if ( exp )
+ {
+ exp->Undo();
+ // Show the updated data
+ active->SelectExpression( index );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void ControlPanel::RedoExpression( int index )
+{
+ if ( index == -1 )
+ return;
+
+ CExpClass *active = expressions->GetActiveClass();
+ if ( !active )
+ return;
+
+ CExpression *exp = active->GetExpression( index );
+ if ( exp )
+ {
+ exp->Redo();
+ // Show the updated data
+ active->SelectExpression( index );
+ }
+}
+
+void ControlPanel::DeleteExpression( int index )
+{
+ CExpClass *active = expressions->GetActiveClass();
+ if ( !active )
+ return;
+
+ CExpression *exp = active->GetExpression( index );
+ if ( exp )
+ {
+ Con_Printf( "Deleting expression %s : %s\n", exp->name, exp->description );
+
+ g_pFlexPanel->DeleteExpression( index );
+
+ active->SelectExpression( max( 0, index - 1 ) );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : dt -
+//-----------------------------------------------------------------------------
+void ControlPanel::Think( float dt )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool ControlPanel::AllToolsDriveSpeech( void )
+{
+ return cbAllWindowsDriveSpeech->isChecked();
+}