📄 flexpanel.cpp
字号:
//
// Half-Life Model Viewer (c) 1999 by Mete Ciragan
//
// file: FlexPanel.cpp
// last modified: May 29 1999, Mete Ciragan
// copyright: The programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
// version: 1.2
//
// email: mete@swissquake.ch
// web: http://www.swissquake.ch/chumbalum-soft/
//
#include "FlexPanel.h"
#include "ViewerSettings.h"
#include "StudioModel.h"
#include "MatSysWin.h"
#include "ControlPanel.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mx/mx.h>
#include <mx/mxBmp.h>
#include "mxbitmapwindow.h"
#include "mxExpressionTray.h"
#include "expressions.h"
#include "cmdlib.h"
#include "mdlviewer.h"
#include "hlfaceposer.h"
#include "ExpressionProperties.h"
#include "expclass.h"
#include "choreowidgetdrawhelper.h"
#include "mxExpressionSlider.h"
#include "faceposer_models.h"
extern char g_appTitle[];
#define LINE_HEIGHT 20
FlexPanel *g_pFlexPanel = 0;
void FlexPanel::PositionControls( int width, int height )
{
int buttonwidth = 80;
int buttonx = 3;
int row = height - 18;
int buttonheight = 18;
btnResetSliders->setBounds( buttonx, row, buttonwidth, buttonheight );
}
FlexPanel::FlexPanel (mxWindow *parent)
: IFacePoserToolWindow( "FlexPanel", "Flex Sliders" ), mxWindow( parent, 0, 0, 0, 0 )
{
m_nViewableFlexControllerCount = 0;
m_bNewExpressionMode = true;
btnResetSliders = new mxButton( this, 0, 0, 100, 20, "Zero Sliders", IDC_EXPRESSIONRESET );
mxWindow *wFlex = this;
for (int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++)
{
int w = 5; // (i / 4) * 156 + 5;
int h = i * LINE_HEIGHT + 5; // (i % 4) * 20 + 5;
slFlexScale[i] = new mxExpressionSlider (wFlex, w, h, 220, LINE_HEIGHT, IDC_FLEXSCALE + i);
}
slScrollbar = new mxScrollbar( wFlex, 0, 0, 18, 100, IDC_FLEXSCROLL, mxScrollbar::Vertical );
slScrollbar->setRange( 0, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * LINE_HEIGHT );
slScrollbar->setPagesize( 100 );
}
FlexPanel::~FlexPanel ()
{
}
void FlexPanel::redraw()
{
if ( !ToolCanDraw() )
return;
CChoreoWidgetDrawHelper helper( this, GetSysColor( COLOR_BTNFACE ) );
HandleToolRedraw( helper );
BaseClass::redraw();
}
void FlexPanel::PositionSliders( int sboffset )
{
int reservedheight = GetCaptionHeight() + 5 /*gap at top*/ + 1 * 20 /* space for buttons/edit controls*/;
int widthofslidercolumn = slFlexScale[ 0 ]->w() + 10;
int colsavailable = ( this->w2() - 20 /*scrollbar*/ - 10 /*left edge gap + right gap*/ ) / widthofslidercolumn;
// Need at least one column
colsavailable = max( colsavailable, 1 );
int rowsneeded = GLOBAL_STUDIO_FLEX_CONTROL_COUNT;
studiohdr_t *hdr = models->GetActiveStudioModel()->getStudioHeader ();
if ( hdr )
{
rowsneeded = m_nViewableFlexControllerCount;
}
int rowsvisible = ( this->h2() - reservedheight ) / LINE_HEIGHT;
int rowspercol = rowsvisible;
if ( rowsvisible * colsavailable < rowsneeded )
{
// Figure out how many controls should go in each available column
rowspercol = (rowsneeded + (colsavailable - 1)) / colsavailable;
slScrollbar->setPagesize( rowsvisible * LINE_HEIGHT );
slScrollbar->setRange( 0, rowspercol * LINE_HEIGHT );
}
int row = 0;
int col = 0;
for (int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++)
{
int x = 5 + col * widthofslidercolumn;
int y = row * LINE_HEIGHT + 5 + GetCaptionHeight() - sboffset; // (i % 4) * 20 + 5;
slFlexScale[ i ]->setBounds( x, y, slFlexScale[i]->w(), slFlexScale[i]->h() );
if ( i >= rowsneeded ||
( y + LINE_HEIGHT - 5 > ( this->h2() - reservedheight ) ) )
{
slFlexScale[ i ]->setVisible( false );
}
else
{
slFlexScale[ i ]->setVisible( true );
}
row++;
if ( row >= rowspercol )
{
col++;
row = 0;
}
}
}
int FlexPanel::handleEvent (mxEvent *event)
{
int iret = 0;
if ( HandleToolEvent( event ) )
{
return iret;
}
switch ( event->event )
{
case mxEvent::Size:
{
int trueh = h2() - GetCaptionHeight();
PositionControls( w2(), h2() );
slScrollbar->setPagesize( trueh );
slScrollbar->setBounds( w2() - 18, GetCaptionHeight(), 18, trueh );
PositionSliders( 0 );
iret = 1;
}
break;
case mxEvent::Action:
{
iret = 1;
switch ( event->action )
{
default:
iret = 0;
break;
case IDC_FLEXSCROLL:
{
if ( event->event == mxEvent::Action &&
event->modifiers == SB_THUMBTRACK)
{
int offset = event->height; // ((mxScrollbar *) event->widget)->getValue( );
slScrollbar->setValue( offset ); // if (offset > slScrollbar->getPagesize()
PositionSliders( offset );
IFacePoserToolWindow::SetActiveTool( this );
}
}
break;
case IDC_EXPRESSIONRESET:
{
ResetSliders( true );
IFacePoserToolWindow::SetActiveTool( this );
}
break;
}
if ( event->action >= IDC_FLEXSCALE && event->action < IDC_FLEXSCALE + GLOBAL_STUDIO_FLEX_CONTROL_COUNT)
{
iret = 1;
bool pushundo = false;
mxExpressionSlider *slider = ( mxExpressionSlider * )event->widget;
int barnumber = event->height;
int slidernum = ( event->action - IDC_FLEXSCALE );
float value = slider->getValue ( barnumber );
float influ = slider->getInfluence( );
switch( event->modifiers )
{
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
break;
case SB_ENDSCROLL:
pushundo = true;
break;
}
int flex = LookupFlex( slidernum, barnumber );
int flex2 = LookupPairedFlex( flex );
float value2 = GetSlider( flex2 );
CExpClass *active = expressions->GetActiveClass();
if ( active )
{
int index = active->GetSelectedExpression();
if ( pushundo && index != -1 )
{
CExpression *exp = active->GetExpression( index );
if ( exp )
{
float *settings = exp->GetSettings();
float *weights = exp->GetWeights();
Assert( settings );
if ( settings[ flex ] != value ||
settings[ flex2 ] != value2 ||
weights[ flex ] != influ )
{
exp->PushUndoInformation();
active->SetDirty( true );
settings[ flex ] = value;
settings[ flex2 ] = value2;
weights[ flex ] = influ;
weights[ flex2 ] = influ;
exp->PushRedoInformation();
g_pExpressionTrayTool->redraw();
}
}
}
}
// Update the face
models->GetActiveStudioModel()->SetFlexController( flex, value * influ );
if (flex2 != flex)
models->GetActiveStudioModel()->SetFlexController( flex2, value2 * influ );
g_viewerSettings.solveHeadTurn = 1;
IFacePoserToolWindow::SetActiveTool( this );
}
}
}
return iret;
}
void FlexPanel::initFlexes ()
{
m_nViewableFlexControllerCount = 0;
memset( nFlexSliderIndex, 0, sizeof( nFlexSliderIndex ) );
memset( nFlexSliderBarnum, 0, sizeof( nFlexSliderBarnum ) );
studiohdr_t *hdr = models->GetActiveStudioModel()->getStudioHeader ();
if (hdr)
{
for (int j = 0; j < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; j++)
{
slFlexScale[j]->setVisible( false );
slFlexScale[j]->setLabel( "" );
}
// J is the slider number we're filling in
j = 0;
for ( int k = 0; k < hdr->numflexcontrollers; k++ )
{
// Lookup global flex controller index
int controller = hdr->pFlexcontroller( k )->link;
Assert( controller != -1 );
//Con_Printf( "%i Setting up %s global %i\n", k, hdr->pFlexcontroller(k)->pszName(), controller );
slFlexScale[j]->setLabel( hdr->pFlexcontroller(k)->pszName() );
if ( nFlexSliderIndex[controller] == 0 )
{
nFlexSliderIndex[controller] = j;
nFlexSliderBarnum[controller] = 0;
}
if (hdr->pFlexcontroller(k)->min != hdr->pFlexcontroller(k)->max)
slFlexScale[j]->setRange( 0, hdr->pFlexcontroller(k)->min, hdr->pFlexcontroller(k)->max );
if (strncmp( "right_", hdr->pFlexcontroller(k)->pszName(), 6 ) == 0)
{
if (hdr->pFlexcontroller(k)->min != hdr->pFlexcontroller(k)->max)
slFlexScale[j]->setRange( 1, hdr->pFlexcontroller(k+1)->min, hdr->pFlexcontroller(k+1)->max );
slFlexScale[j]->setLabel( &hdr->pFlexcontroller(k)->pszName()[6] );
slFlexScale[j]->SetMode( true );
k++;
controller = hdr->pFlexcontroller( k )->link;
Assert( controller != -1 );
if ( nFlexSliderIndex[controller] == 0 )
{
nFlexSliderIndex[controller] = j;
nFlexSliderBarnum[controller] = 1;
}
}
m_nViewableFlexControllerCount++;
slFlexScale[j]->setVisible( true );
slFlexScale[j]->redraw();
j++;
}
}
slScrollbar->setRange( 0, m_nViewableFlexControllerCount * LINE_HEIGHT + 5 );
int trueh = h2() - GetCaptionHeight();
PositionControls( w2(), h2() );
slScrollbar->setPagesize( trueh );
slScrollbar->setBounds( w2() - 18, GetCaptionHeight(), 18, trueh );
PositionSliders( 0 );
}
float
FlexPanel::GetSlider( int iFlexController )
{
return slFlexScale[ nFlexSliderIndex[ iFlexController ] ]->getValue( nFlexSliderBarnum[ iFlexController ] );
}
float FlexPanel::GetSliderRawValue( int iFlexController )
{
return slFlexScale[ nFlexSliderIndex[ iFlexController ] ]->getRawValue( nFlexSliderBarnum[ iFlexController ] );
}
void FlexPanel::GetSliderRange( int iFlexController, float& minvalue, float& maxvalue )
{
int barnum = nFlexSliderBarnum[ iFlexController ];
mxExpressionSlider *sl = slFlexScale[ nFlexSliderIndex[ iFlexController ] ];
Assert( sl );
minvalue = sl->getMinValue( barnum );
maxvalue = sl->getMaxValue( barnum );
}
void
FlexPanel::SetSlider( int iFlexController, float value )
{
slFlexScale[ nFlexSliderIndex[ iFlexController ] ]->setValue( nFlexSliderBarnum[ iFlexController ], value );
}
float
FlexPanel::GetInfluence( int iFlexController )
{
return slFlexScale[ nFlexSliderIndex[ iFlexController ] ]->getInfluence( );
}
void
FlexPanel::SetInfluence( int iFlexController, float value )
{
// Con_Printf( "SetInfluence( %d, %.0f ) : %d %d\n", iFlexController, value, nFlexSliderIndex[ iFlexController ], nFlexSliderBarnum[ iFlexController ] );
if ( nFlexSliderBarnum[ iFlexController ] == 0)
{
slFlexScale[ nFlexSliderIndex[ iFlexController ] ]->setInfluence( value );
}
}
char const *GetGlobalFlexControllerName( int index );
int
FlexPanel::LookupFlex( int iSlider, int barnum )
{
for (int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++)
{
if (nFlexSliderIndex[i] == iSlider && nFlexSliderBarnum[i] == barnum)
{
//char const *name = GetGlobalFlexControllerName( i );
//Con_Printf( "lookup slider %i bar %i == %s\n",
//iSlider, barnum, name );
return i;
}
}
Con_Printf( "lookup slider %i bar %i failed\n",
iSlider, barnum);
return 0;
}
int
FlexPanel::LookupPairedFlex( int iFlexController )
{
if (nFlexSliderBarnum[ iFlexController ] == 1)
{
return iFlexController - 1;
}
else if (nFlexSliderIndex[ iFlexController + 1 ] == nFlexSliderIndex[ iFlexController ])
{
return iFlexController + 1;
}
return iFlexController;
}
void
FlexPanel::setExpression( int index )
{
if ( !models->GetActiveStudioModel() )
return;
studiohdr_t *hdr = models->GetActiveStudioModel()->getStudioHeader ();
if ( !hdr )
return;
CExpClass *active = expressions->GetActiveClass();
if ( !active )
return;
CExpression *exp = active->GetExpression( index );
if ( !exp )
return;
// Con_Printf( "Setting expression to %i:'%s'\n", index, exp->name );
if ( FacePoser_GetOverridesShowing() )
{
if ( exp->HasOverride() && exp->GetOverride() )
{
exp = exp->GetOverride();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -