initial
This commit is contained in:
726
vgui2/matsys_controls/QCGenerator.cpp
Normal file
726
vgui2/matsys_controls/QCGenerator.cpp
Normal file
@@ -0,0 +1,726 @@
|
||||
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#if defined(WIN32) && !defined( _GAMECONSOLE )
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "filesystem.h"
|
||||
#include "filesystem_init.h"
|
||||
#include "appframework/IAppSystemGroup.h"
|
||||
#include "appframework/iappsystem.h"
|
||||
#include "appframework/AppFramework.h"
|
||||
#include "filesystem_helpers.h"
|
||||
|
||||
#include "matsys_controls/QCGenerator.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "tier2/vconfig.h"
|
||||
#include "vgui_controls/ListPanel.h"
|
||||
#include "vgui_controls/TextEntry.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/FileOpenDialog.h"
|
||||
#include "vgui_controls/DirectorySelectDialog.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "vgui_controls/CheckButton.h"
|
||||
#include "vgui_controls/MessageBox.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/Cursor.h"
|
||||
#include "vgui_controls/KeyBoardEditorDialog.h"
|
||||
|
||||
#if defined( _X360 )
|
||||
#include "xbox/xbox_win32stubs.h"
|
||||
#endif
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#define MAX_KEYVALUE 1024
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a pointer to the 'count' occurence of a character from the end of a string
|
||||
// returns 0 of there aren't 'count' number of the character in the string
|
||||
//-----------------------------------------------------------------------------
|
||||
char *strrchrcount(char *string, int character, int count )
|
||||
{
|
||||
int j = count;
|
||||
int numChars = strlen( string );
|
||||
for( int i = numChars; i > 0; i-- )
|
||||
{
|
||||
if( string[i-1] == character )
|
||||
{
|
||||
j--;
|
||||
}
|
||||
if( j == 0 )
|
||||
{
|
||||
return string + i-1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CModalPreserveMessageBox : public vgui::MessageBox
|
||||
{
|
||||
public:
|
||||
CModalPreserveMessageBox(const char *title, const char *text, vgui::Panel *parent)
|
||||
: vgui::MessageBox( title, text, parent )
|
||||
{
|
||||
m_PrevAppFocusPanel = vgui::input()->GetAppModalSurface();
|
||||
}
|
||||
|
||||
~CModalPreserveMessageBox()
|
||||
{
|
||||
vgui::input()->SetAppModalSurface( m_PrevAppFocusPanel );
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
vgui::VPANEL m_PrevAppFocusPanel;
|
||||
};
|
||||
|
||||
void VGUIMessageBox( vgui::Panel *pParent, const char *pTitle, const char *pMsg, ... )
|
||||
{
|
||||
char msg[4096];
|
||||
va_list marker;
|
||||
va_start( marker, pMsg );
|
||||
Q_vsnprintf( msg, sizeof( msg ), pMsg, marker );
|
||||
va_end( marker );
|
||||
|
||||
vgui::MessageBox *dlg = new CModalPreserveMessageBox( pTitle, msg, pParent );
|
||||
dlg->DoModal();
|
||||
dlg->Activate();
|
||||
dlg->RequestFocus();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Places all the info from the vgui controls into the QCInfo struct
|
||||
//-----------------------------------------------------------------------------
|
||||
void QCInfo::SyncFromControls()
|
||||
{
|
||||
char tempText[MAX_PATH];
|
||||
|
||||
vgui::Panel *pTargetField = pQCGenerator->FindChildByName( "staticPropCheck" );
|
||||
bStaticProp = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "mostlyOpaqueCheck" );
|
||||
bMostlyOpaque = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "disableCollisionsCheck" );
|
||||
bDisableCollision = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "referencePhysicsCheck" );
|
||||
bReferenceAsPhys = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "concaveCheck" );
|
||||
bConcave = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "automassCheck" );
|
||||
bAutomass = ((CheckButton *)pTargetField)->IsSelected();
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "massField" );
|
||||
((TextEntry *)pTargetField)->GetText(tempText, MAX_PATH);
|
||||
fMass = atof(tempText);
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "scaleField" );
|
||||
((TextEntry *)pTargetField)->GetText(tempText, MAX_PATH);
|
||||
fScale = atof(tempText);
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "collisionSMDField" );
|
||||
((TextEntry *)pTargetField)->GetText( tempText, MAX_PATH );
|
||||
Q_strcpy( pszCollisionPath, tempText );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "surfacePropertyDropDown" );
|
||||
((ComboBox *)pTargetField)->GetText( tempText, MAX_PATH );
|
||||
Q_strcpy( pszSurfaceProperty, tempText );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "materialsField" );
|
||||
((TextEntry *)pTargetField)->GetText( tempText, MAX_PATH );
|
||||
Q_strcpy( pszMaterialPath, tempText );
|
||||
|
||||
LODs.RemoveAll();
|
||||
pTargetField = pQCGenerator->FindChildByName( "LODList" );
|
||||
int numLOD = ((ListPanel *)pTargetField)->GetItemCount();
|
||||
for ( int i = 0; i < numLOD; i++ )
|
||||
{
|
||||
KeyValues *key = ((ListPanel *)pTargetField)->GetItem( i );
|
||||
LODInfo newLOD;
|
||||
|
||||
Q_strcpy( newLOD.pszFilename, key->GetString( "SMD" ) );
|
||||
newLOD.iLOD = key->GetInt( "LOD" );
|
||||
LODs.AddToTail( newLOD );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called during intialization to setup the initial state of the VGUI controls
|
||||
//-----------------------------------------------------------------------------
|
||||
void QCInfo::SyncToControls()
|
||||
{
|
||||
char tempText[MAX_PATH];
|
||||
|
||||
vgui::Panel *pTargetField = pQCGenerator->FindChildByName( "staticPropCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bStaticProp );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "mostlyOpaqueCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bMostlyOpaque );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "disableCollisionsCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bDisableCollision );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "referencePhysicsCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bReferenceAsPhys );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "concaveCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bConcave );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "automassCheck" );
|
||||
((CheckButton *)pTargetField)->SetSelected( bAutomass );
|
||||
|
||||
Q_snprintf( tempText, 10, "%d", (int)fMass );
|
||||
pTargetField = pQCGenerator->FindChildByName( "massField" );
|
||||
((TextEntry *)pTargetField)->SetText( tempText );
|
||||
|
||||
Q_snprintf( tempText, 10, "%d", (int)fScale );
|
||||
pTargetField = pQCGenerator->FindChildByName( "scaleField" );
|
||||
((TextEntry *)pTargetField)->SetText( tempText );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "collisionSMDField" );
|
||||
((TextEntry *)pTargetField)->SetText( pszCollisionPath );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "materialsField" );
|
||||
((TextEntry *)pTargetField)->SetText( pszMaterialPath );
|
||||
|
||||
pTargetField = pQCGenerator->FindChildByName( "surfacePropertyDropDown" );
|
||||
int numItems = ((ComboBox *)pTargetField)->GetItemCount();
|
||||
for( int i = 0; i < numItems; i++ )
|
||||
{
|
||||
((ComboBox *)pTargetField)->GetItemText( i, tempText, MAX_PATH );
|
||||
if ( !Q_strcmp( tempText, pszSurfaceProperty ) )
|
||||
{
|
||||
((ComboBox *)pTargetField)->SetItemEnabled( i, true );
|
||||
((ComboBox *)pTargetField)->SetText( tempText );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CBrowseButton::CBrowseButton( vgui::Panel *pParent ) : BaseClass( pParent, "Browse Button", "...", pParent, "browse" )
|
||||
{
|
||||
SetParent( pParent );
|
||||
pszStartingDirectory = NULL;
|
||||
pszFileFilter = NULL;
|
||||
pszTargetField = NULL;
|
||||
}
|
||||
|
||||
CBrowseButton::~CBrowseButton()
|
||||
{
|
||||
}
|
||||
|
||||
void CBrowseButton::SetCharVar( char **pVar, const char *pszNewText )
|
||||
{
|
||||
if ( *pVar && pszNewText && !Q_strcmp( *pVar, pszNewText ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( *pVar )
|
||||
{
|
||||
delete [] *pVar;
|
||||
*pVar = NULL;
|
||||
}
|
||||
|
||||
if ( pszNewText )
|
||||
{
|
||||
int len = Q_strlen( pszNewText ) + 1;
|
||||
*pVar = new char[ len ];
|
||||
Q_strncpy( *pVar, pszNewText, len );
|
||||
}
|
||||
}
|
||||
|
||||
void CBrowseButton::InitBrowseInfo( int x, int y, char *pszName, const char *pszDir, char *pszFilter, char *pszField )
|
||||
{
|
||||
SetSize( 24, 24 );
|
||||
SetPos( x, y );
|
||||
SetName( pszName );
|
||||
SetCharVar( GetStartingDirectory(), pszDir );
|
||||
SetCharVar( GetFileFilter(), pszFilter );
|
||||
SetCharVar( GetTargetField(), pszField );
|
||||
SetActionMessage();
|
||||
}
|
||||
|
||||
void CBrowseButton::SetActionMessage()
|
||||
{
|
||||
KeyValues *newActionMessage = new KeyValues( "browse", "directory", pszStartingDirectory, "filter", pszFileFilter);
|
||||
newActionMessage->SetString( "targetField", pszTargetField );
|
||||
SetCommand( newActionMessage );
|
||||
}
|
||||
|
||||
const char *ParseKeyvalue( const char *pBuffer, char *key, char *value )
|
||||
{
|
||||
char com_token[1024];
|
||||
|
||||
pBuffer = (const char *)ParseFile( pBuffer, com_token, NULL );
|
||||
if ( Q_strlen( com_token ) < MAX_KEYVALUE )
|
||||
{
|
||||
Q_strncpy( key, com_token, MAX_KEYVALUE );
|
||||
Q_strlower( key );
|
||||
}
|
||||
// no value on a close brace
|
||||
if ( !Q_strcmp( key, "}" ) )
|
||||
{
|
||||
value[0] = 0;
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
pBuffer = (const char *)ParseFile( pBuffer, com_token, NULL );
|
||||
if ( Q_strlen( com_token ) < MAX_KEYVALUE )
|
||||
{
|
||||
Q_strncpy( value, com_token, MAX_KEYVALUE );
|
||||
Q_strlower( value );
|
||||
}
|
||||
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CQCGenerator::CQCGenerator( vgui::Panel *pParent, const char *pszPath, const char *pszScene ) : BaseClass( pParent, "QCGenerator" )
|
||||
{
|
||||
m_QCInfo_t.Init( this );
|
||||
|
||||
SetMinimumSize(846, 770);
|
||||
|
||||
m_pLODPanel = new ListPanel(this, "LODList");
|
||||
m_pLODPanel->SetSelectIndividualCells( true );
|
||||
m_pLODPanel->AddColumnHeader(0, "SMD", "LOD SMD", 450, 0);
|
||||
m_pLODPanel->AddColumnHeader(1, "LOD", "LOD Distance", 50, 0);
|
||||
m_pLODPanel->AddActionSignalTarget( this );
|
||||
m_pLODPanel->SetMouseInputEnabled( true );
|
||||
|
||||
LoadControlSettings( "QCGenerator.res" );
|
||||
|
||||
m_pCollisionBrowseButton = new CBrowseButton( this );
|
||||
m_pCollisionBrowseButton->InitBrowseInfo( 808, 158, "collisionBrowseButton", pszPath, "*.smd", "collisionSMDField" );
|
||||
|
||||
char szTerminatedPath[1024] = "\0";
|
||||
sprintf( szTerminatedPath, "%s\\", pszPath );
|
||||
|
||||
InitializeSMDPaths( szTerminatedPath, pszScene );
|
||||
|
||||
char *pszMaterialsStart = strrchrcount( szTerminatedPath, '\\', 3 ) + 1;
|
||||
char *pszMaterialsEnd = strrchr( szTerminatedPath, '\\');
|
||||
Q_strncpy( m_QCInfo_t.pszMaterialPath, pszMaterialsStart, pszMaterialsEnd - pszMaterialsStart + 1 );
|
||||
|
||||
SetParent( pParent );
|
||||
|
||||
char szGamePath[1024] = "\0";
|
||||
char szSearchPath[1024] = "\0";
|
||||
|
||||
// Get the currently set game configuration
|
||||
GetVConfigRegistrySetting( GAMEDIR_TOKEN, szGamePath, sizeof( szGamePath ) );
|
||||
static const char *pSurfacePropFilename = "\\scripts\\surfaceproperties.txt";
|
||||
|
||||
sprintf( szSearchPath, "%s%s", szGamePath, pSurfacePropFilename );
|
||||
|
||||
FileHandle_t fp = g_pFullFileSystem->Open( szSearchPath, "rb" );
|
||||
|
||||
if ( !fp )
|
||||
{
|
||||
//the set game configuration didn't have a surfaceproperties file; we are grabbing it from hl2
|
||||
//TODO: This only works if they are in a subdirectory that is a peer to an hl2 directory
|
||||
// that contains the file. It potentially needs to search the entire drive or prompt for the location
|
||||
char *pszEndGamePath = Q_strrchr( szGamePath, '\\' );
|
||||
Q_strcpy( pszEndGamePath, "\\hl2" );
|
||||
sprintf( szSearchPath, "%s%s", szGamePath, pSurfacePropFilename );
|
||||
fp = g_pFullFileSystem->Open( szSearchPath, "rb" );
|
||||
}
|
||||
|
||||
int len = g_pFullFileSystem->Size( fp );
|
||||
|
||||
const char *szSurfacePropContents = new char[len+1];
|
||||
g_pFullFileSystem->Read( (void *)szSurfacePropContents, len, fp );
|
||||
|
||||
char key[MAX_KEYVALUE], value[MAX_KEYVALUE];
|
||||
|
||||
vgui::Panel *pSurfacePropDropDown = FindChildByName( "surfacePropertyDropDown" );
|
||||
|
||||
//filling up the surface property dropdown
|
||||
while ( szSurfacePropContents )
|
||||
{
|
||||
szSurfacePropContents = ParseKeyvalue( szSurfacePropContents, key, value );
|
||||
((ComboBox *)pSurfacePropDropDown)->AddItem( key, NULL );
|
||||
while ( szSurfacePropContents )
|
||||
{
|
||||
szSurfacePropContents = ParseKeyvalue( szSurfacePropContents, key, value );
|
||||
if (!stricmp( key, "}" ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_QCInfo_t.SyncToControls();
|
||||
|
||||
m_pLODEdit = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CQCGenerator::~CQCGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
void CQCGenerator::OnCommand( const char *command )
|
||||
{
|
||||
if ( Q_stricmp( command, "createQC" ) == 0 )
|
||||
{
|
||||
m_QCInfo_t.SyncFromControls();
|
||||
GenerateQCFile();
|
||||
}
|
||||
if ( Q_stricmp( command, "deleteSeq" ) == 0 )
|
||||
{
|
||||
//delete it
|
||||
DeleteLOD();
|
||||
}
|
||||
if ( Q_stricmp( command, "editSeq" ) == 0 )
|
||||
{
|
||||
//edit
|
||||
EditLOD();
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( command );
|
||||
}
|
||||
|
||||
|
||||
void CQCGenerator::OnKeyCodeTyped( KeyCode code )
|
||||
{
|
||||
switch ( code )
|
||||
{
|
||||
case KEY_ENTER:
|
||||
EditLOD();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CQCGenerator::OnBrowse( KeyValues *data )
|
||||
{
|
||||
Q_strcpy( m_szTargetField, data->GetString( "targetField" ) );
|
||||
const char *filter = data->GetString( "filter" );
|
||||
|
||||
if ( Q_strlen( filter ) == 0 )
|
||||
{
|
||||
// BrowseDirectory( data );
|
||||
}
|
||||
else
|
||||
{
|
||||
BrowseFile( data );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
//This function is no longer used in the current version of the program.
|
||||
void CQCGenerator::BrowseDirectory( KeyValues *data )
|
||||
{
|
||||
DirectorySelectDialog *pDialog = new DirectorySelectDialog( this, "Select Directory" );
|
||||
pDialog->AddActionSignalTarget( this );
|
||||
pDialog->DoModal();
|
||||
pDialog->SetStartDirectory( data->GetString( "directory" ) );
|
||||
}
|
||||
*/
|
||||
|
||||
void CQCGenerator::BrowseFile( KeyValues *data )
|
||||
{
|
||||
const char *filter = data->GetString( "filter" );
|
||||
|
||||
FileOpenDialog *pDialog = new FileOpenDialog( this, "Select File", true );
|
||||
pDialog->AddFilter( filter, filter, true );
|
||||
pDialog->AddActionSignalTarget(this);
|
||||
pDialog->SetStartDirectory( data->GetString( "directory" ) );
|
||||
pDialog->DoModal( true );
|
||||
}
|
||||
|
||||
void CQCGenerator::OnFileSelected( KeyValues *data )
|
||||
{
|
||||
if ( m_szTargetField )
|
||||
{
|
||||
vgui::Panel *pTargetField = FindChildByName( m_szTargetField );
|
||||
((TextEntry *)pTargetField)->SetText( data->GetString( "fullpath" ) );
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void CQCGenerator::OnDirectorySelected( KeyValues *data )
|
||||
{
|
||||
if ( m_szTargetField )
|
||||
{
|
||||
vgui::Panel *pTargetField = FindChildByName( m_szTargetField );
|
||||
((TextEntry *)pTargetField)->SetText( data->GetString( "dir" ) );
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
bool CQCGenerator::GenerateQCFile()
|
||||
{
|
||||
//TODO: clean this up. Consider creating a datatype that includes the string to write out when the QC file is created
|
||||
char *nameBegin = strrchr( m_QCInfo_t.pszSMDPath, '\\' );
|
||||
|
||||
char szPath[MAX_PATH];
|
||||
char szName[MAX_PATH];
|
||||
Q_strncpy( szPath, m_QCInfo_t.pszSMDPath, nameBegin - m_QCInfo_t.pszSMDPath + 2 );
|
||||
strcpy( szName, szPath);
|
||||
strcat( szName, m_QCInfo_t.pszSceneName);
|
||||
strcat( szName, ".qc" );
|
||||
FileHandle_t pSaveFile = g_pFullFileSystem->Open( szName, "wt" );
|
||||
if (!pSaveFile)
|
||||
{
|
||||
char szSaveError[1024] = "";
|
||||
Q_snprintf( szSaveError, 1024, "Save failed: invalid file name '%s'\n\nDirectory '%s' must exist.", szName, szPath );
|
||||
VGUIMessageBox( this, "QC Generator error", szSaveError );
|
||||
return 0;
|
||||
}
|
||||
|
||||
//write qc header
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "//\n// .qc file version 1.0\n\n");
|
||||
//write out modelname info
|
||||
char szModelName[MAX_PATH];
|
||||
char *modelStart = strrchrcount( szName, '\\', 2) + 1;
|
||||
char *modelEnd = strrchr( szName, '.' );
|
||||
Q_strncpy( szModelName, modelStart, modelEnd - modelStart + 1 );
|
||||
strcat( szModelName, ".mdl" );
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$modelname %s\n\n", szModelName );
|
||||
//write out scale info
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$scale %f\n", m_QCInfo_t.fScale );
|
||||
//write out body info
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$body \"Body\" \"%s\"\n", strrchr( m_QCInfo_t.pszSMDPath, '\\' ) + 1 );
|
||||
|
||||
if ( m_QCInfo_t.bStaticProp == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$staticprop\n" );
|
||||
}
|
||||
|
||||
if ( m_QCInfo_t.bMostlyOpaque == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$mostlyopaque\n" );
|
||||
}
|
||||
|
||||
//write out surfaceprop info
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$surfaceprop \"%s\"\n\n", m_QCInfo_t.pszSurfaceProperty );
|
||||
//write materials
|
||||
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$cdmaterials %s\n\n", m_QCInfo_t.pszMaterialPath);
|
||||
|
||||
if ( m_QCInfo_t.bStaticProp || m_QCInfo_t.bNoAnimation )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "// --------- Animation sequences -------\n");
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$sequence \"idle\" \"%s\" fps 30\n\n", strrchr(m_QCInfo_t.pszSMDPath, '\\')+1);
|
||||
}
|
||||
|
||||
//write out lod info
|
||||
for( int i = 0; i < m_QCInfo_t.LODs.Count(); i++ )
|
||||
{
|
||||
LODInfo thisLOD = m_QCInfo_t.LODs.Element( i );
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$lod %d\n{\n\treplacemodel \"%s\" \"%s\"\n}\n\n", thisLOD.iLOD, strrchr(m_QCInfo_t.pszSMDPath, '\\')+1, thisLOD.pszFilename );
|
||||
}
|
||||
|
||||
if ( m_QCInfo_t.bDisableCollision != true )
|
||||
{
|
||||
//write out collision header
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\n" );
|
||||
//write out collision info
|
||||
if ( m_QCInfo_t.bReferenceAsPhys == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$collisionmodel \"%s\"", strrchr( m_QCInfo_t.pszSMDPath, '\\' ) + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( Q_strcmp( m_QCInfo_t.pszCollisionPath, "" ) )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "$collisionmodel \"%s\"", strrchr( m_QCInfo_t.pszCollisionPath, '\\' ) + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, " {\n\t// Mass in kilograms\n ");
|
||||
|
||||
if ( m_QCInfo_t.bAutomass == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\t$automass\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\t$mass %f\n", m_QCInfo_t.fMass );
|
||||
}
|
||||
|
||||
if ( m_QCInfo_t.bConcave == true )
|
||||
{
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "\t$concave\n" );
|
||||
}
|
||||
g_pFullFileSystem->FPrintf( pSaveFile, "}\n\n");
|
||||
}
|
||||
|
||||
g_pFullFileSystem->Close( pSaveFile );
|
||||
|
||||
char szCommand[MAX_PATH];
|
||||
char szGamePath[MAX_PATH];
|
||||
|
||||
char studiomdlPath[512];
|
||||
g_pFullFileSystem->RelativePathToFullPath( "studiomdl.bat", NULL, studiomdlPath, sizeof( studiomdlPath ));
|
||||
|
||||
GetVConfigRegistrySetting( GAMEDIR_TOKEN, szGamePath, sizeof( szGamePath ) );
|
||||
|
||||
#ifdef WIN32
|
||||
STARTUPINFO startup;
|
||||
PROCESS_INFORMATION process;
|
||||
|
||||
|
||||
memset(&startup, 0, sizeof(startup));
|
||||
startup.cb = sizeof(startup);
|
||||
|
||||
|
||||
sprintf( szCommand, "%s -game %s %s", studiomdlPath, szGamePath, szName);
|
||||
bool bReturn = CreateProcess( NULL, szCommand, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &startup, &process) ? true : false;
|
||||
#else
|
||||
Assert( !"Implement me, why aren't we using a thread tool abstraction?" );
|
||||
bool bReturn = false;
|
||||
#endif
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
void CQCGenerator::InitializeSMDPaths( const char *pszPath, const char *pszScene )
|
||||
{
|
||||
strcpy( m_QCInfo_t.pszSceneName, pszScene );
|
||||
|
||||
FileFindHandle_t *pFileHandle = new FileFindHandle_t();
|
||||
|
||||
g_pFullFileSystem->AddSearchPath( pszPath, "SMD_DIR" );
|
||||
|
||||
const char *filename = g_pFullFileSystem->FindFirst( "*.smd", pFileHandle );
|
||||
|
||||
bool bFoundReference = false;
|
||||
bool bFoundCollision = false;
|
||||
bool bFoundLOD = false;
|
||||
|
||||
//iterate through .smd files
|
||||
const char *startName = pszScene;
|
||||
|
||||
int nSearchLength = Q_strlen( pszScene );
|
||||
|
||||
int currentLOD = 1;
|
||||
|
||||
while( filename )
|
||||
{
|
||||
if ( !strncmp( startName, filename, nSearchLength ) )
|
||||
{
|
||||
const char *filenameEnd = filename + nSearchLength;
|
||||
if ( !strncmp( filenameEnd, "_ref", 4 ) || !strncmp( filenameEnd, ".smd", 4 ) )
|
||||
{
|
||||
bFoundReference = true;
|
||||
//we have found the reference smd.
|
||||
strcpy( m_QCInfo_t.pszSMDPath, pszPath );
|
||||
strcat( m_QCInfo_t.pszSMDPath, filename );
|
||||
}
|
||||
if ( !strncmp( filenameEnd, "_phy", 4) || !strncmp( filenameEnd, "_col", 4 ) )
|
||||
{
|
||||
bFoundCollision = true;
|
||||
//we have found the collision smd.
|
||||
strcpy( m_QCInfo_t.pszCollisionPath, pszPath );
|
||||
strcat( m_QCInfo_t.pszCollisionPath, filename );
|
||||
}
|
||||
if ( !strncmp( filenameEnd, "_lod", 4) )
|
||||
{
|
||||
bFoundLOD = true;
|
||||
//we found an LOD smd.
|
||||
char lodName[255];
|
||||
Q_snprintf( lodName, Q_strlen( lodName ), "lod%d", currentLOD );
|
||||
//we found an LOD
|
||||
KeyValues *newKv = new KeyValues( lodName, "SMD", filename, "LOD", "10" );
|
||||
m_pLODPanel->AddItem( newKv, currentLOD, false, false );
|
||||
currentLOD++;
|
||||
}
|
||||
}
|
||||
filename = g_pFullFileSystem->FindNext( *pFileHandle );
|
||||
}
|
||||
char pszMessage[2048] = "";
|
||||
char pszRefMessage[1024] = "";
|
||||
char pszColMessage[1024] = "";
|
||||
if (!bFoundReference )
|
||||
{
|
||||
strcat( m_QCInfo_t.pszSMDPath, pszPath );
|
||||
strcat( m_QCInfo_t.pszSMDPath, pszScene );
|
||||
strcat( m_QCInfo_t.pszSMDPath, ".smd" );
|
||||
Q_snprintf( pszRefMessage, 1024, "Reference SMD not found.\n\nValid default reference SMDs are %s%s_ref*.smd and %s%s.smd\nUsing default of %s. Model will not compile.\n\n", pszPath, pszScene, pszPath, pszScene, m_QCInfo_t.pszSMDPath );
|
||||
}
|
||||
if ( !bFoundCollision )
|
||||
{
|
||||
Q_snprintf( pszColMessage, 1024, "Collision SMD not found.\n\nThe valid default collision SMD is %s%s_phy*.smd.\nUsing reference SMD as default.\n", pszPath, pszScene );
|
||||
strcpy( m_QCInfo_t.pszCollisionPath, m_QCInfo_t.pszSMDPath );
|
||||
m_QCInfo_t.bReferenceAsPhys = true;
|
||||
}
|
||||
if ( !bFoundReference || !bFoundCollision)
|
||||
{
|
||||
Q_strcpy( pszMessage, pszRefMessage );
|
||||
Q_strcat( pszMessage, pszColMessage, 1024 );
|
||||
VGUIMessageBox( this, "Error Initializing Paths", pszMessage );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CQCGenerator::DeleteLOD()
|
||||
{
|
||||
int numSelected = m_pLODPanel->GetSelectedItemsCount();
|
||||
int selected;
|
||||
for ( int i = numSelected-1; i >= 0; i-- )
|
||||
{
|
||||
selected = m_pLODPanel->GetSelectedItem( i );
|
||||
m_pLODPanel->RemoveItem( selected );
|
||||
}
|
||||
}
|
||||
|
||||
void CQCGenerator::EditLOD()
|
||||
{
|
||||
int numSelected = m_pLODPanel->GetSelectedItemsCount();
|
||||
if ( numSelected == 1 && !m_pLODPanel->IsInEditMode() )
|
||||
{
|
||||
if ( m_pLODEdit )
|
||||
{
|
||||
m_pLODEdit->DeletePanel();
|
||||
m_pLODEdit = 0;
|
||||
}
|
||||
m_pLODEdit = new vgui::TextEntry( this, "Edit" );
|
||||
m_pLODEdit->SendNewLine( true );
|
||||
m_nSelectedSequence = m_pLODPanel->GetSelectedItem( 0 );
|
||||
m_nSelectedColumn = m_pLODPanel->GetSelectedColumn();
|
||||
m_pLODPanel->EnterEditMode( m_nSelectedSequence, m_nSelectedColumn, m_pLODEdit );
|
||||
}
|
||||
}
|
||||
|
||||
void CQCGenerator::OnNewLODText()
|
||||
{
|
||||
KeyValues *pEditItem = m_pLODPanel->GetItem( m_nSelectedSequence );
|
||||
KeyValues *pListItem = pEditItem;
|
||||
wchar_t szEditText[MAX_PATH];
|
||||
|
||||
pEditItem = pEditItem->GetFirstValue();
|
||||
const char *name = pEditItem->GetName();
|
||||
for( int i = 0; i < m_nSelectedColumn; i++ )
|
||||
{
|
||||
pEditItem = pEditItem->GetNextValue();
|
||||
name = pEditItem->GetName();
|
||||
}
|
||||
m_pLODEdit->GetText( szEditText, MAX_PATH );
|
||||
|
||||
pListItem->SetWString( name, szEditText );
|
||||
|
||||
m_pLODPanel->LeaveEditMode();
|
||||
m_pLODPanel->InvalidateLayout();
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
// ----------------------------------------- //
|
||||
// File generated by VPC //
|
||||
// ----------------------------------------- //
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\assetpicker.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\assetpicker.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\assetpicker.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\baseassetpicker.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\baseassetpicker.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\baseassetpicker.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\colorpickerpanel.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\colorpickerpanel.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\colorpickerpanel.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\curveeditorpanel.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\curveeditorpanel.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\curveeditorpanel.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\gamefiletreeview.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\gamefiletreeview.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\gamefiletreeview.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\manipulator.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\manipulator.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\manipulator.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\matsyscontrols.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\matsyscontrols.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\matsyscontrols.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\mdlpanel.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\mdlpanel.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\mdlpanel.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\mdlpicker.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\mdlpicker.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\mdlpicker.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\mdlsequencepicker.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\mdlsequencepicker.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\mdlsequencepicker.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\particlepicker.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\particlepicker.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\particlepicker.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\picker.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\picker.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\picker.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\potterywheelpanel.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\potterywheelpanel.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\potterywheelpanel.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\proceduraltexturepanel.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\proceduraltexturepanel.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\proceduraltexturepanel.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\QCGenerator.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\QCGenerator.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\QCGenerator.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\sequencepicker.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\sequencepicker.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\sequencepicker.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\sheetsequencepanel.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\sheetsequencepanel.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\sheetsequencepanel.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\tgapicker.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\tgapicker.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\tgapicker.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\tgapreviewpanel.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\tgapreviewpanel.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\tgapreviewpanel.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vmtpanel.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vmtpanel.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vmtpanel.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vmtpicker.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vmtpicker.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vmtpicker.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vmtpreviewpanel.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vmtpreviewpanel.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vmtpreviewpanel.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vtfpicker.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vtfpicker.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vtfpicker.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vtfpreviewpanel.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vtfpreviewpanel.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\vgui2\matsys_controls\vtfpreviewpanel.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
50
vgui2/matsys_controls/assetpicker.cpp
Normal file
50
vgui2/matsys_controls/assetpicker.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/assetpicker.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Asset Picker with no preview
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAssetPicker::CAssetPicker( vgui::Panel *pParent, const char *pAssetType,
|
||||
const char *pExt, const char *pSubDir, const char *pTextType ) :
|
||||
BaseClass( pParent, pAssetType, pExt, pSubDir, pTextType )
|
||||
{
|
||||
CreateStandardControls( this );
|
||||
LoadControlSettingsAndUserConfig( "resource/assetpicker.res" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CAssetPickerFrame::CAssetPickerFrame( vgui::Panel *pParent, const char *pTitle,
|
||||
const char *pAssetType, const char *pExt, const char *pSubDir, const char *pTextType ) :
|
||||
BaseClass( pParent )
|
||||
{
|
||||
SetAssetPicker( new CAssetPicker( this, pAssetType, pExt, pSubDir, pTextType ) );
|
||||
LoadControlSettingsAndUserConfig( "resource/assetpickerframe.res" );
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
1936
vgui2/matsys_controls/baseassetpicker.cpp
Normal file
1936
vgui2/matsys_controls/baseassetpicker.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1259
vgui2/matsys_controls/colorpickerpanel.cpp
Normal file
1259
vgui2/matsys_controls/colorpickerpanel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
204
vgui2/matsys_controls/curveeditorpanel.cpp
Normal file
204
vgui2/matsys_controls/curveeditorpanel.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/curveeditorpanel.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/MouseCode.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CCurveEditorPanel::CCurveEditorPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
m_nSelectedPoint = -1;
|
||||
SetMouseInputEnabled( true );
|
||||
SetKeyBoardInputEnabled( true );
|
||||
m_nHighlightedPoint = -1;
|
||||
}
|
||||
|
||||
CCurveEditorPanel::~CCurveEditorPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Converts screen location to normalized values
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::ScreenToValue( int x, int y, float *pIn, float *pOut )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
*pIn = (float)x / (w-1);
|
||||
*pOut = 1.0f - ((float)y / (h-1));
|
||||
}
|
||||
|
||||
void CCurveEditorPanel::ValueToScreen( float flIn, float flOut, int *x, int *y )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
*x = (int)(flIn * (w-1) + 0.5f);
|
||||
*y = (h-1) - (int)(flOut * (h-1) + 0.5f);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle input
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::OnMousePressed( vgui::MouseCode code )
|
||||
{
|
||||
BaseClass::OnMousePressed( code );
|
||||
|
||||
int x, y;
|
||||
input()->GetCursorPos( x, y );
|
||||
ScreenToLocal( x, y );
|
||||
|
||||
if ( code == MOUSE_LEFT )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
float flIn, flOut;
|
||||
ScreenToValue( x, y, &flIn, &flOut );
|
||||
float flTolerance = 5.0f / (w-1); // +/- 3 pixels to select the point
|
||||
m_nSelectedPoint = FindOrAddControlPoint( flIn, flTolerance, flOut );
|
||||
}
|
||||
}
|
||||
|
||||
void CCurveEditorPanel::OnMouseReleased( vgui::MouseCode code )
|
||||
{
|
||||
BaseClass::OnMouseReleased( code );
|
||||
|
||||
if ( code == MOUSE_LEFT )
|
||||
{
|
||||
m_nSelectedPoint = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void CCurveEditorPanel::OnCursorMoved( int x, int y )
|
||||
{
|
||||
BaseClass::OnCursorMoved( x, y );
|
||||
|
||||
float flIn, flOut;
|
||||
ScreenToValue( x, y, &flIn, &flOut );
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
float flTolerance = 5.0f / (w-1); // +/- 3 pixels to select the point
|
||||
m_nHighlightedPoint = FindControlPoint( flIn, flTolerance );
|
||||
|
||||
if ( m_nSelectedPoint < 0 )
|
||||
return;
|
||||
m_nSelectedPoint = ModifyControlPoint( m_nSelectedPoint, flIn, flOut );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handles keypresses
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::OnKeyCodePressed( vgui::KeyCode code )
|
||||
{
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
|
||||
if ( m_nSelectedPoint >= 0 )
|
||||
{
|
||||
RemoveControlPoint( m_nSelectedPoint );
|
||||
m_nSelectedPoint = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This paints the grid behind the curves
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::PaintBackground( void )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
|
||||
vgui::surface()->DrawFilledRect( 0, 0, w, h );
|
||||
|
||||
vgui::surface()->DrawSetColor( 128, 128, 128, 255 );
|
||||
vgui::surface()->DrawLine( 0, h/4, w, h/4 );
|
||||
vgui::surface()->DrawLine( 0, h/2, w, h/2 );
|
||||
vgui::surface()->DrawLine( 0, 3*h/4, w, 3*h/4 );
|
||||
|
||||
vgui::surface()->DrawLine( w/4, 0, w/4, h );
|
||||
vgui::surface()->DrawLine( w/2, 0, w/2, h );
|
||||
vgui::surface()->DrawLine( 3*w/4, 0, 3*w/4, h );
|
||||
|
||||
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
|
||||
vgui::surface()->DrawLine( 0, 0, w, 0 );
|
||||
vgui::surface()->DrawLine( w, 0, w, h );
|
||||
vgui::surface()->DrawLine( w, h, 0, h );
|
||||
vgui::surface()->DrawLine( 0, h, 0, 0 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the color curves operation to edit
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCurveEditorPanel::Paint( void )
|
||||
{
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
int x0 = 0, y0 = 0;
|
||||
|
||||
// FIXME: Add method to draw multiple lines DrawPolyLine connects the 1st and last points... bleah
|
||||
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
|
||||
for ( int i = 0; i < w; ++i )
|
||||
{
|
||||
float flIn = (float)i / (w-1);
|
||||
float flOut = GetValue( flIn );
|
||||
int x = i;
|
||||
int y = (h-1) - (int)(flOut * (h-1) + 0.5f);
|
||||
y = clamp( y, 0, h-1 );
|
||||
|
||||
if ( i != 0 )
|
||||
{
|
||||
vgui::surface()->DrawLine( x0, y0, x, y );
|
||||
}
|
||||
|
||||
x0 = x; y0 = y;
|
||||
}
|
||||
|
||||
|
||||
// This will paint the control points
|
||||
// The currently selected one will be painted red and filled.
|
||||
for ( int i = ControlPointCount(); --i >= 0; )
|
||||
{
|
||||
float flIn, flOut;
|
||||
GetControlPoint( i, &flIn, &flOut );
|
||||
|
||||
int cx, cy;
|
||||
ValueToScreen( flIn, flOut, &cx, &cy );
|
||||
|
||||
if ( (i == m_nSelectedPoint) || ((m_nSelectedPoint == -1) && (i == m_nHighlightedPoint)) )
|
||||
{
|
||||
vgui::surface()->DrawSetColor( 255, 0, 0, 255 );
|
||||
vgui::surface()->DrawFilledRect( cx-3, cy-3, cx+3, cy+3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
|
||||
vgui::surface()->DrawOutlinedRect( cx-3, cy-3, cx+3, cy+3 );
|
||||
}
|
||||
}
|
||||
}
|
||||
301
vgui2/matsys_controls/gamefiletreeview.cpp
Normal file
301
vgui2/matsys_controls/gamefiletreeview.cpp
Normal file
@@ -0,0 +1,301 @@
|
||||
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#if defined(WIN32) && !defined( _GAMECONSOLE )
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#undef PropertySheet
|
||||
|
||||
#include "matsys_controls/gamefiletreeview.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/Cursor.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// list of all tree view icons
|
||||
//-----------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
IMAGE_FOLDER = 1,
|
||||
IMAGE_OPENFOLDER,
|
||||
IMAGE_FILE,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CGameFileTreeView::CGameFileTreeView( Panel *parent, const char *name, const char *pRootFolderName, const char *pRootDir, const char *pExtension ) : BaseClass(parent, name), m_Images( false )
|
||||
{
|
||||
m_RootDir = pRootDir;
|
||||
|
||||
m_Ext = pExtension;
|
||||
m_bUseExt = ( pExtension != NULL );
|
||||
|
||||
m_RootFolderName = pRootFolderName;
|
||||
|
||||
// build our list of images
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder", false ) );
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder_selected", false ) );
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_file", false ) );
|
||||
SetImageList( &m_Images, false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Refreshes the active file list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::RefreshFileList()
|
||||
{
|
||||
RemoveAll();
|
||||
SetFgColor(Color(216, 222, 211, 255));
|
||||
|
||||
// add the base node
|
||||
KeyValues *pkv = new KeyValues( "root" );
|
||||
pkv->SetString( "text", m_RootFolderName );
|
||||
pkv->SetInt( "root", 1 );
|
||||
pkv->SetInt( "expand", 1 );
|
||||
int iRoot = AddItem( pkv, GetRootItemIndex() );
|
||||
pkv->deleteThis();
|
||||
ExpandItem( iRoot, true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Selects the root folder
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::SelectRoot()
|
||||
{
|
||||
AddSelectedItem( GetRootItemIndex(), true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the number of root directories
|
||||
//-----------------------------------------------------------------------------
|
||||
int CGameFileTreeView::GetRootDirectoryCount()
|
||||
{
|
||||
return GetNumChildren( GetRootItemIndex() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the ith root directory
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CGameFileTreeView::GetRootDirectory( int nIndex )
|
||||
{
|
||||
int nItemIndex = GetChild( GetRootItemIndex(), nIndex );
|
||||
KeyValues *kv = GetItemData( nItemIndex );
|
||||
if ( !kv )
|
||||
return NULL;
|
||||
return kv->GetString( "path", NULL );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node (necessary since tree view can't have multiple roots)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::PopulateRootNode( int itemIndex )
|
||||
{
|
||||
AddDirectoriesOfNode( itemIndex, m_RootDir );
|
||||
|
||||
if ( m_bUseExt )
|
||||
{
|
||||
AddFilesOfNode( itemIndex, m_RootDir, m_Ext );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node with directories
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CGameFileTreeView::DoesDirectoryHaveSubdirectories( const char *pFilePath )
|
||||
{
|
||||
char pSearchString[MAX_PATH];
|
||||
Q_snprintf( pSearchString, MAX_PATH, "%s\\*", pFilePath );
|
||||
|
||||
// get the list of files
|
||||
FileFindHandle_t findHandle;
|
||||
|
||||
// generate children
|
||||
// add all the items
|
||||
const char *pszFileName = g_pFullFileSystem->FindFirstEx( pSearchString, "GAME", &findHandle );
|
||||
while ( pszFileName )
|
||||
{
|
||||
bool bIsDirectory = g_pFullFileSystem->FindIsDirectory( findHandle );
|
||||
if ( bIsDirectory && Q_strnicmp( pszFileName, ".", 2 ) && Q_strnicmp( pszFileName, "..", 3 ) )
|
||||
return true;
|
||||
|
||||
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FindClose( findHandle );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node with directories
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::AddDirectoriesOfNode( int itemIndex, const char *pFilePath )
|
||||
{
|
||||
char pSearchString[MAX_PATH];
|
||||
Q_snprintf( pSearchString, MAX_PATH, "%s\\*", pFilePath );
|
||||
|
||||
// get the list of files
|
||||
FileFindHandle_t findHandle;
|
||||
|
||||
// generate children
|
||||
// add all the items
|
||||
const char *pszFileName = g_pFullFileSystem->FindFirstEx( pSearchString, "GAME", &findHandle );
|
||||
while ( pszFileName )
|
||||
{
|
||||
bool bIsDirectory = g_pFullFileSystem->FindIsDirectory( findHandle );
|
||||
if ( bIsDirectory && Q_strnicmp( pszFileName, ".", 2 ) && Q_strnicmp( pszFileName, "..", 3 ) )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "node", "text", pszFileName );
|
||||
|
||||
char pFullPath[MAX_PATH];
|
||||
Q_snprintf( pFullPath, sizeof(pFullPath), "%s/%s", pFilePath, pszFileName );
|
||||
Q_FixSlashes( pFullPath );
|
||||
Q_strlower( pFullPath );
|
||||
bool bHasSubdirectories = DoesDirectoryHaveSubdirectories( pFullPath );
|
||||
kv->SetString( "path", pFullPath );
|
||||
|
||||
kv->SetInt( "expand", bHasSubdirectories );
|
||||
kv->SetInt( "dir", 1 );
|
||||
kv->SetInt( "image", IMAGE_FOLDER );
|
||||
|
||||
int itemID = AddItem(kv, itemIndex);
|
||||
kv->deleteThis();
|
||||
|
||||
// mark directories in orange
|
||||
SetItemColorForDirectories( itemID );
|
||||
}
|
||||
|
||||
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FindClose( findHandle );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Populate the root node with files
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::AddFilesOfNode( int itemIndex, const char *pFilePath, const char *pExt )
|
||||
{
|
||||
char pSearchString[MAX_PATH];
|
||||
Q_snprintf( pSearchString, MAX_PATH, "%s\\*.%s", pFilePath, pExt );
|
||||
|
||||
// get the list of files
|
||||
FileFindHandle_t findHandle;
|
||||
|
||||
// generate children
|
||||
// add all the items
|
||||
const char *pszFileName = g_pFullFileSystem->FindFirst( pSearchString, &findHandle );
|
||||
while ( pszFileName )
|
||||
{
|
||||
if ( !g_pFullFileSystem->FindIsDirectory( findHandle ) )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "node", "text", pszFileName );
|
||||
|
||||
char pFullPath[MAX_PATH];
|
||||
Q_snprintf( pFullPath, MAX_PATH, "%s\\%s", pFilePath, pszFileName );
|
||||
kv->SetString( "path", pFullPath );
|
||||
kv->SetInt( "image", IMAGE_FILE );
|
||||
|
||||
AddItem(kv, itemIndex);
|
||||
kv->deleteThis();
|
||||
}
|
||||
|
||||
pszFileName = g_pFullFileSystem->FindNext( findHandle );
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FindClose( findHandle );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// override to incremental request and show p4 directories
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::GenerateChildrenOfNode(int itemIndex)
|
||||
{
|
||||
KeyValues *pkv = GetItemData(itemIndex);
|
||||
if ( pkv->GetInt("root") )
|
||||
{
|
||||
PopulateRootNode( itemIndex );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pkv->GetInt("dir"))
|
||||
return;
|
||||
|
||||
const char *pFilePath = pkv->GetString("path", "");
|
||||
if (!pFilePath[0])
|
||||
return;
|
||||
|
||||
surface()->SetCursor(dc_waitarrow);
|
||||
|
||||
AddDirectoriesOfNode( itemIndex, pFilePath );
|
||||
|
||||
if ( m_bUseExt )
|
||||
{
|
||||
AddFilesOfNode( itemIndex, pFilePath, m_Ext );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setup a context menu whenever a directory is clicked on
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::GenerateContextMenu( int itemIndex, int x, int y )
|
||||
{
|
||||
return;
|
||||
|
||||
/*
|
||||
KeyValues *pkv = GetItemData(itemIndex);
|
||||
const char *pFilePath = pkv->GetString("path", "");
|
||||
if (!pFilePath[0])
|
||||
return;
|
||||
|
||||
Menu *pContext = new Menu(this, "FileContext");
|
||||
pContext->AddMenuItem("Cloak folder", new KeyValues("CloakFolder", "item", itemIndex), GetParent(), NULL);
|
||||
|
||||
// show the context menu
|
||||
pContext->SetPos(x, y);
|
||||
pContext->SetVisible(true);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets an item to be colored as if its a menu
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::SetItemColorForDirectories( int itemID )
|
||||
{
|
||||
// mark directories in orange
|
||||
SetItemFgColor( itemID, Color(224, 192, 0, 255) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setup a smaller font
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGameFileTreeView::ApplySchemeSettings(IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
SetFont( pScheme->GetFont("DefaultSmall") );
|
||||
}
|
||||
|
||||
205
vgui2/matsys_controls/manipulator.cpp
Normal file
205
vgui2/matsys_controls/manipulator.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
//========= Copyright <20> 1996-2001, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/manipulator.h"
|
||||
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/ISystem.h"
|
||||
#include "vgui/MouseCode.h"
|
||||
|
||||
#include "mathlib/vector.h"
|
||||
#include "mathlib/vmatrix.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// local helper functions
|
||||
//-----------------------------------------------------------------------------
|
||||
static float UpdateTime( float &flLastTime )
|
||||
{
|
||||
float flTime = vgui::system()->GetFrameTime();
|
||||
float dt = flTime - flLastTime;
|
||||
flLastTime = flTime;
|
||||
return dt;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Base class for manipulators which operate on transforms
|
||||
//-----------------------------------------------------------------------------
|
||||
CTransformManipulator::CTransformManipulator( matrix3x4_t *pTransform ) :
|
||||
m_pTransform( pTransform )
|
||||
{
|
||||
}
|
||||
|
||||
void CTransformManipulator::SetTransform( matrix3x4_t *pTransform )
|
||||
{
|
||||
m_pTransform = pTransform;
|
||||
}
|
||||
|
||||
matrix3x4_t *CTransformManipulator::GetTransform( void )
|
||||
{
|
||||
return m_pTransform;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CPotteryWheelManip - nendo-style camera manipulator
|
||||
//-----------------------------------------------------------------------------
|
||||
CPotteryWheelManip::CPotteryWheelManip( matrix3x4_t *pTransform ) :
|
||||
CTransformManipulator( pTransform ),
|
||||
m_lastx( -1 ), m_lasty( -1 ),
|
||||
m_zoom( 100.0f ), m_altitude( 0.0f ), m_azimuth( 0.0f ),
|
||||
m_prevZoom( 100.0f ), m_prevAltitude( 0.0f ), m_prevAzimuth( 0.0f ),
|
||||
m_flLastMouseTime( 0.0f ), m_flLastTickTime( 0.0f ),
|
||||
m_flSpin( 0.0f ), m_bSpin( false )
|
||||
{
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnBeginManipulation( void )
|
||||
{
|
||||
m_prevZoom = m_zoom;
|
||||
m_prevAltitude = m_altitude;
|
||||
m_prevAzimuth = m_azimuth;
|
||||
m_flLastMouseTime = m_flLastTickTime = vgui::system()->GetFrameTime();
|
||||
m_flSpin = 0.0f;
|
||||
m_bSpin = false;
|
||||
}
|
||||
|
||||
// Sets the zoom level
|
||||
void CPotteryWheelManip::SetZoom( float flZoom )
|
||||
{
|
||||
m_prevZoom = m_zoom = flZoom;
|
||||
}
|
||||
|
||||
|
||||
void CPotteryWheelManip::OnAcceptManipulation( void )
|
||||
{
|
||||
m_flSpin = 0.0f;
|
||||
m_bSpin = false;
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnCancelManipulation( void )
|
||||
{
|
||||
m_zoom = m_prevZoom;
|
||||
m_altitude = m_prevAltitude;
|
||||
m_azimuth = m_prevAzimuth;
|
||||
m_flSpin = 0.0f;
|
||||
m_bSpin = false;
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
|
||||
void CPotteryWheelManip::OnTick( void )
|
||||
{
|
||||
float dt = UpdateTime( m_flLastTickTime );
|
||||
|
||||
if ( m_bSpin )
|
||||
{
|
||||
m_azimuth += dt * m_flSpin;
|
||||
UpdateTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnCursorMoved( int x, int y )
|
||||
{
|
||||
float dt = UpdateTime( m_flLastMouseTime );
|
||||
|
||||
if ( m_bSpin )
|
||||
{
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( input()->IsMouseDown( MOUSE_MIDDLE ) )
|
||||
{
|
||||
int dy = y - m_lasty;
|
||||
int dx = x - m_lastx;
|
||||
|
||||
if ( abs( dx ) < 2 * abs( dy ) )
|
||||
{
|
||||
UpdateZoom( 0.2f * dy );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flSpin = (dt != 0.0f) ? 0.002f * dx / dt : 0.0f;
|
||||
m_azimuth += 0.002f * dx;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_azimuth += 0.002f * ( x - m_lastx );
|
||||
m_altitude -= 0.002f * ( y - m_lasty );
|
||||
m_altitude = MAX( -M_PI/2, MIN( M_PI/2, m_altitude ) );
|
||||
}
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnMousePressed( vgui::MouseCode code, int x, int y )
|
||||
{
|
||||
UpdateTime( m_flLastMouseTime );
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
m_bSpin = false;
|
||||
m_flSpin = 0.0f;
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnMouseReleased( vgui::MouseCode code, int x, int y )
|
||||
{
|
||||
UpdateTime( m_flLastMouseTime );
|
||||
|
||||
if ( code == MOUSE_MIDDLE )
|
||||
{
|
||||
m_bSpin = ( fabs( m_flSpin ) > 1.0f );
|
||||
}
|
||||
|
||||
m_lastx = x;
|
||||
m_lasty = y;
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::OnMouseWheeled( int delta )
|
||||
{
|
||||
UpdateTime( m_flLastMouseTime );
|
||||
|
||||
UpdateZoom( -10.0f * delta );
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
void CPotteryWheelManip::UpdateTransform()
|
||||
{
|
||||
if ( !m_pTransform )
|
||||
return;
|
||||
|
||||
float y = m_zoom * sin( m_altitude );
|
||||
float xz = m_zoom * cos( m_altitude );
|
||||
float x = xz * sin( m_azimuth );
|
||||
float z = xz * cos( m_azimuth );
|
||||
|
||||
Vector position(x, y, z);
|
||||
AngleMatrix( RadianEuler( -m_altitude, m_azimuth, 0 ), position, *m_pTransform );
|
||||
}
|
||||
|
||||
|
||||
void CPotteryWheelManip::UpdateZoom( float delta )
|
||||
{
|
||||
m_zoom *= pow( 1.01f, delta );
|
||||
}
|
||||
72
vgui2/matsys_controls/matsys_controls.vpc
Normal file
72
vgui2/matsys_controls/matsys_controls.vpc
Normal file
@@ -0,0 +1,72 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// MATSYS_CONTROLS.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$macro SRCDIR "..\.."
|
||||
|
||||
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
|
||||
|
||||
$Project "matsys_controls"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "assetpicker.cpp"
|
||||
$File "baseassetpicker.cpp"
|
||||
$File "colorpickerpanel.cpp"
|
||||
$File "curveeditorpanel.cpp"
|
||||
$File "gamefiletreeview.cpp"
|
||||
$File "manipulator.cpp"
|
||||
$File "matsyscontrols.cpp"
|
||||
$File "mdlpanel.cpp"
|
||||
$File "mdlpicker.cpp"
|
||||
$File "mdlsequencepicker.cpp"
|
||||
$File "particlepicker.cpp"
|
||||
$File "picker.cpp"
|
||||
$File "potterywheelpanel.cpp"
|
||||
$File "proceduraltexturepanel.cpp"
|
||||
$File "QCGenerator.cpp"
|
||||
$File "sequencepicker.cpp"
|
||||
$File "sheetsequencepanel.cpp"
|
||||
$File "tgapicker.cpp"
|
||||
$File "tgapreviewpanel.cpp"
|
||||
$File "vmtpicker.cpp"
|
||||
$File "vmtpreviewpanel.cpp"
|
||||
$File "vtfpicker.cpp"
|
||||
$File "vtfpreviewpanel.cpp"
|
||||
$File "vmtpanel.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\matsys_controls\assetpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\baseassetpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\colorpickerpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\gamefiletreeview.h"
|
||||
$File "$SRCDIR\public\matsys_controls\manipulator.h"
|
||||
$File "$SRCDIR\public\matsys_controls\matsyscontrols.h"
|
||||
$File "$SRCDIR\public\matsys_controls\mdlpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\mdlpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\mdlsequencepicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\particlepicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\picker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\potterywheelpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\proceduraltexturepanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\QCGenerator.h"
|
||||
$File "$SRCDIR\public\matsys_controls\sequencepicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\sheetsequencepanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\tgapicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\tgapreviewpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vmtpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vmtpreviewpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vtfpicker.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vtfpreviewpanel.h"
|
||||
$File "$SRCDIR\public\matsys_controls\vmtpanel.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries" [$WINDOWS]
|
||||
{
|
||||
$Lib bitmap
|
||||
}
|
||||
}
|
||||
13
vgui2/matsys_controls/matsys_controls.vpc.vpc_cache
Normal file
13
vgui2/matsys_controls/matsys_controls.vpc.vpc_cache
Normal file
@@ -0,0 +1,13 @@
|
||||
"vpc_cache"
|
||||
{
|
||||
"CacheVersion" "1"
|
||||
"win32"
|
||||
{
|
||||
"CRCFile" "matsys_controls.vcxproj.vpc_crc"
|
||||
"OutputFiles"
|
||||
{
|
||||
"0" "matsys_controls.vcxproj"
|
||||
"1" "matsys_controls.vcxproj.filters"
|
||||
}
|
||||
}
|
||||
}
|
||||
100
vgui2/matsys_controls/matsyscontrols.cpp
Normal file
100
vgui2/matsys_controls/matsyscontrols.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include <materialsystem/imaterialsystem.h>
|
||||
#include <materialsystem/imaterialsystemhardwareconfig.h>
|
||||
#include <datacache/imdlcache.h>
|
||||
#include <VGuiMatSurface/IMatSystemSurface.h>
|
||||
#include <istudiorender.h>
|
||||
#include "vgui_controls/Controls.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
IMaterialSystem *g_pMaterialSystem = NULL;
|
||||
IMaterialSystem *MaterialSystem()
|
||||
{
|
||||
return g_pMaterialSystem;
|
||||
}
|
||||
|
||||
IMaterialSystemHardwareConfig *g_pMaterialSystemHardwareConfig = NULL;
|
||||
IMaterialSystemHardwareConfig *MaterialSystemHardwareConfig()
|
||||
{
|
||||
return g_pMaterialSystemHardwareConfig;
|
||||
}
|
||||
|
||||
IMDLCache *g_pMDLCache = NULL;
|
||||
IMDLCache *MDLCache()
|
||||
{
|
||||
return g_pMDLCache;
|
||||
}
|
||||
|
||||
IMatSystemSurface *g_pMatSystemSurface = NULL;
|
||||
IMatSystemSurface *MatSystemSurface()
|
||||
{
|
||||
return g_pMatSystemSurface;
|
||||
}
|
||||
|
||||
IStudioRender *g_pStudioRender = NULL;
|
||||
IStudioRender *StudioRender()
|
||||
{
|
||||
return g_pStudioRender;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: finds a particular interface in the factory set
|
||||
//-----------------------------------------------------------------------------
|
||||
static void *InitializeInterface( char const *interfaceName, CreateInterfaceFn *factoryList, int numFactories )
|
||||
{
|
||||
void *retval;
|
||||
|
||||
for ( int i = 0; i < numFactories; i++ )
|
||||
{
|
||||
CreateInterfaceFn factory = factoryList[ i ];
|
||||
if ( !factory )
|
||||
continue;
|
||||
|
||||
retval = factory( interfaceName, NULL );
|
||||
if ( retval )
|
||||
return retval;
|
||||
}
|
||||
|
||||
// No provider for requested interface!!!
|
||||
// Assert( !"No provider for requested interface!!!" );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initializes the controls
|
||||
//-----------------------------------------------------------------------------
|
||||
bool VGui_InitMatSysInterfacesList( const char *moduleName, CreateInterfaceFn *factoryList, int numFactories )
|
||||
{
|
||||
if ( !vgui::VGui_InitInterfacesList( moduleName, factoryList, numFactories ) )
|
||||
return false;
|
||||
|
||||
g_pMaterialSystem = (IMaterialSystem *)InitializeInterface( MATERIAL_SYSTEM_INTERFACE_VERSION, factoryList, numFactories );
|
||||
g_pMatSystemSurface = (IMatSystemSurface *)InitializeInterface( MAT_SYSTEM_SURFACE_INTERFACE_VERSION, factoryList, numFactories );
|
||||
g_pMDLCache = (IMDLCache *)InitializeInterface( MDLCACHE_INTERFACE_VERSION, factoryList, numFactories );
|
||||
g_pStudioRender = (IStudioRender *)InitializeInterface( STUDIO_RENDER_INTERFACE_VERSION, factoryList, numFactories );
|
||||
g_pMaterialSystemHardwareConfig = (IMaterialSystemHardwareConfig *)InitializeInterface( MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION, factoryList, numFactories );
|
||||
|
||||
// MDL cache + studiorender are optional
|
||||
return ( g_pMaterialSystem && g_pMatSystemSurface && g_pMaterialSystemHardwareConfig );
|
||||
}
|
||||
|
||||
|
||||
} // namespace vgui
|
||||
|
||||
|
||||
|
||||
631
vgui2/matsys_controls/mdlpanel.cpp
Normal file
631
vgui2/matsys_controls/mdlpanel.cpp
Normal file
@@ -0,0 +1,631 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/mdlpanel.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/imaterialsystemhardwareconfig.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "vgui_controls/Frame.h"
|
||||
#include "tier1/convar.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "istudiorender.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "vcollide.h"
|
||||
#include "vcollide_parse.h"
|
||||
#include "bone_setup.h"
|
||||
#include "renderparm.h"
|
||||
#include "vphysics_interface.h"
|
||||
#include "game/client/irendercaptureconfiguration.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
DECLARE_BUILD_FACTORY( CMDLPanel );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Keeps a global clock to autoplay sequences to run from
|
||||
// Also deals with speedScale changes
|
||||
//-----------------------------------------------------------------------------
|
||||
static float GetAutoPlayTime( void )
|
||||
{
|
||||
static int g_prevTicks;
|
||||
static float g_time;
|
||||
|
||||
int ticks = Plat_MSTime();
|
||||
|
||||
// limit delta so that float time doesn't overflow
|
||||
if (g_prevTicks == 0)
|
||||
{
|
||||
g_prevTicks = ticks;
|
||||
}
|
||||
|
||||
g_time += ( ticks - g_prevTicks ) / 1000.0f;
|
||||
g_prevTicks = ticks;
|
||||
|
||||
return g_time;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDLPanel::CMDLPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
SetVisible( true );
|
||||
|
||||
// Used to poll input
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
|
||||
SetIdentityMatrix( m_RootMDL.m_MDLToWorld );
|
||||
m_bDrawCollisionModel = false;
|
||||
m_bWireFrame = false;
|
||||
m_bGroundGrid = false;
|
||||
m_bLockView = false;
|
||||
m_bLookAtCamera = true;
|
||||
m_bAnimationPause = false;
|
||||
|
||||
m_iCameraAttachment = -1;
|
||||
m_iRenderCaptureCameraAttachment = -1;
|
||||
Q_memset( m_iDirectionalLightAttachments, ~0, sizeof( m_iDirectionalLightAttachments ) );
|
||||
|
||||
m_flAutoPlayTimeBase = GetAutoPlayTime();
|
||||
|
||||
m_bCameraOrientOverrideEnabled = false;
|
||||
m_bCameraPositionOverrideEnabled = false;
|
||||
m_vecCameraOrientOverride.Init();
|
||||
m_vecCameraPositionOverride.Init();
|
||||
}
|
||||
|
||||
CMDLPanel::~CMDLPanel()
|
||||
{
|
||||
m_aMergeMDLs.Purge();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scheme settings
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
SetBackgroundColor( GetBgColor() );
|
||||
SetBorder( pScheme->GetBorder( "MenuBorder") );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Rendering options
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetCollsionModel( bool bVisible )
|
||||
{
|
||||
m_bDrawCollisionModel = bVisible;
|
||||
}
|
||||
|
||||
void CMDLPanel::SetGroundGrid( bool bVisible )
|
||||
{
|
||||
m_bGroundGrid = bVisible;
|
||||
}
|
||||
|
||||
void CMDLPanel::SetWireFrame( bool bVisible )
|
||||
{
|
||||
m_bWireFrame = bVisible;
|
||||
}
|
||||
|
||||
void CMDLPanel::SetLockView( bool bLocked )
|
||||
{
|
||||
m_bLockView = bLocked;
|
||||
}
|
||||
|
||||
void CMDLPanel::SetLookAtCamera( bool bLookAtCamera )
|
||||
{
|
||||
m_bLookAtCamera = bLookAtCamera;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Lock the camera position and angles to an attachment point
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetCameraAttachment( const char *pszAttachment )
|
||||
{
|
||||
// Check to see if we have a valid model to look at.
|
||||
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
||||
return;
|
||||
|
||||
SetLookAtCamera( false );
|
||||
|
||||
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
||||
|
||||
m_iCameraAttachment = Studio_FindAttachment( &studioHdr, pszAttachment );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the light render capture camera position and angles to an attachment point
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetRenderCaptureCameraAttachment( const char *pszAttachment )
|
||||
{
|
||||
// Check to see if we have a valid model to look at.
|
||||
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
||||
return;
|
||||
|
||||
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
||||
|
||||
m_iRenderCaptureCameraAttachment = Studio_FindAttachment( &studioHdr, pszAttachment );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the directional light attachment point for direction animation
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::SetDirectionalLightAttachment( int idx, const char *pszAttachment )
|
||||
{
|
||||
// Check to see if we have a valid model to look at.
|
||||
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
||||
return;
|
||||
if ( idx < 0 || idx >= MATERIAL_MAX_LIGHT_COUNT )
|
||||
return;
|
||||
|
||||
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
||||
|
||||
m_iDirectionalLightAttachments[idx] = Studio_FindAttachment( &studioHdr, pszAttachment );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the camera to look at the model
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::LookAtMDL()
|
||||
{
|
||||
// Check to see if we have a valid model to look at.
|
||||
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
||||
return;
|
||||
|
||||
if ( m_bLockView )
|
||||
return;
|
||||
|
||||
float flRadius;
|
||||
Vector vecCenter;
|
||||
GetBoundingSphere( vecCenter, flRadius );
|
||||
LookAt( vecCenter, flRadius );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FIXME: This should be moved into studiorender
|
||||
//-----------------------------------------------------------------------------
|
||||
static ConVar r_showenvcubemap( "r_showenvcubemap", "0", FCVAR_CHEAT );
|
||||
static ConVar r_eyegloss ( "r_eyegloss", "1", FCVAR_ARCHIVE ); // wet eyes
|
||||
static ConVar r_eyemove ( "r_eyemove", "1", FCVAR_ARCHIVE ); // look around
|
||||
static ConVar r_eyeshift_x ( "r_eyeshift_x", "0", FCVAR_ARCHIVE ); // eye X position
|
||||
static ConVar r_eyeshift_y ( "r_eyeshift_y", "0", FCVAR_ARCHIVE ); // eye Y position
|
||||
static ConVar r_eyeshift_z ( "r_eyeshift_z", "0", FCVAR_ARCHIVE ); // eye Z position
|
||||
static ConVar r_eyesize ( "r_eyesize", "0", FCVAR_ARCHIVE ); // adjustment to iris textures
|
||||
static ConVar mat_softwareskin( "mat_softwareskin", "0", FCVAR_CHEAT );
|
||||
static ConVar r_nohw ( "r_nohw", "0", FCVAR_CHEAT );
|
||||
static ConVar r_nosw ( "r_nosw", "0", FCVAR_CHEAT );
|
||||
static ConVar r_teeth ( "r_teeth", "1" );
|
||||
static ConVar r_drawentities ( "r_drawentities", "1", FCVAR_CHEAT );
|
||||
static ConVar r_flex ( "r_flex", "1" );
|
||||
static ConVar r_eyes ( "r_eyes", "1" );
|
||||
static ConVar r_skin ( "r_skin","0", FCVAR_CHEAT );
|
||||
static ConVar r_maxmodeldecal ( "r_maxmodeldecal", "50" );
|
||||
static ConVar r_modelwireframedecal ( "r_modelwireframedecal", "0", FCVAR_CHEAT );
|
||||
static ConVar mat_normals ( "mat_normals", "0", FCVAR_CHEAT );
|
||||
static ConVar r_eyeglintlodpixels ( "r_eyeglintlodpixels", "0" );
|
||||
static ConVar r_rootlod ( "r_rootlod", "0" );
|
||||
|
||||
static StudioRenderConfig_t s_StudioRenderConfig;
|
||||
|
||||
void CMDLPanel::UpdateStudioRenderConfig( void )
|
||||
{
|
||||
memset( &s_StudioRenderConfig, 0, sizeof(s_StudioRenderConfig) );
|
||||
|
||||
s_StudioRenderConfig.bEyeMove = !!r_eyemove.GetInt();
|
||||
s_StudioRenderConfig.fEyeShiftX = r_eyeshift_x.GetFloat();
|
||||
s_StudioRenderConfig.fEyeShiftY = r_eyeshift_y.GetFloat();
|
||||
s_StudioRenderConfig.fEyeShiftZ = r_eyeshift_z.GetFloat();
|
||||
s_StudioRenderConfig.fEyeSize = r_eyesize.GetFloat();
|
||||
if( mat_softwareskin.GetInt() || m_bWireFrame )
|
||||
{
|
||||
s_StudioRenderConfig.bSoftwareSkin = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_StudioRenderConfig.bSoftwareSkin = false;
|
||||
}
|
||||
s_StudioRenderConfig.bNoHardware = !!r_nohw.GetInt();
|
||||
s_StudioRenderConfig.bNoSoftware = !!r_nosw.GetInt();
|
||||
s_StudioRenderConfig.bTeeth = !!r_teeth.GetInt();
|
||||
s_StudioRenderConfig.drawEntities = r_drawentities.GetInt();
|
||||
s_StudioRenderConfig.bFlex = !!r_flex.GetInt();
|
||||
s_StudioRenderConfig.bEyes = !!r_eyes.GetInt();
|
||||
s_StudioRenderConfig.bWireframe = m_bWireFrame;
|
||||
s_StudioRenderConfig.bDrawNormals = mat_normals.GetBool();
|
||||
s_StudioRenderConfig.skin = r_skin.GetInt();
|
||||
s_StudioRenderConfig.maxDecalsPerModel = r_maxmodeldecal.GetInt();
|
||||
s_StudioRenderConfig.bWireframeDecals = r_modelwireframedecal.GetInt() != 0;
|
||||
|
||||
s_StudioRenderConfig.fullbright = false;
|
||||
s_StudioRenderConfig.bSoftwareLighting = false;
|
||||
|
||||
s_StudioRenderConfig.bShowEnvCubemapOnly = r_showenvcubemap.GetBool();
|
||||
s_StudioRenderConfig.fEyeGlintPixelWidthLODThreshold = r_eyeglintlodpixels.GetFloat();
|
||||
|
||||
StudioRender()->UpdateConfig( s_StudioRenderConfig );
|
||||
}
|
||||
|
||||
void CMDLPanel::DrawCollisionModel()
|
||||
{
|
||||
vcollide_t *pCollide = MDLCache()->GetVCollide( m_RootMDL.m_MDL.GetMDL() );
|
||||
|
||||
if ( !pCollide || pCollide->solidCount <= 0 )
|
||||
return;
|
||||
|
||||
static color32 color = {255,0,0,0};
|
||||
|
||||
IVPhysicsKeyParser *pParser = g_pPhysicsCollision->VPhysicsKeyParserCreate( pCollide );
|
||||
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
|
||||
|
||||
matrix3x4_t pBoneToWorld[MAXSTUDIOBONES];
|
||||
m_RootMDL.m_MDL.SetUpBones( m_RootMDL.m_MDLToWorld, MAXSTUDIOBONES, pBoneToWorld );
|
||||
|
||||
// PERFORMANCE: Just parse the script each frame. It's fast enough for tools. If you need
|
||||
// this to go faster then cache off the bone index mapping in an array like HLMV does
|
||||
while ( !pParser->Finished() )
|
||||
{
|
||||
const char *pBlock = pParser->GetCurrentBlockName();
|
||||
if ( !stricmp( pBlock, "solid" ) )
|
||||
{
|
||||
solid_t solid;
|
||||
|
||||
pParser->ParseSolid( &solid, NULL );
|
||||
int boneIndex = Studio_BoneIndexByName( &studioHdr, solid.name );
|
||||
Vector *outVerts;
|
||||
int vertCount = g_pPhysicsCollision->CreateDebugMesh( pCollide->solids[solid.index], &outVerts );
|
||||
|
||||
if ( vertCount )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
|
||||
// NOTE: assumes these have been set up already by the model render code
|
||||
// So this is a little bit of a back door to a cache of the bones
|
||||
// this code wouldn't work unless you draw the model this frame before calling
|
||||
// this routine. CMDLPanel always does this, but it's worth noting.
|
||||
// A better solution would be to move the ragdoll visulization into the CDmeMdl
|
||||
// and either draw it there or make it queryable and query/draw here.
|
||||
matrix3x4_t xform;
|
||||
SetIdentityMatrix( xform );
|
||||
if ( boneIndex >= 0 )
|
||||
{
|
||||
MatrixCopy( pBoneToWorld[ boneIndex ], xform );
|
||||
}
|
||||
IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, GetWireframeMaterial() );
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, vertCount/3 );
|
||||
|
||||
for ( int j = 0; j < vertCount; j++ )
|
||||
{
|
||||
Vector out;
|
||||
VectorTransform( outVerts[j].Base(), xform, out.Base() );
|
||||
meshBuilder.Position3fv( out.Base() );
|
||||
meshBuilder.Color4ub( color.r, color.g, color.b, color.a );
|
||||
meshBuilder.TexCoord2f( 0, 0, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
g_pPhysicsCollision->DestroyDebugMesh( vertCount, outVerts );
|
||||
}
|
||||
else
|
||||
{
|
||||
pParser->SkipBlock();
|
||||
}
|
||||
}
|
||||
g_pPhysicsCollision->VPhysicsKeyParserDestroy( pParser );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// paint it!
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::OnPaint3D()
|
||||
{
|
||||
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID )
|
||||
return;
|
||||
|
||||
// FIXME: Move this call into DrawModel in StudioRender
|
||||
StudioRenderConfig_t oldStudioRenderConfig;
|
||||
StudioRender()->GetCurrentConfig( oldStudioRenderConfig );
|
||||
|
||||
UpdateStudioRenderConfig();
|
||||
|
||||
CMatRenderContextPtr pRenderContext( vgui::MaterialSystem() );
|
||||
|
||||
// We want the models to use their natural alpha, not depth in alpha
|
||||
pRenderContext->SetIntRenderingParameter( INT_RENDERPARM_WRITE_DEPTH_TO_DESTALPHA, 0 );
|
||||
|
||||
if ( IsPaint3dForRenderCapture() )
|
||||
{
|
||||
// We are rendering into flashlight depth texture
|
||||
pRenderContext->SetFlashlightMode( false ); // disable shadows since we should be using DEPTH_WRITE material
|
||||
}
|
||||
else if ( GetRenderingWithFlashlightConfiguration() )
|
||||
{
|
||||
// Setup shadow state that we configured
|
||||
g_pStudioRender->ClearAllShadows();
|
||||
// NOTE: flashlight shadow is added post bone setup
|
||||
}
|
||||
else
|
||||
{
|
||||
// flashlights can't work in the model panel under queued mode (the state isn't ready yet, so causes a crash)
|
||||
pRenderContext->SetFlashlightMode( false );
|
||||
}
|
||||
|
||||
ITexture *pMyCube = materials->FindTexture( "engine/defaultcubemap", TEXTURE_GROUP_CUBE_MAP, true );
|
||||
|
||||
if ( HasLightProbe() )
|
||||
{
|
||||
pMyCube = GetLightProbeCubemap( vgui::MaterialSystemHardwareConfig()->GetHDRType() != HDR_TYPE_NONE );
|
||||
}
|
||||
pRenderContext->BindLocalCubemap( pMyCube );
|
||||
|
||||
if ( m_bGroundGrid )
|
||||
{
|
||||
DrawGrid();
|
||||
}
|
||||
|
||||
if ( m_bLookAtCamera )
|
||||
{
|
||||
matrix3x4_t worldToCamera;
|
||||
ComputeCameraTransform( &worldToCamera );
|
||||
|
||||
Vector vecPosition;
|
||||
MatrixGetColumn( worldToCamera, 3, vecPosition );
|
||||
m_RootMDL.m_MDL.m_bWorldSpaceViewTarget = true;
|
||||
m_RootMDL.m_MDL.m_vecViewTarget = vecPosition;
|
||||
}
|
||||
|
||||
Draw();
|
||||
|
||||
if ( m_bDrawCollisionModel )
|
||||
{
|
||||
DrawCollisionModel();
|
||||
}
|
||||
|
||||
if ( IsPaint3dForRenderCapture() )
|
||||
{
|
||||
// We are finished rendering into flashlight buffer
|
||||
}
|
||||
else if ( GetRenderingWithFlashlightConfiguration() )
|
||||
{
|
||||
// Clear all shadow state that we configured and used now
|
||||
g_pStudioRender->ClearAllShadows();
|
||||
}
|
||||
|
||||
pRenderContext->Flush();
|
||||
StudioRender()->UpdateConfig( oldStudioRenderConfig );
|
||||
}
|
||||
|
||||
void CMDLPanel::OnModelDrawPassStart( int iPass, CStudioHdr *pStudioHdr, int &nFlags )
|
||||
{
|
||||
if ( IsPaint3dForRenderCapture() )
|
||||
nFlags |= STUDIORENDER_SHADOWDEPTHTEXTURE;
|
||||
else if ( GetRenderingWithFlashlightConfiguration() )
|
||||
nFlags &=~STUDIORENDER_DRAW_NO_SHADOWS;
|
||||
}
|
||||
|
||||
void CMDLPanel::OnModelDrawPassFinished( int iPass, CStudioHdr *pStudioHdr, int &nFlags )
|
||||
{
|
||||
}
|
||||
|
||||
void CMDLPanel::OnPostSetUpBonesPreDraw()
|
||||
{
|
||||
bool bFlashlightPosKnown = false;
|
||||
Vector vecPositionFlashlight;
|
||||
QAngle anglesFlashlight;
|
||||
|
||||
bool bCameraPosKnown = false;
|
||||
Vector vecPositionCamera;
|
||||
QAngle anglesCamera;
|
||||
|
||||
if ( m_iRenderCaptureCameraAttachment >= 0 )
|
||||
{
|
||||
matrix3x4_t camera;
|
||||
if ( GetAttachment( m_iRenderCaptureCameraAttachment+1, camera ) )
|
||||
{
|
||||
Vector vecPosition;
|
||||
QAngle angles;
|
||||
|
||||
MatrixPosition( camera, vecPosition );
|
||||
MatrixAngles( camera, angles );
|
||||
|
||||
bFlashlightPosKnown = true;
|
||||
vecPositionFlashlight = vecPosition;
|
||||
anglesFlashlight = angles;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_iCameraAttachment >= 0 )
|
||||
{
|
||||
matrix3x4_t camera;
|
||||
if ( GetAttachment( m_iCameraAttachment+1, camera ) )
|
||||
{
|
||||
Vector vecPosition;
|
||||
QAngle angles;
|
||||
|
||||
MatrixPosition( camera, vecPosition );
|
||||
MatrixAngles( camera, angles );
|
||||
|
||||
bCameraPosKnown = true;
|
||||
vecPositionCamera = vecPosition;
|
||||
anglesCamera = angles;
|
||||
|
||||
if ( IsCameraPositionOverrideEnabled() )
|
||||
{
|
||||
vecPositionCamera += m_vecCameraPositionOverride;
|
||||
}
|
||||
|
||||
if ( !bFlashlightPosKnown )
|
||||
{
|
||||
// DEBUG: move light off from the actual camera
|
||||
Vector basisUp, basisRight, basisForward;
|
||||
AngleVectors( angles, &basisForward, &basisRight, &basisUp );
|
||||
|
||||
float flCycle0to1 = ( m_RootMDL.m_MDL.m_flTime - floor( m_RootMDL.m_MDL.m_flTime ) );
|
||||
float flDistance = 1.0f + ( flCycle0to1 - 0.5f ) * ( flCycle0to1 - 0.5f ) * 4 * 9;
|
||||
vecPosition += basisUp * flDistance;
|
||||
|
||||
bFlashlightPosKnown = true;
|
||||
vecPositionFlashlight = vecPosition;
|
||||
anglesFlashlight = angles;
|
||||
}
|
||||
|
||||
if ( IsCameraOrientOverrideEnabled() )
|
||||
{
|
||||
anglesCamera.x += m_vecCameraOrientOverride.x;
|
||||
anglesCamera.y += m_vecCameraOrientOverride.y;
|
||||
anglesCamera.z += m_vecCameraOrientOverride.z;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( bFlashlightPosKnown && GetRenderingWithFlashlightConfiguration() != NULL )
|
||||
{
|
||||
CRenderCaptureConfigurationState *pFlashlightInfo = reinterpret_cast< CRenderCaptureConfigurationState * >( GetRenderingWithFlashlightConfiguration() );
|
||||
|
||||
//
|
||||
// Update flashlight position
|
||||
//
|
||||
{
|
||||
pFlashlightInfo->m_renderFlashlightState.m_vecLightOrigin = vecPositionFlashlight;
|
||||
AngleQuaternion( anglesFlashlight, pFlashlightInfo->m_renderFlashlightState.m_quatOrientation );
|
||||
}
|
||||
|
||||
//
|
||||
// Build world to shadow matrix, then perspective projection and concatenate
|
||||
//
|
||||
{
|
||||
VMatrix matWorldToShadowView, matPerspective;
|
||||
matrix3x4_t matOrientation;
|
||||
QuaternionMatrix( pFlashlightInfo->m_renderFlashlightState.m_quatOrientation, matOrientation ); // Convert quat to matrix3x4
|
||||
PositionMatrix( vec3_origin, matOrientation ); // Zero out translation elements
|
||||
|
||||
VMatrix matBasis( matOrientation ); // Convert matrix3x4 to VMatrix
|
||||
|
||||
Vector vForward, vLeft, vUp;
|
||||
matBasis.GetBasisVectors( vForward, vLeft, vUp );
|
||||
matBasis.SetForward( vLeft ); // Bizarre vector flip inherited from earlier code, WTF?
|
||||
matBasis.SetLeft( vUp );
|
||||
matBasis.SetUp( vForward );
|
||||
matWorldToShadowView = matBasis.Transpose(); // Transpose
|
||||
|
||||
Vector translation;
|
||||
Vector3DMultiply( matWorldToShadowView, pFlashlightInfo->m_renderFlashlightState.m_vecLightOrigin, translation );
|
||||
|
||||
translation *= -1.0f;
|
||||
matWorldToShadowView.SetTranslation( translation );
|
||||
|
||||
// The the bottom row.
|
||||
matWorldToShadowView[3][0] = matWorldToShadowView[3][1] = matWorldToShadowView[3][2] = 0.0f;
|
||||
matWorldToShadowView[3][3] = 1.0f;
|
||||
|
||||
MatrixBuildPerspective( matPerspective, pFlashlightInfo->m_renderFlashlightState.m_fHorizontalFOVDegrees,
|
||||
pFlashlightInfo->m_renderFlashlightState.m_fVerticalFOVDegrees,
|
||||
pFlashlightInfo->m_renderFlashlightState.m_NearZ, pFlashlightInfo->m_renderFlashlightState.m_FarZ );
|
||||
|
||||
MatrixMultiply( matPerspective, matWorldToShadowView, pFlashlightInfo->m_renderMatrixWorldToShadow );
|
||||
}
|
||||
}
|
||||
|
||||
for ( int j = 0; j < ( int ) MIN( m_LightingState.m_nLocalLightCount, Q_ARRAYSIZE( m_iDirectionalLightAttachments ) ); ++ j )
|
||||
{
|
||||
if ( m_iDirectionalLightAttachments[j] >= 0 )
|
||||
{
|
||||
matrix3x4_t camera;
|
||||
if ( GetAttachment( m_iDirectionalLightAttachments[j]+1, camera ) )
|
||||
{
|
||||
Vector vecPosition;
|
||||
QAngle angles;
|
||||
|
||||
MatrixPosition( camera, vecPosition );
|
||||
MatrixAngles( camera, angles );
|
||||
|
||||
Vector vecForward;
|
||||
AngleVectors( angles, &vecForward );
|
||||
m_LightingState.m_pLocalLightDesc[j].m_Direction = vecForward;
|
||||
m_LightingState.m_pLocalLightDesc[j].RecalculateDerivedValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( IsPaint3dForRenderCapture() )
|
||||
{
|
||||
Assert( bFlashlightPosKnown );
|
||||
CRenderCaptureConfigurationState *pFlashlightInfo = reinterpret_cast< CRenderCaptureConfigurationState * >( GetRenderingWithFlashlightConfiguration() );
|
||||
SetCameraPositionAndAngles( vecPositionFlashlight, anglesFlashlight );
|
||||
|
||||
Camera_t &cameraSettings = GetCameraSettings();
|
||||
float flZnear = cameraSettings.m_flZNear, flZfar = cameraSettings.m_flZFar;
|
||||
cameraSettings.m_flZNear = pFlashlightInfo->m_renderFlashlightState.m_NearZ;
|
||||
cameraSettings.m_flZFar = pFlashlightInfo->m_renderFlashlightState.m_FarZ;
|
||||
SetupRenderStateDelayed(); // Configure view with the updated camera settings and restore Z planes
|
||||
cameraSettings.m_flZNear = flZnear, cameraSettings.m_flZFar = flZfar;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bCameraPosKnown )
|
||||
{
|
||||
SetCameraPositionAndAngles( vecPositionCamera, anglesCamera );
|
||||
}
|
||||
SetupRenderStateDelayed();
|
||||
if ( GetRenderingWithFlashlightConfiguration() )
|
||||
{
|
||||
Assert( bFlashlightPosKnown );
|
||||
// Add the shadow we rendered in previous pass to our model
|
||||
CRenderCaptureConfigurationState *pFlashlightInfo = reinterpret_cast< CRenderCaptureConfigurationState * >( GetRenderingWithFlashlightConfiguration() );
|
||||
g_pStudioRender->AddShadow( NULL, NULL, &pFlashlightInfo->m_renderFlashlightState, &pFlashlightInfo->m_renderMatrixWorldToShadow, pFlashlightInfo->m_pFlashlightDepthTexture );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// called when we're ticked...
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
float flCurrentTime = GetAutoPlayTime();
|
||||
float flMdlTime = flCurrentTime - m_flAutoPlayTimeBase;
|
||||
m_flAutoPlayTimeBase = flCurrentTime;
|
||||
if ( m_RootMDL.m_MDL.GetMDL() != MDLHANDLE_INVALID && !m_bAnimationPause )
|
||||
{
|
||||
m_RootMDL.m_MDL.AdjustTime( flMdlTime );
|
||||
}
|
||||
for ( int k = 0; k < m_aMergeMDLs.Count(); ++ k )
|
||||
{
|
||||
if ( m_aMergeMDLs[k].m_MDL.GetMDL() != MDLHANDLE_INVALID && !m_bAnimationPause )
|
||||
{
|
||||
m_aMergeMDLs[k].m_MDL.AdjustTime( flMdlTime );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// input
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPanel::OnMouseDoublePressed( vgui::MouseCode code )
|
||||
{
|
||||
float flRadius;
|
||||
Vector vecCenter;
|
||||
GetBoundingSphere( vecCenter, flRadius );
|
||||
LookAt( vecCenter, flRadius );
|
||||
|
||||
BaseClass::OnMouseDoublePressed( code );
|
||||
}
|
||||
|
||||
|
||||
788
vgui2/matsys_controls/mdlpicker.cpp
Normal file
788
vgui2/matsys_controls/mdlpicker.cpp
Normal file
@@ -0,0 +1,788 @@
|
||||
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/mdlpicker.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "tier1/utldict.h"
|
||||
#include "filesystem.h"
|
||||
#include "studio.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "matsys_controls/mdlpanel.h"
|
||||
#include "vgui_controls/Splitter.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui_controls/PropertySheet.h"
|
||||
#include "vgui_controls/MessageBox.h"
|
||||
#include "vgui_controls/PropertyPage.h"
|
||||
#include "vgui_controls/CheckButton.h"
|
||||
#include "vgui_controls/DirectorySelectDialog.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/Cursor.h"
|
||||
#include "matsys_controls/assetpicker.h"
|
||||
#include "matsys_controls/colorpickerpanel.h"
|
||||
#include "dmxloader/dmxloader.h"
|
||||
#include "utlbuffer.h"
|
||||
#include "bitmap/tgawriter.h"
|
||||
#include "tier3/tier3.h"
|
||||
#include "istudiorender.h"
|
||||
#include "../vgui2/src/VPanel.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// MDL Picker
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sort by MDL name
|
||||
//-----------------------------------------------------------------------------
|
||||
static int __cdecl MDLBrowserSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
|
||||
{
|
||||
const char *string1 = item1.kv->GetString("mdl");
|
||||
const char *string2 = item2.kv->GetString("mdl");
|
||||
return stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDLPicker::CMDLPicker( vgui::Panel *pParent, int nFlags ) :
|
||||
BaseClass( pParent, "MDL Files", "mdl", "models", "mdlName" )
|
||||
{
|
||||
m_hSelectedMDL = MDLHANDLE_INVALID;
|
||||
|
||||
m_nFlags = nFlags; // remember what we show and what not
|
||||
|
||||
m_pRenderPage = NULL;
|
||||
m_pSequencesPage = NULL;
|
||||
m_pActivitiesPage = NULL;
|
||||
m_pSkinsPage = NULL;
|
||||
m_pInfoPage = NULL;
|
||||
|
||||
m_pSequencesList = NULL;
|
||||
m_pActivitiesList = NULL;
|
||||
|
||||
// Horizontal splitter for mdls
|
||||
m_pFileBrowserSplitter = new Splitter( this, "FileBrowserSplitter", SPLITTER_MODE_VERTICAL, 1 );
|
||||
|
||||
float flFractions[] = { 0.33f, 0.67f };
|
||||
|
||||
m_pFileBrowserSplitter->RespaceSplitters( flFractions );
|
||||
|
||||
vgui::Panel *pSplitterLeftSide = m_pFileBrowserSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterRightSide = m_pFileBrowserSplitter->GetChild( 1 );
|
||||
|
||||
// Standard browser controls
|
||||
pSplitterLeftSide->RequestFocus();
|
||||
CreateStandardControls( pSplitterLeftSide, false );
|
||||
|
||||
// property sheet - revisions, changes, etc.
|
||||
m_pPreviewSplitter = new Splitter( pSplitterRightSide, "PreviewSplitter", SPLITTER_MODE_HORIZONTAL, 1 );
|
||||
|
||||
vgui::Panel *pSplitterTopSide = m_pPreviewSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterBottomSide = m_pPreviewSplitter->GetChild( 1 );
|
||||
|
||||
// MDL preview
|
||||
m_pMDLPreview = new CMDLPanel( pSplitterTopSide, "MDLPreview" );
|
||||
SetSkipChildDuringPainting( m_pMDLPreview );
|
||||
|
||||
m_pViewsSheet = new vgui::PropertySheet( pSplitterBottomSide, "ViewsSheet" );
|
||||
m_pViewsSheet->AddActionSignalTarget( this );
|
||||
|
||||
// now add wanted features
|
||||
if ( nFlags & PAGE_RENDER )
|
||||
{
|
||||
m_pRenderPage = new vgui::PropertyPage( m_pViewsSheet, "RenderPage" );
|
||||
|
||||
m_pRenderPage->AddActionSignalTarget( this );
|
||||
|
||||
m_pRenderPage->LoadControlSettingsAndUserConfig( "resource/mdlpickerrender.res" );
|
||||
|
||||
RefreshRenderSettings();
|
||||
|
||||
// ground
|
||||
Button *pSelectProbe = (Button*)m_pRenderPage->FindChildByName( "ChooseLightProbe" );
|
||||
pSelectProbe->AddActionSignalTarget( this );
|
||||
}
|
||||
|
||||
if ( nFlags & PAGE_SEQUENCES )
|
||||
{
|
||||
m_pSequencesPage = new vgui::PropertyPage( m_pViewsSheet, "SequencesPage" );
|
||||
|
||||
m_pSequencesList = new vgui::ListPanel( m_pSequencesPage, "SequencesList" );
|
||||
m_pSequencesList->AddColumnHeader( 0, "sequence", "sequence", 52, 0 );
|
||||
m_pSequencesList->AddActionSignalTarget( this );
|
||||
m_pSequencesList->SetSelectIndividualCells( true );
|
||||
m_pSequencesList->SetEmptyListText("No .MDL file currently selected.");
|
||||
m_pSequencesList->SetDragEnabled( true );
|
||||
m_pSequencesList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 6, 6, -6, -6 );
|
||||
}
|
||||
|
||||
if ( nFlags & PAGE_ACTIVITIES )
|
||||
{
|
||||
m_pActivitiesPage = new vgui::PropertyPage( m_pViewsSheet, "ActivitiesPage" );
|
||||
|
||||
m_pActivitiesList = new vgui::ListPanel( m_pActivitiesPage, "ActivitiesList" );
|
||||
m_pActivitiesList->AddColumnHeader( 0, "activity", "activity", 52, 0 );
|
||||
m_pActivitiesList->AddActionSignalTarget( this );
|
||||
m_pActivitiesList->SetSelectIndividualCells( true );
|
||||
m_pActivitiesList->SetEmptyListText( "No .MDL file currently selected." );
|
||||
m_pActivitiesList->SetDragEnabled( true );
|
||||
m_pActivitiesList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 6, 6, -6, -6 );
|
||||
}
|
||||
|
||||
if ( nFlags & PAGE_SKINS )
|
||||
{
|
||||
m_pSkinsPage = new vgui::PropertyPage( m_pViewsSheet, "SkinsPage" );
|
||||
|
||||
m_pSkinsList = new vgui::ListPanel( m_pSkinsPage, "SkinsList" );
|
||||
m_pSkinsList->AddColumnHeader( 0, "skin", "skin", 52, 0 );
|
||||
m_pSkinsList->AddActionSignalTarget( this );
|
||||
m_pSkinsList->SetSelectIndividualCells( true );
|
||||
m_pSkinsList->SetEmptyListText( "No .MDL file currently selected." );
|
||||
m_pSkinsList->SetDragEnabled( true );
|
||||
m_pSkinsList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 6, 6, -6, -6 );
|
||||
}
|
||||
|
||||
if ( nFlags & PAGE_INFO )
|
||||
{
|
||||
m_pInfoPage = new vgui::PropertyPage( m_pViewsSheet, "InfoPage" );
|
||||
|
||||
m_pInfoPage->AddActionSignalTarget( this );
|
||||
|
||||
m_pInfoPage->LoadControlSettingsAndUserConfig( "resource/mdlpickerinfo.res" );
|
||||
|
||||
CheckButton * pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName( "PhysicsObject" );
|
||||
pTempCheck->SetDisabledFgColor1( pTempCheck->GetFgColor());
|
||||
pTempCheck->SetDisabledFgColor2( pTempCheck->GetFgColor());
|
||||
pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName( "StaticObject" );
|
||||
pTempCheck->SetDisabledFgColor1( pTempCheck->GetFgColor());
|
||||
pTempCheck->SetDisabledFgColor2( pTempCheck->GetFgColor());
|
||||
pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName( "DynamicObject" );
|
||||
pTempCheck->SetDisabledFgColor1( pTempCheck->GetFgColor());
|
||||
pTempCheck->SetDisabledFgColor2( pTempCheck->GetFgColor());
|
||||
|
||||
m_pPropDataList = new vgui::ListPanel( m_pInfoPage, "PropData" );
|
||||
m_pPropDataList->AddColumnHeader( 0, "key", "key", 250, ListPanel::COLUMN_FIXEDSIZE );
|
||||
m_pPropDataList->AddColumnHeader( 1, "value", "value", 52, 0 );
|
||||
m_pPropDataList->AddActionSignalTarget( this );
|
||||
m_pPropDataList->SetSelectIndividualCells( false );
|
||||
m_pPropDataList->SetEmptyListText( "No prop_data available." );
|
||||
m_pPropDataList->SetDragEnabled( true );
|
||||
m_pPropDataList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 6, 72, -6, -6 );
|
||||
|
||||
RefreshRenderSettings();
|
||||
}
|
||||
|
||||
// Load layout settings; has to happen before pinning occurs in code
|
||||
LoadControlSettingsAndUserConfig( "resource/mdlpicker.res" );
|
||||
|
||||
// Pages must be added after control settings are set up
|
||||
if ( m_pRenderPage )
|
||||
{
|
||||
m_pViewsSheet->AddPage( m_pRenderPage, "Render" );
|
||||
}
|
||||
if ( m_pSequencesPage )
|
||||
{
|
||||
m_pViewsSheet->AddPage( m_pSequencesPage, "Sequences" );
|
||||
}
|
||||
if ( m_pActivitiesPage )
|
||||
{
|
||||
m_pViewsSheet->AddPage( m_pActivitiesPage, "Activities" );
|
||||
}
|
||||
if ( m_pSkinsPage )
|
||||
{
|
||||
m_pViewsSheet->AddPage( m_pSkinsPage, "Skins" );
|
||||
}
|
||||
if ( m_pInfoPage )
|
||||
{
|
||||
m_pViewsSheet->AddPage( m_pInfoPage, "Info" );
|
||||
}
|
||||
}
|
||||
|
||||
void CMDLPicker::RefreshRenderSettings()
|
||||
{
|
||||
vgui::CheckButton *pToggle;
|
||||
|
||||
if ( !m_pRenderPage )
|
||||
return;
|
||||
|
||||
// ground
|
||||
pToggle = (vgui::CheckButton*)m_pRenderPage->FindChildByName("NoGround");
|
||||
pToggle->AddActionSignalTarget( this );
|
||||
m_pMDLPreview->SetGroundGrid( !pToggle->IsSelected() );
|
||||
|
||||
// collision
|
||||
pToggle = (vgui::CheckButton*)m_pRenderPage->FindChildByName("Collision");
|
||||
pToggle->AddActionSignalTarget( this );
|
||||
m_pMDLPreview->SetCollsionModel( pToggle->IsSelected() );
|
||||
|
||||
// wireframe
|
||||
pToggle = (vgui::CheckButton*)m_pRenderPage->FindChildByName("Wireframe");
|
||||
pToggle->AddActionSignalTarget( this );
|
||||
m_pMDLPreview->SetWireFrame( pToggle->IsSelected() );
|
||||
|
||||
// lockview
|
||||
pToggle = (vgui::CheckButton*)m_pRenderPage->FindChildByName("LockView");
|
||||
pToggle->AddActionSignalTarget( this );
|
||||
m_pMDLPreview->SetLockView( pToggle->IsSelected() );
|
||||
|
||||
// look at camera
|
||||
pToggle = (vgui::CheckButton*)m_pRenderPage->FindChildByName("LookAtCamera");
|
||||
pToggle->AddActionSignalTarget( this );
|
||||
m_pMDLPreview->SetLookAtCamera( pToggle->IsSelected() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDLPicker::~CMDLPicker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Performs layout
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPicker::PerformLayout()
|
||||
{
|
||||
// NOTE: This call should cause auto-resize to occur
|
||||
// which should fix up the width of the panels
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
// Layout the mdl splitter
|
||||
m_pFileBrowserSplitter->SetBounds( 0, 0, w, h );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Buttons on various pages
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPicker::OnAssetSelected( KeyValues *pParams )
|
||||
{
|
||||
const char *pAsset = pParams->GetString( "asset" );
|
||||
|
||||
char pProbeBuf[MAX_PATH];
|
||||
Q_snprintf( pProbeBuf, sizeof(pProbeBuf), "materials/lightprobes/%s", pAsset );
|
||||
|
||||
BeginDMXContext();
|
||||
CDmxElement *pLightProbe = NULL;
|
||||
bool bOk = UnserializeDMX( pProbeBuf, "GAME", true, &pLightProbe );
|
||||
if ( !pLightProbe || !bOk )
|
||||
{
|
||||
char pBuf[1024];
|
||||
Q_snprintf( pBuf, sizeof(pBuf), "Error loading lightprobe file '%s'!\n", pProbeBuf );
|
||||
vgui::MessageBox *pMessageBox = new vgui::MessageBox( "Error Loading File!\n", pBuf, GetParent() );
|
||||
pMessageBox->DoModal( );
|
||||
|
||||
EndDMXContext( true );
|
||||
return;
|
||||
}
|
||||
|
||||
m_pMDLPreview->SetLightProbe( pLightProbe );
|
||||
EndDMXContext( true );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Buttons on various pages
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPicker::OnCommand( const char *pCommand )
|
||||
{
|
||||
if ( !Q_stricmp( pCommand, "ChooseLightProbe" ) )
|
||||
{
|
||||
CAssetPickerFrame *pPicker = new CAssetPickerFrame( this, "Select Light Probe (.prb) File",
|
||||
"Light Probe", "prb", "materials/lightprobes", "lightprobe" );
|
||||
pPicker->DoModal();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: rebuilds the list of activities
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPicker::RefreshActivitiesAndSequencesList()
|
||||
{
|
||||
m_pActivitiesList->RemoveAll();
|
||||
m_pSequencesList->RemoveAll();
|
||||
m_pMDLPreview->SetSequence( 0, false );
|
||||
|
||||
if ( m_hSelectedMDL == MDLHANDLE_INVALID )
|
||||
{
|
||||
m_pActivitiesList->SetEmptyListText("No .MDL file currently selected");
|
||||
m_pSequencesList->SetEmptyListText("No .MDL file currently selected");
|
||||
return;
|
||||
}
|
||||
|
||||
m_pActivitiesList->SetEmptyListText(".MDL file contains no activities");
|
||||
m_pSequencesList->SetEmptyListText(".MDL file contains no sequences");
|
||||
|
||||
studiohdr_t *hdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
|
||||
CUtlDict<int, unsigned short> activityNames( true, 0, hdr->GetNumSeq() );
|
||||
|
||||
for (int j = 0; j < hdr->GetNumSeq(); j++)
|
||||
{
|
||||
if ( /*g_viewerSettings.showHidden ||*/ !(hdr->pSeqdesc(j).flags & STUDIO_HIDDEN))
|
||||
{
|
||||
const char *pActivityName = hdr->pSeqdesc(j).pszActivityName();
|
||||
if ( pActivityName && pActivityName[0] )
|
||||
{
|
||||
// Multiple sequences can have the same activity name; only add unique activity names
|
||||
if ( activityNames.Find( pActivityName ) == activityNames.InvalidIndex() )
|
||||
{
|
||||
KeyValues *pkv = new KeyValues("node", "activity", pActivityName );
|
||||
int nItemID = m_pActivitiesList->AddItem( pkv, 0, false, false );
|
||||
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", pActivityName );
|
||||
pDrag->SetString( "texttype", "activityName" );
|
||||
pDrag->SetString( "mdl", vgui::MDLCache()->GetModelName( m_hSelectedMDL ) );
|
||||
m_pActivitiesList->SetItemDragData( nItemID, pDrag );
|
||||
|
||||
activityNames.Insert( pActivityName, j );
|
||||
}
|
||||
}
|
||||
|
||||
const char *pSequenceName = hdr->pSeqdesc(j).pszLabel();
|
||||
if ( pSequenceName && pSequenceName[0] )
|
||||
{
|
||||
KeyValues *pkv = new KeyValues("node", "sequence", pSequenceName);
|
||||
int nItemID = m_pSequencesList->AddItem( pkv, 0, false, false );
|
||||
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", pSequenceName );
|
||||
pDrag->SetString( "texttype", "sequenceName" );
|
||||
pDrag->SetString( "mdl", vgui::MDLCache()->GetModelName( m_hSelectedMDL ) );
|
||||
m_pSequencesList->SetItemDragData( nItemID, pDrag );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A MDL was selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPicker::OnSelectedAssetPicked( const char *pMDLName )
|
||||
{
|
||||
char pRelativePath[MAX_PATH];
|
||||
if ( pMDLName )
|
||||
{
|
||||
Q_snprintf( pRelativePath, sizeof(pRelativePath), "models\\%s", pMDLName );
|
||||
SelectMDL( pRelativePath );
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectMDL( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Allows external apps to select a MDL
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPicker::SelectMDL( const char *pRelativePath )
|
||||
{
|
||||
MDLHandle_t hSelectedMDL = pRelativePath ? vgui::MDLCache()->FindMDL( pRelativePath ) : MDLHANDLE_INVALID;
|
||||
|
||||
// We didn't change models after all...
|
||||
if ( hSelectedMDL == m_hSelectedMDL )
|
||||
{
|
||||
// vgui::MDLCache()->FindMDL adds a reference by default we don't use, release it again
|
||||
if ( hSelectedMDL != MDLHANDLE_INVALID )
|
||||
{
|
||||
vgui::MDLCache()->Release( hSelectedMDL );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_hSelectedMDL = hSelectedMDL;
|
||||
|
||||
if ( vgui::MDLCache()->IsErrorModel( m_hSelectedMDL ) )
|
||||
{
|
||||
m_hSelectedMDL = MDLHANDLE_INVALID;
|
||||
}
|
||||
m_pMDLPreview->SetMDL( m_hSelectedMDL );
|
||||
|
||||
m_pMDLPreview->LookAtMDL();
|
||||
|
||||
|
||||
if ( m_nFlags & ( PAGE_SKINS ) )
|
||||
{
|
||||
UpdateSkinsList();
|
||||
}
|
||||
|
||||
if ( m_nFlags & ( PAGE_INFO ) )
|
||||
{
|
||||
UpdateInfoTab();
|
||||
}
|
||||
|
||||
if ( m_nFlags & (PAGE_ACTIVITIES|PAGE_SEQUENCES) )
|
||||
{
|
||||
RefreshActivitiesAndSequencesList();
|
||||
}
|
||||
|
||||
// vgui::MDLCache()->FindMDL adds a reference by default we don't use, release it again
|
||||
if ( hSelectedMDL != MDLHANDLE_INVALID )
|
||||
{
|
||||
vgui::MDLCache()->Release( hSelectedMDL );
|
||||
}
|
||||
|
||||
PostActionSignal( new KeyValues( "MDLPreviewChanged", "mdl", pRelativePath ? pRelativePath : "" ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: updates revision view on a file being selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPicker::OnCheckButtonChecked(KeyValues *kv)
|
||||
{
|
||||
// RefreshMDLList();
|
||||
BaseClass::OnCheckButtonChecked( kv );
|
||||
RefreshRenderSettings();
|
||||
}
|
||||
|
||||
|
||||
void CMDLPicker::GetSelectedMDLName( char *pBuffer, int nMaxLen )
|
||||
{
|
||||
Assert( nMaxLen > 0 );
|
||||
if ( GetSelectedAssetCount() > 0 )
|
||||
{
|
||||
Q_snprintf( pBuffer, nMaxLen, "models\\%s", GetSelectedAsset( ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pBuffer[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the selected activity/sequence
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMDLPicker::GetSelectedPage( )
|
||||
{
|
||||
if ( m_pSequencesPage && ( m_pViewsSheet->GetActivePage() == m_pSequencesPage ) )
|
||||
return PAGE_SEQUENCES;
|
||||
|
||||
if ( m_pActivitiesPage && ( m_pViewsSheet->GetActivePage() == m_pActivitiesPage ) )
|
||||
return PAGE_ACTIVITIES;
|
||||
|
||||
return PAGE_NONE;
|
||||
}
|
||||
|
||||
const char *CMDLPicker::GetSelectedSequenceName()
|
||||
{
|
||||
if ( !m_pSequencesPage )
|
||||
return NULL;
|
||||
|
||||
int nIndex = m_pSequencesList->GetSelectedItem( 0 );
|
||||
if ( nIndex >= 0 )
|
||||
{
|
||||
KeyValues *pkv = m_pSequencesList->GetItem( nIndex );
|
||||
return pkv->GetString( "sequence", NULL );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *CMDLPicker::GetSelectedActivityName()
|
||||
{
|
||||
if ( !m_pActivitiesPage )
|
||||
return NULL;
|
||||
|
||||
int nIndex = m_pActivitiesList->GetSelectedItem( 0 );
|
||||
if ( nIndex >= 0 )
|
||||
{
|
||||
KeyValues *pkv = m_pActivitiesList->GetItem( nIndex );
|
||||
return pkv->GetString( "activity", NULL );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CMDLPicker::GetSelectedSkin()
|
||||
{
|
||||
if ( !m_pSkinsPage )
|
||||
return NULL;
|
||||
|
||||
int nIndex = m_pSkinsList->GetSelectedItem( 0 );
|
||||
if ( nIndex >= 0 )
|
||||
{
|
||||
return nIndex;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plays the selected activity
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPicker::SelectActivity( const char *pActivityName )
|
||||
{
|
||||
studiohdr_t *pstudiohdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
for ( int i = 0; i < pstudiohdr->GetNumSeq(); i++ )
|
||||
{
|
||||
mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i );
|
||||
if ( stricmp( seqdesc.pszActivityName(), pActivityName ) == 0 )
|
||||
{
|
||||
// FIXME: Add weighted sequence selection logic?
|
||||
m_pMDLPreview->SetSequence( i, false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PostActionSignal( new KeyValues( "SequenceSelectionChanged", "activity", pActivityName ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plays the selected sequence
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPicker::SelectSequence( const char *pSequenceName )
|
||||
{
|
||||
studiohdr_t *pstudiohdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
for (int i = 0; i < pstudiohdr->GetNumSeq(); i++)
|
||||
{
|
||||
mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i );
|
||||
if ( !Q_stricmp( seqdesc.pszLabel(), pSequenceName ) )
|
||||
{
|
||||
m_pMDLPreview->SetSequence( i, false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PostActionSignal( new KeyValues( "SequenceSelectionChanged", "sequence", pSequenceName ) );
|
||||
}
|
||||
|
||||
void CMDLPicker::SelectSkin( int nSkin )
|
||||
{
|
||||
m_pMDLPreview->SetSkin( nSkin );
|
||||
PostActionSignal( new KeyValues( "SkinSelectionChanged", "skin", nSkin));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Updates preview when an item is selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPicker::OnItemSelected( KeyValues *kv )
|
||||
{
|
||||
Panel *pPanel = (Panel *)kv->GetPtr("panel", NULL);
|
||||
if ( m_pSequencesList && (pPanel == m_pSequencesList ) )
|
||||
{
|
||||
const char *pSequenceName = GetSelectedSequenceName();
|
||||
if ( pSequenceName )
|
||||
{
|
||||
SelectSequence( pSequenceName );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_pActivitiesList && ( pPanel == m_pActivitiesList ) )
|
||||
{
|
||||
const char *pActivityName = GetSelectedActivityName();
|
||||
if ( pActivityName )
|
||||
{
|
||||
SelectActivity( pActivityName );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_pSkinsList && ( pPanel == m_pSkinsList ) )
|
||||
{
|
||||
int nSelectedSkin = GetSelectedSkin();
|
||||
SelectSkin( nSelectedSkin );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnItemSelected( kv );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when a page is shown
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPicker::OnPageChanged( )
|
||||
{
|
||||
if ( m_pSequencesPage && ( m_pViewsSheet->GetActivePage() == m_pSequencesPage ) )
|
||||
{
|
||||
m_pSequencesList->RequestFocus();
|
||||
|
||||
const char *pSequenceName = GetSelectedSequenceName();
|
||||
|
||||
if ( pSequenceName )
|
||||
{
|
||||
SelectSequence( pSequenceName );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_pActivitiesPage && ( m_pViewsSheet->GetActivePage() == m_pActivitiesPage ) )
|
||||
{
|
||||
m_pActivitiesList->RequestFocus();
|
||||
|
||||
const char *pActivityName = GetSelectedActivityName();
|
||||
|
||||
if ( pActivityName )
|
||||
{
|
||||
SelectActivity( pActivityName );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDLPickerFrame::CMDLPickerFrame( vgui::Panel *pParent, const char *pTitle, int nFlags ) :
|
||||
BaseClass( pParent )
|
||||
{
|
||||
SetAssetPicker( new CMDLPicker( this, nFlags ) );
|
||||
LoadControlSettingsAndUserConfig( "resource/mdlpickerframe.res" );
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
CMDLPickerFrame::~CMDLPickerFrame()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Allows external apps to select a MDL
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLPickerFrame::SelectMDL( const char *pRelativePath )
|
||||
{
|
||||
static_cast<CMDLPicker*>( GetAssetPicker() )->SelectMDL( pRelativePath );
|
||||
}
|
||||
|
||||
int CMDLPicker::UpdateSkinsList()
|
||||
{
|
||||
int nNumSkins = 0;
|
||||
|
||||
if ( m_pSkinsList )
|
||||
{
|
||||
m_pSkinsList->RemoveAll();
|
||||
|
||||
studiohdr_t *hdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
if ( hdr )
|
||||
{
|
||||
nNumSkins = hdr->numskinfamilies;
|
||||
for ( int i = 0; i < nNumSkins; i++ )
|
||||
{
|
||||
char skinText[25] = "";
|
||||
sprintf( skinText, "skin%i", i );
|
||||
KeyValues *pkv = new KeyValues("node", "skin", skinText );
|
||||
m_pSkinsList->AddItem( pkv, 0, false, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nNumSkins;
|
||||
}
|
||||
|
||||
void CMDLPicker::UpdateInfoTab()
|
||||
{
|
||||
studiohdr_t *hdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
if ( !hdr )
|
||||
return;
|
||||
|
||||
int nMass = hdr->mass;
|
||||
Panel *pTempPanel = m_pInfoPage->FindChildByName("MassValue");
|
||||
char massBuff[10];
|
||||
Q_snprintf( massBuff, 10, "%d", nMass );
|
||||
((vgui::Label *)pTempPanel)->SetText( massBuff );
|
||||
bool bIsStatic = ( hdr->flags & STUDIOHDR_FLAGS_STATIC_PROP ) ? true : false;
|
||||
bool bIsPhysics = false;
|
||||
|
||||
Label *pTempLabel = (Label *)m_pInfoPage->FindChildByName("StaticText");
|
||||
pTempLabel->SetVisible( false );
|
||||
|
||||
KeyValues *pkvModelKeys = new KeyValues( "modelkeys" );
|
||||
pkvModelKeys->LoadFromBuffer( "modelkeys", hdr->KeyValueText() );
|
||||
|
||||
KeyValues *kvPropData = pkvModelKeys->FindKey( "prop_data" );
|
||||
if ( kvPropData )
|
||||
{
|
||||
int iPropDataCount = UpdatePropDataList( kvPropData, bIsStatic );
|
||||
if( iPropDataCount )
|
||||
{
|
||||
bIsPhysics = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pPropDataList->RemoveAll();
|
||||
}
|
||||
|
||||
pkvModelKeys->deleteThis();
|
||||
|
||||
CheckButton * pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName("StaticObject");
|
||||
pTempCheck->SetCheckButtonCheckable( true );
|
||||
pTempCheck->SetSelected( bIsStatic );
|
||||
pTempCheck->SetCheckButtonCheckable( false );
|
||||
pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName("PhysicsObject");
|
||||
pTempCheck->SetCheckButtonCheckable( true );
|
||||
pTempCheck->SetSelected( bIsPhysics );
|
||||
pTempCheck->SetCheckButtonCheckable( false );
|
||||
pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName("DynamicObject");
|
||||
pTempCheck->SetCheckButtonCheckable( true );
|
||||
pTempCheck->SetSelected( !bIsPhysics );
|
||||
pTempCheck->SetCheckButtonCheckable( false );
|
||||
}
|
||||
|
||||
|
||||
int CMDLPicker::UpdatePropDataList( KeyValues *pkvPropData, bool &bIsStatic )
|
||||
{
|
||||
int iCount = 0;
|
||||
|
||||
if ( m_pPropDataList )
|
||||
{
|
||||
m_pPropDataList->RemoveAll();
|
||||
|
||||
KeyValues *kvItem = pkvPropData->GetFirstSubKey();
|
||||
while ( kvItem )
|
||||
{
|
||||
if ( kvItem->GetDataType() != KeyValues::TYPE_NONE )
|
||||
{
|
||||
// Special handling for some keys
|
||||
if ( !Q_strcmp( kvItem->GetName(), "allowstatic" ) && !Q_strcmp( kvItem->GetString() , "1" ) )
|
||||
{
|
||||
if ( !bIsStatic )
|
||||
{
|
||||
Label *pTempLabel = (Label *)m_pInfoPage->FindChildByName( "StaticText" );
|
||||
pTempLabel->SetVisible( true );
|
||||
}
|
||||
bIsStatic &= true;
|
||||
}
|
||||
|
||||
KeyValues *pkv = new KeyValues("node", "key", kvItem->GetName(), "value", kvItem->GetString() );
|
||||
m_pPropDataList->AddItem( pkv, 0, false, false );
|
||||
iCount++;
|
||||
}
|
||||
|
||||
kvItem = kvItem->GetNextKey();
|
||||
}
|
||||
}
|
||||
|
||||
return iCount;
|
||||
}
|
||||
539
vgui2/matsys_controls/mdlsequencepicker.cpp
Normal file
539
vgui2/matsys_controls/mdlsequencepicker.cpp
Normal file
@@ -0,0 +1,539 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "matsys_controls/mdlsequencepicker.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "tier1/utldict.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "filesystem.h"
|
||||
#include "studio.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui/Cursor.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui_controls/Splitter.h"
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "vgui_controls/PropertySheet.h"
|
||||
#include "vgui_controls/PropertyPage.h"
|
||||
#include "vgui_controls/ToolWindow.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "matsys_controls/gamefiletreeview.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// MDL Sequence Picker
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDLSequencePicker::CMDLSequencePicker( vgui::Panel *pParent ) : BaseClass(pParent, "MDLSequencePicker"), m_Images(false)
|
||||
{
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
|
||||
m_hSelectedMDL = MDLHANDLE_INVALID;
|
||||
|
||||
// Horizontal splitter for mdls
|
||||
m_pMDLSplitter = new Splitter( this, "MDLSplitter", SPLITTER_MODE_VERTICAL, 1 );
|
||||
|
||||
vgui::Panel *pSplitterLeftSide = m_pMDLSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterRightSide = m_pMDLSplitter->GetChild( 1 );
|
||||
|
||||
// filter selection
|
||||
m_pFilterList = new ComboBox( pSplitterLeftSide, "FilterList", 16, true );
|
||||
m_pFilterList->AddActionSignalTarget( this );
|
||||
|
||||
// file browser tree controls
|
||||
m_pFileTree = new CGameFileTreeView( pSplitterLeftSide, "FileTree", "All .MDLs", "models", "mdl" );
|
||||
|
||||
// build our list of images
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder", false ) );
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_folder_selected", false ) );
|
||||
m_Images.AddImage( scheme()->GetImage( "resource/icon_file", false ) );
|
||||
m_pFileTree->SetImageList( &m_Images, false );
|
||||
m_pFileTree->AddActionSignalTarget( this );
|
||||
|
||||
// property sheet - revisions, changes, etc.
|
||||
m_pSequenceSplitter = new Splitter( pSplitterRightSide, "SequenceSplitter", SPLITTER_MODE_HORIZONTAL, 1 );
|
||||
|
||||
vgui::Panel *pSplitterTopSide = m_pSequenceSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterBottomSide = m_pSequenceSplitter->GetChild( 1 );
|
||||
|
||||
// MDL preview
|
||||
m_pMDLPreview = new CMDLPanel( pSplitterTopSide, "MDLPreview" );
|
||||
SetSkipChildDuringPainting( m_pMDLPreview );
|
||||
|
||||
m_pViewsSheet = new vgui::PropertySheet( pSplitterBottomSide, "ViewsSheet" );
|
||||
m_pViewsSheet->AddActionSignalTarget( this );
|
||||
|
||||
// sequences
|
||||
m_pSequencesPage = new PropertyPage( m_pViewsSheet, "SequencesPage" );
|
||||
m_pViewsSheet->AddPage( m_pSequencesPage, "Sequences" );
|
||||
m_pSequencesList = new ListPanel( m_pSequencesPage, "SequencesList" );
|
||||
m_pSequencesList->AddColumnHeader( 0, "sequence", "sequence", 52, 0 );
|
||||
m_pSequencesList->AddActionSignalTarget( this );
|
||||
m_pSequencesList->SetSelectIndividualCells( true );
|
||||
m_pSequencesList->SetEmptyListText("No .MDL file currently selected.");
|
||||
m_pSequencesList->SetDragEnabled( true );
|
||||
m_pSequencesList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 0, 0, 0, 0 );
|
||||
|
||||
// Activities
|
||||
m_pActivitiesPage = new PropertyPage( m_pViewsSheet, "ActivitiesPage" );
|
||||
m_pViewsSheet->AddPage( m_pActivitiesPage, "Activities" );
|
||||
m_pActivitiesList = new ListPanel( m_pActivitiesPage, "ActivitiesList" );
|
||||
m_pActivitiesList->AddColumnHeader( 0, "activity", "activity", 52, 0 );
|
||||
m_pActivitiesList->AddActionSignalTarget( this );
|
||||
m_pActivitiesList->SetSelectIndividualCells( true );
|
||||
m_pActivitiesList->SetEmptyListText( "No .MDL file currently selected." );
|
||||
m_pActivitiesList->SetDragEnabled( true );
|
||||
m_pActivitiesList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 0, 0, 0, 0 );
|
||||
|
||||
// Load layout settings; has to happen before pinning occurs in code
|
||||
LoadControlSettingsAndUserConfig( "resource/mdlsequencepicker.res" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDLSequencePicker::~CMDLSequencePicker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is a bit of a hack to make sure that the ToolWindow containing this picker punches
|
||||
// a hold for the rendering viewport, too
|
||||
// Input : -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
if ( GetParent() )
|
||||
{
|
||||
ToolWindow *tw = dynamic_cast< ToolWindow * >( GetParent()->GetParent() );
|
||||
|
||||
if ( tw )
|
||||
{
|
||||
tw->SetSkipChildDuringPainting( IsVisible() ? m_pMDLPreview : NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: stops app on close
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnClose()
|
||||
{
|
||||
BaseClass::OnClose();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called to open
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::Activate()
|
||||
{
|
||||
RefreshFileList();
|
||||
RefreshActivitiesAndSequencesList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Performs layout
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::PerformLayout()
|
||||
{
|
||||
// NOTE: This call should cause auto-resize to occur
|
||||
// which should fix up the width of the panels
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
|
||||
// Layout the mdl splitter
|
||||
m_pMDLSplitter->SetBounds( 0, 0, w, h );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Refreshes the active file list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::RefreshFileList()
|
||||
{
|
||||
m_pFileTree->RefreshFileList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: rebuilds the list of activities
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::RefreshActivitiesAndSequencesList()
|
||||
{
|
||||
m_pActivitiesList->RemoveAll();
|
||||
m_pSequencesList->RemoveAll();
|
||||
m_pMDLPreview->SetSequence( 0, false );
|
||||
|
||||
if ( m_hSelectedMDL == MDLHANDLE_INVALID )
|
||||
{
|
||||
m_pActivitiesList->SetEmptyListText("No .MDL file currently selected");
|
||||
m_pSequencesList->SetEmptyListText("No .MDL file currently selected");
|
||||
return;
|
||||
}
|
||||
|
||||
m_pActivitiesList->SetEmptyListText(".MDL file contains no activities");
|
||||
m_pSequencesList->SetEmptyListText(".MDL file contains no sequences");
|
||||
|
||||
studiohdr_t *hdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
|
||||
CUtlDict<int, unsigned short> activityNames( true, 0, hdr->GetNumSeq() );
|
||||
|
||||
for (int j = 0; j < hdr->GetNumSeq(); j++)
|
||||
{
|
||||
if ( /*g_viewerSettings.showHidden ||*/ !(hdr->pSeqdesc(j).flags & STUDIO_HIDDEN))
|
||||
{
|
||||
const char *pActivityName = hdr->pSeqdesc(j).pszActivityName();
|
||||
if ( pActivityName && pActivityName[0] )
|
||||
{
|
||||
// Multiple sequences can have the same activity name; only add unique activity names
|
||||
if ( activityNames.Find( pActivityName ) == activityNames.InvalidIndex() )
|
||||
{
|
||||
KeyValues *pkv = new KeyValues("node", "activity", pActivityName );
|
||||
int nItemID = m_pActivitiesList->AddItem( pkv, 0, false, false );
|
||||
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", pActivityName );
|
||||
pDrag->SetString( "texttype", "activityName" );
|
||||
pDrag->SetString( "mdl", vgui::MDLCache()->GetModelName( m_hSelectedMDL ) );
|
||||
m_pActivitiesList->SetItemDragData( nItemID, pDrag );
|
||||
|
||||
activityNames.Insert( pActivityName, j );
|
||||
}
|
||||
}
|
||||
|
||||
const char *pSequenceName = hdr->pSeqdesc(j).pszLabel();
|
||||
if ( pSequenceName && pSequenceName[0] )
|
||||
{
|
||||
KeyValues *pkv = new KeyValues("node", "sequence", pSequenceName);
|
||||
pkv->SetInt( "seqindex", j );
|
||||
|
||||
int nItemID = m_pSequencesList->AddItem( pkv, 0, false, false );
|
||||
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", pSequenceName );
|
||||
pDrag->SetString( "texttype", "sequenceName" );
|
||||
pDrag->SetString( "mdl", vgui::MDLCache()->GetModelName( m_hSelectedMDL ) );
|
||||
m_pSequencesList->SetItemDragData( nItemID, pDrag );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes dialog on text changing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnTextChanged( vgui::Panel *pPanel, const char *pText )
|
||||
{
|
||||
// m_pFileTree->SetFilter( pText );
|
||||
RefreshFileList();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Selects an sequence based on an activity
|
||||
//-----------------------------------------------------------------------------
|
||||
int SelectWeightedSequence( studiohdr_t *pstudiohdr, int activity, int curSequence )
|
||||
{
|
||||
if (! pstudiohdr)
|
||||
return 0;
|
||||
|
||||
VerifySequenceIndex( pstudiohdr );
|
||||
|
||||
int weighttotal = 0;
|
||||
int seq = ACTIVITY_NOT_AVAILABLE;
|
||||
int weight = 0;
|
||||
for (int i = 0; i < pstudiohdr->GetNumSeq(); i++)
|
||||
{
|
||||
int curActivity = GetSequenceActivity( pstudiohdr, i, &weight );
|
||||
if (curActivity == activity)
|
||||
{
|
||||
if ( curSequence == i && weight < 0 )
|
||||
{
|
||||
seq = i;
|
||||
break;
|
||||
}
|
||||
weighttotal += iabs(weight);
|
||||
|
||||
int randomValue;
|
||||
if ( IsInPrediction() )
|
||||
randomValue = SharedRandomInt( "SelectWeightedSequence", 0, weighttotal - 1, i );
|
||||
else
|
||||
randomValue = RandomInt( 0, weighttotal - 1 );
|
||||
|
||||
if (!weighttotal || randomValue < iabs(weight))
|
||||
seq = i;
|
||||
}
|
||||
}
|
||||
|
||||
return seq;
|
||||
}
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plays the selected activity
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::PlaySelectedActivity( )
|
||||
{
|
||||
int nIndex = m_pActivitiesList->GetSelectedItem( 0 );
|
||||
if ( nIndex < 0 )
|
||||
return;
|
||||
|
||||
KeyValues *pkv = m_pActivitiesList->GetItem( nIndex );
|
||||
const char *pActivityName = pkv->GetString( "activity", NULL );
|
||||
if ( !pActivityName )
|
||||
return;
|
||||
|
||||
studiohdr_t *pstudiohdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
for ( int i = 0; i < pstudiohdr->GetNumSeq(); i++ )
|
||||
{
|
||||
mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i );
|
||||
if ( stricmp( seqdesc.pszActivityName(), pActivityName ) == 0 )
|
||||
{
|
||||
// FIXME: Add weighted sequence selection logic?
|
||||
m_pMDLPreview->SetSequence( i, false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plays the selected sequence
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::PlaySelectedSequence( )
|
||||
{
|
||||
int nIndex = m_pSequencesList->GetSelectedItem( 0 );
|
||||
if ( nIndex < 0 )
|
||||
return;
|
||||
|
||||
KeyValues *pkv = m_pSequencesList->GetItem( nIndex );
|
||||
const char *pSequenceName = pkv->GetString( "sequence", NULL );
|
||||
if ( !pSequenceName )
|
||||
return;
|
||||
|
||||
studiohdr_t *pstudiohdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
|
||||
for (int i = 0; i < pstudiohdr->GetNumSeq(); i++)
|
||||
{
|
||||
mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i );
|
||||
if ( !Q_stricmp( seqdesc.pszLabel(), pSequenceName ) )
|
||||
{
|
||||
m_pMDLPreview->SetSequence( i, false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when a page is shown
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnPageChanged( )
|
||||
{
|
||||
if ( m_pViewsSheet->GetActivePage() == m_pSequencesPage )
|
||||
{
|
||||
PlaySelectedSequence();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_pViewsSheet->GetActivePage() == m_pActivitiesPage )
|
||||
{
|
||||
PlaySelectedActivity();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes dialog on text changing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnItemSelected( KeyValues *kv )
|
||||
{
|
||||
Panel *pPanel = (Panel *)kv->GetPtr("panel", NULL);
|
||||
if ( pPanel == m_pSequencesList )
|
||||
{
|
||||
PlaySelectedSequence();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pPanel == m_pActivitiesList )
|
||||
{
|
||||
PlaySelectedActivity();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// An MDL was selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::SelectMDL( const char *pMDLName )
|
||||
{
|
||||
m_hSelectedMDL = pMDLName ? vgui::MDLCache()->FindMDL( pMDLName ) : MDLHANDLE_INVALID;
|
||||
if ( vgui::MDLCache()->IsErrorModel( m_hSelectedMDL ) )
|
||||
{
|
||||
m_hSelectedMDL = MDLHANDLE_INVALID;
|
||||
}
|
||||
m_pMDLPreview->SetMDL( m_hSelectedMDL );
|
||||
m_pMDLPreview->LookAtMDL();
|
||||
RefreshActivitiesAndSequencesList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: updates revision view on a file being selected
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMDLSequencePicker::OnFileSelected()
|
||||
{
|
||||
// update list
|
||||
int iItem = m_pFileTree->GetFirstSelectedItem();
|
||||
if ( iItem < 0 )
|
||||
return;
|
||||
|
||||
// Don't bother to change if a directory was selected
|
||||
KeyValues *pkv = m_pFileTree->GetItemData(iItem);
|
||||
if ( pkv->GetInt("dir") || pkv->GetInt("root") )
|
||||
return;
|
||||
|
||||
surface()->SetCursor(dc_waitarrow);
|
||||
|
||||
const char *pFullPathName = pkv->GetString( "path" );
|
||||
|
||||
char pRelativePathName[MAX_PATH];
|
||||
g_pFullFileSystem->FullPathToRelativePath( pFullPathName, pRelativePathName, sizeof(pRelativePathName) );
|
||||
|
||||
// FIXME: Check that we're not actually opening the wrong file!!
|
||||
SelectMDL( pRelativePathName );
|
||||
}
|
||||
|
||||
char const *CMDLSequencePicker::GetModelName()
|
||||
{
|
||||
if ( MDLHANDLE_INVALID == m_hSelectedMDL )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return vgui::MDLCache()->GetModelName( m_hSelectedMDL );
|
||||
}
|
||||
|
||||
char const *CMDLSequencePicker::GetSequenceName()
|
||||
{
|
||||
int nIndex = m_pSequencesList->GetSelectedItem( 0 );
|
||||
if ( nIndex < 0 )
|
||||
return "";
|
||||
|
||||
KeyValues *pkv = m_pSequencesList->GetItem( nIndex );
|
||||
const char *pSequenceName = pkv->GetString( "sequence", NULL );
|
||||
if ( !pSequenceName )
|
||||
return "";
|
||||
|
||||
return pSequenceName;
|
||||
}
|
||||
|
||||
int CMDLSequencePicker::GetSequenceNumber()
|
||||
{
|
||||
int nIndex = m_pSequencesList->GetSelectedItem( 0 );
|
||||
if ( nIndex < 0 )
|
||||
return -1;
|
||||
KeyValues *pkv = m_pSequencesList->GetItem( nIndex );
|
||||
return pkv->GetInt( "seqindex", -1 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sequence picker frame
|
||||
//-----------------------------------------------------------------------------
|
||||
CMDLSequencePickerFrame::CMDLSequencePickerFrame( vgui::Panel *parent, char const *title ) :
|
||||
BaseClass( parent, "MDLSequencePickerFrame" )
|
||||
{
|
||||
m_pMDLSequencePicker = new CMDLSequencePicker( this );
|
||||
SetTitle( title, true );
|
||||
SetSizeable( false );
|
||||
SetCloseButtonVisible( false );
|
||||
SetMoveable( true );
|
||||
SetMinimumSize( 640, 480 );
|
||||
Activate();
|
||||
m_pMDLSequencePicker->Activate();
|
||||
|
||||
m_pOK = new Button( this, "OK", "#vgui_ok", this );
|
||||
m_pOK->SetCommand( new KeyValues( "OnOK" ) );
|
||||
m_pCancel= new Button( this, "Cancel", "#vgui_cancel", this );
|
||||
m_pOK->SetCommand( new KeyValues( "OnCancel" ) );
|
||||
m_pOK->SetEnabled( false );
|
||||
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel(), 0 );
|
||||
}
|
||||
|
||||
CMDLSequencePickerFrame::~CMDLSequencePickerFrame()
|
||||
{
|
||||
}
|
||||
|
||||
void CMDLSequencePickerFrame::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
bool bHasModel = m_pMDLSequencePicker->GetModelName()[ 0 ] != 0 ? true : false;
|
||||
bool bHasSequence = m_pMDLSequencePicker->GetSequenceNumber() != -1 ? true : false;
|
||||
|
||||
m_pOK->SetEnabled( bHasModel && bHasSequence );
|
||||
}
|
||||
|
||||
void CMDLSequencePickerFrame::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
int x, y, w, h;
|
||||
GetClientArea( x, y, w, h );
|
||||
h -= 24;
|
||||
m_pMDLSequencePicker->SetBounds( x, y, w, h );
|
||||
|
||||
h += 5;
|
||||
|
||||
|
||||
int bw = 120;
|
||||
int bwwithGap = 2 * bw + 10;
|
||||
|
||||
x = ( w - bwwithGap ) / 2;
|
||||
m_pOK->SetBounds( x, y + h, bw, 16 );
|
||||
x += bw + 10;
|
||||
m_pCancel->SetBounds( x, y + h, bw, 16 );
|
||||
}
|
||||
|
||||
void CMDLSequencePickerFrame::OnCancel()
|
||||
{
|
||||
KeyValues *pActionKeys = new KeyValues( "AssetSelected" );
|
||||
pActionKeys->SetString( "ModelName", m_pMDLSequencePicker->GetModelName() );
|
||||
pActionKeys->SetString( "SequenceName", m_pMDLSequencePicker->GetSequenceName() );
|
||||
pActionKeys->SetInt( "SequenceNumber", m_pMDLSequencePicker->GetSequenceNumber() );
|
||||
|
||||
PostActionSignal( pActionKeys );
|
||||
|
||||
CloseModal();
|
||||
}
|
||||
|
||||
void CMDLSequencePickerFrame::OnOK()
|
||||
{
|
||||
CloseModal();
|
||||
}
|
||||
|
||||
|
||||
1311
vgui2/matsys_controls/particlepicker.cpp
Normal file
1311
vgui2/matsys_controls/particlepicker.cpp
Normal file
File diff suppressed because it is too large
Load Diff
321
vgui2/matsys_controls/picker.cpp
Normal file
321
vgui2/matsys_controls/picker.cpp
Normal file
@@ -0,0 +1,321 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "matsys_controls/picker.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "vgui_controls/ListPanel.h"
|
||||
#include "vgui_controls/TextEntry.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IInput.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Base asset Picker
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sort by asset name
|
||||
//-----------------------------------------------------------------------------
|
||||
static int __cdecl PickerBrowserSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
|
||||
{
|
||||
const char *string1 = item1.kv->GetString("choice");
|
||||
const char *string2 = item2.kv->GetString("choice");
|
||||
return stricmp( string1, string2 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CPicker::CPicker( vgui::Panel *pParent, const char *pColumnHeader, const char *pTextType ) :
|
||||
BaseClass( pParent, "Picker" )
|
||||
{
|
||||
m_pPickerType = pColumnHeader;
|
||||
m_pPickerTextType = pTextType;
|
||||
|
||||
// FIXME: Make this an image browser
|
||||
m_pPickerBrowser = new vgui::ListPanel( this, "Browser" );
|
||||
m_pPickerBrowser->AddColumnHeader( 0, "choice", m_pPickerType, 52, 0 );
|
||||
m_pPickerBrowser->SetSelectIndividualCells( true );
|
||||
m_pPickerBrowser->SetEmptyListText( "Nothing to pick" );
|
||||
m_pPickerBrowser->SetDragEnabled( true );
|
||||
m_pPickerBrowser->AddActionSignalTarget( this );
|
||||
m_pPickerBrowser->SetSortFunc( 0, PickerBrowserSortFunc );
|
||||
m_pPickerBrowser->SetSortColumn( 0 );
|
||||
|
||||
// filter selection
|
||||
m_pFilterList = new TextEntry( this, "FilterList" );
|
||||
m_pFilterList->AddActionSignalTarget( this );
|
||||
m_pFilterList->RequestFocus();
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/picker.res" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CPicker::~CPicker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPicker::OnKeyCodeTyped( KeyCode code )
|
||||
{
|
||||
if (( code == KEY_UP ) || ( code == KEY_DOWN ) || ( code == KEY_PAGEUP ) || ( code == KEY_PAGEDOWN ))
|
||||
{
|
||||
KeyValues *pMsg = new KeyValues("KeyCodeTyped", "code", code);
|
||||
vgui::ipanel()->SendMessage( m_pPickerBrowser->GetVPanel(), pMsg, GetVPanel());
|
||||
pMsg->deleteThis();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnKeyCodeTyped( code );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes the asset list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPicker::SetStringList( const PickerList_t &list )
|
||||
{
|
||||
m_Type = list.m_Type;
|
||||
m_pPickerBrowser->RemoveAll();
|
||||
|
||||
int nCount = list.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
const char *pPickerName = list[i].m_pChoiceString;
|
||||
KeyValues *kv = new KeyValues( "node", "choice", pPickerName );
|
||||
if ( m_Type == PICKER_CHOICE_STRING )
|
||||
{
|
||||
kv->SetString( "value", list[i].m_pChoiceValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
kv->SetPtr( "value", list[i].m_pChoiceValuePtr );
|
||||
}
|
||||
int nItemID = m_pPickerBrowser->AddItem( kv, 0, false, false );
|
||||
|
||||
if ( m_Type == PICKER_CHOICE_STRING )
|
||||
{
|
||||
KeyValues *pDrag = new KeyValues( "drag", "text", list[i].m_pChoiceValue );
|
||||
if ( m_pPickerTextType )
|
||||
{
|
||||
pDrag->SetString( "texttype", m_pPickerTextType );
|
||||
}
|
||||
m_pPickerBrowser->SetItemDragData( nItemID, pDrag );
|
||||
}
|
||||
}
|
||||
RefreshChoiceList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes the choice list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPicker::RefreshChoiceList( )
|
||||
{
|
||||
// Check the filter matches
|
||||
int nMatchingCount = 0;
|
||||
int nTotalCount = 0;
|
||||
for ( int nItemID = m_pPickerBrowser->FirstItem(); nItemID != m_pPickerBrowser->InvalidItemID(); nItemID = m_pPickerBrowser->NextItem( nItemID ) )
|
||||
{
|
||||
KeyValues *kv = m_pPickerBrowser->GetItem( nItemID );
|
||||
const char *pPickerName = kv->GetString( "choice" );
|
||||
bool bVisible = !m_Filter.Length() || Q_stristr( pPickerName, m_Filter.Get() );
|
||||
m_pPickerBrowser->SetItemVisible( nItemID, bVisible );
|
||||
if ( bVisible )
|
||||
{
|
||||
++nMatchingCount;
|
||||
}
|
||||
++nTotalCount;
|
||||
}
|
||||
|
||||
char pColumnTitle[512];
|
||||
Q_snprintf( pColumnTitle, sizeof(pColumnTitle), "%s (%d/%d)",
|
||||
m_pPickerType, nMatchingCount, nTotalCount );
|
||||
m_pPickerBrowser->SetColumnHeaderText( 0, pColumnTitle );
|
||||
|
||||
m_pPickerBrowser->SortList();
|
||||
if ( ( m_pPickerBrowser->GetSelectedItemsCount() == 0 ) && ( m_pPickerBrowser->GetItemCount() > 0 ) )
|
||||
{
|
||||
int nItemID = m_pPickerBrowser->GetItemIDFromRow( 0 );
|
||||
m_pPickerBrowser->SetSelectedCell( nItemID, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes dialog on text changing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPicker::OnTextChanged( )
|
||||
{
|
||||
int nLength = m_pFilterList->GetTextLength();
|
||||
m_Filter.SetLength( nLength );
|
||||
if ( nLength > 0 )
|
||||
{
|
||||
m_pFilterList->GetText( m_Filter.Get(), nLength+1 );
|
||||
}
|
||||
RefreshChoiceList();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the selected string
|
||||
//-----------------------------------------------------------------------------
|
||||
PickerChoiceType_t CPicker::GetSelectionType() const
|
||||
{
|
||||
return m_Type;
|
||||
}
|
||||
|
||||
const char *CPicker::GetSelectedString( ) const
|
||||
{
|
||||
if ( m_pPickerBrowser->GetSelectedItemsCount() == 0 )
|
||||
return NULL;
|
||||
|
||||
if ( m_Type != PICKER_CHOICE_STRING )
|
||||
return NULL;
|
||||
|
||||
int nIndex = m_pPickerBrowser->GetSelectedItem( 0 );
|
||||
KeyValues *pItemKeyValues = m_pPickerBrowser->GetItem( nIndex );
|
||||
return pItemKeyValues->GetString( "value" );
|
||||
}
|
||||
|
||||
void *CPicker::GetSelectedPtr( ) const
|
||||
{
|
||||
if ( m_pPickerBrowser->GetSelectedItemsCount() == 0 )
|
||||
return NULL;
|
||||
|
||||
if ( m_Type != PICKER_CHOICE_PTR )
|
||||
return NULL;
|
||||
|
||||
int nIndex = m_pPickerBrowser->GetSelectedItem( 0 );
|
||||
KeyValues *pItemKeyValues = m_pPickerBrowser->GetItem( nIndex );
|
||||
return pItemKeyValues->GetPtr( "value" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the index of the selected string
|
||||
//-----------------------------------------------------------------------------
|
||||
int CPicker::GetSelectedIndex()
|
||||
{
|
||||
if ( m_pPickerBrowser->GetSelectedItemsCount() == 0 )
|
||||
return -1;
|
||||
|
||||
return m_pPickerBrowser->GetSelectedItem( 0 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CPickerFrame::CPickerFrame( vgui::Panel *pParent, const char *pTitle, const char *pPickerType, const char *pTextType ) :
|
||||
BaseClass( pParent, "PickerFrame" )
|
||||
{
|
||||
m_pContextKeyValues = NULL;
|
||||
SetDeleteSelfOnClose( true );
|
||||
m_pPicker = new CPicker( this, pPickerType, pTextType );
|
||||
m_pPicker->AddActionSignalTarget( this );
|
||||
m_pOpenButton = new Button( this, "OpenButton", "#FileOpenDialog_Open", this, "Open" );
|
||||
m_pCancelButton = new Button( this, "CancelButton", "#FileOpenDialog_Cancel", this, "Cancel" );
|
||||
SetBlockDragChaining( true );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/pickerframe.res" );
|
||||
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
CPickerFrame::~CPickerFrame()
|
||||
{
|
||||
CleanUpMessage();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deletes the message
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPickerFrame::CleanUpMessage()
|
||||
{
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
m_pContextKeyValues->deleteThis();
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Activate the dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPickerFrame::DoModal( const PickerList_t &list, KeyValues *pContextKeyValues )
|
||||
{
|
||||
CleanUpMessage();
|
||||
m_pContextKeyValues = pContextKeyValues;
|
||||
m_pPicker->SetStringList( list );
|
||||
BaseClass::DoModal();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On command
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPickerFrame::OnCommand( const char *pCommand )
|
||||
{
|
||||
if ( !Q_stricmp( pCommand, "Open" ) )
|
||||
{
|
||||
KeyValues *pActionKeys = new KeyValues( "Picked" );
|
||||
pActionKeys->SetInt( "choiceIndex", m_pPicker->GetSelectedIndex( ) );
|
||||
|
||||
if ( m_pPicker->GetSelectionType() == PICKER_CHOICE_STRING )
|
||||
{
|
||||
const char *pPickerName = m_pPicker->GetSelectedString( );
|
||||
pActionKeys->SetString( "choice", pPickerName );
|
||||
}
|
||||
else
|
||||
{
|
||||
void *pPickerPtr = m_pPicker->GetSelectedPtr( );
|
||||
pActionKeys->SetPtr( "choice", pPickerPtr );
|
||||
}
|
||||
|
||||
if ( m_pContextKeyValues )
|
||||
{
|
||||
pActionKeys->AddSubKey( m_pContextKeyValues );
|
||||
m_pContextKeyValues = NULL;
|
||||
}
|
||||
PostActionSignal( pActionKeys );
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( pCommand, "Cancel" ) )
|
||||
{
|
||||
CloseModal();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
|
||||
|
||||
1191
vgui2/matsys_controls/potterywheelpanel.cpp
Normal file
1191
vgui2/matsys_controls/potterywheelpanel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
265
vgui2/matsys_controls/proceduraltexturepanel.cpp
Normal file
265
vgui2/matsys_controls/proceduraltexturepanel.cpp
Normal file
@@ -0,0 +1,265 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/proceduraltexturepanel.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "pixelwriter.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CProceduralTexturePanel::CProceduralTexturePanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
m_pImageBuffer = NULL;
|
||||
m_bMaintainProportions = false;
|
||||
m_bUsePaintRect = false;
|
||||
m_PaintRect.x = m_PaintRect.y = 0;
|
||||
m_PaintRect.width = m_PaintRect.height = 0;
|
||||
|
||||
m_nTextureID = -1;
|
||||
}
|
||||
|
||||
CProceduralTexturePanel::~CProceduralTexturePanel()
|
||||
{
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initialization, shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CProceduralTexturePanel::Init( int nWidth, int nHeight, bool bAllocateImageBuffer )
|
||||
{
|
||||
m_nWidth = nWidth;
|
||||
m_nHeight = nHeight;
|
||||
if ( bAllocateImageBuffer )
|
||||
{
|
||||
m_pImageBuffer = new BGRA8888_t[nWidth * nHeight];
|
||||
}
|
||||
|
||||
m_TextureSubRect.x = m_TextureSubRect.y = 0;
|
||||
m_TextureSubRect.width = nWidth;
|
||||
m_TextureSubRect.height = nHeight;
|
||||
|
||||
char pTemp[512];
|
||||
Q_snprintf( pTemp, 512, "__%s", GetName() );
|
||||
|
||||
ITexture *pTex = MaterialSystem()->CreateProceduralTexture( pTemp, TEXTURE_GROUP_VGUI,
|
||||
m_nWidth, m_nHeight, IMAGE_FORMAT_BGRX8888,
|
||||
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT | TEXTUREFLAGS_NOMIP |
|
||||
TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_PROCEDURAL | TEXTUREFLAGS_SINGLECOPY );
|
||||
pTex->SetTextureRegenerator( this );
|
||||
m_ProceduralTexture.Init( pTex );
|
||||
pTex->DecrementReferenceCount();
|
||||
|
||||
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
|
||||
pVMTKeyValues->SetString( "$basetexture", pTemp );
|
||||
pVMTKeyValues->SetInt( "$nocull", 1 );
|
||||
pVMTKeyValues->SetInt( "$nodebug", 1 );
|
||||
IMaterial *pMaterial = MaterialSystem()->CreateMaterial( pTemp, pVMTKeyValues );
|
||||
m_ProceduralMaterial.Init( pMaterial );
|
||||
pMaterial->DecrementReferenceCount();
|
||||
static unsigned int textureVarCache = 0;
|
||||
IMaterialVar *pTextureVar = m_ProceduralMaterial->FindVarFast( "$basetexture", &textureVarCache );
|
||||
pTextureVar->SetTextureValue( pTex );
|
||||
|
||||
m_nTextureID = MatSystemSurface()->CreateNewTextureID( false );
|
||||
MatSystemSurface()->DrawSetTextureMaterial( m_nTextureID, m_ProceduralMaterial );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CProceduralTexturePanel::Shutdown()
|
||||
{
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Maintain proportions when drawing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::MaintainProportions( bool bEnable )
|
||||
{
|
||||
m_bMaintainProportions = bEnable;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the image buffer + dimensions
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::CleanUp()
|
||||
{
|
||||
if ( m_nTextureID != -1 )
|
||||
{
|
||||
MatSystemSurface()->DestroyTextureID( m_nTextureID );
|
||||
m_nTextureID = -1;
|
||||
}
|
||||
|
||||
if ( m_ProceduralMaterial )
|
||||
{
|
||||
m_ProceduralMaterial.Shutdown( true );
|
||||
}
|
||||
|
||||
if ( m_ProceduralTexture )
|
||||
{
|
||||
m_ProceduralTexture->SetTextureRegenerator( NULL );
|
||||
m_ProceduralTexture.Shutdown( true );
|
||||
}
|
||||
|
||||
if ( m_pImageBuffer )
|
||||
{
|
||||
delete[] m_pImageBuffer;
|
||||
m_pImageBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Default implementation of regenerate texture bits
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::RegenerateTextureBits( ITexture *pTexture, IVTFTexture *pVTFTexture, Rect_t *pRect )
|
||||
{
|
||||
Assert( m_pImageBuffer );
|
||||
Assert( pVTFTexture->FrameCount() == 1 );
|
||||
Assert( pVTFTexture->FaceCount() == 1 );
|
||||
Assert( !pTexture->IsMipmapped() );
|
||||
|
||||
int nWidth, nHeight, nDepth;
|
||||
pVTFTexture->ComputeMipLevelDimensions( 0, &nWidth, &nHeight, &nDepth );
|
||||
Assert( nDepth == 1 );
|
||||
Assert( nWidth == m_nWidth && nHeight == m_nHeight );
|
||||
|
||||
CPixelWriter pixelWriter;
|
||||
pixelWriter.SetPixelMemory( pVTFTexture->Format(),
|
||||
pVTFTexture->ImageData( 0, 0, 0 ), pVTFTexture->RowSizeInBytes( 0 ) );
|
||||
|
||||
for ( int y = 0; y < nHeight; ++y )
|
||||
{
|
||||
pixelWriter.Seek( 0, y );
|
||||
BGRA8888_t *pTexel = &m_pImageBuffer[y * m_nWidth];
|
||||
for ( int x = 0; x < nWidth; ++x, ++pTexel )
|
||||
{
|
||||
pixelWriter.WritePixel( pTexel->r, pTexel->g, pTexel->b, pTexel->a );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the image buffer + dimensions
|
||||
//-----------------------------------------------------------------------------
|
||||
BGRA8888_t *CProceduralTexturePanel::GetImageBuffer()
|
||||
{
|
||||
Assert( m_pImageBuffer );
|
||||
return m_pImageBuffer;
|
||||
}
|
||||
|
||||
int CProceduralTexturePanel::GetImageWidth() const
|
||||
{
|
||||
return m_nWidth;
|
||||
}
|
||||
|
||||
int CProceduralTexturePanel::GetImageHeight() const
|
||||
{
|
||||
return m_nHeight;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the paint rect
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::SetPaintRect( const Rect_t *pPaintRect )
|
||||
{
|
||||
m_bUsePaintRect = ( pPaintRect != NULL );
|
||||
if ( m_bUsePaintRect )
|
||||
{
|
||||
m_PaintRect = *pPaintRect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the draw rect
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::SetTextureSubRect( const Rect_t &subRect )
|
||||
{
|
||||
m_TextureSubRect = subRect;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redownloads the procedural texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::DownloadTexture()
|
||||
{
|
||||
m_ProceduralTexture->Download();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints the texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CProceduralTexturePanel::Paint( void )
|
||||
{
|
||||
if ( m_nTextureID == -1 )
|
||||
return;
|
||||
|
||||
vgui::surface()->DrawSetTexture( m_nTextureID );
|
||||
vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
if ( m_bUsePaintRect )
|
||||
{
|
||||
x = m_PaintRect.x;
|
||||
y = m_PaintRect.y;
|
||||
w = m_PaintRect.width;
|
||||
h = m_PaintRect.height;
|
||||
}
|
||||
|
||||
if ( m_bMaintainProportions )
|
||||
{
|
||||
if ( m_TextureSubRect.width > m_TextureSubRect.height )
|
||||
{
|
||||
h = w * m_TextureSubRect.height / m_TextureSubRect.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = h * m_TextureSubRect.width / m_TextureSubRect.height;
|
||||
}
|
||||
}
|
||||
|
||||
// Rotated version of the bitmap!
|
||||
// Rotate about the center of the bitmap
|
||||
vgui::Vertex_t verts[4];
|
||||
verts[0].m_Position.Init( x, y );
|
||||
verts[0].m_TexCoord.Init( (float)m_TextureSubRect.x / m_nWidth, (float)m_TextureSubRect.y / m_nHeight );
|
||||
|
||||
verts[1].m_Position.Init( w+x, y );
|
||||
verts[1].m_TexCoord.Init( (float)(m_TextureSubRect.x + m_TextureSubRect.width) / m_nWidth, (float)m_TextureSubRect.y / m_nHeight );
|
||||
|
||||
verts[2].m_Position.Init( w+x, h+y );
|
||||
verts[2].m_TexCoord.Init( (float)(m_TextureSubRect.x + m_TextureSubRect.width) / m_nWidth, (float)(m_TextureSubRect.y + m_TextureSubRect.height) / m_nHeight );
|
||||
|
||||
verts[3].m_Position.Init( x, h+y );
|
||||
verts[3].m_TexCoord.Init( (float)m_TextureSubRect.x / m_nWidth, (float)(m_TextureSubRect.y + m_TextureSubRect.height) / m_nHeight );
|
||||
|
||||
vgui::surface()->DrawTexturedPolygon( 4, verts );
|
||||
}
|
||||
1156
vgui2/matsys_controls/sequencepicker.cpp
Normal file
1156
vgui2/matsys_controls/sequencepicker.cpp
Normal file
File diff suppressed because it is too large
Load Diff
393
vgui2/matsys_controls/sheetsequencepanel.cpp
Normal file
393
vgui2/matsys_controls/sheetsequencepanel.cpp
Normal file
@@ -0,0 +1,393 @@
|
||||
//======= Copyright (c) 1996-2009, Valve Corporation, All rights reserved. ======
|
||||
//
|
||||
// CSheetSequencePanel - Panel for selecting one sequence from a sprite sheet
|
||||
//
|
||||
//===============================================================================
|
||||
|
||||
#include "matsys_controls/sheetsequencepanel.h"
|
||||
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "bitmap/psheet.h"
|
||||
#include "vgui/IScheme.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// MOC_TODO: Power of two FB texture - do I really need to do this?
|
||||
static CTextureReference s_pPowerOfTwoFrameBufferTexture_SheetSeq;
|
||||
|
||||
static ITexture *GetPowerOfTwoFrameBufferTexture( void )
|
||||
{
|
||||
if ( !s_pPowerOfTwoFrameBufferTexture_SheetSeq )
|
||||
{
|
||||
s_pPowerOfTwoFrameBufferTexture_SheetSeq.Init( vgui::MaterialSystem()->FindTexture( "_rt_PowerOfTwoFB", TEXTURE_GROUP_RENDER_TARGET ) );
|
||||
}
|
||||
|
||||
return s_pPowerOfTwoFrameBufferTexture_SheetSeq;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Statics
|
||||
bool CSheetSequencePanel::m_sMaterialsInitialized = false;
|
||||
CMaterialReference CSheetSequencePanel::m_sColorMat;
|
||||
CMaterialReference CSheetSequencePanel::m_sAlphaMat;
|
||||
|
||||
|
||||
const int SEQUENCE_PANEL_BORDER = 2;
|
||||
const int SEQUENCE_PANEL_MAX_SIZE = 256;
|
||||
|
||||
CSheetSequencePanel::CSheetSequencePanel( vgui::Panel *pParent, const char *pPanelName ):
|
||||
BaseClass(pParent,pPanelName),
|
||||
m_pSheet(NULL),
|
||||
m_Material(NULL)
|
||||
{
|
||||
m_nHighlightedSequence = -1;
|
||||
m_bSeparateAlphaColorMaterial = false;
|
||||
m_bIsSecondSequenceView = false;
|
||||
|
||||
EnsureMaterialsExist();
|
||||
}
|
||||
|
||||
|
||||
void CSheetSequencePanel::EnsureMaterialsExist()
|
||||
{
|
||||
if ( !m_sMaterialsInitialized )
|
||||
{
|
||||
KeyValues *pKeyValues = new KeyValues( "DebugTextureView" );
|
||||
pKeyValues->SetString( "$basetexture", "" );
|
||||
pKeyValues->SetInt( "$ShowAlpha", 1 );
|
||||
m_sAlphaMat.Init( "SheetSequenceAlphaMaterial", pKeyValues );
|
||||
m_sAlphaMat->Refresh();
|
||||
|
||||
pKeyValues = new KeyValues( "DebugTextureView" );
|
||||
pKeyValues->SetString( "$basetexture", "" );
|
||||
pKeyValues->SetInt( "$ShowAlpha", 0 );
|
||||
m_sColorMat.Init( "SheetSequenceColorMaterial", pKeyValues );
|
||||
m_sColorMat->Refresh();
|
||||
|
||||
m_sMaterialsInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
CSheetSequencePanel::~CSheetSequencePanel()
|
||||
{
|
||||
delete m_pSheet;
|
||||
m_pSheet = NULL;
|
||||
}
|
||||
|
||||
void CSheetSequencePanel::PrepareMaterials()
|
||||
{
|
||||
if ( !m_Material )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_bSeparateAlphaColorMaterial = CSheetExtended::IsMaterialSeparateAlphaColorMaterial( m_Material );
|
||||
|
||||
bool bFound = false;
|
||||
IMaterialVar *pVar = m_Material->FindVar( "$basetexture", &bFound );
|
||||
if ( !pVar || !bFound || !pVar->IsDefined() )
|
||||
return;
|
||||
|
||||
ITexture *pTex = pVar->GetTextureValue();
|
||||
if ( !pTex || pTex->IsError() )
|
||||
return;
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
IMaterialVar *BaseTextureVar = m_sAlphaMat->FindVar( "$basetexture", &bFound );
|
||||
|
||||
if ( !bFound || !BaseTextureVar )
|
||||
return;
|
||||
|
||||
BaseTextureVar->SetTextureValue( pTex );
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
BaseTextureVar = m_sColorMat->FindVar( "$basetexture", &bFound );
|
||||
|
||||
if ( !bFound || !BaseTextureVar )
|
||||
return;
|
||||
|
||||
BaseTextureVar->SetTextureValue( pTex );
|
||||
}
|
||||
|
||||
void CSheetSequencePanel::SetSecondSequenceView( bool bIsSecondSequenceView )
|
||||
{
|
||||
m_bIsSecondSequenceView = bIsSecondSequenceView;
|
||||
}
|
||||
|
||||
void CSheetSequencePanel::SetFromMaterialName( const char* pMaterialName )
|
||||
{
|
||||
if ( m_pSheet )
|
||||
{
|
||||
delete m_pSheet;
|
||||
}
|
||||
|
||||
m_Material.Init( pMaterialName, "editor material" );
|
||||
m_pSheet = new CSheetExtended(m_Material);
|
||||
|
||||
PrepareMaterials();
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
void CSheetSequencePanel::SetFromMaterial( IMaterial* sourceMaterial )
|
||||
{
|
||||
if ( m_pSheet )
|
||||
{
|
||||
delete m_pSheet;
|
||||
}
|
||||
|
||||
m_Material.Init(sourceMaterial);
|
||||
m_pSheet = new CSheetExtended(m_Material);
|
||||
|
||||
PrepareMaterials();
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
void CSheetSequencePanel::PerformLayout()
|
||||
{
|
||||
int newWidth = SequenceGridCount() * SequenceGridSquareSize() + SEQUENCE_PANEL_BORDER*2;
|
||||
int newHeight = SequenceGridRows() * SequenceGridSquareSize() + SEQUENCE_PANEL_BORDER*2;
|
||||
|
||||
if ( SequenceGridCount() == 0 )
|
||||
{
|
||||
newWidth = 32;
|
||||
newHeight = 32;
|
||||
}
|
||||
|
||||
SetSize( newWidth, newHeight );
|
||||
Repaint();
|
||||
}
|
||||
|
||||
void CSheetSequencePanel::OnCursorExited()
|
||||
{
|
||||
m_nHighlightedSequence = -1;
|
||||
}
|
||||
|
||||
void CSheetSequencePanel::OnCursorMoved(int x, int y)
|
||||
{
|
||||
BaseClass::OnCursorMoved(x,y);
|
||||
|
||||
if ( m_pSheet == NULL || m_pSheet->GetSheetSequenceCount() == 0 )
|
||||
{
|
||||
m_nHighlightedSequence = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
int nGridCount = SequenceGridCount();
|
||||
int nGridSize = SequenceGridSquareSize();
|
||||
|
||||
int nGridX = (x - SEQUENCE_PANEL_BORDER) / nGridSize;
|
||||
int nGridY = (y - SEQUENCE_PANEL_BORDER) / nGridSize;
|
||||
|
||||
if ( nGridX >= 0 && nGridY >= 0 &&
|
||||
nGridX < nGridCount && nGridY < nGridCount )
|
||||
{
|
||||
int nSeqIndex = nGridX + nGridY*nGridCount;
|
||||
|
||||
if ( nSeqIndex < m_pSheet->GetSheetSequenceCount() )
|
||||
{
|
||||
m_nHighlightedSequence = nSeqIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nHighlightedSequence = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nHighlightedSequence = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int CSheetSequencePanel::SequenceGridCount()
|
||||
{
|
||||
return m_pSheet ? Ceil2Int(sqrt((float)m_pSheet->GetSheetSequenceCount())) : 0;
|
||||
}
|
||||
|
||||
int CSheetSequencePanel::SequenceGridSquareSize()
|
||||
{
|
||||
int nGridCount = SequenceGridCount();
|
||||
|
||||
if ( nGridCount == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (SEQUENCE_PANEL_MAX_SIZE / nGridCount);
|
||||
}
|
||||
}
|
||||
|
||||
int CSheetSequencePanel::SequenceGridRows()
|
||||
{
|
||||
if ( !m_pSheet )
|
||||
return 0;
|
||||
|
||||
int nSequences = m_pSheet->GetSheetSequenceCount();
|
||||
int nGridCount = SequenceGridCount();
|
||||
|
||||
if ( nSequences == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nSequences / nGridCount, rounded up
|
||||
return (nSequences + nGridCount - 1) / nGridCount;
|
||||
}
|
||||
}
|
||||
|
||||
void CSheetSequencePanel::OnMouseReleased( vgui::MouseCode mouseCode )
|
||||
{
|
||||
if ( m_nHighlightedSequence != -1 )
|
||||
{
|
||||
KeyValues *k = new KeyValues("SheetSequenceSelected");
|
||||
k->SetPtr("panel", this);
|
||||
k->SetInt("nSequenceNumber", m_nHighlightedSequence);
|
||||
k->SetBool("bIsSecondSequence", m_bIsSecondSequenceView );
|
||||
PostActionSignal( k );
|
||||
}
|
||||
|
||||
SetVisible(false);
|
||||
}
|
||||
|
||||
void CSheetSequencePanel::Paint( void )
|
||||
{
|
||||
int x, y, w, h;
|
||||
GetSize(w, h);
|
||||
GetPos(x,y);
|
||||
|
||||
vgui::surface()->DrawSetColor( Color(0,0,0,255) );
|
||||
vgui::surface()->DrawOutlinedRect( 1, 1, w-1, h-1 );
|
||||
|
||||
if ( m_pSheet == NULL || !m_pSheet->ValidSheetData() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CMatRenderContextPtr pRenderContext( vgui::MaterialSystem() );
|
||||
vgui::MatSystemSurface()->Begin3DPaint( 2, 2, w-2, h-2 );
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->PushMatrix();
|
||||
pRenderContext->LoadIdentity();
|
||||
pRenderContext->Ortho( 2, 2, w-2, h-2, -1.0f, 1.0f );
|
||||
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
||||
pRenderContext->PushMatrix();
|
||||
pRenderContext->LoadIdentity();
|
||||
|
||||
// Deal with refraction
|
||||
if ( m_Material->NeedsPowerOfTwoFrameBufferTexture() )
|
||||
{
|
||||
ITexture *pTexture = GetPowerOfTwoFrameBufferTexture();
|
||||
if ( pTexture && !pTexture->IsError() )
|
||||
{
|
||||
pRenderContext->CopyRenderTargetToTexture( pTexture );
|
||||
pRenderContext->SetFrameBufferCopyTexture( pTexture );
|
||||
}
|
||||
}
|
||||
|
||||
Color bgColor = GetBgColor();
|
||||
pRenderContext->ClearColor4ub( bgColor.r(), bgColor.g(), bgColor.b(), 255 );
|
||||
pRenderContext->ClearBuffers( true, true );
|
||||
|
||||
pRenderContext->FogMode( MATERIAL_FOG_NONE );
|
||||
pRenderContext->SetNumBoneWeights( 0 );
|
||||
|
||||
bool bOverrideSpriteCard = false;
|
||||
bool bOnlyColor = false;
|
||||
bool bOnlyAlpha = false;
|
||||
if ( m_bSeparateAlphaColorMaterial )
|
||||
{
|
||||
if ( !m_bIsSecondSequenceView )
|
||||
{
|
||||
pRenderContext->Bind( m_sAlphaMat );
|
||||
bOnlyAlpha = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pRenderContext->Bind( m_sColorMat );
|
||||
bOnlyColor = true;
|
||||
}
|
||||
|
||||
bOverrideSpriteCard = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pRenderContext->Bind( m_Material );
|
||||
}
|
||||
|
||||
IMesh *pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
float flAge = fmodf( Plat_FloatTime(), m_pSheet->GetSequenceTimeSpan(0) );
|
||||
|
||||
int nGridCount = SequenceGridCount();
|
||||
float flGridSquareSize = SequenceGridSquareSize();
|
||||
float flOffset = 0.5f*flGridSquareSize+SEQUENCE_PANEL_BORDER;
|
||||
int nSequences = m_pSheet->GetSheetSequenceCount();
|
||||
|
||||
for ( int i = 0; i < nSequences; ++i )
|
||||
{
|
||||
float x = i % nGridCount;
|
||||
float y = i / nGridCount;
|
||||
|
||||
if ( bOnlyColor && !m_pSheet->SequenceHasColorData( i )
|
||||
|| bOnlyAlpha && !m_pSheet->SequenceHasAlphaData( i ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m_pSheet->DrawSheet( pMesh, Vector(flOffset+x*flGridSquareSize,h-(flOffset+y*flGridSquareSize),0), flGridSquareSize*0.5f, i, flAge, 750.0f, true, -1, bOverrideSpriteCard );
|
||||
}
|
||||
|
||||
pRenderContext->PopMatrix();
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->PopMatrix();
|
||||
|
||||
vgui::MatSystemSurface()->End3DPaint( );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
flOffset = SEQUENCE_PANEL_BORDER;
|
||||
for ( int i = 0; i < nSequences; ++i )
|
||||
{
|
||||
float x = i % nGridCount;
|
||||
float y = i / nGridCount;
|
||||
|
||||
Color drawColor = Color(0,0,0,255);
|
||||
|
||||
if ( m_nHighlightedSequence == i )
|
||||
{
|
||||
drawColor = Color(255,255,255,255);
|
||||
}
|
||||
|
||||
vgui::surface()->DrawSetColor(drawColor);
|
||||
vgui::surface()->DrawSetTextColor(drawColor);
|
||||
|
||||
vgui::surface()->DrawOutlinedRect( flOffset+x*flGridSquareSize, flOffset+y*flGridSquareSize, flOffset+(x+1)*flGridSquareSize, flOffset+(y+1)*flGridSquareSize );
|
||||
|
||||
wchar_t strBuffer[8];
|
||||
V_snwprintf( strBuffer, ARRAYSIZE( strBuffer ), L"%d", i );
|
||||
vgui::surface()->DrawSetTextFont( vgui::scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultVerySmall" ) );
|
||||
vgui::surface()->DrawSetTextPos(flOffset+x*flGridSquareSize+2, flOffset+y*flGridSquareSize+1);
|
||||
vgui::surface()->DrawUnicodeString( strBuffer );
|
||||
|
||||
if ( bOnlyColor && !m_pSheet->SequenceHasColorData( i )
|
||||
|| bOnlyAlpha && !m_pSheet->SequenceHasAlphaData( i ) )
|
||||
{
|
||||
vgui::surface()->DrawSetTextColor( Color(255,0,0,255) );
|
||||
vgui::surface()->DrawSetTextPos(flOffset+(x+0.5f)*flGridSquareSize, flOffset+(y+0.5f)*flGridSquareSize+1);
|
||||
vgui::surface()->DrawUnicodeString( L"x" );
|
||||
}
|
||||
}
|
||||
}
|
||||
76
vgui2/matsys_controls/tgapicker.cpp
Normal file
76
vgui2/matsys_controls/tgapicker.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "matsys_controls/tgapicker.h"
|
||||
#include "matsys_controls/tgapreviewpanel.h"
|
||||
#include "vgui_controls/Splitter.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Asset Picker with no preview
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CTGAPicker::CTGAPicker( vgui::Panel *pParent ) :
|
||||
BaseClass( pParent, "TGA Files", "tga", "materialsrc", "tgaName", "CONTENT" )
|
||||
{
|
||||
// Horizontal splitter for preview
|
||||
m_pPreviewSplitter = new Splitter( this, "PreviewSplitter", SPLITTER_MODE_VERTICAL, 1 );
|
||||
vgui::Panel *pSplitterLeftSide = m_pPreviewSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterRightSide = m_pPreviewSplitter->GetChild( 1 );
|
||||
|
||||
// TGA preview
|
||||
m_pTGAPreview = new CTGAPreviewPanel( pSplitterRightSide, "TGAPreview" );
|
||||
m_pTGAPreview->MaintainProportions( true );
|
||||
|
||||
// Standard browser controls
|
||||
CreateStandardControls( pSplitterLeftSide );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/tgapicker.res" );
|
||||
}
|
||||
|
||||
CTGAPicker::~CTGAPicker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derived classes have this called when the previewed asset changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGAPicker::OnSelectedAssetPicked( const char *pAssetName )
|
||||
{
|
||||
char pFullPath[ MAX_PATH ];
|
||||
char pRelativePath[MAX_PATH];
|
||||
Q_snprintf( pRelativePath, sizeof(pRelativePath), "materialsrc\\%s", pAssetName );
|
||||
g_pFullFileSystem->RelativePathToFullPath( pRelativePath, "CONTENT", pFullPath, sizeof(pFullPath) );
|
||||
m_pTGAPreview->SetTGA( pFullPath );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CTGAPickerFrame::CTGAPickerFrame( vgui::Panel *pParent, const char *pTitle ) :
|
||||
BaseClass( pParent )
|
||||
{
|
||||
SetAssetPicker( new CTGAPicker( this ) );
|
||||
LoadControlSettingsAndUserConfig( "resource/tgapickerframe.res" );
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
94
vgui2/matsys_controls/tgapreviewpanel.cpp
Normal file
94
vgui2/matsys_controls/tgapreviewpanel.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/tgapreviewpanel.h"
|
||||
#include "bitmap/tgaloader.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// TGA Preview panel
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CTGAPreviewPanel::CTGAPreviewPanel( vgui::Panel *pParent, const char *pName ) :
|
||||
BaseClass( pParent, pName )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the current TGA
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGAPreviewPanel::SetTGA( const char *pFullPath )
|
||||
{
|
||||
int nWidth, nHeight;
|
||||
ImageFormat format;
|
||||
float flGamma;
|
||||
|
||||
CUtlBuffer buf;
|
||||
if ( !g_pFullFileSystem->ReadFile( pFullPath, NULL, buf ) )
|
||||
{
|
||||
Warning( "Can't open TGA file: %s\n", pFullPath );
|
||||
return;
|
||||
}
|
||||
|
||||
TGALoader::GetInfo( buf, &nWidth, &nHeight, &format, &flGamma );
|
||||
|
||||
Shutdown();
|
||||
Init( nWidth, nHeight, true );
|
||||
m_TGAName = pFullPath;
|
||||
|
||||
|
||||
buf.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
|
||||
if ( !TGALoader::Load( (unsigned char*)GetImageBuffer(), buf,
|
||||
nWidth, nHeight, IMAGE_FORMAT_BGRA8888, flGamma, false ) )
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
DownloadTexture();
|
||||
}
|
||||
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the current TGA
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CTGAPreviewPanel::GetTGA() const
|
||||
{
|
||||
return m_TGAName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Lays out the panel
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGAPreviewPanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
Rect_t paintRect;
|
||||
paintRect.x = 0;
|
||||
paintRect.y = 0;
|
||||
paintRect.width = GetImageWidth();
|
||||
paintRect.height = GetImageHeight();
|
||||
SetPaintRect( &paintRect );
|
||||
}
|
||||
462
vgui2/matsys_controls/vmtpanel.cpp
Normal file
462
vgui2/matsys_controls/vmtpanel.cpp
Normal file
@@ -0,0 +1,462 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/vmtpanel.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "vgui_controls/ScrollBar.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui_controls/ToolWindow.h"
|
||||
#include "tier2/renderutils.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enums
|
||||
//-----------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
SCROLLBAR_SIZE=18, // the width of a scrollbar
|
||||
WINDOW_BORDER_WIDTH=2 // the width of the window's border
|
||||
};
|
||||
|
||||
#define SPHERE_RADIUS 10.0f
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVMTPanel::CVMTPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
|
||||
{
|
||||
m_bUseActualSize = true;
|
||||
m_pMaterial = NULL;
|
||||
|
||||
m_pHorizontalBar = new ScrollBar( this, "HorizScrollBar", false );
|
||||
m_pHorizontalBar->AddActionSignalTarget(this);
|
||||
m_pHorizontalBar->SetVisible(false);
|
||||
|
||||
m_pVerticalBar = new ScrollBar( this, "VertScrollBar", true );
|
||||
m_pVerticalBar->AddActionSignalTarget(this);
|
||||
m_pVerticalBar->SetVisible(false);
|
||||
|
||||
LookAt( SPHERE_RADIUS );
|
||||
|
||||
m_pLightmapTexture.Init( "//platform/materials/debug/defaultlightmap", "editor" );
|
||||
m_DefaultEnvCubemap.Init( "editor/cubemap", "editor", true );
|
||||
}
|
||||
|
||||
CVMTPanel::~CVMTPanel()
|
||||
{
|
||||
m_pLightmapTexture.Shutdown();
|
||||
m_DefaultEnvCubemap.Shutdown();
|
||||
if (m_pMaterial)
|
||||
{
|
||||
m_pMaterial->DecrementReferenceCount();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scheme
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
SetBorder( pScheme->GetBorder( "MenuBorder") );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the material to draw
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::SetMaterial( IMaterial *pMaterial )
|
||||
{
|
||||
if (pMaterial)
|
||||
{
|
||||
pMaterial->IncrementReferenceCount();
|
||||
}
|
||||
if (m_pMaterial)
|
||||
{
|
||||
m_pMaterial->DecrementReferenceCount();
|
||||
}
|
||||
m_pMaterial = pMaterial;
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set rendering mode (stretch to full screen, or use actual size)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::RenderUsingActualSize( bool bEnable )
|
||||
{
|
||||
m_bUseActualSize = bEnable;
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: relayouts out the panel after any internal changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
return;
|
||||
|
||||
// Get the current size, see if it's big enough to view the entire thing
|
||||
int iWidth, iHeight;
|
||||
GetSize( iWidth, iHeight );
|
||||
|
||||
// In the case of stretching, just stretch to the size and blow off
|
||||
// the scrollbars. Same holds true if there's no material
|
||||
if (!m_bUseActualSize || !m_pMaterial)
|
||||
{
|
||||
m_iViewableWidth = iWidth;
|
||||
m_iViewableHeight = iHeight;
|
||||
m_pHorizontalBar->SetVisible(false);
|
||||
m_pVerticalBar->SetVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the size of the material...
|
||||
int iMaterialWidth = m_pMaterial->GetMappingWidth();
|
||||
int iMaterialHeight = m_pMaterial->GetMappingHeight();
|
||||
|
||||
// Check if the scroll bars are visible
|
||||
bool bHorizScrollVisible = (iMaterialWidth > iWidth);
|
||||
bool bVertScrollVisible = (iMaterialHeight > iHeight);
|
||||
|
||||
m_pHorizontalBar->SetVisible(bHorizScrollVisible);
|
||||
m_pVerticalBar->SetVisible(bVertScrollVisible);
|
||||
|
||||
// Shrink the bars if both are visible
|
||||
m_iViewableWidth = bVertScrollVisible ? iWidth - SCROLLBAR_SIZE - WINDOW_BORDER_WIDTH : iWidth;
|
||||
m_iViewableHeight = bHorizScrollVisible ? iHeight - SCROLLBAR_SIZE - WINDOW_BORDER_WIDTH : iHeight;
|
||||
|
||||
// Set the position of the horizontal bar...
|
||||
if (bHorizScrollVisible)
|
||||
{
|
||||
m_pHorizontalBar->SetPos(0, iHeight - SCROLLBAR_SIZE);
|
||||
m_pHorizontalBar->SetSize( m_iViewableWidth, SCROLLBAR_SIZE );
|
||||
|
||||
m_pHorizontalBar->SetRangeWindow( m_iViewableWidth );
|
||||
m_pHorizontalBar->SetRange( 0, iMaterialWidth );
|
||||
|
||||
// FIXME: Change scroll amount based on how much is not visible?
|
||||
m_pHorizontalBar->SetButtonPressedScrollValue( 5 );
|
||||
}
|
||||
|
||||
// Set the position of the vertical bar...
|
||||
if (bVertScrollVisible)
|
||||
{
|
||||
m_pVerticalBar->SetPos(iWidth - SCROLLBAR_SIZE, 0);
|
||||
m_pVerticalBar->SetSize(SCROLLBAR_SIZE, m_iViewableHeight);
|
||||
|
||||
m_pVerticalBar->SetRangeWindow( m_iViewableHeight );
|
||||
m_pVerticalBar->SetRange( 0, iMaterialHeight);
|
||||
m_pVerticalBar->SetButtonPressedScrollValue( 5 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// paint it stretched to the window size
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::DrawStretchedToPanel( CMeshBuilder &meshBuilder )
|
||||
{
|
||||
// Draw a polygon the size of the panel
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( 0, 0, 0 );
|
||||
meshBuilder.TexCoord2f( 0, 0, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( 0, m_iViewableHeight, 0 );
|
||||
meshBuilder.TexCoord2f( 0, 0, 1 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( m_iViewableWidth, m_iViewableHeight, 0 );
|
||||
meshBuilder.TexCoord2f( 0, 1, 1 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( m_iViewableWidth, 0, 0 );
|
||||
meshBuilder.TexCoord2f( 0, 0, 1 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// paint it actual size
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::DrawActualSize( CMeshBuilder &meshBuilder )
|
||||
{
|
||||
// Check the size of the material...
|
||||
int iMaterialWidth = m_pMaterial->GetMappingWidth();
|
||||
int iMaterialHeight = m_pMaterial->GetMappingHeight();
|
||||
|
||||
Vector2D ul;
|
||||
Vector2D lr;
|
||||
Vector2D tul;
|
||||
Vector2D tlr;
|
||||
|
||||
if (m_iViewableWidth >= iMaterialWidth)
|
||||
{
|
||||
// Center the material if we've got enough horizontal space
|
||||
ul.x = (m_iViewableWidth - iMaterialWidth) * 0.5f;
|
||||
lr.x = ul.x + iMaterialWidth;
|
||||
tul.x = 0.0f; tlr.x = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the scrollbars here...
|
||||
int val = m_pHorizontalBar->GetValue();
|
||||
tul.x = (float)val / (float)iMaterialWidth;
|
||||
tlr.x = tul.x + (float)m_iViewableWidth / (float)iMaterialWidth;
|
||||
|
||||
ul.x = 0;
|
||||
lr.x = m_iViewableWidth;
|
||||
}
|
||||
|
||||
if (m_iViewableHeight >= iMaterialHeight)
|
||||
{
|
||||
// Center the material if we've got enough vertical space
|
||||
ul.y = (m_iViewableHeight - iMaterialHeight) * 0.5f;
|
||||
lr.y = ul.y + iMaterialHeight;
|
||||
tul.y = 0.0f; tlr.y = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the scrollbars here...
|
||||
int val = m_pVerticalBar->GetValue();
|
||||
|
||||
tul.y = (float)val / (float)iMaterialHeight;
|
||||
tlr.y = tul.y + (float)m_iViewableHeight / (float)iMaterialHeight;
|
||||
|
||||
ul.y = 0;
|
||||
lr.y = m_iViewableHeight;
|
||||
}
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( ul.x, ul.y, 0 );
|
||||
meshBuilder.TexCoord2f( 0, tul.x, tul.y );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( lr.x, ul.y, 0 );
|
||||
meshBuilder.TexCoord2f( 0, tlr.x, tul.y );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( lr.x, lr.y, 0 );
|
||||
meshBuilder.TexCoord2f( 0, tlr.x, tlr.y );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
meshBuilder.Position3f( ul.x, lr.y, 0 );
|
||||
meshBuilder.TexCoord2f( 0, tul.x, tlr.y );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw it on a sphere
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::RenderSphere( const Vector &vCenter, float flRadius, int nTheta, int nPhi )
|
||||
{
|
||||
int nVertices = nTheta * nPhi;
|
||||
int nIndices = 2 * ( nTheta + 1 ) * ( nPhi - 1 );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
pRenderContext->FogMode( MATERIAL_FOG_NONE );
|
||||
pRenderContext->SetNumBoneWeights( 0 );
|
||||
pRenderContext->Bind( m_pMaterial );
|
||||
pRenderContext->BindLightmapTexture( m_pLightmapTexture );
|
||||
pRenderContext->BindLocalCubemap( m_DefaultEnvCubemap );
|
||||
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, nVertices, nIndices );
|
||||
|
||||
bool bIsUsingLightmap = m_pMaterial->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_LIGHTMAP );
|
||||
bool bIsUsingBumpedLightmap = m_pMaterial->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS );
|
||||
|
||||
int nLightmapWidth = m_pLightmapTexture->GetActualWidth();
|
||||
float flHalfLuxel = 0.5f / nLightmapWidth;
|
||||
|
||||
//
|
||||
// Build the index buffer.
|
||||
//
|
||||
int i, j;
|
||||
for ( i = 0; i < nPhi; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
float u = j / ( float )(nTheta - 1);
|
||||
float v = i / ( float )(nPhi - 1);
|
||||
float theta = ( j != nTheta-1 ) ? 2.0f * M_PI * u : 0.0f;
|
||||
float phi = M_PI * v;
|
||||
|
||||
Vector vecPos;
|
||||
vecPos.x = flRadius * sin(phi) * cos(theta);
|
||||
vecPos.y = flRadius * sin(phi) * sin(theta);
|
||||
vecPos.z = flRadius * cos(phi);
|
||||
|
||||
Vector vecNormal = vecPos;
|
||||
VectorNormalize( vecNormal );
|
||||
|
||||
Vector4D vecTangentS;
|
||||
Vector vecTangentT;
|
||||
vecTangentS.Init( -vecPos.y, vecPos.x, 0.0f, 1.0f );
|
||||
if ( VectorNormalize( vecTangentS.AsVector3D() ) == 0.0f )
|
||||
{
|
||||
vecTangentS.Init( 1.0f, 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
CrossProduct( vecNormal, vecTangentS.AsVector3D(), vecTangentT );
|
||||
|
||||
unsigned char red = (int)( u * 255.0f );
|
||||
unsigned char green = (int)( v * 255.0f );
|
||||
unsigned char blue = (int)( v * 255.0f );
|
||||
unsigned char alpha = (int)( v * 255.0f );
|
||||
|
||||
vecPos += vCenter;
|
||||
|
||||
float u1, u2, v1, v2;
|
||||
u1 = u2 = u;
|
||||
v1 = v2 = v;
|
||||
|
||||
if ( bIsUsingLightmap )
|
||||
{
|
||||
u1 = RemapVal( u1, 0.0f, 1.0f, flHalfLuxel, 0.25 - flHalfLuxel );
|
||||
|
||||
if ( bIsUsingBumpedLightmap )
|
||||
{
|
||||
u2 = 0.25f;
|
||||
v2 = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.Position3fv( vecPos.Base() );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
meshBuilder.Color4ub( red, green, blue, alpha );
|
||||
meshBuilder.TexCoord2f( 0, u, v );
|
||||
meshBuilder.TexCoord2f( 1, u1, v1 );
|
||||
meshBuilder.TexCoord2f( 2, u2, v2 );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Emit the triangle strips.
|
||||
//
|
||||
int idx = 0;
|
||||
for ( i = 0; i < nPhi - 1; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
idx = nTheta * i + j;
|
||||
|
||||
meshBuilder.FastIndex( idx );
|
||||
meshBuilder.FastIndex( idx + nTheta );
|
||||
}
|
||||
|
||||
//
|
||||
// Emit a degenerate triangle to skip to the next row without
|
||||
// a connecting triangle.
|
||||
//
|
||||
if ( i < nPhi - 2 )
|
||||
{
|
||||
meshBuilder.FastIndex( idx + 1 );
|
||||
meshBuilder.FastIndex( idx + 1 + nTheta );
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Power of two FB texture
|
||||
//-----------------------------------------------------------------------------
|
||||
static CTextureReference s_pPowerOfTwoFrameBufferTexture;
|
||||
|
||||
static ITexture *GetPowerOfTwoFrameBufferTexture( void )
|
||||
{
|
||||
if( !s_pPowerOfTwoFrameBufferTexture )
|
||||
{
|
||||
s_pPowerOfTwoFrameBufferTexture.Init( materials->FindTexture( "_rt_PowerOfTwoFB", TEXTURE_GROUP_RENDER_TARGET ) );
|
||||
}
|
||||
|
||||
return s_pPowerOfTwoFrameBufferTexture;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// paint it!
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPanel::OnPaint3D()
|
||||
{
|
||||
if (!m_pMaterial)
|
||||
return;
|
||||
|
||||
// Deal with refraction
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
if ( m_pMaterial->NeedsPowerOfTwoFrameBufferTexture() )
|
||||
{
|
||||
ITexture *pTexture = GetPowerOfTwoFrameBufferTexture();
|
||||
if ( pTexture && !pTexture->IsError() )
|
||||
{
|
||||
pRenderContext->CopyRenderTargetToTexture( pTexture );
|
||||
pRenderContext->SetFrameBufferCopyTexture( pTexture );
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a background (translucent objects will appear that way)
|
||||
|
||||
// FIXME: Draw the outline of this panel?
|
||||
|
||||
pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
|
||||
|
||||
RenderSphere( vec3_origin, SPHERE_RADIUS, 20, 20 );
|
||||
/*
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->LoadIdentity();
|
||||
pRenderContext->Ortho( 0, 0, m_iViewableWidth, m_iViewableHeight, 0, 1 );
|
||||
|
||||
pRenderContext->Bind( m_pMaterial );
|
||||
IMesh *pMesh = pRenderContext->GetDynamicMesh();
|
||||
CMeshBuilder meshBuilder;
|
||||
|
||||
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
|
||||
|
||||
if (!m_bUseActualSize)
|
||||
{
|
||||
DrawStretchedToPanel( meshBuilder );
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawActualSize( meshBuilder );
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
*/
|
||||
}
|
||||
|
||||
300
vgui2/matsys_controls/vmtpicker.cpp
Normal file
300
vgui2/matsys_controls/vmtpicker.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "matsys_controls/vmtpicker.h"
|
||||
#include "matsys_controls/vmtpreviewpanel.h"
|
||||
#include "vgui_controls/Splitter.h"
|
||||
#include "vgui_controls/CheckButton.h"
|
||||
#include "vgui_controls/Slider.h"
|
||||
#include "vgui_controls/MenuButton.h"
|
||||
#include "vgui_controls/Panel.h"
|
||||
#include "matsys_controls/sheetsequencepanel.h"
|
||||
#include "bitmap/psheet.h"
|
||||
#include "keyvalues.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// VMT Preview Toolbar - controls for tweaking the VMT preview
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CVMTPreviewToolbar::CVMTPreviewToolbar( vgui::Panel *parent, const char *panelName, CVMTPicker *parentpicker ) :
|
||||
BaseClass( parent, panelName ), m_pParentPicker( parentpicker )
|
||||
{
|
||||
vgui::CBoxSizer* pSizer = new vgui::CBoxSizer( vgui::ESLD_HORIZONTAL );
|
||||
SetSizer( pSizer );
|
||||
|
||||
// buttons + controls
|
||||
|
||||
vgui::SizerAddArgs_t buttonAddArgs = vgui::SizerAddArgs_t().FixedSize(-1,18).Padding(2);
|
||||
|
||||
pSizer->AddSpacer( vgui::SizerAddArgs_t().Padding( 15 ) );
|
||||
|
||||
m_pPrevSeqButton = new vgui::Button( this, "PrevSeqButton", "<", this );
|
||||
m_pPrevSeqButton->SetCommand( new KeyValues( "OnPrevSequence" ) );
|
||||
pSizer->AddPanel( m_pPrevSeqButton, buttonAddArgs );
|
||||
|
||||
m_pSequenceSelection = new vgui::MenuButton( this, "SequenceSelection", "-" );
|
||||
pSizer->AddPanel( m_pSequenceSelection, vgui::SizerAddArgs_t().FixedSize(120,18).Padding(2) );
|
||||
|
||||
m_pNextSeqButton = new vgui::Button( this, "NextSeqButton", ">", this );
|
||||
m_pNextSeqButton->SetCommand( new KeyValues( "OnNextSequence" ) );
|
||||
pSizer->AddPanel( m_pNextSeqButton, buttonAddArgs );
|
||||
|
||||
m_pSequenceSelection_Second = new vgui::MenuButton( this, "SequenceSelection", "(Color)" );
|
||||
pSizer->AddPanel( m_pSequenceSelection_Second, buttonAddArgs );
|
||||
|
||||
m_pSheetPreviewSpeed = new vgui::Slider( this, "SheetPreviewSpeed" );
|
||||
m_pSheetPreviewSpeed->SetRange( 5, 3000 );
|
||||
m_pSheetPreviewSpeed->SetValue( 750 );
|
||||
m_pSheetPreviewSpeed->AddActionSignalTarget( this );
|
||||
pSizer->AddPanel( m_pSheetPreviewSpeed, vgui::SizerAddArgs_t().FixedSize(150,18).Padding(2) );
|
||||
|
||||
// preview panels
|
||||
|
||||
m_pSheetPanel = new CSheetSequencePanel(this, "sheetpanel");
|
||||
m_pSheetPanel->AddActionSignalTarget( this );
|
||||
m_pSequenceSelection->SetMenu( m_pSheetPanel );
|
||||
|
||||
m_pSheetPanel_Second = new CSheetSequencePanel(this, "sheetpanel_second");
|
||||
m_pSheetPanel_Second->SetSecondSequenceView( true );
|
||||
m_pSheetPanel_Second->AddActionSignalTarget( this );
|
||||
m_pSequenceSelection_Second->SetMenu( m_pSheetPanel_Second );
|
||||
|
||||
UpdateToolbarGUI();
|
||||
}
|
||||
|
||||
|
||||
void CVMTPreviewToolbar::OnNextSequence( )
|
||||
{
|
||||
int nSeq = m_pParentPicker->GetCurrentSequence();
|
||||
nSeq = (nSeq + 1) % m_pParentPicker->GetSheetSequenceCount();
|
||||
|
||||
m_pParentPicker->SetSelectedSequence( nSeq );
|
||||
UpdateToolbarGUI();
|
||||
}
|
||||
|
||||
void CVMTPreviewToolbar::OnPrevSequence( )
|
||||
{
|
||||
int nSeq = m_pParentPicker->GetCurrentSequence();
|
||||
|
||||
if ( nSeq == 0 )
|
||||
{
|
||||
nSeq = m_pParentPicker->GetSheetSequenceCount()-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nSeq = (nSeq - 1) % m_pParentPicker->GetSheetSequenceCount();
|
||||
}
|
||||
|
||||
m_pParentPicker->SetSelectedSequence( nSeq );
|
||||
UpdateToolbarGUI();
|
||||
}
|
||||
|
||||
void CVMTPreviewToolbar::OnSliderMoved( KeyValues *pData )
|
||||
{
|
||||
vgui::Panel *pPanel = reinterpret_cast<vgui::Panel *>( const_cast<KeyValues*>(pData)->GetPtr("panel") );
|
||||
|
||||
if ( pPanel == m_pSheetPreviewSpeed )
|
||||
{
|
||||
m_pParentPicker->SetSheetPreviewSpeed( m_pSheetPreviewSpeed->GetValue() );
|
||||
}
|
||||
}
|
||||
|
||||
void CVMTPreviewToolbar::PopulateSequenceMenu( vgui::Menu *menu )
|
||||
{
|
||||
menu->DeleteAllItems();
|
||||
|
||||
int nSequences = m_pParentPicker->GetSheetSequenceCount();
|
||||
for ( int i = 0; i < nSequences; ++i )
|
||||
{
|
||||
char sz[64];
|
||||
Q_snprintf( sz, sizeof( sz ), "Sequence %d", i );
|
||||
menu->AddMenuItem( "seqitem", sz, new KeyValues( "OnSelectSequence", "nSequenceNumber", i ), this );
|
||||
}
|
||||
}
|
||||
|
||||
int CVMTPreviewToolbar::GetSequenceMenuItemCount( )
|
||||
{
|
||||
return m_pParentPicker->GetSheetSequenceCount();
|
||||
}
|
||||
|
||||
void CVMTPreviewToolbar::OnSelectSequence( int nSequenceNumber )
|
||||
{
|
||||
m_pParentPicker->SetSelectedSequence(nSequenceNumber);
|
||||
UpdateToolbarGUI();
|
||||
}
|
||||
|
||||
void CVMTPreviewToolbar::OnSheetSequenceSelected( KeyValues *pData )
|
||||
{
|
||||
if ( pData->GetBool("bIsSecondSequence") )
|
||||
{
|
||||
m_pParentPicker->SetSelectedSecondarySequence( pData->GetInt("nSequenceNumber") );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pParentPicker->SetSelectedSequence( pData->GetInt("nSequenceNumber") );
|
||||
}
|
||||
UpdateToolbarGUI();
|
||||
}
|
||||
|
||||
void CVMTPreviewToolbar::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
|
||||
m_pSequenceSelection->SetFont( pScheme->GetFont( "DefaultVerySmall" ) );
|
||||
}
|
||||
|
||||
void CVMTPreviewToolbar::UpdateToolbarGUI()
|
||||
{
|
||||
int nSequences = m_pParentPicker->GetSheetSequenceCount();
|
||||
int nCurrentSequence = m_pParentPicker->GetCurrentSequence();
|
||||
int nRealSeqNumber = m_pParentPicker->GetRealSequenceNumber();
|
||||
bool bSecondPicker = CSheetExtended::IsMaterialSeparateAlphaColorMaterial( m_pParentPicker->GetMaterial() );
|
||||
|
||||
if ( nSequences == 0 )
|
||||
{
|
||||
m_pSequenceSelection->SetText( "No Sequences" );
|
||||
m_pSequenceSelection->SetEnabled(false);
|
||||
m_pNextSeqButton->SetEnabled(false);
|
||||
m_pPrevSeqButton->SetEnabled(false);
|
||||
m_pSequenceSelection_Second->SetVisible(false);
|
||||
|
||||
m_pSheetPanel->SetFromMaterial( NULL );
|
||||
m_pSheetPanel_Second->SetFromMaterial( NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
char sz[64];
|
||||
Q_snprintf( sz, sizeof( sz ), "%d/%d Sequences (#%d)", nCurrentSequence+1, nSequences, nRealSeqNumber );
|
||||
m_pSequenceSelection->SetText( sz );
|
||||
m_pSequenceSelection->SetEnabled(true);
|
||||
m_pSequenceSelection_Second->SetVisible(bSecondPicker);
|
||||
|
||||
m_pNextSeqButton->SetEnabled(true);
|
||||
m_pPrevSeqButton->SetEnabled(true);
|
||||
|
||||
m_pSheetPanel->SetFromMaterial( m_pParentPicker->GetMaterial() );
|
||||
m_pSheetPanel_Second->SetFromMaterial( m_pParentPicker->GetMaterial() );
|
||||
}
|
||||
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVMTPicker::CVMTPicker( vgui::Panel *pParent, bool bAllowMultiselect ) :
|
||||
BaseClass( pParent, "VMT Files", "vmt", "materials", "vmtName" )
|
||||
{
|
||||
// Horizontal splitter for preview
|
||||
m_pPreviewSplitter = new vgui::Splitter( this, "PreviewSplitter", vgui::SPLITTER_MODE_VERTICAL, 1 );
|
||||
vgui::Panel *pSplitterLeftSide = m_pPreviewSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterRightSide = m_pPreviewSplitter->GetChild( 1 );
|
||||
|
||||
m_p2D3DSplitter = new vgui::Splitter( pSplitterRightSide, "2D3DSplitter", vgui::SPLITTER_MODE_HORIZONTAL, 1 );
|
||||
vgui::Panel *pSplitterTopSide = m_p2D3DSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterBottomSide = m_p2D3DSplitter->GetChild( 1 );
|
||||
|
||||
// VMT preview
|
||||
m_pVMTPreview2D = new CVMTPreviewPanel( pSplitterTopSide, "VMTPreview2D" );
|
||||
m_pVMTPreview3D = new CVMTPreviewPanel( pSplitterBottomSide, "VMTPreview3D" );
|
||||
m_pVMTPreview3D->DrawIn3DMode( true );
|
||||
|
||||
m_pVMTPreviewToolbar = new CVMTPreviewToolbar( pSplitterBottomSide, "PreviewToolbar", this );
|
||||
|
||||
// Standard browser controls
|
||||
CreateStandardControls( pSplitterLeftSide, bAllowMultiselect );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/vmtpicker.res" );
|
||||
}
|
||||
|
||||
CVMTPicker::~CVMTPicker()
|
||||
{
|
||||
}
|
||||
|
||||
void CVMTPicker::SetSheetPreviewSpeed( float flPreviewSpeed )
|
||||
{
|
||||
m_pVMTPreview2D->SetSheetPreviewSpeed( flPreviewSpeed );
|
||||
m_pVMTPreview3D->SetSheetPreviewSpeed( flPreviewSpeed );
|
||||
}
|
||||
|
||||
void CVMTPicker::SetSelectedSequence( int nSequence )
|
||||
{
|
||||
m_pVMTPreview2D->SetSheetSequence( nSequence );
|
||||
m_pVMTPreview3D->SetSheetSequence( nSequence );
|
||||
}
|
||||
|
||||
void CVMTPicker::SetSelectedSecondarySequence( int nSequence )
|
||||
{
|
||||
m_pVMTPreview2D->SetSecondarySheetSequence( nSequence );
|
||||
m_pVMTPreview3D->SetSecondarySheetSequence( nSequence );
|
||||
}
|
||||
|
||||
int CVMTPicker::GetSheetSequenceCount()
|
||||
{
|
||||
return m_pVMTPreview3D->GetSheetSequenceCount();
|
||||
}
|
||||
|
||||
int CVMTPicker::GetCurrentSequence()
|
||||
{
|
||||
return m_pVMTPreview3D->GetCurrentSequence();
|
||||
}
|
||||
|
||||
int CVMTPicker::GetCurrentSecondarySequence()
|
||||
{
|
||||
return m_pVMTPreview3D->GetCurrentSecondarySequence();
|
||||
}
|
||||
|
||||
int CVMTPicker::GetRealSequenceNumber()
|
||||
{
|
||||
return m_pVMTPreview3D->GetRealSequenceNumber();
|
||||
}
|
||||
|
||||
void CVMTPicker::CustomizeSelectionMessage( KeyValues *pKeyValues )
|
||||
{
|
||||
BaseClass::CustomizeSelectionMessage(pKeyValues);
|
||||
|
||||
pKeyValues->SetInt( "sheet_sequence_count", GetSheetSequenceCount() );
|
||||
pKeyValues->SetInt( "sheet_sequence_number", GetCurrentSequence() );
|
||||
pKeyValues->SetInt( "sheet_sequence_secondary_number", GetCurrentSecondarySequence() );
|
||||
}
|
||||
|
||||
CSheetExtended* CVMTPicker::GetSheet()
|
||||
{
|
||||
return m_pVMTPreview3D->GetSheet();
|
||||
}
|
||||
|
||||
IMaterial* CVMTPicker::GetMaterial()
|
||||
{
|
||||
return m_pVMTPreview3D->GetMaterial();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derived classes have this called when the previewed asset changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPicker::OnSelectedAssetPicked( const char *pAssetName )
|
||||
{
|
||||
m_pVMTPreview2D->SetVMT( pAssetName );
|
||||
m_pVMTPreview3D->SetVMT( pAssetName );
|
||||
m_pVMTPreviewToolbar->UpdateToolbarGUI();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CVMTPickerFrame::CVMTPickerFrame( vgui::Panel *pParent, const char *pTitle, bool bAllowMultiselect ) :
|
||||
BaseClass( pParent )
|
||||
{
|
||||
SetAssetPicker( new CVMTPicker( this, bAllowMultiselect ) );
|
||||
LoadControlSettingsAndUserConfig( "resource/vmtpickerframe.res" );
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
738
vgui2/matsys_controls/vmtpreviewpanel.cpp
Normal file
738
vgui2/matsys_controls/vmtpreviewpanel.cpp
Normal file
@@ -0,0 +1,738 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/vmtpreviewpanel.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "matsys_controls/sheetsequencepanel.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "materialsystem/MaterialSystemUtil.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "bitmap/psheet.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
#define FOV 90.0f
|
||||
#define ZNEAR 0.1f
|
||||
#define ZFAR 2000.0f
|
||||
#define ROTATION_SPEED 40.0f // degrees/sec
|
||||
#define VIEW_DISTANCE 12.0f
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// VMT Preview panel
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CVMTPreviewPanel::CVMTPreviewPanel( vgui::Panel *pParent, const char *pName ) :
|
||||
BaseClass( pParent, pName )
|
||||
{
|
||||
m_pMaterialSheet = NULL;
|
||||
|
||||
SetVMT( "//platform/materials/vgui/vtfnotloaded" );
|
||||
|
||||
m_pLightmapTexture.Init( "//platform/materials/debug/defaultlightmap", "editor" );
|
||||
m_DefaultEnvCubemap.Init( "editor/cubemap", "editor", true );
|
||||
m_LightDirection.Init( 0.0f, 1.0f, -1.0f );
|
||||
m_LightColor.SetColor( 255, 255, 255, 255 );
|
||||
m_flLightIntensity = 2.0f;
|
||||
m_bDrawIn3DMode = false;
|
||||
|
||||
m_flSheetPreviewSpeed = 750.0f;
|
||||
m_nCurrentSheetSequence = 0;
|
||||
m_nCurrentSecondarySheetSequence = 0;
|
||||
|
||||
// Reset the camera direction
|
||||
m_vecCameraDirection.Init( 1.0f, 0.0f, 0.0f );
|
||||
m_flLastRotationTime = Plat_FloatTime();
|
||||
m_flLastSwitchTime = Plat_FloatTime();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the current VMT
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::SetVMT( const char *pMaterialName )
|
||||
{
|
||||
m_Material.Init( pMaterialName, "editor material" );
|
||||
m_VMTName = pMaterialName;
|
||||
|
||||
m_flLastSwitchTime = Plat_FloatTime();
|
||||
|
||||
if ( m_pMaterialSheet )
|
||||
{
|
||||
delete m_pMaterialSheet;
|
||||
}
|
||||
|
||||
if ( m_bDrawIn3DMode )
|
||||
{
|
||||
m_pMaterialSheet = new CSheetExtended( m_Material );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pMaterialSheet = NULL;
|
||||
}
|
||||
|
||||
m_nCurrentSheetSequence = 0;
|
||||
m_nCurrentSecondarySheetSequence = 0;
|
||||
}
|
||||
|
||||
void CVMTPreviewPanel::SetSheetPreviewSpeed( float flPreviewSpeed )
|
||||
{
|
||||
m_flSheetPreviewSpeed = flPreviewSpeed;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the current VMT
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CVMTPreviewPanel::GetVMT() const
|
||||
{
|
||||
return m_VMTName;
|
||||
}
|
||||
|
||||
CSheetExtended* CVMTPreviewPanel::GetSheet()
|
||||
{
|
||||
return m_pMaterialSheet;
|
||||
}
|
||||
|
||||
IMaterial* CVMTPreviewPanel::GetMaterial()
|
||||
{
|
||||
return m_Material;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// View it in 3D or 2D mode
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::DrawIn3DMode( bool b3DMode )
|
||||
{
|
||||
m_bDrawIn3DMode = b3DMode;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up lighting state
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::SetupLightingState()
|
||||
{
|
||||
MaterialLightingState_t state;
|
||||
memset( &state, 0, sizeof(state) );
|
||||
|
||||
state.m_nLocalLightCount = 1;
|
||||
LightDesc_t &desc = state.m_pLocalLightDesc[0];
|
||||
|
||||
desc.m_Type = MATERIAL_LIGHT_DIRECTIONAL;
|
||||
|
||||
desc.m_Color[0] = m_LightColor.r();
|
||||
desc.m_Color[1] = m_LightColor.g();
|
||||
desc.m_Color[2] = m_LightColor.b();
|
||||
desc.m_Color *= m_flLightIntensity / 255.0f;
|
||||
|
||||
desc.m_Attenuation0 = 1.0f;
|
||||
desc.m_Attenuation1 = 0.0f;
|
||||
desc.m_Attenuation2 = 0.0f;
|
||||
|
||||
desc.m_Direction = m_LightDirection;
|
||||
VectorNormalize( desc.m_Direction );
|
||||
|
||||
desc.m_Theta = 0.0f;
|
||||
desc.m_Phi = 0.0f;
|
||||
desc.m_Falloff = 1.0f;
|
||||
desc.RecalculateDerivedValues();
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
pRenderContext->SetLightingState( state );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw a sphere
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::RenderSphere( const Vector &vCenter, float flRadius, int nTheta, int nPhi )
|
||||
{
|
||||
int nVertices = nTheta * nPhi;
|
||||
int nIndices = 2 * ( nTheta + 1 ) * ( nPhi - 1 );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, nVertices, nIndices );
|
||||
|
||||
bool bIsUsingLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_LIGHTMAP );
|
||||
bool bIsUsingBumpedLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS );
|
||||
|
||||
int nLightmapWidth = m_pLightmapTexture->GetActualWidth();
|
||||
float flHalfLuxel = 0.5f / nLightmapWidth;
|
||||
|
||||
//
|
||||
// Build the index buffer.
|
||||
//
|
||||
int i, j;
|
||||
for ( i = 0; i < nPhi; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
float u = j / ( float )(nTheta - 1);
|
||||
float v = i / ( float )(nPhi - 1);
|
||||
float theta = ( j != nTheta-1 ) ? 2.0f * M_PI * u : 0.0f;
|
||||
float phi = M_PI * v;
|
||||
|
||||
Vector vecPos;
|
||||
vecPos.x = flRadius * sin(phi) * cos(theta);
|
||||
vecPos.y = flRadius * sin(phi) * sin(theta);
|
||||
vecPos.z = flRadius * cos(phi);
|
||||
|
||||
Vector vecNormal = vecPos;
|
||||
VectorNormalize( vecNormal );
|
||||
|
||||
Vector4D vecTangentS;
|
||||
Vector vecTangentT;
|
||||
vecTangentS.Init( vecPos.z, -vecPos.x, 0.0f, 1.0f );
|
||||
if ( VectorNormalize( vecTangentS.AsVector3D() ) == 0.0f )
|
||||
{
|
||||
vecTangentS.Init( 1.0f, 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
CrossProduct( vecNormal, vecTangentS.AsVector3D(), vecTangentT );
|
||||
|
||||
unsigned char red = (int)( u * 255.0f );
|
||||
unsigned char green = (int)( v * 255.0f );
|
||||
unsigned char blue = (int)( v * 255.0f );
|
||||
unsigned char alpha = (int)( v * 255.0f );
|
||||
|
||||
vecPos += vCenter;
|
||||
|
||||
float u1, u2, v1, v2;
|
||||
u1 = u2 = u;
|
||||
v1 = v2 = v;
|
||||
|
||||
if ( bIsUsingLightmap )
|
||||
{
|
||||
u1 = RemapVal( u1, 0.0f, 1.0f, flHalfLuxel, 0.25 - flHalfLuxel );
|
||||
|
||||
if ( bIsUsingBumpedLightmap )
|
||||
{
|
||||
u2 = 0.25f;
|
||||
v2 = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.Position3fv( vecPos.Base() );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
meshBuilder.Color4ub( red, green, blue, alpha );
|
||||
meshBuilder.TexCoord4f( 0, 2.0f * u, v, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 1, u1, v1, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 2, u2, v2, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 3, u1, v1, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 4, u2, v2, 0, 0 );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Emit the triangle strips.
|
||||
//
|
||||
int idx = 0;
|
||||
for ( i = 0; i < nPhi - 1; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
idx = nTheta * i + j;
|
||||
|
||||
meshBuilder.FastIndex( idx );
|
||||
meshBuilder.FastIndex( idx + nTheta );
|
||||
}
|
||||
|
||||
//
|
||||
// Emit a degenerate triangle to skip to the next row without
|
||||
// a connecting triangle.
|
||||
//
|
||||
if ( i < nPhi - 2 )
|
||||
{
|
||||
meshBuilder.FastIndex( idx + 1 );
|
||||
meshBuilder.FastIndex( idx + 1 + nTheta );
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw sprite-card based materials
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::RenderSheet( const Vector &vCenter, float flRadius )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
IMesh *pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
if ( !m_pMaterialSheet->ValidSheetData() )
|
||||
return;
|
||||
|
||||
float flAge = fmodf( Plat_FloatTime() - m_flLastSwitchTime, m_pMaterialSheet->GetSequenceTimeSpan( m_nCurrentSheetSequence ) );
|
||||
m_pMaterialSheet->DrawSheet( pMesh, vCenter, flRadius, m_nCurrentSheetSequence, flAge, m_flSheetPreviewSpeed, true, m_nCurrentSecondarySheetSequence );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a regular texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::DrawRectangle( void )
|
||||
{
|
||||
// Get the aspect ratio of the material
|
||||
int tw = m_Material->GetMappingWidth();
|
||||
int th = m_Material->GetMappingHeight();
|
||||
|
||||
if ( tw <= 0 || th <= 0 )
|
||||
return;
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
if ( w == 0 || h == 0 )
|
||||
return;
|
||||
|
||||
SetupOrthoMatrix( w, h );
|
||||
SetupLightingState();
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
||||
pRenderContext->LoadIdentity();
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
||||
pRenderContext->LoadIdentity();
|
||||
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 4, 4 );
|
||||
|
||||
bool bIsUsingLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_LIGHTMAP );
|
||||
bool bIsUsingBumpedLightmap = m_Material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS );
|
||||
|
||||
int nLightmapWidth = m_pLightmapTexture->GetActualWidth();
|
||||
float flHalfLuxel = 0.5f / nLightmapWidth;
|
||||
Vector2D halfTexel( 0.5f / tw, 0.5f / th );
|
||||
|
||||
Vector vecNormal( 0.0f, 0.0f, 1.0f );
|
||||
Vector4D vecTangentS( 1.0f, 0.0f, 0.0f, 1.0f );
|
||||
Vector vecTangentT;
|
||||
CrossProduct( vecNormal, vecTangentS.AsVector3D(), vecTangentT );
|
||||
|
||||
float screenaspect = (float)tw / (float)th;
|
||||
float aspect = (float)w / (float)h;
|
||||
|
||||
float ratio = screenaspect / aspect;
|
||||
|
||||
// Screen is wider, need bars at top and bottom
|
||||
int x2, y2;
|
||||
int x, y;
|
||||
x = y = 0;
|
||||
int nXBorder = w > 15 ? 5 : w / 3;
|
||||
int nYBorder = h > 15 ? 5 : h / 3;
|
||||
w -= 2 * nXBorder;
|
||||
h -= 2 * nYBorder;
|
||||
if ( ratio > 1.0f )
|
||||
{
|
||||
int usetall = (float)w / screenaspect;
|
||||
y = ( h - usetall ) / 2;
|
||||
h = usetall;
|
||||
}
|
||||
// Screen is narrower, need bars at left/right
|
||||
else
|
||||
{
|
||||
int usewide = (float)h * screenaspect;
|
||||
x = ( w - usewide ) / 2;
|
||||
w = usewide;
|
||||
}
|
||||
x += nXBorder;
|
||||
y += nYBorder;
|
||||
|
||||
x2 = x+w; y2 = y+h;
|
||||
|
||||
float u = halfTexel.x;
|
||||
float v = halfTexel.y;
|
||||
|
||||
float u1_l, u1_r, v1_t, v1_b;
|
||||
float u2_l, u2_r, v2_t, v2_b;
|
||||
|
||||
u1_l = u2_l = u;
|
||||
u1_r = u2_r = 1.0f - u;
|
||||
v1_t = v2_t = v;
|
||||
v1_b = v2_b = 1.0f - v;
|
||||
|
||||
if ( bIsUsingLightmap )
|
||||
{
|
||||
u1_l = v1_t = flHalfLuxel;
|
||||
u1_r = v1_b = 0.25 - flHalfLuxel;
|
||||
if ( bIsUsingBumpedLightmap )
|
||||
{
|
||||
u2_l = u2_r = 0.25f;
|
||||
v2_t = v2_b = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
bool m_bPreviewVertexColors = false;
|
||||
|
||||
meshBuilder.Position3f( x, y2, 0.0f );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
if ( m_bPreviewVertexColors )
|
||||
{
|
||||
meshBuilder.Color4ub( 255, 0, 0, 255 );
|
||||
}
|
||||
else
|
||||
{
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
meshBuilder.TexCoord4f( 0, u, v, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 1, u1_l, v1_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 2, u2_l, v2_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 3, u1_l, v1_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 4, u2_l, v2_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 5, u1_l, v1_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 6, u2_l, v2_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 7, u1_l, v1_t, 0, 0 );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3f( x, y, 0.0f );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
if ( m_bPreviewVertexColors )
|
||||
{
|
||||
meshBuilder.Color4ub( 255, 255, 255, 64 );
|
||||
}
|
||||
else
|
||||
{
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
meshBuilder.TexCoord4f( 0, u, 1.0f - v, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 1, u1_l, v1_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 2, u2_l, v2_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 3, u1_l, v1_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 4, u2_l, v2_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 5, u1_l, v1_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 6, u2_l, v2_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 7, u1_l, v1_b, 0, 0 );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3f( x2, y2, 0.0f );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
if ( m_bPreviewVertexColors )
|
||||
{
|
||||
meshBuilder.Color4ub( 0, 0, 255, 255 );
|
||||
}
|
||||
else
|
||||
{
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
meshBuilder.TexCoord4f( 0, 1.0f - u, v, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 1, u1_r, v1_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 2, u2_r, v2_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 3, u1_r, v1_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 4, u2_r, v2_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 5, u1_r, v1_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 6, u2_r, v2_t, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 7, u1_r, v1_t, 0, 0 );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3f( x2, y, 0.0f );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
if ( m_bPreviewVertexColors )
|
||||
{
|
||||
meshBuilder.Color4ub( 0, 255, 0, 64 );
|
||||
}
|
||||
else
|
||||
{
|
||||
meshBuilder.Color4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
meshBuilder.TexCoord4f( 0, 1.0f - u, 1.0f - v, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 1, u1_r, v1_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 2, u2_r, v2_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 3, u1_r, v1_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 4, u2_r, v2_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 5, u1_r, v1_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 6, u2_r, v2_b, 0, 0 );
|
||||
meshBuilder.TexCoord4f( 7, u1_r, v1_b, 0, 0 );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.FastIndex( 0 );
|
||||
meshBuilder.FastIndex( 1 );
|
||||
meshBuilder.FastIndex( 2 );
|
||||
meshBuilder.FastIndex( 3 );
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a cubemap texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::DrawSphere( void )
|
||||
{
|
||||
float flNewTime = Plat_FloatTime();
|
||||
|
||||
// Circle the camera around the origin
|
||||
VMatrix rot;
|
||||
MatrixBuildRotateZ( rot, ROTATION_SPEED * (flNewTime - m_flLastRotationTime ) );
|
||||
Vector vecTemp;
|
||||
Vector3DMultiply( rot, m_vecCameraDirection, vecTemp );
|
||||
m_vecCameraDirection = vecTemp;
|
||||
m_flLastRotationTime = flNewTime;
|
||||
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
SetupProjectionMatrix( w, h );
|
||||
SetupLightingState();
|
||||
|
||||
LookAt( vec3_origin, VIEW_DISTANCE );
|
||||
|
||||
// Draw a sphere at the origin
|
||||
// RenderSphere( vec3_origin, 10.0f, 20, 20 );
|
||||
if ( m_pMaterialSheet && m_pMaterialSheet->ValidSheetData() )
|
||||
{
|
||||
RenderSheet( vec3_origin, 10.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderSphere( vec3_origin, 10.0f, 20, 20 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the camera to look at the the thing we're spinning around
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::LookAt( const Vector &vecLookAt, float flRadius )
|
||||
{
|
||||
// Compute the distance to the camera for the object based on its
|
||||
// radius and fov.
|
||||
|
||||
// since tan( fov/2 ) = f/d
|
||||
// cos( fov/2 ) = r / r' where r = sphere radius, r' = perp distance from sphere center to max extent of camera
|
||||
// d/f = r'/d' where d' is distance of camera to sphere
|
||||
// d' = r' / tan( fov/2 ) * r' = r / ( cos (fov/2) * tan( fov/2 ) ) = r / sin( fov/2 )
|
||||
float flFOVx = FOV;
|
||||
|
||||
// Compute fov/2 in radians
|
||||
flFOVx *= M_PI / 360.0f;
|
||||
|
||||
// Compute an effective fov based on the aspect ratio
|
||||
// if the height is smaller than the width
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
if ( h < w )
|
||||
{
|
||||
flFOVx = atan( h * tan( flFOVx ) / w );
|
||||
}
|
||||
|
||||
float flDistance = flRadius / sin( flFOVx );
|
||||
|
||||
Vector vecMDLOrigin = vecLookAt;
|
||||
Vector vecCameraOrigin;
|
||||
VectorMA( vecMDLOrigin, -flDistance, m_vecCameraDirection, vecCameraOrigin );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
QAngle angles;
|
||||
VectorAngles( m_vecCameraDirection, angles );
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
||||
pRenderContext->LoadIdentity();
|
||||
|
||||
// convert from a right handed system to a left handed system
|
||||
// since dx for wants it that way.
|
||||
// pRenderContext->Scale( 1.0f, 1.0f, -1.0f );
|
||||
|
||||
pRenderContext->Rotate( -90, 1, 0, 0 ); // put Z going up
|
||||
pRenderContext->Rotate( 90, 0, 0, 1 ); // put Z going up
|
||||
pRenderContext->Rotate( -angles[2], 1, 0, 0 );
|
||||
pRenderContext->Rotate( -angles[0], 0, 1, 0 );
|
||||
pRenderContext->Rotate( -angles[1], 0, 0, 1 );
|
||||
pRenderContext->Translate( -vecCameraOrigin[0], -vecCameraOrigin[1], -vecCameraOrigin[2] );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set up a projection matrix for a 90 degree fov
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::SetupProjectionMatrix( int nWidth, int nHeight )
|
||||
{
|
||||
VMatrix proj;
|
||||
float flFOV = FOV;
|
||||
float flZNear = ZNEAR;
|
||||
float flZFar = ZFAR;
|
||||
float flApsectRatio = (nHeight != 0.0f) ? (float)nWidth / (float)nHeight : 100.0f;
|
||||
|
||||
float halfWidth = tan( flFOV * M_PI / 360.0 );
|
||||
float halfHeight = halfWidth / flApsectRatio;
|
||||
|
||||
memset( proj.Base(), 0, sizeof( proj ) );
|
||||
proj[0][0] = 1.0f / halfWidth;
|
||||
proj[1][1] = 1.0f / halfHeight;
|
||||
proj[2][2] = flZFar / ( flZNear - flZFar );
|
||||
proj[3][2] = -1.0f;
|
||||
proj[2][3] = flZNear * flZFar / ( flZNear - flZFar );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->LoadMatrix( proj );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set up a orthographic projection matrix
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::SetupOrthoMatrix( int nWidth, int nHeight )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->LoadIdentity();
|
||||
pRenderContext->Ortho( 0, 0, nWidth, nHeight, -1.0f, 1.0f );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Power of two FB texture
|
||||
//-----------------------------------------------------------------------------
|
||||
static CTextureReference s_pPowerOfTwoFrameBufferTexture;
|
||||
|
||||
static ITexture *GetPowerOfTwoFrameBufferTexture( void )
|
||||
{
|
||||
if ( !s_pPowerOfTwoFrameBufferTexture )
|
||||
{
|
||||
s_pPowerOfTwoFrameBufferTexture.Init( vgui::MaterialSystem()->FindTexture( "_rt_PowerOfTwoFB", TEXTURE_GROUP_RENDER_TARGET ) );
|
||||
}
|
||||
|
||||
return s_pPowerOfTwoFrameBufferTexture;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints the texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVMTPreviewPanel::Paint( void )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
vgui::MatSystemSurface()->Begin3DPaint( 0, 0, w, h );
|
||||
|
||||
// Deal with refraction
|
||||
if ( m_Material->NeedsPowerOfTwoFrameBufferTexture() )
|
||||
{
|
||||
ITexture *pTexture = GetPowerOfTwoFrameBufferTexture();
|
||||
if ( pTexture && !pTexture->IsError() )
|
||||
{
|
||||
pRenderContext->CopyRenderTargetToTexture( pTexture );
|
||||
pRenderContext->SetFrameBufferCopyTexture( pTexture );
|
||||
}
|
||||
}
|
||||
|
||||
pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
|
||||
pRenderContext->ClearBuffers( true, true );
|
||||
|
||||
pRenderContext->FogMode( MATERIAL_FOG_NONE );
|
||||
pRenderContext->SetNumBoneWeights( 0 );
|
||||
pRenderContext->Bind( m_Material );
|
||||
pRenderContext->BindLightmapTexture( m_pLightmapTexture );
|
||||
pRenderContext->BindLocalCubemap( m_DefaultEnvCubemap );
|
||||
|
||||
if ( m_bDrawIn3DMode )
|
||||
{
|
||||
DrawSphere();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawRectangle();
|
||||
}
|
||||
|
||||
vgui::MatSystemSurface()->End3DPaint( );
|
||||
}
|
||||
|
||||
bool CVMTPreviewPanel::VMTUsesSheets()
|
||||
{
|
||||
return m_pMaterialSheet != NULL;
|
||||
}
|
||||
|
||||
int CVMTPreviewPanel::GetSheetSequenceCount()
|
||||
{
|
||||
if ( m_pMaterialSheet == NULL )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_pMaterialSheet->GetSheetSequenceCount();
|
||||
}
|
||||
|
||||
// TODO: sort this out - sequence #n != nth sequence
|
||||
int CVMTPreviewPanel::GetCurrentSequence()
|
||||
{
|
||||
return m_nCurrentSheetSequence;
|
||||
}
|
||||
|
||||
int CVMTPreviewPanel::GetCurrentSecondarySequence()
|
||||
{
|
||||
return m_nCurrentSecondarySheetSequence;
|
||||
}
|
||||
|
||||
|
||||
int CVMTPreviewPanel::GetRealSequenceNumber()
|
||||
{
|
||||
return m_nCurrentSheetSequence;
|
||||
}
|
||||
|
||||
void CVMTPreviewPanel::SetSheetSequence( int nSequence )
|
||||
{
|
||||
if ( m_pMaterialSheet == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_nCurrentSheetSequence = m_pMaterialSheet->GetNthSequenceIndex(nSequence);
|
||||
}
|
||||
|
||||
void CVMTPreviewPanel::SetSecondarySheetSequence( int nSequence )
|
||||
{
|
||||
if ( m_pMaterialSheet == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_nCurrentSecondarySheetSequence = m_pMaterialSheet->GetNthSequenceIndex(nSequence);
|
||||
}
|
||||
2
vgui2/matsys_controls/vsi.nul
Normal file
2
vgui2/matsys_controls/vsi.nul
Normal file
@@ -0,0 +1,2 @@
|
||||
SN Visual Studio Integration
|
||||
IMPORTANT: Do not remove the custom build step for this file
|
||||
74
vgui2/matsys_controls/vtfpicker.cpp
Normal file
74
vgui2/matsys_controls/vtfpicker.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "matsys_controls/vtfpicker.h"
|
||||
#include "matsys_controls/vtfpreviewpanel.h"
|
||||
#include "vgui_controls/Splitter.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Asset Picker with no preview
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVTFPicker::CVTFPicker( vgui::Panel *pParent ) :
|
||||
BaseClass( pParent, "VTF Files", "vtf", "materials", "vtfName" )
|
||||
{
|
||||
// Horizontal splitter for preview
|
||||
m_pPreviewSplitter = new Splitter( this, "PreviewSplitter", SPLITTER_MODE_VERTICAL, 1 );
|
||||
vgui::Panel *pSplitterLeftSide = m_pPreviewSplitter->GetChild( 0 );
|
||||
vgui::Panel *pSplitterRightSide = m_pPreviewSplitter->GetChild( 1 );
|
||||
|
||||
// VTF preview
|
||||
m_pVTFPreview = new CVTFPreviewPanel( pSplitterRightSide, "VTFPreview" );
|
||||
|
||||
// Standard browser controls
|
||||
CreateStandardControls( pSplitterLeftSide );
|
||||
|
||||
LoadControlSettingsAndUserConfig( "resource/vtfpicker.res" );
|
||||
}
|
||||
|
||||
CVTFPicker::~CVTFPicker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derived classes have this called when the previewed asset changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPicker::OnSelectedAssetPicked( const char *pAssetName )
|
||||
{
|
||||
m_pVTFPreview->SetVTF( pAssetName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: Modal picker frame
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CVTFPickerFrame::CVTFPickerFrame( vgui::Panel *pParent, const char *pTitle ) :
|
||||
BaseClass( pParent )
|
||||
{
|
||||
SetAssetPicker( new CVTFPicker( this ) );
|
||||
LoadControlSettingsAndUserConfig( "resource/vtfpickerframe.res" );
|
||||
SetTitle( pTitle, false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
432
vgui2/matsys_controls/vtfpreviewpanel.cpp
Normal file
432
vgui2/matsys_controls/vtfpreviewpanel.cpp
Normal file
@@ -0,0 +1,432 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "matsys_controls/vtfpreviewpanel.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "materialsystem/MaterialSystemUtil.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
#define FOV 90.0f
|
||||
#define ZNEAR 0.1f
|
||||
#define ZFAR 2000.0f
|
||||
#define ROTATION_SPEED 120.0f // degrees/sec
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// VTF Preview panel
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVTFPreviewPanel::CVTFPreviewPanel( vgui::Panel *pParent, const char *pName ) :
|
||||
BaseClass( pParent, pName )
|
||||
{
|
||||
SetVTF( "//platform/materials/vgui/vtfnotloaded", true );
|
||||
m_nTextureID = MatSystemSurface()->CreateNewTextureID( false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the current VTF
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::SetVTF( const char *pFullPath, bool bLoadImmediately )
|
||||
{
|
||||
m_PreviewTexture.Init( pFullPath, "editor texture" );
|
||||
m_VTFName = pFullPath;
|
||||
|
||||
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
|
||||
if ( m_PreviewTexture->IsCubeMap() )
|
||||
{
|
||||
pVMTKeyValues->SetString( "$envmap", pFullPath );
|
||||
}
|
||||
else if ( m_PreviewTexture->IsNormalMap() )
|
||||
{
|
||||
pVMTKeyValues->SetString( "$bumpmap", pFullPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
pVMTKeyValues->SetString( "$basetexture", pFullPath );
|
||||
}
|
||||
pVMTKeyValues->SetInt( "$nocull", 1 );
|
||||
pVMTKeyValues->SetInt( "$nodebug", 1 );
|
||||
m_PreviewMaterial.Init( MaterialSystem()->CreateMaterial( pFullPath, pVMTKeyValues ));
|
||||
|
||||
MatSystemSurface()->DrawSetTextureMaterial( m_nTextureID, m_PreviewMaterial );
|
||||
|
||||
// Reset the camera direction
|
||||
m_vecCameraDirection.Init( 1.0f, 0.0f, 0.0f );
|
||||
m_flLastRotationTime = Plat_FloatTime();
|
||||
}
|
||||
|
||||
void CVTFPreviewPanel::SetTwoVTFs( const char *pFullPath, const char *pSecondFullPath )
|
||||
{
|
||||
m_PreviewTexture.Init( pFullPath, "editor texture" );
|
||||
m_VTFName = pFullPath;
|
||||
m_SecondPreviewTexture.Init( pSecondFullPath, "editor texture" );
|
||||
m_SecondVTFName = pSecondFullPath;
|
||||
|
||||
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
|
||||
if ( m_PreviewTexture->IsCubeMap() )
|
||||
{
|
||||
pVMTKeyValues->SetString( "$envmap", pFullPath );
|
||||
}
|
||||
else if ( m_PreviewTexture->IsNormalMap() )
|
||||
{
|
||||
pVMTKeyValues->SetString( "$bumpmap", pFullPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
pVMTKeyValues->SetString( "$basetexture", pFullPath );
|
||||
}
|
||||
|
||||
pVMTKeyValues->SetString( "$detail", pSecondFullPath );
|
||||
pVMTKeyValues->SetInt( "$detailscale", 1 );
|
||||
pVMTKeyValues->SetInt( "$detailblendmode", 1 ); // additive
|
||||
|
||||
pVMTKeyValues->SetInt( "$nocull", 1 );
|
||||
pVMTKeyValues->SetInt( "$nodebug", 1 );
|
||||
m_PreviewMaterial.Init( MaterialSystem()->CreateMaterial( pFullPath, pVMTKeyValues ));
|
||||
|
||||
MatSystemSurface()->DrawSetTextureMaterial( m_nTextureID, m_PreviewMaterial );
|
||||
|
||||
// Reset the camera direction
|
||||
m_vecCameraDirection.Init( 1.0f, 0.0f, 0.0f );
|
||||
m_flLastRotationTime = Plat_FloatTime();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the current VTF
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CVTFPreviewPanel::GetVTF() const
|
||||
{
|
||||
return m_VTFName;
|
||||
}
|
||||
|
||||
const char *CVTFPreviewPanel::GetSecondVTF() const
|
||||
{
|
||||
return m_SecondVTFName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw a sphere
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::RenderSphere( const Vector &vCenter, float flRadius, int nTheta, int nPhi )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
|
||||
int nVertices = nTheta * nPhi;
|
||||
int nIndices = 2 * ( nTheta + 1 ) * ( nPhi - 1 );
|
||||
|
||||
pRenderContext->FogMode( MATERIAL_FOG_NONE );
|
||||
pRenderContext->SetNumBoneWeights( 0 );
|
||||
pRenderContext->Bind( m_PreviewMaterial );
|
||||
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, nVertices, nIndices );
|
||||
|
||||
//
|
||||
// Build the index buffer.
|
||||
//
|
||||
int i, j;
|
||||
for ( i = 0; i < nPhi; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
float u = j / ( float )(nTheta - 1);
|
||||
float v = i / ( float )(nPhi - 1);
|
||||
float theta = ( j != nTheta-1 ) ? 2.0f * M_PI * u : 0.0f;
|
||||
float phi = M_PI * v;
|
||||
|
||||
Vector vecPos;
|
||||
vecPos.x = flRadius * sin(phi) * cos(theta);
|
||||
vecPos.y = flRadius * cos(phi);
|
||||
vecPos.z = -flRadius * sin(phi) * sin(theta);
|
||||
|
||||
Vector vecNormal = vecPos;
|
||||
VectorNormalize( vecNormal );
|
||||
|
||||
Vector4D vecTangentS;
|
||||
Vector vecTangentT;
|
||||
vecTangentS.Init( vecPos.z, -vecPos.x, 0.0f, 1.0f );
|
||||
if ( VectorNormalize( vecTangentS.AsVector3D() ) == 0.0f )
|
||||
{
|
||||
vecTangentS.Init( 1.0f, 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
CrossProduct( vecNormal, vecTangentS.AsVector3D(), vecTangentT );
|
||||
|
||||
unsigned char red = (int)( u * 255.0f );
|
||||
unsigned char green = (int)( v * 255.0f );
|
||||
unsigned char blue = (int)( v * 255.0f );
|
||||
unsigned char alpha = (int)( v * 255.0f );
|
||||
|
||||
vecPos += vCenter;
|
||||
|
||||
float u1, u2, v1, v2;
|
||||
u1 = u2 = u;
|
||||
v1 = v2 = v;
|
||||
|
||||
meshBuilder.Position3fv( vecPos.Base() );
|
||||
meshBuilder.Normal3fv( vecNormal.Base() );
|
||||
meshBuilder.Color4ub( red, green, blue, alpha );
|
||||
meshBuilder.TexCoord2f( 0, u, v );
|
||||
meshBuilder.TexCoord2f( 1, u1, v1 );
|
||||
meshBuilder.TexCoord2f( 2, u2, v2 );
|
||||
meshBuilder.TangentS3fv( vecTangentS.Base() );
|
||||
meshBuilder.TangentT3fv( vecTangentT.Base() );
|
||||
meshBuilder.BoneWeight( 0, 1.0f );
|
||||
meshBuilder.BoneMatrix( 0, 0 );
|
||||
meshBuilder.UserData( vecTangentS.Base() );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Emit the triangle strips.
|
||||
//
|
||||
int idx = 0;
|
||||
for ( i = 0; i < nPhi - 1; ++i )
|
||||
{
|
||||
for ( j = 0; j < nTheta; ++j )
|
||||
{
|
||||
idx = nTheta * i + j;
|
||||
|
||||
meshBuilder.FastIndex( idx );
|
||||
meshBuilder.FastIndex( idx + nTheta );
|
||||
}
|
||||
|
||||
//
|
||||
// Emit a degenerate triangle to skip to the next row without
|
||||
// a connecting triangle.
|
||||
//
|
||||
if ( i < nPhi - 2 )
|
||||
{
|
||||
meshBuilder.FastIndex( idx + 1 );
|
||||
meshBuilder.FastIndex( idx + 1 + nTheta );
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a regular texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::PaintStandardTexture( void )
|
||||
{
|
||||
int x, y, w, h;
|
||||
x = y = 0;
|
||||
GetSize( w, h );
|
||||
vgui::surface()->DrawSetTexture( m_nTextureID );
|
||||
vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
|
||||
|
||||
// Get the aspect ratio of the texture
|
||||
int tw = m_PreviewTexture->GetActualWidth();
|
||||
int th = m_PreviewTexture->GetActualHeight();
|
||||
|
||||
if ( th > 0 && h > 0 )
|
||||
{
|
||||
float screenaspect = (float)tw / (float)th;
|
||||
float aspect = (float)w / (float)h;
|
||||
|
||||
float ratio = screenaspect / aspect;
|
||||
|
||||
// Screen is wider, need bars at top and bottom
|
||||
if ( ratio > 1.0f )
|
||||
{
|
||||
int usetall = (float)w / screenaspect;
|
||||
y = ( h - usetall ) / 2;
|
||||
h = usetall;
|
||||
}
|
||||
// Screen is narrower, need bars at left/right
|
||||
else
|
||||
{
|
||||
int usewide = (float)h * screenaspect;
|
||||
x = ( w - usewide ) / 2;
|
||||
w = usewide;
|
||||
}
|
||||
}
|
||||
|
||||
vgui::surface()->DrawTexturedRect( x, y, x+w, y+h );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a normalmap texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::PaintNormalMapTexture( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a volume texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::PaintVolumeTexture( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints a cubemap texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::PaintCubeTexture( void )
|
||||
{
|
||||
float flNewTime = Plat_FloatTime();
|
||||
|
||||
// Circle the camera around the origin
|
||||
VMatrix rot;
|
||||
MatrixBuildRotateZ( rot, ROTATION_SPEED * (flNewTime - m_flLastRotationTime ) );
|
||||
Vector vecTemp;
|
||||
Vector3DMultiply( rot, m_vecCameraDirection, vecTemp );
|
||||
m_vecCameraDirection = vecTemp;
|
||||
m_flLastRotationTime = flNewTime;
|
||||
|
||||
LookAt( vec3_origin, 12.0f );
|
||||
|
||||
// Draw a sphere at the origin
|
||||
RenderSphere( vec3_origin, 10.0f, 20, 20 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the camera to look at the the thing we're spinning around
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::LookAt( const Vector &vecLookAt, float flRadius )
|
||||
{
|
||||
// Compute the distance to the camera for the object based on its
|
||||
// radius and fov.
|
||||
|
||||
// since tan( fov/2 ) = f/d
|
||||
// cos( fov/2 ) = r / r' where r = sphere radius, r' = perp distance from sphere center to max extent of camera
|
||||
// d/f = r'/d' where d' is distance of camera to sphere
|
||||
// d' = r' / tan( fov/2 ) * r' = r / ( cos (fov/2) * tan( fov/2 ) ) = r / sin( fov/2 )
|
||||
float flFOVx = FOV;
|
||||
|
||||
// Compute fov/2 in radians
|
||||
flFOVx *= M_PI / 360.0f;
|
||||
|
||||
// Compute an effective fov based on the aspect ratio
|
||||
// if the height is smaller than the width
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
if ( h < w )
|
||||
{
|
||||
flFOVx = atan( h * tan( flFOVx ) / w );
|
||||
}
|
||||
|
||||
float flDistance = flRadius / sin( flFOVx );
|
||||
|
||||
Vector vecMDLOrigin = vecLookAt;
|
||||
Vector vecCameraOrigin;
|
||||
VectorMA( vecMDLOrigin, -flDistance, m_vecCameraDirection, vecCameraOrigin );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
QAngle angles;
|
||||
VectorAngles( m_vecCameraDirection, angles );
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
||||
pRenderContext->LoadIdentity();
|
||||
|
||||
// convert from a right handed system to a left handed system
|
||||
// since dx for wants it that way.
|
||||
// pRenderContext->Scale( 1.0f, 1.0f, -1.0f );
|
||||
|
||||
pRenderContext->Rotate( -90, 1, 0, 0 ); // put Z going up
|
||||
pRenderContext->Rotate( 90, 0, 0, 1 ); // put Z going up
|
||||
pRenderContext->Rotate( -angles[2], 1, 0, 0 );
|
||||
pRenderContext->Rotate( -angles[0], 0, 1, 0 );
|
||||
pRenderContext->Rotate( -angles[1], 0, 0, 1 );
|
||||
pRenderContext->Translate( -vecCameraOrigin[0], -vecCameraOrigin[1], -vecCameraOrigin[2] );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set up a projection matrix for a 90 degree fov
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::SetupProjectionMatrix( int nWidth, int nHeight )
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
VMatrix proj;
|
||||
float flFOV = FOV;
|
||||
float flZNear = ZNEAR;
|
||||
float flZFar = ZFAR;
|
||||
float flApsectRatio = (nHeight != 0.0f) ? (float)nWidth / (float)nHeight : 100.0f;
|
||||
|
||||
#if 1
|
||||
float halfWidth = tan( flFOV * M_PI / 360.0 );
|
||||
float halfHeight = halfWidth / flApsectRatio;
|
||||
#else
|
||||
float halfHeight = tan( flFOV * M_PI / 360.0 );
|
||||
float halfWidth = flApsectRatio * halfHeight;
|
||||
#endif
|
||||
memset( proj.Base(), 0, sizeof( proj ) );
|
||||
proj[0][0] = 1.0f / halfWidth;
|
||||
proj[1][1] = 1.0f / halfHeight;
|
||||
proj[2][2] = flZFar / ( flZNear - flZFar );
|
||||
proj[3][2] = -1.0f;
|
||||
proj[2][3] = flZNear * flZFar / ( flZNear - flZFar );
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->LoadMatrix( proj );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paints the texture
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVTFPreviewPanel::Paint( void )
|
||||
{
|
||||
if ( !m_PreviewTexture->IsCubeMap() && /*!m_PreviewTexture->IsNormalMap() &&*/ !m_PreviewTexture->IsVolumeTexture() )
|
||||
{
|
||||
PaintStandardTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
CMatRenderContextPtr pRenderContext( MaterialSystem() );
|
||||
int w, h;
|
||||
GetSize( w, h );
|
||||
vgui::MatSystemSurface()->Begin3DPaint( 0, 0, w, h );
|
||||
|
||||
pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
|
||||
pRenderContext->ClearBuffers( true, true );
|
||||
|
||||
SetupProjectionMatrix( w, h );
|
||||
|
||||
if ( m_PreviewTexture->IsCubeMap() )
|
||||
{
|
||||
PaintCubeTexture();
|
||||
}
|
||||
else if ( m_PreviewTexture->IsNormalMap() )
|
||||
{
|
||||
PaintNormalMapTexture();
|
||||
}
|
||||
else if ( m_PreviewTexture->IsVolumeTexture() )
|
||||
{
|
||||
PaintVolumeTexture();
|
||||
}
|
||||
|
||||
vgui::MatSystemSurface()->End3DPaint( );
|
||||
}
|
||||
Reference in New Issue
Block a user