You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
976 lines
22 KiB
976 lines
22 KiB
//========= 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(); |
|
}
|
|
|