This commit is contained in:
nephacks
2025-06-04 03:22:50 +02:00
parent f234f23848
commit f12416cffd
14243 changed files with 6446499 additions and 26 deletions

View 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;
}

View File

@@ -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:

View 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 );
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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 );
}
}
}

View 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") );
}

View 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 );
}

View 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
}
}

View 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"
}
}
}

View 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

View 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 );
}

View 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;
}

View 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();
}

File diff suppressed because it is too large Load Diff

View 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 );
}

File diff suppressed because it is too large Load Diff

View 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 );
}

File diff suppressed because it is too large Load Diff

View 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" );
}
}
}

View 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 );
}

View 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 );
}

View 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();
*/
}

View 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 );
}

View 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);
}

View File

@@ -0,0 +1,2 @@
SN Visual Studio Integration
IMPORTANT: Do not remove the custom build step for this file

View 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 );
}

View 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( );
}